This is an archive of the discontinued LLVM Phabricator instance.

[HWASan] Add __hwasan_init to .preinit_array.
ClosedPublic

Authored by morehouse on Jan 25 2022, 11:51 AM.

Details

Summary

Fixes segfaults on x86_64 caused by instrumented code running before
shadow is set up.

Diff Detail

Event Timeline

morehouse created this revision.Jan 25 2022, 11:51 AM
morehouse requested review of this revision.Jan 25 2022, 11:51 AM
Herald added a project: Restricted Project. · View Herald TranscriptJan 25 2022, 11:51 AM
Herald added a subscriber: Restricted Project. · View Herald Transcript

I'm concerned that this might break android by moving hwasan initialization before libc constructor, and there are things that you can not do that early, and these things are libc-specific.
Please test on Android. LLVM buildbot is insufficient because it does not cover the interesting case of non-interceptor (platform) build.

fmayer added a subscriber: fmayer.Jan 31 2022, 5:10 PM

I'm concerned that this might break android by moving hwasan initialization before libc constructor, and there are things that you can not do that early, and these things are libc-specific.
Please test on Android. LLVM buildbot is insufficient because it does not cover the interesting case of non-interceptor (platform) build.

I cherry picked this onto the Android LLVM toolchain, and built Android. It still boots and works okay.

Could you test with a fully static binary, too?

Could you test with a fully static binary, too?

I statically compiled a Hello World executable and it works.

This change does not handle the -shared-libsan case, and does not have any effect on Android other than in static executables. It also makes the comment in hwasan_preinit.cpp incorrect - that code is NOT linked into the main executable. I think we should replicate the "asan-preinit" driver logic for hwasan.

Note that ASan does not link the static preinit bit on Android. I believe that's a bug in the initial implementation of -shared-libsan - the code comment says "Do not link static runtime to DSOs or if compiling for Android", but that is clearly meant to refer to the full runtime library (because Android historically used shared runtime only) and not the preinit stub. See https://reviews.llvm.org/D3043.

This change does not handle the -shared-libsan case, and does not have any effect on Android other than in static executables. It also makes the comment in hwasan_preinit.cpp incorrect - that code is NOT linked into the main executable. I think we should replicate the "asan-preinit" driver logic for hwasan.

Note that ASan does not link the static preinit bit on Android. I believe that's a bug in the initial implementation of -shared-libsan - the code comment says "Do not link static runtime to DSOs or if compiling for Android", but that is clearly meant to refer to the full runtime library (because Android historically used shared runtime only) and not the preinit stub. See https://reviews.llvm.org/D3043.

I don't see any existing tests for HWASan + -shared-libsan. Is this a mode we really care about?

I can mimic the asan-preinit logic, but I'm not sure how to test it.

It is the mode that we use on Android, so yes. LLVM buildbot runs android tests with shared runtime library + interceptors, it should reproduce the issue.

morehouse updated this revision to Diff 405283.Feb 2 2022, 7:59 AM
  • In shared library mode, link preinit stub with every DSO.
Herald added a project: Restricted Project. · View Herald TranscriptFeb 2 2022, 7:59 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
eugenis added a subscriber: pcc.Feb 2 2022, 1:20 PM

LGTM, but I'd like @pcc to take a look.

pcc added a comment.Feb 2 2022, 1:45 PM

What guarantee do we have that the __hwasan_init .preinit_array entry will be placed before the user's .preinit_array entries?

clang/lib/Driver/ToolChains/CommonArgs.cpp
842

Shouldn't it be added to HelperStaticRuntimes? Otherwise I'm not sure how this would work because the library would need to be enclosed in --whole-archive in order to be included in the link.

compiler-rt/lib/hwasan/hwasan_preinit.cpp
23

Can it be static?

The driver seems to always add sanitizer runtimes first on the linker command line.

clang/lib/Driver/ToolChains/CommonArgs.cpp
842

Right, good point.

morehouse updated this revision to Diff 405435.Feb 2 2022, 1:59 PM
morehouse marked 3 inline comments as done.
  • Make __local_hwasan_preinit static.
  • Use HelperStaticRuntimes.
clang/lib/Driver/ToolChains/CommonArgs.cpp
842

Yes, good catch!

pcc added inline comments.Feb 2 2022, 2:02 PM
clang/lib/Driver/ToolChains/CommonArgs.cpp
842

Thanks. We'd better test on Android again because I imagine that the previous patch wouldn't have had any effect.

fmayer added inline comments.Feb 2 2022, 5:42 PM
clang/lib/Driver/ToolChains/CommonArgs.cpp
842

I patched the Android LLVM toolchain with this, build Android, it booted. Built static Hello World executable and it works.

pcc accepted this revision.Feb 3 2022, 1:05 PM

LGTM

This revision is now accepted and ready to land.Feb 3 2022, 1:05 PM
This revision was landed with ongoing or failed builds.Feb 3 2022, 1:08 PM
This revision was automatically updated to reflect the committed changes.