Skip to content

Commit 2b7a2cb

Browse files
author
Julian Lettner
committed
[TSan][Darwin] Handle NULL argument in interceptor
Handle NULL address argument in the `mach_vm_[de]allocate()` interceptors and fix test: `Assignment 2` is not valid if we weren't able to re-allocate memory. rdar://67680613
1 parent b9496ef commit 2b7a2cb

File tree

2 files changed

+26
-21
lines changed

2 files changed

+26
-21
lines changed

compiler-rt/lib/tsan/rtl/tsan_interceptors_mach_vm.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,34 +19,35 @@
1919

2020
namespace __tsan {
2121

22-
static bool intersects_with_shadow(mach_vm_address_t *address,
22+
static bool intersects_with_shadow(mach_vm_address_t address,
2323
mach_vm_size_t size, int flags) {
2424
// VM_FLAGS_FIXED is 0x0, so we have to test for VM_FLAGS_ANYWHERE.
2525
if (flags & VM_FLAGS_ANYWHERE) return false;
26-
uptr ptr = *address;
27-
return !IsAppMem(ptr) || !IsAppMem(ptr + size - 1);
26+
return !IsAppMem(address) || !IsAppMem(address + size - 1);
2827
}
2928

3029
TSAN_INTERCEPTOR(kern_return_t, mach_vm_allocate, vm_map_t target,
3130
mach_vm_address_t *address, mach_vm_size_t size, int flags) {
3231
SCOPED_TSAN_INTERCEPTOR(mach_vm_allocate, target, address, size, flags);
3332
if (target != mach_task_self())
3433
return REAL(mach_vm_allocate)(target, address, size, flags);
35-
if (intersects_with_shadow(address, size, flags))
34+
if (address && intersects_with_shadow(*address, size, flags))
3635
return KERN_NO_SPACE;
37-
kern_return_t res = REAL(mach_vm_allocate)(target, address, size, flags);
38-
if (res == KERN_SUCCESS)
36+
kern_return_t kr = REAL(mach_vm_allocate)(target, address, size, flags);
37+
if (kr == KERN_SUCCESS)
3938
MemoryRangeImitateWriteOrResetRange(thr, pc, *address, size);
40-
return res;
39+
return kr;
4140
}
4241

4342
TSAN_INTERCEPTOR(kern_return_t, mach_vm_deallocate, vm_map_t target,
4443
mach_vm_address_t address, mach_vm_size_t size) {
4544
SCOPED_TSAN_INTERCEPTOR(mach_vm_deallocate, target, address, size);
4645
if (target != mach_task_self())
4746
return REAL(mach_vm_deallocate)(target, address, size);
48-
UnmapShadow(thr, address, size);
49-
return REAL(mach_vm_deallocate)(target, address, size);
47+
kern_return_t kr = REAL(mach_vm_deallocate)(target, address, size);
48+
if (kr == KERN_SUCCESS && address)
49+
UnmapShadow(thr, address, size);
50+
return kr;
5051
}
5152

5253
} // namespace __tsan

compiler-rt/test/tsan/Darwin/mach_vm_allocate.c

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,28 +13,28 @@
1313

1414
const mach_vm_size_t alloc_size = sizeof(int);
1515
static int *global_ptr;
16-
static bool realloc_success = false;
1716

1817
static int *alloc() {
1918
mach_vm_address_t addr;
20-
kern_return_t res =
19+
kern_return_t kr =
2120
mach_vm_allocate(mach_task_self(), &addr, alloc_size, VM_FLAGS_ANYWHERE);
22-
assert(res == KERN_SUCCESS);
21+
assert(kr == KERN_SUCCESS);
2322
return (int *)addr;
2423
}
2524

2625
static void alloc_fixed(int *ptr) {
2726
mach_vm_address_t addr = (mach_vm_address_t)ptr;
2827
// Re-allocation via VM_FLAGS_FIXED sporadically fails.
29-
kern_return_t res =
28+
kern_return_t kr =
3029
mach_vm_allocate(mach_task_self(), &addr, alloc_size, VM_FLAGS_FIXED);
31-
realloc_success = res == KERN_SUCCESS;
30+
if (kr != KERN_SUCCESS)
31+
global_ptr = NULL;
3232
}
3333

3434
static void dealloc(int *ptr) {
35-
kern_return_t res =
35+
kern_return_t kr =
3636
mach_vm_deallocate(mach_task_self(), (mach_vm_address_t)ptr, alloc_size);
37-
assert(res == KERN_SUCCESS);
37+
assert(kr == KERN_SUCCESS);
3838
}
3939

4040
static void *Thread(void *arg) {
@@ -53,26 +53,30 @@ static void *Thread(void *arg) {
5353
return NULL;
5454
}
5555

56-
static void try_realloc_on_same_address() {
56+
static bool try_realloc_on_same_address() {
5757
barrier_init(&barrier, 2);
5858
global_ptr = alloc();
5959
pthread_t t;
6060
pthread_create(&t, NULL, Thread, NULL);
6161

6262
barrier_wait(&barrier);
63-
*global_ptr = 8; // Assignment 2
63+
if (global_ptr)
64+
*global_ptr = 8; // Assignment 2
6465

6566
pthread_join(t, NULL);
6667
dealloc(global_ptr);
68+
69+
return global_ptr != NULL;
6770
}
6871

6972
int main(int argc, const char *argv[]) {
73+
bool success;
7074
for (int i = 0; i < 10; i++) {
71-
try_realloc_on_same_address();
72-
if (realloc_success) break;
75+
success = try_realloc_on_same_address();
76+
if (success) break;
7377
}
7478

75-
if (!realloc_success)
79+
if (!success)
7680
fprintf(stderr, "Unable to set up testing condition; silently pass test\n");
7781

7882
printf("Done.\n");

0 commit comments

Comments
 (0)