Skip to content

Commit 2707880

Browse files
rmacnak-googlecommit-bot@chromium.org
authored andcommitted
[vm] Fix various UBSan failures.
Bug: #39427 Change-Id: I74e0eee623d88005fb2893d03e284a87daa09260 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/146696 Reviewed-by: Alexander Markov <[email protected]> Commit-Queue: Ryan Macnak <[email protected]>
1 parent 8c79102 commit 2707880

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+278
-151
lines changed

runtime/bin/file_android.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ int64_t File::LengthFromPath(Namespace* namespc, const char* name) {
484484
static void MillisecondsToTimespec(int64_t millis, struct timespec* t) {
485485
ASSERT(t != NULL);
486486
t->tv_sec = millis / kMillisecondsPerSecond;
487-
t->tv_nsec = (millis - (t->tv_sec * kMillisecondsPerSecond)) * 1000L;
487+
t->tv_nsec = (millis % kMillisecondsPerSecond) * 1000L;
488488
}
489489

490490
void File::Stat(Namespace* namespc, const char* name, int64_t* data) {

runtime/bin/file_fuchsia.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ static int64_t TimespecToMilliseconds(const struct timespec& t) {
480480
static void MillisecondsToTimespec(int64_t millis, struct timespec* t) {
481481
ASSERT(t != NULL);
482482
t->tv_sec = millis / kMillisecondsPerSecond;
483-
t->tv_nsec = (millis - (t->tv_sec * kMillisecondsPerSecond)) * 1000L;
483+
t->tv_nsec = (millis % kMillisecondsPerSecond) * 1000L;
484484
}
485485

486486
void File::Stat(Namespace* namespc, const char* name, int64_t* data) {

runtime/bin/file_linux.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@ static int64_t TimespecToMilliseconds(const struct timespec& t) {
489489
static void MillisecondsToTimespec(int64_t millis, struct timespec* t) {
490490
ASSERT(t != NULL);
491491
t->tv_sec = millis / kMillisecondsPerSecond;
492-
t->tv_nsec = (millis - (t->tv_sec * kMillisecondsPerSecond)) * 1000L;
492+
t->tv_nsec = (millis % kMillisecondsPerSecond) * 1000L;
493493
}
494494

495495
void File::Stat(Namespace* namespc, const char* name, int64_t* data) {

runtime/bin/hashmap_test.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,12 +123,12 @@ void TestSet(IntKeyHash hash, int size) {
123123
EXPECT_EQ(0u, set.occupancy());
124124

125125
// Insert a long series of values.
126-
const int start = 453;
127-
const int factor = 13;
128-
const int offset = 7;
126+
const uint32_t start = 453;
127+
const uint32_t factor = 13;
128+
const uint32_t offset = 7;
129129
const uint32_t n = size;
130130

131-
int x = start;
131+
uint32_t x = start;
132132
for (uint32_t i = 0; i < n; i++) {
133133
EXPECT_EQ(i, set.occupancy());
134134
set.Insert(x);

runtime/bin/process_test.cc

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@
66
#include <stdlib.h>
77
#include <string.h>
88

9+
#if defined(__GNUC__) || defined(__Clang__)
10+
__attribute__((no_sanitize("undefined")))
11+
#endif
12+
void Crash() {
13+
int* segfault = NULL;
14+
*segfault = 1;
15+
}
16+
917
/*
1018
* Run ./process_test <outstream> <echocount> <exitcode> <crash>
1119
* <outstream>: 0 = stdout, 1 = stderr, 2 = stdout and stderr
@@ -32,8 +40,7 @@ int main(int argc, char* argv[]) {
3240
int crash = atoi(argv[4]);
3341

3442
if (crash == 1) {
35-
int* segfault = NULL;
36-
*segfault = 1;
43+
Crash();
3744
}
3845

3946
const int kLineSize = 128;

runtime/lib/double.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ DEFINE_NATIVE_ENTRY(Double_hashCode, 0, 1) {
8989
if (FLAG_trace_intrinsified_natives) {
9090
OS::PrintErr("Double_hashCode %f\n", val);
9191
}
92-
if (val >= static_cast<double>(kMinInt64) &&
93-
val <= static_cast<double>(kMaxInt64)) {
92+
if ((val >= kMinInt64RepresentableAsDouble) &&
93+
(val <= kMaxInt64RepresentableAsDouble)) {
9494
int64_t ival = static_cast<int64_t>(val);
9595
if (static_cast<double>(ival) == val) {
9696
return Integer::New(ival);

runtime/platform/globals.h

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,8 @@ const int32_t kMaxInt32 = 0x7FFFFFFF;
459459
const uint32_t kMaxUint32 = 0xFFFFFFFF;
460460
const int64_t kMinInt64 = DART_INT64_C(0x8000000000000000);
461461
const int64_t kMaxInt64 = DART_INT64_C(0x7FFFFFFFFFFFFFFF);
462+
const int64_t kMinInt64RepresentableAsDouble = kMinInt64;
463+
const int64_t kMaxInt64RepresentableAsDouble = DART_INT64_C(0x7FFFFFFFFFFFFC00);
462464
const uint64_t kMaxUint64 = DART_2PART_UINT64_C(0xFFFFFFFF, FFFFFFFF);
463465
const int64_t kSignBitDouble = DART_INT64_C(0x8000000000000000);
464466

@@ -636,36 +638,6 @@ inline D bit_copy(const S& source) {
636638
return destination;
637639
}
638640

639-
#if defined(HOST_ARCH_ARM) || defined(HOST_ARCH_ARM64)
640-
// Similar to bit_copy and bit_cast, but does take the type from the argument.
641-
template <typename T>
642-
static inline T ReadUnaligned(const T* ptr) {
643-
T value;
644-
memcpy(reinterpret_cast<void*>(&value), reinterpret_cast<const void*>(ptr),
645-
sizeof(value));
646-
return value;
647-
}
648-
649-
// Similar to bit_copy and bit_cast, but does take the type from the argument.
650-
template <typename T>
651-
static inline void StoreUnaligned(T* ptr, T value) {
652-
memcpy(reinterpret_cast<void*>(ptr), reinterpret_cast<const void*>(&value),
653-
sizeof(value));
654-
}
655-
#else // !(HOST_ARCH_ARM || HOST_ARCH_ARM64)
656-
// Similar to bit_copy and bit_cast, but does take the type from the argument.
657-
template <typename T>
658-
static inline T ReadUnaligned(const T* ptr) {
659-
return *ptr;
660-
}
661-
662-
// Similar to bit_copy and bit_cast, but does take the type from the argument.
663-
template <typename T>
664-
static inline void StoreUnaligned(T* ptr, T value) {
665-
*ptr = value;
666-
}
667-
#endif // !(HOST_ARCH_ARM || HOST_ARCH_ARM64)
668-
669641
// On Windows the reentrent version of strtok is called
670642
// strtok_s. Unify on the posix name strtok_r.
671643
#if defined(HOST_OS_WINDOWS)

runtime/platform/growable_array.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,9 @@ class BaseGrowableArray : public B {
205205
template <typename T, typename B, typename Allocator>
206206
inline void BaseGrowableArray<T, B, Allocator>::Sort(int compare(const T*,
207207
const T*)) {
208+
// Avoid calling qsort with a null array.
209+
if (length_ == 0) return;
210+
208211
typedef int (*CompareFunction)(const void*, const void*);
209212
qsort(data_, length_, sizeof(T), reinterpret_cast<CompareFunction>(compare));
210213
}

runtime/platform/safe_stack.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
#ifndef RUNTIME_PLATFORM_SAFE_STACK_H_
66
#define RUNTIME_PLATFORM_SAFE_STACK_H_
77

8-
#include "platform/globals.h"
9-
108
#if defined(__has_feature)
119
#if __has_feature(safe_stack)
1210
#define USING_SAFE_STACK

runtime/platform/unaligned.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
#ifndef RUNTIME_PLATFORM_UNALIGNED_H_
6+
#define RUNTIME_PLATFORM_UNALIGNED_H_
7+
8+
#include "platform/globals.h"
9+
#include "platform/undefined_behavior_sanitizer.h"
10+
11+
namespace dart {
12+
13+
#if defined(HOST_ARCH_ARM) || defined(HOST_ARCH_ARM64)
14+
template <typename T>
15+
static inline T LoadUnaligned(const T* ptr) {
16+
T value;
17+
memcpy(reinterpret_cast<void*>(&value), reinterpret_cast<const void*>(ptr),
18+
sizeof(value));
19+
return value;
20+
}
21+
22+
template <typename T>
23+
static inline void StoreUnaligned(T* ptr, T value) {
24+
memcpy(reinterpret_cast<void*>(ptr), reinterpret_cast<const void*>(&value),
25+
sizeof(value));
26+
}
27+
#else // !(HOST_ARCH_ARM || HOST_ARCH_ARM64)
28+
template <typename T>
29+
NO_SANITIZE_UNDEFINED("alignment")
30+
static inline T LoadUnaligned(const T* ptr) {
31+
return *ptr;
32+
}
33+
34+
template <typename T>
35+
NO_SANITIZE_UNDEFINED("alignment")
36+
static inline void StoreUnaligned(T* ptr, T value) {
37+
*ptr = value;
38+
}
39+
#endif // !(HOST_ARCH_ARM || HOST_ARCH_ARM64)
40+
41+
} // namespace dart
42+
43+
#endif // RUNTIME_PLATFORM_UNALIGNED_H_

0 commit comments

Comments
 (0)