В тривиальном примере:
#include <stdio.h>
#include <stdlib.h>
int main() {
void* test = malloc(10);
printf("%p\n", test);
return 0;
}
Когда я вхожу в malloc
с gdb
, я получаю libc
:
#0 __GI___libc_malloc (bytes=10) at malloc.c:3028
#1 0x000055555555469c in main () at test.c:7
Если я компилирую с ASan gcc -fsanitize=address -g test.c -o test
В итоге меня перехватывает ASan:
#0 0x00007ffff6ef8a80 in malloc () from /usr/lib/x86_64-linux-gnu/libasan.so.4
#1 0x000055555555495c in main () at test.c:7
Это потому, что ASan загружается первым и экспортирует слабый символ:
$ readelf -W -a /usr/lib/x86_64-linux-gnu/libasan.so.4
...
314: 00000000000dea80 479 FUNC WEAK DEFAULT 12 malloc
...
$ readelf -W -a test
...
Dynamic section at offset 0xd70 contains 30 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libasan.so.4]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
...
$ readelf -W -a /lib/x86_64-linux-gnu/libc.so.6
...
1229: 00000000000970e0 923 FUNC GLOBAL DEFAULT 13 malloc@@GLIBC_2.2.5
...
Это можно закрепить malloc
для вызова версии libc
, а не ASan?
Я безуспешно пробовал следующее:
#include <stdio.h>
#include <stdlib.h>
__asm__(".symver malloc,malloc@GLIBC_2.2.5");
int main() {
void* test = malloc(10);
printf("%p\n", test);
return 0;
}
$ ./test
ASAN:DEADLYSIGNAL
=================================================================
==4616==ERROR: AddressSanitizer: SEGV on unknown address 0x55f589f7294a (pc 0x55f589f72820 bp 0x7fff24457f70 sp 0x7fff24457f58 T0)
==4616==The signal is caused by a WRITE memory access.
#0 0x55f589f7281f (/home/vagrant/symbol-ver/test+0x81f)
#1 0x55f589f7295b in main /home/vagrant/symbol-ver/test.c:7
#2 0x7f5abfddeb96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
#3 0x55f589f72869 in _start (/home/vagrant/symbol-ver/test+0x869)
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (/home/vagrant/symbol-ver/test+0x81f)
==4616==ABORTING