💾 Archived View for thrig.me › blog › 2023 › 06 › 10 › shared-libraries.gmi captured on 2023-06-14 at 14:01:15. Gemini links have been rewritten to link to archived content
-=-=-=-=-=-=-
https://amir.rachum.com/shared-libraries/
Is an educational document, good to work through to better understand compiling and linking shared libraries. To recap, and using C instead of C++ one needs a program that uses a library, plus a few supporting scripts:
Probably you do not need to know much about ELF unless you are getting deep into ELF guts. It may however be instructive to compare a program on OpenBSD with what they list for a Linux. The NEEDED libraries are good to know about:
$ readelf -d main | fgrep NEEDED 0x0000000000000001 (NEEDED) Shared library: [libmyrand.so] 0x0000000000000001 (NEEDED) Shared library: [libc.so.97.0] $ readelf -d `which httpd` | fgrep NEEDED 0x0000000000000001 (NEEDED) Shared library: [libevent.so.4.1] 0x0000000000000001 (NEEDED) Shared library: [libtls.so.26.2] 0x0000000000000001 (NEEDED) Shared library: [libssl.so.53.2] 0x0000000000000001 (NEEDED) Shared library: [libcrypto.so.50.2] 0x0000000000000001 (NEEDED) Shared library: [libutil.so.16.0] 0x0000000000000001 (NEEDED) Shared library: [libc.so.97.0] $ readelf -d /bin/ksh | fgrep NEEDED $
This is from OpenBSD 7.3. It is good to see what other binaries on the system use by way of libraries. ksh(1) in particular is a static compile, which has pros and cons. Having a working shell might be nice if /usr is not mounted or libc is messed up, though if libc is messed up you may need to use ed(1) instead of your fancy text editor—or, more likely, to reinstall or to mount the bad partition on a system with usable tools.
See ld.so(1) for how things are done on OpenBSD.
$ ldd `which httpd` /usr/sbin/httpd: Start End Type Open Ref GrpRef Name 000000828e0c5000 000000828e0f5000 exe 1 0 0 /usr/sbin/httpd 000001a3bb5bd000 000001a3bb5ce000 rlib 0 1 0 /usr/lib/libevent.so.4.1 ... $ ldd main main: ld.so: main: can't load library 'libmyrand.so' main: signal 9
ldd(1) may not be safe to run on untrusted binaries, by the way. The ELF tools are also pretty complicated and may have security vulns. So if you are inspecting untrusted binaries, maybe do that on an isolated test system?
LD_DEBUG may be good to know about, but is maybe less useful on OpenBSD. There are other environment variables detailed in ld.so(1).
$ LD_DEBUG=1 ldd main ... loading: libmyrand.so required by main ld.so: main: can't load library 'libmyrand.so' main: signal 9 doing dtors
There is also process tracing to show what a binary is up to; this should show the directory names that are searched through:
$ ktrace ./main ... $ kdump | fgrep NAMI ... $ LD_LIBRARY_PATH=foobar ktrace ./main ... $ kdump | fgrep foobar 3804 main NAMI "foobar" 3804 main NAMI "foobar"
$ readelf -d main | egrep -i 'run|path' 0x000000000000001d (RUNPATH) Library runpath: [.]
rpath happens before LD_LIBRARY_PATH, and runpath after. So LD_LIBRARY_PATH can only modify runpath. I generally avoid using LD_LIBRARY_PATH where possible, as it slows down library searches for everything that is run with that environment variable set. This could lead to less than ideal performance should libraries be present on a NFS server, or if an application runs all sorts of other programs that then all go and check on the directories listed in LD_LIBRARY_PATH.
$ORIGIN is pretty neat, if you want a library relative to where the program lives. On OpenBSD this needs -Wl,-z,origin set for $ORIGIN to be honored:
$ cc -o main main.o -lmyrand -L. -Wl,-z,origin -Wl,-rpath,\$ORIGIN $ readelf -d main | grep -i orig 0x000000000000001d (RUNPATH) Library runpath: [$ORIGIN] 0x000000000000001e (FLAGS) ORIGIN 0x000000006ffffffb (FLAGS_1) Flags: ORIGIN PIE
Various magical permission bits (suid, for example) will of course disable various linker tomfoolery. This avoids gaping security holes where an attacker could simply LD_PRELOAD a library of their choice. Duplicate environment variables can also be a problem here. Attacks may still possible if a user can trick a sysadmin into running something; it may be beneficial to first switch to their user account to run something they claim problems with.
https://begriffs.com/posts/2021-07-04-shared-libraries.html
tags #openbsd