Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Thu, 21 May 2020 14:27:24 +0300
From: Alexander Scherbatiy <alexander.scherbatiy@...l-sw.com>
To: musl@...ts.openwall.com
Subject: Shared library loading

Hello,

I use Alpine Linux 3.11.6 with musl libc (x86_64) version 1.1.24.

I have two shared libraries "a" and "b" each of which is placed in its 
own directory and lib "b" depends on "a".
First, I use dlopen to load lib "a" with "RTLD_NOW | RTLD_GLOBAL" flags.
Second, I load lib "b" with  flag "RTLD_LAZY".

The "b" library loading works on my Ubuntu 19.10 and fails on Alpine 
3.11.6 with message:
   dlopen failed: Error loading shared library liba.so: No such file or 
directory (needed by /root/load-lib-sample/bin/b/libb.so)
Should it work on Alpine with musl libc as well?


Below is the source code which reproduces the library loading issue:

--- include/a.h ---
void test_a();
--- include/b.h ---
void test_b();
--- src/a.c ---
#include "a.h"
#include <stdio.h>

void test_a() {
     printf("test a\n");
}
--- src/b.c ---
#include "b.h"
#include "a.h"
#include <stdio.h>

void test_b() {
     printf("test b\n");
     test_a();
}
--- src/main.c ---
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

void *open_lib(const char* base_dir, const char* lib_dir, const char 
*lib_name,int flags) {
     char path_lib[256];
     sprintf(path_lib, "%s/%s/%s", base_dir, lib_dir, lib_name);
     printf("[load lib] %s\n", path_lib);

     void *handle = dlopen(path_lib, flags);

     if (!handle) {
         fprintf(stderr, "dlopen failed: %s\n", dlerror());
         exit(EXIT_FAILURE);
     }
     return handle;
}

void call_func(void *handle, const char *func_name) {
     printf("[call func] %s\n", func_name);

     void (*func_t)(void);
     *(void **) (&func_t) = dlsym(handle, func_name);

     char *error = dlerror();
     if (error != NULL)  {
         fprintf(stderr, "%s\n", error);
         exit(EXIT_FAILURE);
     }

     (*func_t)();
}

int main(int argc, char* argv[]) {
     if (argc < 2) {
         printf("provide base dir.\n");
         exit(-1);
     }

     void *handle_a = open_lib(argv[1], "a", "liba.so", RTLD_NOW | 
RTLD_GLOBAL);
     call_func(handle_a, "test_a");

     void *handle_b = open_lib(argv[1], "b", "libb.so", RTLD_LAZY);
     call_func(handle_b, "test_b");

     dlclose(handle_b);
     dlclose(handle_a);
}
--- build.sh ---
rm -rf ./bin
mkdir -p bin bin/a bin/b
DIR_BIN=$(pwd)/bin

gcc -g -shared src/a.c -Wl,-soname=liba.so -Iinclude -o bin/a/liba.so
gcc -g -shared src/b.c -Wl,-soname=libb.so -Iinclude -la -Lbin/a -o 
bin/b/libb.so
gcc -g src/main.c -Iinclude -o bin/main -ldl

./bin/main $DIR_BIN
--- --- ---

Output on Ubuntu 19.10
----------
./build.sh
[load lib] /home/user/load-lib-sample/bin/a/liba.so
[call func] test_a
test a
[load lib] /home/user/load-lib-sample/bin/b/libb.so
[call func] test_b
test b
test a
----------

Output on Alpine 3.11.6
----------
./build.sh
[load lib] /root/load-lib-sample/bin/a/liba.so
[call func] test_a
test a
[load lib] /root/load-lib-sample/bin/b/libb.so
dlopen failed: Error loading shared library liba.so: No such file or 
directory (needed by /root/load-lib-sample/bin/b/libb.so)
----------

Thanks,
Alexander.

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.