dlsym() returns address of a function in library X when provided the handle of library Y

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.
participants (1)
-
koutheir.attouchiļ¼ microdoc.com