I am on the latest Ubuntu Linux.
Here is a shared library with functions that are called when loading and unloading:
shared.c
:
#include <fcntl.h>
#include <sys/stat.h>
void init() {
open("init", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
}
void fini() {
open("fini", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
}
and this is compiled with
gcc -shared -fPIC -Wl,-init=init -Wl,-fini=fini shared.c -o shared.so
and then I do this:
$ rm init fini
$ LD_PRELOAD=$PWD/shared.so dash /dev/null
$ echo $?
0
$ ls init
init
$ ls fini
ls: cannot access 'fini': No such file or directory
So… loading function is called, but unloading function is not
If I replace dash
with bash
, both are called.
Using __attribute__((destructor))
does not make a difference.
Why isn’t the unloading function called for dash
?
Added per Marco Bonelli’s request:
$ file $(which dash)
/usr/bin/dash: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=f7ab02fc1b8ff61b41647c1e16ec9d95ba5de9f0, for GNU/Linux 3.2.0, stripped
$ ldd $(which dash)
linux-vdso.so.1 (0x00007ffd931c0000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6b19e84000)
/lib64/ld-linux-x86-64.so.2 (0x00007f6b1a0ec000)
2
Answers
I should have put this as a comment, but I put it as an answer for formatting purposes.
The problem is not about the difference between
redirection
andtouch
, because in your dash/touch run, shared.so has been loaded twice, once for dash, once for touch.fini
fired only withtouch
.You can see the diffrence with these two runs :
So this has something to do with
dash
.Hope this provide more materials for your investigation.
Because dash calls
_exit
here which calls exit_group syscall here which terminates the program immediately.Let’s also do a small example:
On execution does not output stop: