Commit 3f52e97
authored
Fix libFuzzer array alignment with empty modules (llvm#159661)
The following assertion was being triggered:
```
assert.h assertion failed at llvm-project/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp:237 in void fuzzer::TracePC::UpdateObservedPCs(): M.Size() == (size_t)(ModulePCTable[i].Stop - ModulePCTable[i].Start)
```
# The bug
When built with `-fsanitize=fuzzer`, each “module” (.so file, or the
binary itself) will be instrumented, and when loaded into the process
will make a call to these two functions:
- `__sanitizer_cov_8bit_counters_init`
- `__sanitizer_cov_pcs_init`
Each of these is called with start and end pointers defining an array.
In libFuzzer, these functions are implemented with
`HandleInline8bitCountersInit` and `HandlePCsInit`. Each of them pushes
back the provided pointers into a separate array, `Modules` and
`ModulePCTable` respectively. These arrays are meant to be kept in-sync;
index i into Modules should refer to the same `.so` as index i into
ModulePCTable. The assertion was triggering because these lists got
out-of-sync.
The problem is that the 8bit handler contains this line:
```
if (Start == Stop) return;
```
but the PC handler contains no such corresponding line. This meant that
if a module was ever instrumented but “empty” (its 8bit counter and PC
arrays were both of length 0), then its PC array would still be added
but its 8bit counter array would not.
# Why this issue was never seen before
The circumstances to trigger this issue are unusual:
- You need a compilation unit that doesn't contain any code (though it
may contain global variable declarations and similar). That doesn't
happen very often.
- That compilation unit must be dynamically linked, not statically
linked. If statically linked, it’ll be merged into a single “module”
with the main binary, and the arrays will be merged as well; you won’t
end up with length-0 arrays.
- To notice the issue, assertions must be enabled. If disabled,
libFuzzer will be buggy (it may have worse coverage), but it won't
crash, and "worse coverage" is extremely unlikely to be noticed.
# This change
This change solves the issue by adding the same `if (Start == Stop)
return;` check to `HandlePCsInit`. This prevents the arrays from getting
out-of-sync. This change also adds a test that identifies the previous
issue when compiled with assertions enabled, but now passes with the
fix.1 parent 725d9e8 commit 3f52e97
File tree
3 files changed
+70
-0
lines changed- compiler-rt
- lib/fuzzer
- test/fuzzer
3 files changed
+70
-0
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
69 | 69 | | |
70 | 70 | | |
71 | 71 | | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
72 | 75 | | |
73 | 76 | | |
74 | 77 | | |
| |||
| 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 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
0 commit comments