-
-
Notifications
You must be signed in to change notification settings - Fork 262
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add AddressSanitizer support to fibers.
- Loading branch information
1 parent
c62b760
commit d1b2321
Showing
6 changed files
with
97 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Submodule druntime
updated
3 files
+41 −0 | src/core/thread.d | |
+36 −0 | src/ldc/sanitizer_common.d | |
+84 −0 | src/ldc/sanitizers_optionally_linked.d |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// AddressSanitizer: Test stack overflow detection of an array on a fiber's local stack. | ||
|
||
// REQUIRES: ASan, RTSupportsSanitizers | ||
|
||
// RUN: %ldc -g -fsanitize=address %s -of=%t%exe && not %t%exe 2>&1 | FileCheck %s | ||
// RUN: %ldc -g -fsanitize=address %s -of=%t%exe -d-version=BAD_AFTER_YIELD && not %t%exe 2>&1 | FileCheck %s | ||
|
||
import core.thread; | ||
|
||
// Note: the ordering of `foo` and `prefoo` is intentional to ease FileCheck checking line numbers, | ||
// because of the order in which ASan reports the stack buffer overflow. | ||
|
||
void foo(int* ptr) | ||
{ | ||
version (BAD_AFTER_YIELD) | ||
Fiber.yield(); | ||
|
||
// CHECK: stack-buffer-overflow | ||
// CHECK: WRITE of size 4 | ||
// CHECK-NEXT: #0 {{.*}} in {{.*foo.*}} {{.*}}asan_fiber.d:[[@LINE+1]] | ||
ptr[10] = 1; | ||
|
||
} | ||
|
||
// CHECK-NOT: wild pointer | ||
// CHECK: Address {{.*}} is located in stack of | ||
// CHECK-NEXT: #0 {{.*}} in {{.*prefoo.*}} {{.*}}asan_fiber.d:[[@LINE+1]] | ||
void prefoo() | ||
{ | ||
int[10] a; | ||
foo(&a[0]); | ||
} | ||
|
||
void main() | ||
{ | ||
auto fib = new Fiber(&prefoo); | ||
fib.call(); | ||
version (BAD_AFTER_YIELD) | ||
fib.call(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// AddressSanitizer: Test stack overflow detection inside a fiber of an array on main's stack. | ||
|
||
// REQUIRES: ASan, RTSupportsSanitizers | ||
|
||
// RUN: %ldc -g -fsanitize=address %s -of=%t1%exe && not %t1%exe 2>&1 | FileCheck %s | ||
// RUN: %ldc -g -fsanitize=address %s -of=%t22%exe -d-version=BAD_AFTER_YIELD && not %t22%exe 2>&1 | FileCheck %s | ||
|
||
// Test with fake stack enabled | ||
// RUN: %ldc -g -fsanitize=address %s -of=%t333%exe | ||
// RUN: env ASAN_OPTIONS="detect_stack_use_after_return=true" %t333%exe 2>&1 | FileCheck %s --check-prefix=FAKESTACK | ||
// RUN: %ldc -g -fsanitize=address %s -of=%t4444%exe -d-version=BAD_AFTER_YIELD | ||
// RUN: env ASAN_OPTIONS="detect_stack_use_after_return=true" %t4444%exe 2>&1 | FileCheck %s --check-prefix=FAKESTACK | ||
|
||
import core.thread; | ||
|
||
void foo(int* arr) | ||
{ | ||
version (BAD_AFTER_YIELD) | ||
Fiber.yield(); | ||
|
||
// CHECK: stack-buffer-overflow | ||
// CHECK: WRITE of size 4 | ||
// CHECK-NEXT: #0 {{.*}} in {{.*foo.*}} {{.*}}asan_fiber_main.d:[[@LINE+1]] | ||
arr[10] = 1; // out-of-bounds write | ||
} | ||
|
||
// Without fake stack, ASan only keeps track of the current stack and thus reports | ||
// the bad memory location as a "wild pointer". | ||
// But with fake stack enabled we get something much better: | ||
// FAKESTACK: Address {{.*}} is located in stack of | ||
// FAKESTACK: #0 {{.*}} in {{.*main.*}} {{.*}}asan_fiber_main.d:[[@LINE+1]] | ||
void main() | ||
{ | ||
int[10] a; | ||
int b; | ||
|
||
// Use an extra variable instead of passing `&a[0]` directly to `foo`. | ||
// This is to keep `a` on the stack: `ptr` may be heap allocated because | ||
// it is used in the lambda (delegate). | ||
int* ptr = &a[0]; | ||
auto fib = new Fiber(() => foo(ptr)); | ||
fib.call(); | ||
version (BAD_AFTER_YIELD) | ||
fib.call(); | ||
} |