tech-toolchain archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

RT linker, rpath and security



Isn't it the way a run time linker uses rpath search path a security
risk?

Here is an example (more code could obviously replace libc; here "/tmp"
is used simply for the example to work for everybody, as well as $HOME:
any writable directory by the user compiling could be used instead of
/tmp):

$ cd # we use $HOME for the "good" library

$ cat <<EOT >Makefile 
SOMEDIR = /tmp

example: libexample.so main.c
	gcc -o $@ main.c -L. -lexample -Wl,-R$(SOMEDIR) -Wl,-R$$HOME

libexample.so: lib.o
	gcc -shared -Wl,-soname,libexample.so -o $@ lib.o

lib.o: lib.c
	gcc -fPIC -c -o $@ lib.c

nasty: $(SOMEDIR)/libexample.so

$(SOMEDIR)/libexample.so: libnasty.o
	gcc -shared -Wl,-soname,libexample.so -o $@ libnasty.o

libnasty.o: libnasty.c
	gcc -fPIC -c -o $@ libnasty.c
EOT

$ cat <<EOT >main.c
extern void publish(char *);

int
main(int argc, char **argv)
{
	publish("Hello world!\n");
	return 0;
}
EOT

$ cat <<EOT >lib.c
#include <stdio.h>

void publish(char *);

void
publish(char *str)
{
	(void)printf(str);
}
EOT

$ cat <<EOT >libnasty.c
#include <stdio.h>

void publish(char *);

void
publish(char *str)
{
	(void)printf("Hello ass!\n");
}
EOT

Now, with an initial invocation of make, the "good" library is compiled
and linked with the program:

$ make
$ readelf -d example


Dynamic section at offset 0xb60 contains 19 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libexample.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.12]
 0x000000000000000f (RPATH)              Library rpath: [/tmp:/home/tlaronde]
 0x000000000000000c (INIT)               0x400550
 0x000000000000000d (FINI)               0x4009c0
 0x0000000000000004 (HASH)               0x400210
 0x0000000000000005 (STRTAB)             0x4003c8
 0x0000000000000006 (SYMTAB)             0x400260
 0x000000000000000a (STRSZ)              187 (bytes)
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000015 (DEBUG)              0x0
 0x0000000000000003 (PLTGOT)             0x600d00
 0x0000000000000002 (PLTRELSZ)           120 (bytes)
 0x0000000000000014 (PLTREL)             RELA
 0x0000000000000017 (JMPREL)             0x4004d0
 0x0000000000000007 (RELA)               0x400488
 0x0000000000000008 (RELASZ)             72 (bytes)
 0x0000000000000009 (RELAENT)            24 (bytes)
 0x0000000000000000 (NULL)               0x0

And if invoking:

$ ./example

Hello world!

OK. Now we compile the nasty version:

$ make nasty
$ ./example

Hello ass!

Uh... And the problem is that this works also with root!

What I mean is that a valid program can be linked with specifying an
rpath search path that starts by directories not used for the moment 
(i.e. not containing for now a library matching) in the version
delivered, considered harmless, but that are writable by somebody else.

Then, after installation, a nasty library is put by this somebody in
the directory so that this nasty library is found first.

Shouldn't be there a mechanism:

1) That always search, first, /usr/lib and /lib before using the rpath
(if someone wants to override a system library, one gives the other
version another name or major/minor/tiny);

2) For root, every directory not owned by root or writable by someone
else is discarded from the search path.

or is there some security feature that already addresses this?
-- 
        Thierry Laronde <tlaronde +AT+ polynum +dot+ com>
                     http://www.kergis.com/
                    http://kertex.kergis.com/
Key fingerprint = 0FF7 E906 FBAF FE95 FD89  250D 52B1 AE95 6006 F40C


Home | Main Index | Thread Index | Old Index