Bug 22280 - relocations not performed on failed dlopen
Summary: relocations not performed on failed dlopen
Status: RESOLVED DUPLICATE of bug 20839
Alias: None
Product: glibc
Classification: Unclassified
Component: libc (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-10-11 04:39 UTC by Ben Woodard
Modified: 2017-10-16 18:32 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:
fweimer: security-


Attachments
reproducer (994 bytes, application/gzip)
2017-10-11 04:39 UTC, Ben Woodard
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Ben Woodard 2017-10-11 04:39:32 UTC
Created attachment 10521 [details]
reproducer

The runtime linker fails to perform relocation on a shared library brought in as a dependency which is marked NODELETE even though it isn't deleted. This causes problems when a subsequent library also tries to make use of the same library.

[ben@Mustang dl-bug]$ make all
cc -g   -c -o main.o main.c
cc -g -o main main.o -ldl
cc -g -c -fpic a.c
cc -g -c -fpic d.c
cc -g -fpic -shared -Wl,-z,nodelete -o libd.so d.o
cc -g -c -fpic e.c
cc -g -fpic -shared -o libe.so e.o
cc -g -fpic -shared -o liba.so a.o -L. -ld -le
cc -g -c -fpic b.c
cc -g -fpic -shared -o libb.so b.o -L. -ld
[ben@Mustang dl-bug]$ make run
LD_LIBRARY_PATH=. ./main
d_fn x=12
inside b_fn
rm libe.so
LD_LIBRARY_PATH=. ./main
Could not open liba.so - libe.so: cannot open shared object file: No such file or directory
make: *** [Makefile:38: run] Segmentation fault (core dumped)

Note that libd.so is marked NODELETE
So when main dlopen's liba.so which needs on libd.so and libe.so because libe.so is missing, the load of liba.so fails. This is expected. However, when libb.so is loaded which also needs libd.so the application crashes because the relocations haven't been done.

[ben@Mustang dl-bug]$ LD_LIBRARY_PATH=. LD_DEBUG=reloc,files ./main 2> foo
d_fn x=12
inside b_fn
[ben@Mustang dl-bug]$ egrep file\|reloc foo
     10901:	file=libdl.so.2 [0];  needed by ./main [0]
     10901:	file=libdl.so.2 [0];  generating link map
     10901:	file=libc.so.6 [0];  needed by ./main [0]
     10901:	file=libc.so.6 [0];  generating link map
     10901:	relocation processing: /lib64/libc.so.6
     10901:	relocation processing: /lib64/libdl.so.2
     10901:	relocation processing: ./main (lazy)
     10901:	relocation processing: /lib64/ld-linux-x86-64.so.2
     10901:	file=liba.so [0];  dynamically loaded by ./main [0]
     10901:	file=liba.so [0];  generating link map
     10901:	file=libd.so [0];  needed by ./liba.so [0]
     10901:	file=libd.so [0];  generating link map
     10901:	file=libe.so [0];  needed by ./liba.so [0]
     10901:	file=libe.so [0];  generating link map
     10901:	relocation processing: ./libe.so
     10901:	relocation processing: ./libd.so
     10901:	relocation processing: ./liba.so
     10901:	opening file=./liba.so [0]; direct_opencount=1
     10901:	file=libb.so [0];  dynamically loaded by ./main [0]
     10901:	file=libb.so [0];  generating link map
     10901:	relocation processing: ./libb.so
     10901:	opening file=./libb.so [0]; direct_opencount=1

vs.

[ben@Mustang dl-bug]$ rm libe.so
[ben@Mustang dl-bug]$ LD_LIBRARY_PATH=. LD_DEBUG=reloc,files ./main 2> foo
Segmentation fault (core dumped)
[ben@Mustang dl-bug]$ egrep file\|reloc foo
     10965:	file=libdl.so.2 [0];  needed by ./main [0]
     10965:	file=libdl.so.2 [0];  generating link map
     10965:	file=libc.so.6 [0];  needed by ./main [0]
     10965:	file=libc.so.6 [0];  generating link map
     10965:	relocation processing: /lib64/libc.so.6
     10965:	relocation processing: /lib64/libdl.so.2
     10965:	relocation processing: ./main (lazy)
     10965:	relocation processing: /lib64/ld-linux-x86-64.so.2
     10965:	file=liba.so [0];  dynamically loaded by ./main [0]
     10965:	file=liba.so [0];  generating link map
     10965:	file=libd.so [0];  needed by ./liba.so [0]
     10965:	file=libd.so [0];  generating link map
     10965:	file=libe.so [0];  needed by ./liba.so [0]
     10965:	file=./liba.so [0];  destroying link map
Could not open liba.so - libe.so: cannot open shared object file: No such file or directory
     10965:	file=libb.so [0];  dynamically loaded by ./main [0]
     10965:	file=libb.so [0];  generating link map
     10965:	relocation processing: ./libb.so

Note on the failing case the relocations are never done on libd.so
Comment 1 Ben Woodard 2017-10-11 04:42:35 UTC
Discovered that there is already a bug reported for this.

*** This bug has been marked as a duplicate of bug 20839 ***