Using ASAN on C code called from other languages

Hi all,

I have haskell code that calls into C code and i'd like to compile the C
code with ASAN. I've managed to convince the build system to compile the
C code with '-fsanitize=address -g' (so that if I get a link errors of
the ASAN library isn't linked) and then also managed to link libasan,
but when my trivial test program with an obvious out-of-bounds access
run, I don't get the ASAN error I was expecting.

Is there some ASAN initialisation step that isn't happening?

Any clues appreciated.

Cheers,
Erik

I don’t know anything about haskell, but if you post a minimal reproducer here
we may be able to help.

–kcc

Kostya Serebryany wrote:

I don't know anything about haskell, but if you post a minimal reproducer
here
we *may* be able to help.

Its just so happens that I do have something here:

    https://github.com/erikd-ambiata/haskell-sanitize

The Readme should have all the information you need. Any problems,
please let mw know.

Cheers,
Erik

What does “ghc -Wall -Icsrc -optc “-fsanitize=address” -optc -g -lasan $+ -o $@” do?
I suspect it performs an optimized compilation (e.g. equivalent of clang’s -O2).
That would explain why you don’t see a bug report:
the .c code is too simple and the buggy access is optimized away. Take a look at the assembly:

0000000000405eba <dodgy_addition>:
405eba: 53 push %rbx
405ebb: 48 8d 1c 37 lea (%rdi,%rsi,1),%rbx
405ebf: 48 83 fb 0a cmp $0xa,%rbx
405ec3: 76 0a jbe 405ecf <dodgy_addition+0x15>
405ec5: bf 00 02 48 00 mov $0x480200,%edi
405eca: e8 f1 cc ff ff callq 402bc0 puts@plt
405ecf: 48 89 d8 mov %rbx,%rax
405ed2: 5b pop %rbx
405ed3: c3 retq

Now, if I insert enough printfs to convince the compiler to keep the buggy access, it’s still hard for asan to find it,
because you dereference an element # 2065 of an array of ten elements.
This simply goes too far from bounds (remember: asan relies on redzones to catch buffer overflows).

If I modify the code like this:

printf(“ZZZ %p %zd\n”, array, sum % 11);
array [sum- 2055] = sum ;

I get a nice

==35617== ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffeccdd9b00 at pc 0x405fcd bp 0x7ffeccdd9a80 sp 0x7ffeccdd9a78
WRITE of size 8 at 0x7ffeccdd9b00 thread T0

–kcc

Thanks for looking at this.

What does "ghc -Wall -Icsrc -optc "-fsanitize=address" -optc -g -lasan $+
-o $@" do?

   -Wall : turns on all warnings
   -Icsrc : is passed on the the C compiler
   -optc "-fsanitize=address"
                 : Passes -fsanitize=address to the C compiler
   -optc -g : Passes -g to the compiler
   -lsan : is passed on the the linker (also the C compiler).

I suspect it performs an optimized compilation (e.g. equivalent of clang's
-O2).
That would explain why you don't see a bug report:
the .c code is too simple and the buggy access is optimized away. Take a
look at the assembly:

Ah, I didn't think of doing that.

Now, if I insert enough printfs to convince the compiler to keep the buggy
access, it's still hard for asan to find it,
because you dereference an element # 2065 of an array of ten elements.
This simply goes too far from bounds (remember: asan relies on redzones to
catch buffer overflows).

If I modify the code like this:
        printf("ZZZ %p %zd\n", array, sum % 11);
        array [sum- 2055] = sum ;

I get a nice
==35617== ERROR: AddressSanitizer: stack-buffer-overflow on address
0x7ffeccdd9b00 at pc 0x405fcd bp 0x7ffeccdd9a80 sp 0x7ffeccdd9a78
WRITE of size 8 at 0x7ffeccdd9b00 thread T0

I can get that too now.

It seems that in trying to produce a minimal test case I out-smarted
myself. I will now build the test case up towards my real problem.

Thanks for your help Kostya!

Cheers,
Erik