If user thread is in the allocator, the allocator
may have no pointer into future user's part of
the allocated block. AddrIsInside ignores such
pointers and lsan reports a false memory leak.
Details
- Reviewers
morehouse kcc eugenis - Commits
- rG9d01612db48f: [Asan] Fix false leak report
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
compiler-rt/lib/asan/asan_allocator.cpp | ||
---|---|---|
1120–1125 |
compiler-rt/lib/asan/asan_allocator.cpp | ||
---|---|---|
1121 | Removing this check seems to introduce some LSan false negatives. Ran into it while playing with libFuzzer: $ bin/clang++ -fsanitize=address,fuzzer ../compiler-rt/test/fuzzer/LeakTest.cpp -m32 -g $ rm -rf corpus && mkdir corpus $ ./a.out -runs=100000 -detect_leaks=1 -entropic=1 -seed=1 corpus/ libFuzzer finds an input H that triggers a leak, but LSan doesn't detect it. Only happens after this patch, and only with -m32. Still trying to figure out why this check is needed... |
compiler-rt/lib/asan/asan_allocator.cpp | ||
---|---|---|
1121 | Presumably we have some internal pointer to the ASanChunk header that is causing the allocation to be marked reachable. |
thanks
compiler-rt/lib/asan/asan_allocator.cpp | ||
---|---|---|
1121 | I don't know what to do about this. |
compiler-rt/lib/asan/asan_allocator.cpp | ||
---|---|---|
1121 | Shouldn't the acquire-load above be enough to guarantee that we've stored a pointer to the user allocation either on stack or in a register, since we store-release in Allocate()? |
compiler-rt/lib/asan/asan_allocator.cpp | ||
---|---|---|
1121 | I think not, memory order only requires that we return same as user_beg calculated before atomic operation. |
compiler-rt/lib/asan/asan_allocator.cpp | ||
---|---|---|
1121 | Can we force the guarantee, for example by storing to a volatile stack variable before store-releasing? If we can, then the LSan false positive this patch fixed shouldn't come back if we add the AddrIsInside check back. |
compiler-rt/lib/asan/asan_allocator.cpp | ||
---|---|---|
1121 | Actually I tried that after landing the patch, and I still see the same bug on that binary. Either my way to pin pointer is too week, or I misdiagnosed the bug. I am trying to add more logs to confirm either way. However even if pinning pointer is possible we have case when we have small allocations without magic. There is a probability that the primary allocator returns CHUNK_ALLOCATED for uninitialized chunk. It's theoretical but I was able to catch that with CHECK(). I tried to solve that with that patch which always adds magic, the one which extends header from 16 to 24 D87359. |
compiler-rt/lib/asan/asan_allocator.cpp | ||
---|---|---|
1121 | Compiler puts pointer into FP registers. |
Removing this check seems to introduce some LSan false negatives. Ran into it while playing with libFuzzer:
libFuzzer finds an input H that triggers a leak, but LSan doesn't detect it. Only happens after this patch, and only with -m32.
Still trying to figure out why this check is needed...