This is an archive of the discontinued LLVM Phabricator instance.

[sanitizer] Fix vfork interception on loongarch64
ClosedPublic

Authored by xry111 on Nov 1 2022, 6:44 AM.

Details

Summary

Fix a brown paper bag error made by me in D129418. I didn't set
ASAN_INTERCEPT_VFORK correctly for loongarch64, but created an all-zero
object for __interception::real_vfork. This caused anything calling
vfork() to die instantly.

Fix this issue by setting ASAN_INTERCEPT_VFORK and remove the bad
all-zero definition. Other ports have an all-zero common definition but
we don't need it at least for now.

And, enable ASAN vfork test for loongarch64 to prevent regression in the
future.

Diff Detail

Event Timeline

xry111 created this revision.Nov 1 2022, 6:44 AM
Herald added a project: Restricted Project. · View Herald TranscriptNov 1 2022, 6:44 AM
xry111 requested review of this revision.Nov 1 2022, 6:44 AM
Herald added a project: Restricted Project. · View Herald TranscriptNov 1 2022, 6:44 AM
xry111 added a comment.Nov 1 2022, 6:45 AM

@tangyouling I guess this will fix some test failures you've noticed.

Hmm, should I modify the diff to make git clang-format happy?

MaskRay accepted this revision.Nov 1 2022, 11:13 AM

If you can write down how to test this somewhere, then I can verify such changes if needed in the future.

This revision is now accepted and ready to land.Nov 1 2022, 11:13 AM
xry111 added a comment.EditedNov 1 2022, 6:37 PM

If you can write down how to test this somewhere, then I can verify such changes if needed in the future.

$ cat t.c
#include <unistd.h>
int main() { vfork(); }
$ gcc t.c -fsanitize=address
$ ./a.out
AddressSanitizer:DEADLYSIGNAL
=================================================================
==101489==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000000000000 bp 0x7ffffba56030 sp 0x7ffffba56020 T0)
==101489==Hint: pc points to the zero page.
==101489==The signal is caused by a UNKNOWN memory access.
==101489==Hint: address points to the zero page.
    #0 0x0  (<unknown module>)
    #1 0x7ffff20228a4 in __libc_start_call_main (/usr/lib/libc.so.6+0x368a4)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (<unknown module>) 
==101489==ABORTING

Using libasan from a new GCC build with this diff applied:

$ LD_LIBRARY_PATH=/home/xry111/git-repos/gcc-asan/loongarch64-unknown-linux-gnu/libsanitizer/asan/.libs ./a.out && echo 'ok'
ok

Strangely, GCC asan test does not cover vfork at all so I failed to notice this issue before. But building GCC with --with-build-config=bootstrap-asan can reveal it.

@tangyouling I guess this will fix some test failures you've noticed.

I'll apply it locally.
BTW, since la.local is not yet supported, I modified it locally as follows:

-        la.local  $a0, _ZN14__interception10real_vforkE
+        pcalau12i $a0, %pc_hi20(_ZN14__interception10real_vforkE)
+        addi.d    $a0, $a0, %pc_lo12(_ZN14__interception10real_vforkE)

So this can make compiler-rt/test/asan/TestCases/Linux/vfork.cpp pass on loongarch64?

If you can write down how to test this somewhere, then I can verify such changes if needed in the future.

$ cat t.c
#include <unistd.h>
int main() { vfork(); }
$ gcc t.c -fsanitize=address
$ ./a.out
AddressSanitizer:DEADLYSIGNAL
=================================================================
==101489==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000000000000 bp 0x7ffffba56030 sp 0x7ffffba56020 T0)
==101489==Hint: pc points to the zero page.
==101489==The signal is caused by a UNKNOWN memory access.
==101489==Hint: address points to the zero page.
    #0 0x0  (<unknown module>)
    #1 0x7ffff20228a4 in __libc_start_call_main (/usr/lib/libc.so.6+0x368a4)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (<unknown module>) 
==101489==ABORTING

Using libasan from a new GCC build with this diff applied:

$ LD_LIBRARY_PATH=/home/xry111/git-repos/gcc-asan/loongarch64-unknown-linux-gnu/libsanitizer/asan/.libs ./a.out && echo 'ok'
ok

Strangely, GCC asan test does not cover vfork at all so I failed to notice this issue before. But building GCC with --with-build-config=bootstrap-asan can reveal it.

Thanks but how to apply a patch to https://gcc.gnu.org/git/?p=gcc.git 's libasan is a step I missed...

xry111 added a comment.Nov 1 2022, 8:06 PM

Thanks but how to apply a patch to https://gcc.gnu.org/git/?p=gcc.git 's libasan is a step I missed...

cd /path/to/git-repos/gcc
patch -d libsanitizer -Np3 < /path/to/D137160.diff
xry111 added a comment.Nov 1 2022, 8:17 PM

So this can make compiler-rt/test/asan/TestCases/Linux/vfork.cpp pass on loongarch64?

The test case compiled and ran OK with patched GCC.

So this can make compiler-rt/test/asan/TestCases/Linux/vfork.cpp pass on loongarch64?

The test case compiled and ran OK with patched GCC.

Good! So do we need to enable this test on loongarch64? Currently it is:

// REQUIRES: aarch64-target-arch || x86_64-target-arch || i386-target-arch || arm-target-arch || riscv64-target-arch
xry111 updated this revision to Diff 472510.Nov 1 2022, 11:00 PM
xry111 edited the summary of this revision. (Show Details)

Enable ASAN vfork test for loongarch64.

SixWeining accepted this revision.Nov 1 2022, 11:51 PM

LGTM. Thanks.

xen0n accepted this revision.Nov 2 2022, 2:32 AM
This revision was landed with ongoing or failed builds.Nov 2 2022, 8:09 PM
This revision was automatically updated to reflect the committed changes.