Reputation: 21878
This simple library
$ cat foo.c
int glob;
int foo() {
return 0;
}
__attribute__((constructor))
void init() {
glob = foo();
}
$ gcc -g -O0 -shared -fPIC foo.c -o libfoo.so
loads fine when I link it normally:
$ cat prog1.c
extern int foo();
int main() {
return foo();
}
$ gcc -g -O0 prog1.c libfoo.so
$ LD_LIBRARY_PATH=. ./a.out
but crashes if I load it via dlopen
:
$ cat prog2.c
#include <dlfcn.h>
int main() {
dlopen("./libfoo.so", RTLD_LAZY | RTLD_GLOBAL);
return 0;
}
$ gcc -g -O0 prog2.c -ldl
$ ./a.out
Segmentation fault
When I inspect it in gdb
it looks like it crashes in init
trying to store to address which does not match glob
. I tested in Ubuntu 24.04 (Glibc 2.39) and Debian 11.11 (Glibc 2.31).
Upvotes: 1
Views: 101
Reputation: 21878
Answered by Mike Kashkarov
glob
is also a name of Glibc function, exported from libc.so
. So in dlopen
case glob
is resolved to address in Glibc's read-only memory segment and we get a crash when writing to it.
Upvotes: 1