Nick Williams
Nick Williams

Reputation: 3188

How do I properly pre-load ASAN libraries on macOS with Java binary (JNI library) with SIP enabled

We have a large C++ library for which we have created Java bindings using SWIG (so a JNI shared library). We build for and run tests on many build platforms across macOS, Linux, and Windows; debug and opt; and ASAN.

We're having problems with ASAN + Java, specifically, on some macOS machines. For our regular C++ library and its tests, on all operating systems, we have no problems. We've sorted out all the compiler flags, linking flags, and runtime environment variables to make ASAN work properly.

But for the Java binding JNI library on macOS (only), things are different. When we load our ASAN-linked binding library and try to use it in Java on macOS, we get the following error and the Java process aborts:

==36055==ERROR: Interceptors are not working. This may be because AddressSanitizer is loaded too late (e.g. via dlopen). Please launch the executable with:
DYLD_INSERT_LIBRARIES=/path/to/libclang_rt.asan_osx_dynamic.dylib
"interceptors not installed" && 0

When we attempted the obvious—launching the Java process with DYLD_INSERT_LIBRARIES specified—it works on our local developer machines but not on our builders. Upon further investigation, we determined that our developer machines have SIP (System Integrity Protection) disabled while our builders have SIP enabled. Our Infra team informed us that disabling SIP is not an option, so we must make this work with SIP enabled.

What is the proper way to force Java to pre-load the ASAN library on SIP-enabled macOS systems to prevent this error?

Upvotes: 0

Views: 112

Answers (1)

Oo.oO
Oo.oO

Reputation: 13405

There are very little details in the original post how things are linked, how SWIG is used, but I have tried to reproduce it with pure JNI, and it worked.

Take a look at the sample code I have used for testing, here: link

If I do as advised (pass DYLD_INSERT_LIBRARIES) before calling Java it's working as expected. If I don't - the code fails.

My SIP is enabled

> csrutil status
System Integrity Protection status: enabled.

And that's the output of make test and make test_asan

> make test
/Library/Java/JavaVirtualMachines/jdk-11.0.13.jdk/Contents/Home/bin/java -Djava.library.path=:./lib -cp target recipeNo082.redux.HelloWorldASAN
==4717==ERROR: Interceptors are not working. This may be because AddressSanitizer is loaded too late (e.g. via dlopen). Please launch the executable with:
DYLD_INSERT_LIBRARIES=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/16/lib/darwin/libclang_rt.asan_osx_dynamic.dylib
"interceptors not installed" && 0
make: *** [test] Abort trap: 6

> make test_asan
DYLD_INSERT_LIBRARIES=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/16/lib/darwin/libclang_rt.asan_osx_dynamic.dylib  /Library/Java/JavaVirtualMachines/jdk-11.0.13.jdk/Contents/Home/bin/java -Djava.library.path=:./lib -cp target recipeNo082.redux.HelloWorldASAN
java(4725,0x7ff84ca4bb40) malloc: nano zone abandoned due to inability to reserve vm space.
library: :./lib
=================================================================
==4725==ERROR: AddressSanitizer: heap-use-after-free on address 0x607000011745 at pc 0x00012e3abead bp 0x70000a6bc9c0 sp 0x70000a6bc9b8
WRITE of size 1 at 0x607000011745 thread T2
    #0 0x12e3abeac in Java_recipeNo082_redux_HelloWorldASAN_displayMessage recipeNo082_redux_HelloWorldASAN.c:24

Upvotes: 0

Related Questions