This is an archive of the discontinued LLVM Phabricator instance.

[compiler-rt] Add opt-in -ftrivial-auto-var-init flag for writing over uninitialized stack variiables
ClosedPublic

Authored by leonardchan on Oct 11 2022, 2:53 PM.

Details

Summary

This might allow lsan to find more leaks that would have gone undetected. When lsan searches for leaked pointers on the stack, if a leaked pointer that was pushed to the stack in a prior function call would not be scrubbed on a future function call, then the scan will see the pointer on the stack and not mark it as leaked. Such holes can exist in the lsan runtime where there may be uninitialized data. Adding auto-var-init can scrub some of that data and might be able to catch more leaks that would've gone undetected this way.

See https://bugs.fuchsia.dev/p/fuchsia/issues/detail?id=111351 for more details.

Diff Detail

Event Timeline

leonardchan created this revision.Oct 11 2022, 2:53 PM
Herald added a project: Restricted Project. · View Herald TranscriptOct 11 2022, 2:53 PM
Herald added subscribers: Enna1, dberris. · View Herald Transcript
leonardchan requested review of this revision.Oct 11 2022, 2:53 PM
Herald added a project: Restricted Project. · View Herald TranscriptOct 11 2022, 2:53 PM
Herald added a subscriber: Restricted Project. · View Herald Transcript
mcgrathr added inline comments.
compiler-rt/lib/lsan/CMakeLists.txt
12

This should note that it won't cover all possible uninitialized stack contents, such as those used for register spill slots or unused portions for alignment, or even local variables not yet in scope at a certain point in the function.

I would prefer it's just externally provided CFLAG
or at most opt-in cmake flag

leonardchan marked an inline comment as done.
leonardchan retitled this revision from [WIP][compiler-rt][lsan] Add -ftrivial-auto-var-init=zero to lsan cflags to [compiler-rt][lsan] Add opt-in -ftrivial-auto-var-init flag for writing over uninitialized stack variiables.
leonardchan edited subscribers, added: dblaikie; removed: vitalybuka, mcgrathr.

BTW, would this one solve the problem D130237 this patch is trying to address?

BTW, would this one solve the problem D130237 this patch is trying to address?

It would solve it for many cases, but not necessarily all. As mentioned earlier, spill slots and unused alignment space (and perhaps even x86-64 red zone) might be left uninitialized and thus perhaps contain falsely-live pointer values.
D130237 is more thorough in one sense, because it minimizes the depth of stack that will be scanned somewhat. Thus anything deeper in the call stack than CheckForLeaks() is already immune and the auto-var-init there isn't helping anything.
However, CheckForLeaks() is called in a few places at various depths in different call stacks inside the runtime. So this may address some of the holes left by that, but not necessarily all.

The most thorough option would be for the SP at each top-level entry into the runtime code that can lead to the leak-check path to be captured at the outset and propagated down. Then the runtime would know that it's never scanning its own stack frames at all (aside from e.g. other threads suspended while in the lsan allocator code).

Bumping in case it missed:

I would prefer it's just externally provided CFLAG
or at most opt-in cmake flag

I am wondering, if don't make it default, why just don't provide external CFLAG into CMAKE when building runtime
But If we enable it by default, maybe do this for for sanitizer_common and everything that depends on it?

vitalybuka added inline comments.Oct 19 2022, 11:51 AM
compiler-rt/lib/lsan/CMakeLists.txt
21

from my experience, zero/patter perf difference is mostly noticeable on functions with large arrays on stack.
This is uncommon for compiler-rt, so maybe pattern only as additional uninitialized bug trigger?

Bumping in case it missed:

I would prefer it's just externally provided CFLAG
or at most opt-in cmake flag

I am wondering, if don't make it default, why just don't provide external CFLAG into CMAKE when building runtime
But If we enable it by default, maybe do this for for sanitizer_common and everything that depends on it?

I believe the initial idea behind this was it addresses an lsan-specific issue and should be limited to lsan, but if it can affect multiple sanitizers, then either of these suggestions works for me also.

vitalybuka added inline comments.Nov 17 2022, 5:24 PM
compiler-rt/lib/lsan/CMakeLists.txt
16–22

I don't see a reason to not enabled for the rest if it's available

vitalybuka requested changes to this revision.Dec 7 2022, 1:59 PM
This revision now requires changes to proceed.Dec 7 2022, 1:59 PM
leonardchan marked an inline comment as done.
leonardchan retitled this revision from [compiler-rt][lsan] Add opt-in -ftrivial-auto-var-init flag for writing over uninitialized stack variiables to [compiler-rt] Add opt-in -ftrivial-auto-var-init flag for writing over uninitialized stack variiables.
vitalybuka accepted this revision.Dec 7 2022, 4:43 PM
vitalybuka added inline comments.
compiler-rt/CMakeLists.txt
512 ↗(On Diff #481097)
514 ↗(On Diff #481097)

compiler-rt/cmake/config-ix.cmake needs to set COMPILER_RT_HAS_TRIVIAL_AUTO_INIT

This revision is now accepted and ready to land.Dec 7 2022, 4:43 PM
vitalybuka added inline comments.Dec 7 2022, 4:45 PM
compiler-rt/CMakeLists.txt
514 ↗(On Diff #481097)

check_cxx_compiler_flag(-Werror -ftrivial-auto-var-init=pattern COMPILER_RT_HAS_TRIVIAL_AUTO_INIT)

This revision was automatically updated to reflect the committed changes.
leonardchan marked 3 inline comments as done.

I just realized that this change may introduce unwanted memsets in compiler rt. It's still the problem even if =pattern is applied to the lsan only.

melver added a subscriber: melver.May 22 2023, 1:24 PM

I noticed -ftrivial-auto-var-init=pattern was added to default builds of compiler-rt, and am seeing that the tsan test for memcpy/set is failing.

I started sprinkling attribute((uninitialized)) in the places that introduce the memset to make the tsan test pass, but I don't think that's the right solution as it doesn't scale.

Are there any patches to solve this issue once and for all?