From f9b80ed7fb83fa585065cccadc8f033a9d566e74 Mon Sep 17 00:00:00 2001 From: Leonard Chan Date: Thu, 8 Dec 2022 19:29:28 +0000 Subject: [PATCH] [compiler-rt] Add opt-in -ftrivial-auto-var-init flag for writing over uninitialized stack variiables 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. Differential Revision: https://reviews.llvm.org/D135716 --- compiler-rt/CMakeLists.txt | 15 +++++++++++++++ compiler-rt/cmake/config-ix.cmake | 1 + 2 files changed, 16 insertions(+) diff --git a/compiler-rt/CMakeLists.txt b/compiler-rt/CMakeLists.txt index e43017d..eb643d6 100644 --- a/compiler-rt/CMakeLists.txt +++ b/compiler-rt/CMakeLists.txt @@ -498,6 +498,21 @@ append_list_if(COMPILER_RT_HAS_WD4800_FLAG /wd4800 SANITIZER_COMMON_CFLAGS) append_list_if(MINGW -fms-extensions SANITIZER_COMMON_CFLAGS) +# When lsan scans the stack for detecting reachable pointers, it's possible for +# a leaked pointer, which was pushed to the stack on an earlier function call, +# to still exist on the stack when doing a leak check if that part of the stack +# was not overwritten. In particular, if there's any uninitialized data in the +# lsan runtime, and the SP we start from is sufficiently deep into the runtime, +# then a leaked pointer could be marked as reachable. Such instances could be +# mitigated by clobbering any uninitialized data. Note that this won't cover +# all possible uninitialized stack contents, such as those used for register +# spill slots, unused portions for alignment, or even local variables not +# yet in scope at a certain point in the function. +# +# Note that this type of issue was discovered with lsan, but can apply to other +# sanitizers. +append_list_if(COMPILER_RT_HAS_TRIVIAL_AUTO_INIT -ftrivial-auto-var-init=pattern SANITIZER_COMMON_CFLAGS) + # Set common link flags. # TODO: We should consider using the same model as libc++, that is use either # -nostdlib++ and --unwindlib=none if supported, or -nodefaultlibs otherwise. diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake index 3f2d38c..39cd9e8 100644 --- a/compiler-rt/cmake/config-ix.cmake +++ b/compiler-rt/cmake/config-ix.cmake @@ -93,6 +93,7 @@ check_cxx_compiler_flag("-Werror -msse4.2" COMPILER_RT_HAS_MSSE4_2_FLAG) check_cxx_compiler_flag(--sysroot=. COMPILER_RT_HAS_SYSROOT_FLAG) check_cxx_compiler_flag("-Werror -mcrc" COMPILER_RT_HAS_MCRC_FLAG) check_cxx_compiler_flag(-fno-partial-inlining COMPILER_RT_HAS_FNO_PARTIAL_INLINING_FLAG) +check_cxx_compiler_flag(-Werror -ftrivial-auto-var-init=pattern COMPILER_RT_HAS_TRIVIAL_AUTO_INIT) if(NOT WIN32 AND NOT CYGWIN) # MinGW warns if -fvisibility-inlines-hidden is used. -- 2.7.4