https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68016

--- Comment #4 from Maxim Ostapenko <chefmax at gcc dot gnu.org> ---
Actualy, LLVM is not better here (perhaps even worse). Consider the following
testcase (it's the same Jakub provided in PR63888):

max@max:/tmp$ cat libfoo.c

long f = 4;
long foo (long *p) {
  return *p;
}

max@max:/tmp$ cat libbar.c

long h = 12;
long i = 13;

max@max:/tmp$ cat main.c

extern void abort (void);
extern long f;
extern long h;
extern long i;
long foo (long *);

int main () {
  if (foo (&f) != 4 || foo (&h) != 12 || foo (&i) != 13)
    abort ();
  return 0;
}


max@max:/tmp$ clang libfoo.c -shared -fpic -o libfoo.so -g
max@max:/tmp$ clang libbar.c -shared -fpic -o libbar.so -g
max@max:/tmp$ clang main.c -c -o main.o -g
max@max:/tmp$ clang  main.o ./libfoo.so ./libbar.so -o main -fsanitize=address
max@max:/tmp$ ./main
max@max:/tmp$ echo $?
0
max@max:/tmp$ clang libfoo.c -shared -fpic -o libfoo.so -g -fsanitize=address
max@max:/tmp$ ./main
./main: Symbol `f' has different size in shared object, consider re-linking
=================================================================
==19089==ERROR: AddressSanitizer: global-buffer-overflow on address
0x00000070fb10 at pc 0x7f0e0b65c931 bp 0x7ffc67828000 sp 0x7ffc67827ff8
READ of size 8 at 0x00000070fb10 thread T0
    #0 0x7f0e0b65c930 in foo /tmp/libfoo.c:2:29
    #1 0x4e166f in main /tmp/main.c:9:42
    #2 0x7f0e0a570ec4 in __libc_start_main
/build/buildd/eglibc-2.19/csu/libc-start.c:287
    #3 0x418fd5 in _start (/tmp/main+0x418fd5)

0x00000070fb10 is located 0 bytes to the right of global variable 'f' defined
in 'libfoo.c:1:6' (0x70fb08) of size 8
SUMMARY: AddressSanitizer: global-buffer-overflow /tmp/libfoo.c:2:29 in foo
Shadow bytes around the buggy address:
  0x0000800d9f10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0000800d9f20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0000800d9f30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0000800d9f40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0000800d9f50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0000800d9f60: 00 00[f9]f9 f9 f9 f9 f9 f9 00 00 00 00 00 00 00
  0x0000800d9f70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0000800d9f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0000800d9f90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0000800d9fa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0000800d9fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==19089==ABORTING 

This happens because in LLVM case ASan changes symbols size ('f' in our case)
and just breaks ABI for the library. Relinking binary each time we replace
non-sanitized library with sanitized one is undesirable for large package
oriented systems (e.g. distributives), so we need a general solution for the
problem.

Reply via email to