Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[asan] Switch allocator to dynamic base address #98511

Merged
merged 2 commits into from
Aug 9, 2024

Conversation

thurstond
Copy link
Contributor

@thurstond thurstond commented Jul 11, 2024

This ports a fix from memprof (#98510), which has a shadow mapping that is similar to ASan (8 bytes of shadow memory per 64 bytes of app memory). This patch changes the allocator to dynamically choose a base address, as suggested by Vitaly for memprof. This simplifies ASan's #ifdef's and avoids potential conflict in the event that ASan were to switch to a dynamic shadow offset in the future [1].

[1] Since shadow memory is mapped before the allocator is mapped:

  • dynamic shadow and fixed allocator (old memprof): could fail if
    "unlucky" (e.g., https://lab.llvm.org/buildbot/#/builders/66/builds/1361/steps/17/logs/stdio)
  • dynamic shadow and dynamic allocator (HWASan; current memprof): always works
  • fixed shadow and fixed allocator (current ASan): always works, if
    constants are carefully chosen
  • fixed shadow and dynamic allocator (ASan with this patch): always works

This ports a proposed memprof fix (llvm#98510), which has a shadow memory and allocator layout that is similar to ASan. Although we have only observed the failure for memprof on a buildbot [*], it could theoretically happen for ASan.

asan_rtl.cpp calls InitializeShadowMemory() - which dynamically/"randomly" chooses a base address for the shadow mapping - prior to InitializeAllocator(). If we are unlucky, the shadow memory may be mapped in the same region where the allocator wants to be.

This patch fixes the issue by changing the allocator to dynamically choosing a base address, as suggested by Vitaly. For comparison, HWASan already dynamically chooses the base addresses for the shadow mapping and allocator.

[*] https://lab.llvm.org/buildbot/#/builders/66/builds/1361/steps/17/logs/stdio
@llvmbot
Copy link
Member

llvmbot commented Jul 11, 2024

@llvm/pr-subscribers-compiler-rt-sanitizer

Author: Thurston Dang (thurstond)

Changes

This ports a proposed memprof fix (#98510), which has a shadow memory and allocator layout that is similar to ASan. Although we have only observed the failure for memprof on a buildbot [*], it could theoretically happen for ASan.

asan_rtl.cpp calls InitializeShadowMemory() - which dynamically/"randomly" chooses a base address for the shadow mapping - prior to InitializeAllocator(). If we are unlucky, the shadow memory may be mapped in the same region where the allocator wants to be.

This patch fixes the issue by changing the allocator to dynamically choosing a base address, as suggested by Vitaly. For comparison, HWASan already dynamically chooses the base addresses for the shadow mapping and allocator.

[*] https://lab.llvm.org/buildbot/#/builders/66/builds/1361/steps/17/logs/stdio


Full diff: https://github.com/llvm/llvm-project/pull/98511.diff

1 Files Affected:

  • (modified) compiler-rt/lib/asan/asan_allocator.h (+1-1)
diff --git a/compiler-rt/lib/asan/asan_allocator.h b/compiler-rt/lib/asan/asan_allocator.h
index c3c4fae85b129..8fb113dd62f98 100644
--- a/compiler-rt/lib/asan/asan_allocator.h
+++ b/compiler-rt/lib/asan/asan_allocator.h
@@ -214,7 +214,7 @@ const uptr kAllocatorSpace = 0x600000000000ULL;
 const uptr kAllocatorSize  =  0x40000000000ULL;  // 4T.
 typedef DefaultSizeClassMap SizeClassMap;
 #  else
-const uptr kAllocatorSpace = 0x500000000000ULL;
+const uptr kAllocatorSpace = ~(uptr)0;
 const uptr kAllocatorSize = 0x40000000000ULL;  // 4T.
 typedef DefaultSizeClassMap SizeClassMap;
 #  endif

@@ -214,7 +214,7 @@ const uptr kAllocatorSpace = 0x600000000000ULL;
const uptr kAllocatorSize = 0x40000000000ULL; // 4T.
typedef DefaultSizeClassMap SizeClassMap;
# else
const uptr kAllocatorSpace = 0x500000000000ULL;
const uptr kAllocatorSpace = ~(uptr)0;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like all but Apple,

maybe include Apple, with apple reviewers, and move out constant from #ifdefs ?

Copy link
Contributor Author

@thurstond thurstond Jul 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jroelofs @wrotki Could you please take a look whether it would be ok to apply the dynamic allocator change to Apple as well? (b195873) Thanks!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ping @wrotki

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Late here - but it looks fine to me

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @wrotki!

@thurstond thurstond requested review from jroelofs and wrotki July 17, 2024 23:08
@thurstond thurstond merged commit 7ede1c4 into llvm:main Aug 9, 2024
6 checks passed
kutemeikito added a commit to kutemeikito/llvm-project that referenced this pull request Aug 10, 2024
* 'main' of https://github.com/llvm/llvm-project: (700 commits)
  [SandboxIR][NFC] SingleLLVMInstructionImpl class (llvm#102687)
  [ThinLTO]Clean up 'import-assume-unique-local' flag. (llvm#102424)
  [nsan] Make #include more conventional
  [SandboxIR][NFC] Use Tracker.emplaceIfTracking()
  [libc]  Moved range_reduction_double ifdef statement (llvm#102659)
  [libc] Fix CFP long double and add tests (llvm#102660)
  [TargetLowering] Handle vector types in expandFixedPointMul (llvm#102635)
  [compiler-rt][NFC] Replace environment variable with %t (llvm#102197)
  [UnitTests] Convert a test to use opaque pointers (llvm#102668)
  [CodeGen][NFCI] Don't re-implement parts of ASTContext::getIntWidth (llvm#101765)
  [SandboxIR] Clean up tracking code with the help of emplaceIfTracking() (llvm#102406)
  [mlir][bazel] remove extra blanks in mlir-tblgen test
  [NVPTX][NFC] Update tests to use bfloat type (llvm#101493)
  [mlir] Add support for parsing nested PassPipelineOptions (llvm#101118)
  [mlir][bazel] add missing td dependency in mlir-tblgen test
  [flang][cuda] Fix lib dependency
  [libc] Clean up remaining use of *_WIDTH macros in printf (llvm#102679)
  [flang][cuda] Convert cuf.alloc for box to fir.alloca in device context (llvm#102662)
  [SandboxIR] Implement the InsertElementInst class (llvm#102404)
  [libc] Fix use of cpp::numeric_limits<...>::digits (llvm#102674)
  [mlir][ODS] Verify type constraints in Types and Attributes (llvm#102326)
  [LTO] enable `ObjCARCContractPass` only on optimized build  (llvm#101114)
  [mlir][ODS] Consistent `cppType` / `cppClassName` usage (llvm#102657)
  [lldb] Move definition of SBSaveCoreOptions dtor out of header (llvm#102539)
  [libc] Use cpp::numeric_limits in preference to C23 <limits.h> macros (llvm#102665)
  [clang] Implement -fptrauth-auth-traps. (llvm#102417)
  [LLVM][rtsan] rtsan transform to preserve CFGAnalyses (llvm#102651)
  Revert "[AMDGPU] Move `AMDGPUAttributorPass` to full LTO post link stage (llvm#102086)"
  [RISCV][GISel] Add missing tests for G_CTLZ/CTTZ instruction selection. NFC
  Return available function types for BindingDecls. (llvm#102196)
  [clang] Wire -fptrauth-returns to "ptrauth-returns" fn attribute. (llvm#102416)
  [RISCV] Remove riscv-experimental-rv64-legal-i32. (llvm#102509)
  [RISCV] Move PseudoVSET(I)VLI expansion to use PseudoInstExpansion. (llvm#102496)
  [NVPTX] support switch statement with brx.idx (reland) (llvm#102550)
  [libc][newhdrgen]sorted function names in yaml (llvm#102544)
  [GlobalIsel] Combine G_ADD and G_SUB with constants (llvm#97771)
  Suppress spurious warnings due to R_RISCV_SET_ULEB128
  [scudo] Separated committed and decommitted entries. (llvm#101409)
  [MIPS] Fix missing ANDI optimization (llvm#97689)
  [Clang] Add env var for nvptx-arch/amdgpu-arch timeout (llvm#102521)
  [asan] Switch allocator to dynamic base address (llvm#98511)
  [AMDGPU] Move `AMDGPUAttributorPass` to full LTO post link stage (llvm#102086)
  [libc][math][c23] Add fadd{l,f128} C23 math functions (llvm#102531)
  [mlir][bazel] revert bazel rule change for DLTITransformOps
  [msan] Support vst{2,3,4}_lane instructions (llvm#101215)
  Revert "[MLIR][DLTI][Transform] Introduce transform.dlti.query (llvm#101561)"
  [X86] pr57673.ll - generate MIR test checks
  [mlir][vector][test] Split tests from vector-transfer-flatten.mlir (llvm#102584)
  [mlir][bazel] add bazel rule for DLTITransformOps
  OpenMPOpt: Remove dead include
  [IR] Add method to GlobalVariable to change type of initializer. (llvm#102553)
  [flang][cuda] Force default allocator in device code (llvm#102238)
  [llvm] Construct SmallVector<SDValue> with ArrayRef (NFC) (llvm#102578)
  [MLIR][DLTI][Transform] Introduce transform.dlti.query (llvm#101561)
  [AMDGPU][AsmParser][NFC] Remove a misleading comment. (llvm#102604)
  [Arm][AArch64][Clang] Respect function's branch protection attributes. (llvm#101978)
  [mlir] Verifier: steal bit to track seen instead of set. (llvm#102626)
  [Clang] Fix Handling of Init Capture with Parameter Packs in LambdaScopeForCallOperatorInstantiationRAII (llvm#100766)
  [X86] Convert truncsat clamping patterns to use SDPatternMatch. NFC.
  [gn] Give two scripts argparse.RawDescriptionHelpFormatter
  [bazel] Add missing dep for the SPIRVToLLVM target
  [Clang] Simplify specifying passes via -Xoffload-linker (llvm#102483)
  [bazel] Port for d45de80
  [SelectionDAG] Use unaligned store/load to move AVX registers onto stack for `insertelement` (llvm#82130)
  [Clang][OMPX] Add the code generation for multi-dim `num_teams` (llvm#101407)
  [ARM] Regenerate big-endian-vmov.ll. NFC
  [AMDGPU][AsmParser][NFCI] All NamedIntOperands to be of the i32 type. (llvm#102616)
  [libc][math][c23] Add totalorderl function. (llvm#102564)
  [mlir][spirv] Support `memref` in `convert-to-spirv` pass (llvm#102534)
  [MLIR][GPU-LLVM] Convert `gpu.func` to `llvm.func` (llvm#101664)
  Fix a unit test input file (llvm#102567)
  [llvm-readobj][COFF] Dump hybrid objects for ARM64X files. (llvm#102245)
  AMDGPU/NewPM: Port SIFixSGPRCopies to new pass manager (llvm#102614)
  [MemoryBuiltins] Simplify getCalledFunction() helper (NFC)
  [AArch64] Add invalid 1 x vscale costs for reductions and reduction-operations. (llvm#102105)
  [MemoryBuiltins] Handle allocator attributes on call-site
  LSV/test/AArch64: add missing lit.local.cfg; fix build (llvm#102607)
  Revert "Enable logf128 constant folding for hosts with 128bit floats (llvm#96287)"
  [RISCV] Add Syntacore SCR5 RV32/64 processors definition (llvm#102285)
  [InstCombine] Remove unnecessary RUN line from test (NFC)
  [flang][OpenMP] Handle multiple ranges in `num_teams` clause (llvm#102535)
  [mlir][vector] Add tests for scalable vectors in one-shot-bufferize.mlir (llvm#102361)
  [mlir][vector] Disable `vector.matrix_multiply` for scalable vectors (llvm#102573)
  [clang] Implement CWG2627 Bit-fields and narrowing conversions (llvm#78112)
  [NFC] Use references to avoid copying (llvm#99863)
  Revert "[mlir][ArmSME] Pattern to swap shape_cast(tranpose) with transpose(shape_cast) (llvm#100731)" (llvm#102457)
  [IRBuilder] Generate nuw GEPs for struct member accesses (llvm#99538)
  [bazel] Port for 9b06e25
  [CodeGen][NewPM] Improve start/stop pass error message CodeGenPassBuilder (llvm#102591)
  [AArch64] Implement TRBMPAM_EL1 system register (llvm#102485)
  [InstCombine] Fixing wrong select folding in vectors with undef elements (llvm#102244)
  [AArch64] Sink operands to fmuladd. (llvm#102297)
  LSV: document hang reported in llvm#37865 (llvm#102479)
  Enable logf128 constant folding for hosts with 128bit floats (llvm#96287)
  [RISCV][clang] Remove bfloat base type in non-zvfbfmin vcreate (llvm#102146)
  [RISCV][clang] Add missing `zvfbfmin` to `vget_v` intrinsic (llvm#102149)
  [mlir][vector] Add mask elimination transform (llvm#99314)
  [Clang][Interp] Fix display of syntactically-invalid note for member function calls (llvm#102170)
  [bazel] Port for 3fffa6d
  [DebugInfo][RemoveDIs] Use iterator-inserters in clang (llvm#102006)
  ...

Signed-off-by: Edwiin Kusuma Jaya <kutemeikito0905@gmail.com>
@zmodem
Copy link
Collaborator

zmodem commented Aug 19, 2024

We're seeing a test failure on Mac that started right around this change, see https://crbug.com/360160858#comment6 Does that make any sense to you?

 FAIL: LeakSanitizer-AddressSanitizer-x86_64 :: TestCases/Darwin/trampoline.mm (75525 of 80517)
 ******************** TEST 'LeakSanitizer-AddressSanitizer-x86_64 :: TestCases/Darwin/trampoline.mm' FAILED ********************
 Exit Code: 1
 
 Command Output (stdout):
 --
 
 =================================================================
 ==78889==ERROR: LeakSanitizer: detected memory leaks
 
 Direct leak of 64 byte(s) in 1 object(s) allocated from:
     #0 0x0001090c8287 in calloc+0x87 (libclang_rt.asan_osx_dynamic.dylib:x86_64+0x55287)
     #1 0x7ff803b8bd73 in _dispatch_continuation_alloc_from_heap+0x47 (libdispatch.dylib:x86_64+0x30d73)
     #2 0x7ff803b6ec88 in _dispatch_apply_with_attr_f+0x459 (libdispatch.dylib:x86_64+0x13c88)
     #3 0x7ff803b6eeae in dispatch_apply+0x2c (libdispatch.dylib:x86_64+0x13eae)
     #4 0x7ff803efb0f1 in __103-[CFPrefsSearchListSource synchronouslySendSystemMessage:andUserMessage:andDirectMessage:replyHandler:]_block_invoke.75+0x60 (CoreFoundation:x86_64h+0x19b0f1)
     #5 0x7ff803d931c2 in CFPREFERENCES_IS_WAITING_FOR_SYSTEM_AND_USER_CFPREFSDS+0x48 (CoreFoundation:x86_64h+0x331c2)
     #6 0x7ff803efa4bb in -[CFPrefsSearchListSource synchronouslySendSystemMessage:andUserMessage:andDirectMessage:replyHandler:]+0xb7 (CoreFoundation:x86_64h+0x19a4bb)
     #7 0x7ff803d91604 in -[CFPrefsSearchListSource alreadylocked_generationCountFromListOfSources:count:]+0xd9 (CoreFoundation:x86_64h+0x31604)
     #8 0x7ff803d9132d in -[CFPrefsSearchListSource alreadylocked_getDictionary:]+0x196 (CoreFoundation:x86_64h+0x3132d)
     #9 0x7ff803d90ed9 in -[CFPrefsSearchListSource alreadylocked_copyValueForKey:]+0x95 (CoreFoundation:x86_64h+0x30ed9)
     #10 0x7ff803d90e27 in -[CFPrefsSource copyValueForKey:]+0x2e (CoreFoundation:x86_64h+0x30e27)
     #11 0x7ff803d90ddf in __76-[_CFXPreferences copyAppValueForKey:identifier:container:configurationURL:]_block_invoke+0x1f (CoreFoundation:x86_64h+0x30ddf)
     #12 0x7ff803d89a39 in __108-[_CFXPreferences(SearchListAdditions) withSearchListForIdentifier:container:cloudConfigurationURL:perform:]_block_invoke+0x167 (CoreFoundation:x86_64h+0x29a39)
     #13 0x7ff803efb86f in -[_CFXPreferences withSearchListForIdentifier:container:cloudConfigurationURL:perform:]+0x15c (CoreFoundation:x86_64h+0x19b86f)
     #14 0x7ff803d89471 in -[_CFXPreferences copyAppValueForKey:identifier:container:configurationURL:]+0x7b (CoreFoundation:x86_64h+0x29471)
     #15 0x7ff803d893b7 in _CFPreferencesCopyAppValueWithContainerAndConfiguration+0x64 (CoreFoundation:x86_64h+0x293b7)
     #16 0x7ff803da157b in _CFPreferencesGetAppBooleanValueWithContainer+0x10 (CoreFoundation:x86_64h+0x4157b)
     #17 0x7ff804d37e6f in -[NSUserDefaults(NSUserDefaults) boolForKey:]+0x5f (Foundation:x86_64+0x8e6f)
     #18 0x7ff80740fff0 in NSViewDebugInitializeMetricsOverlayDebugging+0x3b (AppKit:x86_64+0xcff0)
     #19 0x7ff80740fdbf in +[NSView initialize]+0x3e (AppKit:x86_64+0xcdbf)
     #20 0x7ff80393322b in CALLING_SOME_+initialize_METHOD+0x10 (libobjc.A.dylib:x86_64h+0x822b)
     #21 0x7ff803932f6a in initializeNonMetaClass+0x1fe (libobjc.A.dylib:x86_64h+0x7f6a)
     #22 0x7ff803949434 in initializeAndMaybeRelock(objc_class*, objc_object*, locker_mixin<lockdebug::lock_mixin<objc_lock_base_t>>&, bool)+0xe6 (libobjc.A.dylib:x86_64h+0x1e434)
     #23 0x7ff803932aa9 in lookUpImpOrForward+0x312 (libobjc.A.dylib:x86_64h+0x7aa9)
     #24 0x7ff8039321da in _objc_msgSend_uncached+0x4a (libobjc.A.dylib:x86_64h+0x71da)
     #25 0x0001088fcd5a in main trampoline.mm:14
     #26 0x7ff803973365 in start+0x795 (dyld:x86_64+0xfffffffffff5c365)
 
 Objects leaked above:
 0x006109f038c0 (64 bytes)
 
 SUMMARY: AddressSanitizer: 64 byte(s) leaked in 1 allocation(s).
 
 --
 Command Output (stderr):
 --
 RUN: at line 5: /Volumes/Work/s/w/ir/cache/builder/src/third_party/llvm-build/Release+Asserts/./bin/clang  --driver-mode=g++ -O0  -arch x86_64 -stdlib=libc++ -mmacosx-version-min=10.12 -isysroot /Volumes/Work/s/w/ir/cache/osx_sdk/XCode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.4.sdk -mlinker-version=1053.12  -gline-tables-only -fsanitize=address -I/Volumes/Work/s/w/ir/cache/builder/src/third_party/llvm/compiler-rt/test/lsan/../ /Volumes/Work/s/w/ir/cache/builder/src/third_party/llvm/compiler-rt/test/lsan/TestCases/Darwin/trampoline.mm  -o /Volumes/Work/s/w/ir/cache/builder/src/third_party/llvm-build/Release+Asserts/runtimes/runtimes-bins/compiler-rt/test/lsan/X86_64AsanConfig/TestCases/Darwin/Output/trampoline.mm.tmp -framework Cocoa -fno-objc-arc
 + /Volumes/Work/s/w/ir/cache/builder/src/third_party/llvm-build/Release+Asserts/./bin/clang --driver-mode=g++ -O0 -arch x86_64 -stdlib=libc++ -mmacosx-version-min=10.12 -isysroot /Volumes/Work/s/w/ir/cache/osx_sdk/XCode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.4.sdk -mlinker-version=1053.12 -gline-tables-only -fsanitize=address -I/Volumes/Work/s/w/ir/cache/builder/src/third_party/llvm/compiler-rt/test/lsan/../ /Volumes/Work/s/w/ir/cache/builder/src/third_party/llvm/compiler-rt/test/lsan/TestCases/Darwin/trampoline.mm -o /Volumes/Work/s/w/ir/cache/builder/src/third_party/llvm-build/Release+Asserts/runtimes/runtimes-bins/compiler-rt/test/lsan/X86_64AsanConfig/TestCases/Darwin/Output/trampoline.mm.tmp -framework Cocoa -fno-objc-arc
 RUN: at line 6: env LSAN_OPTIONS=abort_on_error=0:log_to_syslog=0:detect_leaks=1:abort_on_error=0:log_to_syslog=0:"report_objects=1"  /Volumes/Work/s/w/ir/cache/builder/src/third_party/llvm-build/Release+Asserts/runtimes/runtimes-bins/compiler-rt/test/lsan/X86_64AsanConfig/TestCases/Darwin/Output/trampoline.mm.tmp 2>&1  && echo "" | FileCheck /Volumes/Work/s/w/ir/cache/builder/src/third_party/llvm/compiler-rt/test/lsan/TestCases/Darwin/trampoline.mm
 + env LSAN_OPTIONS=abort_on_error=0:log_to_syslog=0:detect_leaks=1:abort_on_error=0:log_to_syslog=0:report_objects=1 /Volumes/Work/s/w/ir/cache/builder/src/third_party/llvm-build/Release+Asserts/runtimes/runtimes-bins/compiler-rt/test/lsan/X86_64AsanConfig/TestCases/Darwin/Output/trampoline.mm.tmp
 
 --

thurstond added a commit to thurstond/llvm-project that referenced this pull request Aug 19, 2024
This partially reverts llvm#98511
- specifically, the SANITIZER_APPLE case - because of a suspected breakage for clang on Mac
(https://g-issues.chromium.org/issues/360160858).
@thurstond
Copy link
Contributor Author

We're seeing a test failure on Mac that started right around this change, see https://crbug.com/360160858#comment6 Does that make any sense to you?

Unfortunately I don't know enough about Mac to know if the leak is genuine, and I don't have a Mac to test whether reverting that change would fix the leak. Instead, I've put in a pull request to revert the Mac-portion of that change: #104818

thurstond added a commit that referenced this pull request Aug 19, 2024
This partially reverts #98511
- specifically, the SANITIZER_APPLE case - because of a suspected
breakage for clang on Mac
(https://g-issues.chromium.org/issues/360160858;
#98511 (comment)).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants