This is an archive of the discontinued LLVM Phabricator instance.

[Driver] Default -fsanitize-address-globals-dead-stripping to true for ELF
ClosedPublic

Authored by MaskRay on Jun 9 2023, 7:39 PM.

Details

Summary

-fsanitize-address-globals-dead-stripping is the default for non-ELF
platforms. For ELF, we disabled it to work around an ancient gold 2.26
bug. However, some platforms (Fuchsia and PS) default the option to
true.

This patch changes -fsanitize-address-globals-dead-stripping to true for all ELF
platforms. Without specifying -fdata-sections (non-default for most ELF
platforms), asan_globals can only be GCed if the monolithic .data/.bss section
is GCed, which makes it less effective.
However, I think this simplified rule is better than making the
-fsanitize-address-globals-dead-stripping default dependent on another option.

Close https://github.com/llvm/llvm-project/issues/63127

Diff Detail

Event Timeline

MaskRay created this revision.Jun 9 2023, 7:39 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 9 2023, 7:39 PM
MaskRay requested review of this revision.Jun 9 2023, 7:39 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 9 2023, 7:39 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript
phosek accepted this revision.Jun 9 2023, 8:00 PM

LGTM

This revision is now accepted and ready to land.Jun 9 2023, 8:00 PM
rnk added a comment.Jun 12 2023, 2:24 PM

I think there's a fair bit more cleanup and simplification to be done, see asanUsesGlobalsGC and the comments there. We could check CGOpts.DataSections right there, for example, and rip out the whole cc1 option. Feel free to approach it incrementally, this makes sense to me policy wise.

MaskRay added a comment.EditedJun 12 2023, 2:31 PM

I think there's a fair bit more cleanup and simplification to be done, see asanUsesGlobalsGC and the comments there. We could check CGOpts.DataSections right there, for example, and rip out the whole cc1 option. Feel free to approach it incrementally, this makes sense to me policy wise.

Thanks for mentioning this piece of code. It seems that I forgot to update this comment in D120394 that allowed -fno-data-sections -fsanitize-address-globals-dead-stripping.

I have thought about not applying -fsanitize-address-globals-dead-stripping in -fno-data-sections mode, so that we won't have sections like .bss.a, but the driver complexity/cognitive load is high, so I think let's just simplify things and make -fsanitize-address-globals-dead-stripping default to true. (PS defaults to -fdata-sections, but Fuchsia doesn't.)

eugenis accepted this revision.Jun 12 2023, 2:32 PM

LGTM

This is long overdue, I think. Thank you!

rnk added a comment.Jun 13 2023, 3:55 PM

I have thought about not applying -fsanitize-address-globals-dead-stripping in -fno-data-sections mode, so that we won't have sections like .bss.a, but the driver complexity/cognitive load is high, so I think let's just simplify things and make -fsanitize-address-globals-dead-stripping default to true. (PS defaults to -fdata-sections, but Fuchsia doesn't.)

I'd like to get further simplifications by always emitting globals into the asan_globals section on ELF (whether the global data is sliced and associated or not) and always making the module ctor comdat, so there is only one initializer per DSO. I think there is cognitive overhead to the way that ELF objects only *sometimes* use the fancy comdat scheme if they provide a unique module signature, but fallback on the portable global registration scheme when a unique signature cannot be computed because all global symbols have local linkage. I'll look into sending a patch.

glandium added a subscriber: glandium.EditedJul 6 2023, 1:02 AM

In the realm of unintended consequences, this broke ODR violation detection when linking a rust static library with asan enabled because, while __asan_globals_registered is COMDAT in clang, for some reason, it's not in rust... So you end up with two asan.module_ctor that call __asan_register_elf_globals, each with their own __asan_globals_registered, but both using the same range of globals, so all globals are registered twice. (That's probably a bug in the rust compiler. I thought I'd mention this here in case someone follows the same path as I did. Edit: it is: https://github.com/rust-lang/rust/issues/113404)

rnk added a comment.Jul 12 2023, 1:34 PM

It sounds like two users have hit this now: Chromium and Rust folks. This is a flag flip, so it's pretty small and safe to rollback, and IMO we should consider that while we debug the underlying issue.

It sounds like two users have hit this now: Chromium and Rust folks.

s/Rust/Firefox/. And it looks like we're hitting it for the same reason: linking a static rust (LTOed) library with C++ code.

It sounds like two users have hit this now: Chromium and Rust folks. This is a flag flip, so it's pretty small and safe to rollback, and IMO we should consider that while we debug the underlying issue.

Chromium's https://crbug.com/1459233 is also a Rust issue. All the evidence so far has shown that there is some issue with Rust or how Chromium and Firefox mix C++ and Rust, probably due to a special use case of LTO+asan.
I don't find justification to revert this Clang Driver change.
Chromium's https://crbug.com/1459233 seems to suggest that it has its own compiler-rt ODR violation issue and should be fixed there. Adding -fno-sanitize-address-globals-dead-stripping can be quite good workaround.

If we do identify a good reason to revert, we will consider reverting, but a downstream language implementation or its user does unsupported things which worked well and now broke due to a changed clang driver default does not seem a strong enough justification.

I suspect there's another unintended consequence of this change with regards to broken ODR violation detection. I filed an issue and am connecting it here should someone find this review first.