admin管理员组

文章数量:1208155

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).

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).

Share Improve this question edited Jan 19 at 12:22 Mat 207k41 gold badges400 silver badges416 bronze badges asked Jan 19 at 12:21 yugryugr 21.9k4 gold badges59 silver badges104 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

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.

本文标签: cCrash when dlopening shared library which accesses global variable in constructorStack Overflow