forked from OSchip/llvm-project
[msan] Fix origin tracking in unaligned load/store.
llvm-svn: 195130
This commit is contained in:
parent
d1cd0be6f3
commit
bfb2016c83
|
@ -33,9 +33,14 @@ static THREADLOCAL int msan_expected_umr_found = 0;
|
|||
|
||||
static int msan_running_under_dr = 0;
|
||||
|
||||
// Function argument shadow. Each argument starts at the next available 8-byte
|
||||
// aligned address.
|
||||
SANITIZER_INTERFACE_ATTRIBUTE
|
||||
THREADLOCAL u64 __msan_param_tls[kMsanParamTlsSizeInWords];
|
||||
|
||||
// Function argument origin. Each argument starts at the same offset as the
|
||||
// corresponding shadow in (__msan_param_tls). Slightly weird, but changing this
|
||||
// would break compatibility with older prebuilt binaries.
|
||||
SANITIZER_INTERFACE_ATTRIBUTE
|
||||
THREADLOCAL u32 __msan_param_origin_tls[kMsanParamTlsSizeInWords];
|
||||
|
||||
|
@ -460,8 +465,8 @@ void __msan_set_origin(const void *a, uptr size, u32 origin) {
|
|||
uptr beg = x & ~3UL; // align down.
|
||||
uptr end = (x + size + 3) & ~3UL; // align up.
|
||||
u64 origin64 = ((u64)origin << 32) | origin;
|
||||
// This is like memset, but the value is 32-bit. We unroll by 2 two write
|
||||
// 64-bits at once. May want to unroll further to get 128-bit stores.
|
||||
// This is like memset, but the value is 32-bit. We unroll by 2 to write
|
||||
// 64 bits at once. May want to unroll further to get 128-bit stores.
|
||||
if (beg & 7ULL) {
|
||||
*(u32*)beg = origin;
|
||||
beg += 4;
|
||||
|
@ -521,37 +526,40 @@ u32 __msan_get_umr_origin() {
|
|||
u16 __sanitizer_unaligned_load16(const uu16 *p) {
|
||||
__msan_retval_tls[0] = *(uu16 *)MEM_TO_SHADOW((uptr)p);
|
||||
if (__msan_get_track_origins())
|
||||
__msan_retval_origin_tls = *(uu32 *)MEM_TO_ORIGIN((uptr)p);
|
||||
__msan_retval_origin_tls = *(uu32 *)(MEM_TO_ORIGIN((uptr)p) & ~3UL);
|
||||
return *p;
|
||||
}
|
||||
u32 __sanitizer_unaligned_load32(const uu32 *p) {
|
||||
__msan_retval_tls[0] = *(uu32 *)MEM_TO_SHADOW((uptr)p);
|
||||
if (__msan_get_track_origins())
|
||||
__msan_retval_origin_tls = *(uu32 *)MEM_TO_ORIGIN((uptr)p);
|
||||
__msan_retval_origin_tls = *(uu32 *)(MEM_TO_ORIGIN((uptr)p) & ~3UL);
|
||||
return *p;
|
||||
}
|
||||
u64 __sanitizer_unaligned_load64(const uu64 *p) {
|
||||
__msan_retval_tls[0] = *(uu64 *)MEM_TO_SHADOW((uptr)p);
|
||||
if (__msan_get_track_origins())
|
||||
__msan_retval_origin_tls = *(uu32 *)MEM_TO_ORIGIN((uptr)p);
|
||||
__msan_retval_origin_tls = *(uu32 *)(MEM_TO_ORIGIN((uptr)p) & ~3UL);
|
||||
return *p;
|
||||
}
|
||||
void __sanitizer_unaligned_store16(uu16 *p, u16 x) {
|
||||
*(uu16 *)MEM_TO_SHADOW((uptr)p) = __msan_param_tls[1];
|
||||
if (__msan_get_track_origins())
|
||||
*(uu32 *)MEM_TO_ORIGIN((uptr)p) = __msan_param_origin_tls[1];
|
||||
if (uu32 o = __msan_param_origin_tls[2])
|
||||
__msan_set_origin(p, 2, o);
|
||||
*p = x;
|
||||
}
|
||||
void __sanitizer_unaligned_store32(uu32 *p, u32 x) {
|
||||
*(uu32 *)MEM_TO_SHADOW((uptr)p) = __msan_param_tls[1];
|
||||
if (__msan_get_track_origins())
|
||||
*(uu32 *)MEM_TO_ORIGIN((uptr)p) = __msan_param_origin_tls[1];
|
||||
if (uu32 o = __msan_param_origin_tls[2])
|
||||
__msan_set_origin(p, 4, o);
|
||||
*p = x;
|
||||
}
|
||||
void __sanitizer_unaligned_store64(uu64 *p, u64 x) {
|
||||
*(uu64 *)MEM_TO_SHADOW((uptr)p) = __msan_param_tls[1];
|
||||
if (__msan_get_track_origins())
|
||||
*(uu32 *)MEM_TO_ORIGIN((uptr)p) = __msan_param_origin_tls[1];
|
||||
if (uu32 o = __msan_param_origin_tls[2])
|
||||
__msan_set_origin(p, 8, o);
|
||||
*p = x;
|
||||
}
|
||||
|
||||
|
|
|
@ -3085,79 +3085,91 @@ TEST(MemorySanitizer, VolatileBitfield) {
|
|||
|
||||
TEST(MemorySanitizer, UnalignedLoad) {
|
||||
char x[32];
|
||||
U4 origin = __LINE__;
|
||||
__msan_set_origin(&x, sizeof(x), origin);
|
||||
|
||||
memset(x + 8, 0, 16);
|
||||
EXPECT_POISONED(__sanitizer_unaligned_load16(x+6));
|
||||
EXPECT_POISONED(__sanitizer_unaligned_load16(x+7));
|
||||
EXPECT_POISONED_O(__sanitizer_unaligned_load16(x+6), origin);
|
||||
EXPECT_POISONED_O(__sanitizer_unaligned_load16(x+7), origin);
|
||||
EXPECT_NOT_POISONED(__sanitizer_unaligned_load16(x+8));
|
||||
EXPECT_NOT_POISONED(__sanitizer_unaligned_load16(x+9));
|
||||
EXPECT_NOT_POISONED(__sanitizer_unaligned_load16(x+22));
|
||||
EXPECT_POISONED(__sanitizer_unaligned_load16(x+23));
|
||||
EXPECT_POISONED(__sanitizer_unaligned_load16(x+24));
|
||||
EXPECT_POISONED_O(__sanitizer_unaligned_load16(x+23), origin);
|
||||
EXPECT_POISONED_O(__sanitizer_unaligned_load16(x+24), origin);
|
||||
|
||||
EXPECT_POISONED(__sanitizer_unaligned_load32(x+4));
|
||||
EXPECT_POISONED(__sanitizer_unaligned_load32(x+7));
|
||||
EXPECT_POISONED_O(__sanitizer_unaligned_load32(x+4), origin);
|
||||
EXPECT_POISONED_O(__sanitizer_unaligned_load32(x+7), origin);
|
||||
EXPECT_NOT_POISONED(__sanitizer_unaligned_load32(x+8));
|
||||
EXPECT_NOT_POISONED(__sanitizer_unaligned_load32(x+9));
|
||||
EXPECT_NOT_POISONED(__sanitizer_unaligned_load32(x+20));
|
||||
EXPECT_POISONED(__sanitizer_unaligned_load32(x+21));
|
||||
EXPECT_POISONED(__sanitizer_unaligned_load32(x+24));
|
||||
EXPECT_POISONED_O(__sanitizer_unaligned_load32(x+21), origin);
|
||||
EXPECT_POISONED_O(__sanitizer_unaligned_load32(x+24), origin);
|
||||
|
||||
EXPECT_POISONED(__sanitizer_unaligned_load64(x));
|
||||
EXPECT_POISONED(__sanitizer_unaligned_load64(x+1));
|
||||
EXPECT_POISONED(__sanitizer_unaligned_load64(x+7));
|
||||
EXPECT_POISONED_O(__sanitizer_unaligned_load64(x), origin);
|
||||
EXPECT_POISONED_O(__sanitizer_unaligned_load64(x+1), origin);
|
||||
EXPECT_POISONED_O(__sanitizer_unaligned_load64(x+7), origin);
|
||||
EXPECT_NOT_POISONED(__sanitizer_unaligned_load64(x+8));
|
||||
EXPECT_NOT_POISONED(__sanitizer_unaligned_load64(x+9));
|
||||
EXPECT_NOT_POISONED(__sanitizer_unaligned_load64(x+16));
|
||||
EXPECT_POISONED(__sanitizer_unaligned_load64(x+17));
|
||||
EXPECT_POISONED(__sanitizer_unaligned_load64(x+21));
|
||||
EXPECT_POISONED(__sanitizer_unaligned_load64(x+24));
|
||||
EXPECT_POISONED_O(__sanitizer_unaligned_load64(x+17), origin);
|
||||
EXPECT_POISONED_O(__sanitizer_unaligned_load64(x+21), origin);
|
||||
EXPECT_POISONED_O(__sanitizer_unaligned_load64(x+24), origin);
|
||||
}
|
||||
|
||||
TEST(MemorySanitizer, UnalignedStore16) {
|
||||
char x[5];
|
||||
U2 y = 0;
|
||||
__msan_poison(&y, 1);
|
||||
__sanitizer_unaligned_store16(x + 1, y);
|
||||
EXPECT_POISONED(x[0]);
|
||||
EXPECT_POISONED(x[1]);
|
||||
U2 y2 = 0;
|
||||
U4 origin = __LINE__;
|
||||
__msan_poison(&y2, 1);
|
||||
__msan_set_origin(&y2, 1, origin);
|
||||
|
||||
__sanitizer_unaligned_store16(x + 1, y2);
|
||||
EXPECT_POISONED_O(x[0], origin);
|
||||
EXPECT_POISONED_O(x[1], origin);
|
||||
EXPECT_NOT_POISONED(x[2]);
|
||||
EXPECT_POISONED(x[3]);
|
||||
EXPECT_POISONED(x[4]);
|
||||
EXPECT_POISONED_O(x[3], origin);
|
||||
EXPECT_POISONED_O(x[4], origin);
|
||||
}
|
||||
|
||||
TEST(MemorySanitizer, UnalignedStore32) {
|
||||
char x[8];
|
||||
U4 y4 = 0;
|
||||
U4 origin = __LINE__;
|
||||
__msan_poison(&y4, 2);
|
||||
__msan_set_origin(&y4, 2, origin);
|
||||
|
||||
__sanitizer_unaligned_store32(x+3, y4);
|
||||
EXPECT_POISONED(x[0]);
|
||||
EXPECT_POISONED(x[1]);
|
||||
EXPECT_POISONED(x[2]);
|
||||
EXPECT_POISONED(x[3]);
|
||||
EXPECT_POISONED(x[4]);
|
||||
EXPECT_POISONED_O(x[0], origin);
|
||||
EXPECT_POISONED_O(x[1], origin);
|
||||
EXPECT_POISONED_O(x[2], origin);
|
||||
EXPECT_POISONED_O(x[3], origin);
|
||||
EXPECT_POISONED_O(x[4], origin);
|
||||
EXPECT_NOT_POISONED(x[5]);
|
||||
EXPECT_NOT_POISONED(x[6]);
|
||||
EXPECT_POISONED(x[7]);
|
||||
EXPECT_POISONED_O(x[7], origin);
|
||||
}
|
||||
|
||||
TEST(MemorySanitizer, UnalignedStore64) {
|
||||
char x[16];
|
||||
U8 y = 0;
|
||||
__msan_poison(&y, 3);
|
||||
__msan_poison(((char *)&y) + sizeof(y) - 2, 1);
|
||||
__sanitizer_unaligned_store64(x+3, y);
|
||||
EXPECT_POISONED(x[0]);
|
||||
EXPECT_POISONED(x[1]);
|
||||
EXPECT_POISONED(x[2]);
|
||||
EXPECT_POISONED(x[3]);
|
||||
EXPECT_POISONED(x[4]);
|
||||
EXPECT_POISONED(x[5]);
|
||||
U8 y8 = 0;
|
||||
U4 origin = __LINE__;
|
||||
__msan_poison(&y8, 3);
|
||||
__msan_poison(((char *)&y8) + sizeof(y8) - 2, 1);
|
||||
__msan_set_origin(&y8, 8, origin);
|
||||
|
||||
__sanitizer_unaligned_store64(x+3, y8);
|
||||
EXPECT_POISONED_O(x[0], origin);
|
||||
EXPECT_POISONED_O(x[1], origin);
|
||||
EXPECT_POISONED_O(x[2], origin);
|
||||
EXPECT_POISONED_O(x[3], origin);
|
||||
EXPECT_POISONED_O(x[4], origin);
|
||||
EXPECT_POISONED_O(x[5], origin);
|
||||
EXPECT_NOT_POISONED(x[6]);
|
||||
EXPECT_NOT_POISONED(x[7]);
|
||||
EXPECT_NOT_POISONED(x[8]);
|
||||
EXPECT_POISONED(x[9]);
|
||||
EXPECT_POISONED_O(x[9], origin);
|
||||
EXPECT_NOT_POISONED(x[10]);
|
||||
EXPECT_POISONED(x[11]);
|
||||
EXPECT_POISONED_O(x[11], origin);
|
||||
}
|
||||
|
||||
TEST(MemorySanitizerDr, StoreInDSOTest) {
|
||||
|
|
Loading…
Reference in New Issue