Consider 3 libraries: `libA`, `libB` and `libC`. Only library `libB`
implements
and exports the function `public_function()`.
A program `dlopen()`s `libA` then `libB` then `libC`. Then the program
calls
`dlsym(libA, "public_function")` then `dlsym(libB,
"public_function")`
then `dlsym(libC, "public_function")`.
Expected behavior:
- `dlsym(libA, "public_function")` and `dlsym(libC,
"public_function")`
return `NULL`, and
- `dlsym(libB, "public_function")` returns a non-`NULL` address.
Erroneous behavior:
- `dlsym(libC, "public_function")` return `NULL`, and
- `dlsym(libA, "public_function")` and `dlsym(libB,
"public_function")`
returns **the same** non-`NULL` address.
Program to reproduce this issue:
```
// dlsym-test1.c
#include <stdio.h>
#include <dlfcn.h>
typedef void (*public_function_t)();
int main() {
int i;
void* lib[3] = {};
void* lib_name[3] = {"liba.so", "libb.so", "libc.so"};
public_function_t public_function[3] = {};
for (i = 0; i < 3; ++i) {
lib[i] = dlopen(lib_name[i], RTLD_NOW | RTLD_LOCAL);
}
for (i = 0; i < 3; ++i) {
if (lib[i] != NULL) {
public_function[i] = dlsym(lib[i], "public_function");
}
}
for (i = 0; i < 3; ++i) {
printf("%s:%#x public_function:%#x.\n",
lib_name[i], lib[i], public_function[i]);
}
for (i = 0; i < 3; ++i) {
if (public_function[i] != NULL) {
(public_function[i])();
}
}
return 0;
}
```
```
// libb.c
#include <stdio.h>
void public_function() __attribute__ ((visibility ("default")));
void public_function() {
puts("libB::public_function()");
}
```
```
#!/bin/bash
CROSS_COMPILE=...
CC=${CROSS_COMPILE}gcc
CFLAGS='-fvisibility=hidden -O0 -g -Wextra -Werror'
rm *.so dlsym-test1
$CC $CFLAGS -fPIC -shared -o liba.so empty.c
$CC $CFLAGS -fPIC -shared -o libb.so libb.c
$CC $CFLAGS -fPIC -shared -o libc.so empty.c
$CC $CFLAGS -fPIE -pie '-Wl,-rpath=$ORIGIN' -o dlsym-test1 dlsym-test1.c
```
```
$ ./dlsym-test1
liba.so:0x80579160 public_function:0xb6eb9584.
libb.so:0x80579348 public_function:0xb6eb9584.
libc.so:0x80579520 public_function:0.
libB::public_function()
libB::public_function()
```
---
Dr. Koutheir Attouchi.
Show replies by date