This is an archive of the discontinued LLVM Phabricator instance.

[HWASan] Remove __libc_longjmp interceptor.
AbandonedPublic

Authored by morehouse on Sep 13 2021, 8:55 AM.

Details

Summary

On Linux __libc_longjmp is called from pthread_exit, and uses a
jmp_buf that was initialized by _setjmp called from
__libc_start_main. The _setjmp call does not use the PLT, so we
cannot intercept it.

The result is a mismatch in jmp_buf format, since _setjmp uses
glibc's format while our __libc_longjmp interceptor uses HWASan's
format. Removing the __libc_longjmp interceptor avoids the mismatch.

See discussion on https://reviews.llvm.org/D69045.

Fixes https://github.com/google/sanitizers/issues/1244.

Diff Detail

Event Timeline

morehouse requested review of this revision.Sep 13 2021, 8:55 AM
morehouse created this revision.
Herald added a project: Restricted Project. · View Herald TranscriptSep 13 2021, 8:55 AM
Herald added a subscriber: Restricted Project. · View Herald Transcript
morehouse edited the summary of this revision. (Show Details)Sep 13 2021, 8:56 AM
morehouse edited the summary of this revision. (Show Details)

From the discussion in D69045, I see that in older glibc versions setjmp in thread creation was intercepted, and we had to intercept this __libc_longjmp to match, but that is no longer the case. If there are no good solutions that work everywhere, then supporting 2.31+ is OK I guess (it's 1.5 years old by now). Could you see if we could detect hwasan vs libc jmpbuf format easily though, and forward to libc in the latter case?

Is there a test that is fixed by this change?

From the discussion in D69045, I see that in older glibc versions setjmp in thread creation was intercepted, and we had to intercept this __libc_longjmp to match, but that is no longer the case. If there are no good solutions that work everywhere, then supporting 2.31+ is OK I guess (it's 1.5 years old by now). Could you see if we could detect hwasan vs libc jmpbuf format easily though, and forward to libc in the latter case?

It is tricky. The hwasan jmpbuf must be no larger than the libc one, and they're currently the same size. So we can't add an extra magic field to distinguish them.

Maybe we could put a magic in the top byte of the saved PC? We never expect the PC to be tagged, right?

I can test this locally for x86. I don't have a great way to do it for aarch64, but I could push it and check the bots.

Is there a test that is fixed by this change?

Without this change the pthread_exit.c test fails locally with my x86 setjmp/longjmp patch.

Actually it looks like libc only uses int __mask_was_saved as a bool. So we could put a magic in the other 31 bits.