Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

LeakSanitizer fails based on stack layout #42557

Open Quuxplusone opened 5 years ago

Quuxplusone commented 5 years ago
Bugzilla Link PR43587
Status NEW
Importance P normal
Reported by Marvin Häuser (mhaeuser@outlook.de)
Reported on 2019-10-07 06:42:44 -0700
Last modified on 2019-10-10 02:49:28 -0700
Version 9.0
Hardware PC Linux
CC llvm-bugs@lists.llvm.org, mhaeuser@outlook.de, vit9696@avp.su, vitalybuka@google.com
Fixed by commit(s)
Attachments LeakBug.c (1317 bytes, text/plain)
Blocks
Blocked by
See also
Created attachment 22639
demonstration and further details

LeakSanitizer may fail to catch leaked memory based on stack layout.

While I did not perform any extensive research, I did verify that stack layout
is the only changing factor in my compiled binaries by disassembly comparison.
I did not verify whether the underlying issue can cause other problems than the
one described by this report.

Please find attached a C program with comments about the verified environments
and different ways to reproduce.
Quuxplusone commented 5 years ago

Attached LeakBug.c (1317 bytes, text/plain): demonstration and further details

Quuxplusone commented 5 years ago

I afraid it's work as intended.

LeakSanitizer scans stack for pointers. It's possible that old frame with dead pointers (main here) overlapped by new frame which does not use bytes with pointers. For leak sanitizer this looks like alive pointers in useful flame, so no leak.

To fix this we can clean stack on return, but it's going to hit performance.

Quuxplusone commented 5 years ago

Thank you very much for your explaination.

I won't pretend to know how LeakSan works, and especially not how it should work, but if I understood it correctly, it does solely by stack analysis. Is it too expensive to keep track of all mallocs? While that obviously does not allow tracing, it at least would give an indicator at termination that there is a leak at all.

Quuxplusone commented 5 years ago
LSAN tracks all mallocs.
But it must not report stuff which is not leak. E.g. pointer in global variable
is not considered a leak even on termination.

Maybe ignoring some pointers from main thread doing final leak-checking will
work.
Quuxplusone commented 5 years ago

While programs keeping allocations alive past the termination of the entry point is a valid concept, I think the majority expects to be purged entirely, especially when not release software itself is sanitized but specific function calls from unit test applications. Can the data segment be scanned in the way the stack is?

I'd imagine there could be 1) a compilation switch to toggle whitelisting all global pointers and/or 2) a way to explicitly flag whitelisted pointers (i.e. alarm on all dangling allocations not referenced by a whitelisted pointer when main terminates). I do not know about implementation difficulties, so please excuse me if this is not feasible.

For instance, in a project I am contributing to, we have small unit test applications that call library functions from the main project and are both fuzzed and sanitized simultaneously and are not supposed to leave anything alive after termination. It would be invaluable to us to be notified about all leaked memory.