Tuesday, March 25, 2014

ASAN and libraries (2nd part)

In ASAN and libraries I claimed you didn't need to compile a library with -fsanitize=address to get ASAN to work over it. Well it turns out that is only true in some cases and in some others like the one in this example you actually need it. So here comes a different example and the differences of using -fsanitize=address and not in the library code.

shared.cpp
#include "shared.h"

Foo::Foo()
{
int a[1];
a[2] = 3;
}



shared.h
class Foo
{
public:
Foo();
};



main.cpp
#include "shared.h"

int main(int, char **)
{
Foo f;
return 0;
}

Let's see what happens if we do
export ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer-3.4
export ASAN_OPTIONS=symbolize=1
g++ -Wl,--no-undefined -shared -o libshared.so shared.cpp -g3
g++ -fno-omit-frame-pointer -fsanitize=address main.cpp -lshared -L . -g3
LD_LIBRARY_PATH=. ./a.out
As the suggested in the previous blog entry.

Nothing, no error detected.

But if we change to
export ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer-3.4
export ASAN_OPTIONS=symbolize=1
g++ -fno-omit-frame-pointer -fsanitize=address -Wl,--no-undefined \
    -shared -o libshared.so shared.cpp -g3 -lasan -fPIC
g++ -fno-omit-frame-pointer -fsanitize=address main.cpp -lshared -L . -g3
LD_LIBRARY_PATH=. ./a.out

==13069== ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fffe74fafa8
at pc 0x7fb0ef71f792 bp 0x7fffe74faf60 sp 0x7fffe74faf58
WRITE of size 4 at 0x7fffe74fafa8 thread T0
    #0 0x7fb0ef71f791 in Foo::Foo() /home/tsdgeos/test/shared.cpp:6
    #1 0x40074a in main /home/tsdgeos/test/main.cpp:5
    #2 0x7fb0ef37aec4 (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)
    #3 0x400638 in _start (/home/tsdgeos/test/a.out+0x400638)
Address 0x7fffe74fafa8 is located at offset 40 in frame <__base_ctor> of T0's stack:

Boom! We get the error :-) So my conclusion that ASAN wasn't needed on libraries was bad. You need it. Thanks Zecke for pointing me to my wrongness :-)

2 comments:

gamemank said...

Thanks for the clarification!
Do you need the -Wl,--no-undefined -lasan ?

Also, any luck with TSAN? I thought it would be similar to configure, but I haven't been able to compile with it using various combinations of flags on the library and the executable.

Albert Astals Cid said...

You don't *need* -Wl,--no-undefined -lasan but -Wl,--no-undefined is a very good practice in general to make sure you're linking to all the libs you need, so your build system should be already adding that flag. Of course you can just hack your build system to remove -Wl,--no-undefined instead of adding -lasan but i think it's probably easier adding -lasan.

About TSAN, i haven't tried using it at all.