Commit a0fb571
committed
[asan] Fix 'unknown-crash' reported for multi-byte errors
Given that a reported error by ASan spans multiple bytes, ASan may
flag the error as an 'unknown-crash' instead of the appropriate error
name.
This error can be reproduced via a partial buffer overflow (any GCC,
or after performing the patch in the previous commit to Clang).
They'll report 'unknown-crash' instead of 'stack-buffer-overflow'
for the below:
# minimal reprod
# https://godbolt.org/z/abrjrvnzj
#
# gcc -fsanitize=address reprod.c
struct X {
char bytes[16];
};
__attribute__((noinline)) struct X out_of_bounds() {
volatile char bytes[16];
struct X* x_ptr = (struct X*)(bytes + 2);
return *x_ptr;
}
int main() {
struct X x = out_of_bounds();
return x.bytes[0];
}
This is due to a flawed heuristic in asan_errors.cpp, which won't
always locate the appropriate shadow byte that would indicate a
corresponding error. This can happen for any reported errors which
span either: exactly 8 bytes, or 16 and more bytes.
This bug was previously hidden from Clang (but has always been present
in GCC) until the previous commit's fix on address reporting.
Specifically, ACCESS_MEMORY_RANGE in ASan previously reports the first
poisoned byte (instead of the start address, like in GCC). This masked
the above bug from occuring, as it coincidentally guarantees the
heuristic will always work, with slightly inaccurate reports.
This patch resolves this issue via a linear scan of applicable
shadow bytes (instead of the original heuristic, which, at best, only
increments the shadow byte address by 1 for these scenarios).1 parent a3fa001 commit a0fb571
File tree
2 files changed
+80
-2
lines changed- compiler-rt
- lib/asan
- test/asan/TestCases
2 files changed
+80
-2
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
437 | 437 | | |
438 | 438 | | |
439 | 439 | | |
440 | | - | |
441 | | - | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
442 | 450 | | |
443 | 451 | | |
444 | 452 | | |
| |||
Lines changed: 70 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
0 commit comments