Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Address Sanitizer on a python extension

I am trying to compile a python extension with Address Sanitizer. When I load the extension, I get

Traceback (most recent call last):
  File "test.py", line 2, in <module>
    from extension import package
  File "/tmp/python_test/extension/package.py", line 28, in <module>
    from extension._ext import *
ImportError: /tmp/python_test/extension/_ext.so: undefined symbol: __asan_version_mismatch_check_v8

The compiler invocation is

clang -g -o _ext.so code.ll -fsanitize=address -lrt -lpthread -ldl -lstdc++ -lm -fPIC -shared

So, it does not load symbols from asan correctly. I've tried using -static-libsan, but the result was the same.

I've seen that some people use LD_PRELOAD to get Asan into shared objects, however, it seems that the libasan.so on my system is from a different version of Address Sanitizer (Installed from Debian's libasan3 package, while I got clang from deb http://apt.llvm.org/stretch/ llvm-toolchain-stretch-8 main).

So, how can I make Address Sanitizer work with a shared object library? Either, I need the correct version of libasan.so (which does not seem to be in deb http://apt.llvm.org/stretch/ llvm-toolchain-stretch-8 main, or I need a way to have clang link that statically).

My clang version:

$ clang -v
clang version 8.0.0-svn356034-1~exp1~20190313094216.53 (branches/release_80)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/6
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/6.3.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/6
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/6.3.0
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/6.3.0
Candidate multilib: .;@m64
Selected multilib: .;@m64
like image 856
Alex Avatar asked Apr 15 '19 15:04

Alex


People also ask

How does address Sanitizer work?

AddressSanitizer dedicates one-eighth of the virtual address space to its shadow memory and uses a direct mapping with a scale and offset to translate an applica- tion address to its corresponding shadow address. Given the application memory address Addr, the address of the shadow byte is computed as (Addr>>3)+Offset.

What is address sanitizer in GCC?

Address Sanitizer is a tool developed by Google detect memory access error such as use-after-free and memory leaks. It is built into GCC versions >= 4.8 and can be used on both C and C++ codes.


1 Answers

To sanitize a single library (without sanitizing main python executable) with Clang you should

  • add -shared-libasan to LDFLAGS (Clang defaults to -static-libasan, unlike GCC)
  • run with LD_PRELOAD=$(clang -print-file-name=libclang_rt.asan-x86_64.so) (it should be somewhere with standard Clang libs)

(see AddressSanitizerAsDso wiki).

Another option is using GCC, in which case -shared-libasan is not needed and LD_PRELOAD value becomes libasan.so.N (N depends on GCC version, use $(gcc -print-file-name=libasan.so) to locate it).

For more details on differences between GCC and Clang with respect to sanitization of shlibs see this answer.

like image 176
yugr Avatar answered Oct 20 '22 16:10

yugr