Correção de link dinâmico codificado para executável

4

Eu tenho um arquivo executável chamado reg com as seguintes dependências da biblioteca compartilhada:

[terminal]$ ldd ./reg
linux-vdso.so.1 => (0x00007ffc40d90000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003be0c00000)
/usr/dep/packages/opt/intel/mkl/10.0.2.018/lib/em64t/libmkl_intel_lp64.so => not found

Ao executar o binário, recebo o seguinte:

[terminal]$ ./reg
./reg: error while loading shared libraries: /usr/dep/packages/opt/intel/mkl/10.0.2.018/lib/em64t/libmkl_intel_lp64.so: cannot open shared object file: No such file or directory.

O problema é que não tenho direitos administrativos para criar o caminho do diretório especificado e colocar a biblioteca lá. Além disso, eu não tenho o código fonte, então eu não posso re-compilá-lo, mas eu tenho a biblioteca libmkl_intel_lp64.so armazenada em outro lugar. Tentei usar a variável de ambiente LD_PRELOAD , mas ela ainda precisa dessa biblioteca nesse local específico. Existe uma solução para resolver este problema?

Obrigado!

    
por Donatas 09.06.2018 / 13:11

1 resposta

8

Eu não tenho o mesmo binário que você tem, mas fiz um pequeno teste e parece que patchelf pode funcionar aqui. Eu tenho um binário hello compilado com -Wl,-rpath=/home/ja/c/hello-puts/make/lib e libtest.so como dependência:

$ ldd hello
        linux-vdso.so.1 (0x00007ffedb4f0000)
        libtest.so => /home/ja/c/hello-puts/make/lib/libtest.so (0x00007f04a2437000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f04a200f000)
        /lib64/ld-linux-x86-64.so.2 (0x0000564a42e36000)

Eu corro patchelf com --make-needed-absolute usando patchelf do link :

$ patchelf --make-needed-absolute hello
$ ldd hello
        linux-vdso.so.1 (0x00007fff9baa3000)
        /home/ja/c/hello-puts/make/lib/libtest.so (0x00007f81bd0e2000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f81bccba000)
        /lib64/ld-linux-x86-64.so.2 (0x0000556714bb5000)

Eu acho que é isso que você tem. Eu copiei hello para outra máquina e:

$ ldd ./hello
        linux-vdso.so.1 =>  (0x00007fff92e7d000)
        /home/ja/c/hello-puts/make/lib/libtest.so => not found
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff381c9b000)
        /lib64/ld-linux-x86-64.so.2 (0x00007ff382065000)

Primeiro removi uma dependência libtest.so necessária:

$ patchelf --remove-needed /home/ja/c/hello-puts/make/lib/libtest.so hello
$ ldd hello
        linux-vdso.so.1 =>  (0x00007ffdcedfb000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f60705c5000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f607098f000)

Eu tentei executar o hello , ele foi iniciado, mas devido à ligação preguiçosa feita pelo intérprete apenas a primeira linha da saída esperada foi mostrada:

$ ./hello
hello world
./hello: symbol lookup error: ./hello: undefined symbol: foo

Eu adicionei libtest.so novamente, mas sem um caminho absoluto:

$ patchelf --add-needed libtest.so hello
$ ldd hello
        linux-vdso.so.1 =>  (0x00007ffda155c000)
        libtest.so => not found
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ffbdb8c3000)
        /lib64/ld-linux-x86-64.so.2 (0x00007ffbdbc8d000)

Copiei libtest.so para $PWD e consegui iniciar hello :

$ LD_LIBRARY_PATH=. ./hello
hello world
inside foo()
    
por 09.06.2018 / 14:07