Dynamic library loaders are having a feature called RPATH which is used to search libraries being outside of standard paths. They are given to the linker at buildtime of a binary and can be inspected e.g. by readelf -a binary | grep RPATH
. Wrongly used, they can cause just unneeded work, break functionality or are a security risk. Citing from /usr/lib/rpm/check-rpaths-worker, the following issues are possible:
- the RPATH is empty; there is no reason for such RPATHs and they cause unneeded work while loading libraries
- the special '$ORIGIN' RPATHs are appearing after other RPATHs; this is just a minor issue but usually unwanted
- an RPATH references '..' of an absolute path; this will break the functionality when the path before '..' is a symlink.
/usr/lib/../lib64
is an example of such an RPATH. - invalid RPATHs; these are RPATHs which are neither absolute nor relative filenames and can therefore be a SECURITY risk
- insecure RPATHs; these are relative RPATHs which are a SECURITY risk
- standard RPATHs (e.g. /usr/lib); such RPATHs are a minor issue but are introducing redundant searchpaths without providing a benefit. They can also cause errors in multilib environments. E.g. people reported that accelerated libglx.so libraries were not used because applications had /usr/lib64 in RPATHs
The fedora-rpmdevtools package provides scripts which check automatically for the issues above while building a package. When an issue will be detected, the build will fail or an warning will be issued; the exact behavior can be configured by an environment variable.
It should be easy to do this test on every build made on the Fedora Extras buildsystem. This requires adding the
%__arch_install_post \ /usr/lib/rpm/check-rpaths \ /usr/lib/rpm/check-buildroot
lines either to /etc/rpm/macros or to ~/.rpmmacros of the builduser.
PROs
- RPATH issues will be detected on packages passed the initial review already; although 'rpmlint' has similar checks, this tool will be usually used only once to get the package into Extras but RPATH issues (among other things) can arise when the package evolves. Failures at package buildtime would force correction of these issues.
- it should be easy to add it to the existing buildsystem
CONs
- the 'check-rpaths' tool checks """every""" file in $RPM_BUILD_ROOT -- inclusive these excluded by
%exclude
directives. There is no easy solution or workaround for this. - almost every 'libtool' based tarball not created with the Fedora Core multilib patched 'libtool' will have a standard RPATH of /usr/lib64 on 64bit architectures. Workarounds are:
- libtoolize the tarball at buildtime; this step is -- similarly to executing
autoreconf
-- deprecated by Fedora Extras packaging guidelines - execute
export LIBTOOL=libtool
before%configure
; this might work sometimes but because ./libtool is created based on ./configure result, it will break horribly when host-tripled compilernames (e.g. 'i686-redhat-linux-gnu-gcc') are used. - Some configure scripts do not allow overriding the LIBTOOL variable through an environment variable. In these cases it's usually possible to override the value of LIBTOOL on the make command line like so:
make LIBTOOL=/usr/bin/libtool
- ignore this kind of errors; 'check-rpaths' knows a $QA_RPATHS environment variable which allows to disable certain checks. Obviously, this will hide the RPATH problem...
- do some dirty patching of ./configure; this is not very portable and causes a bunch of problems when people do not use
AM_MAINTAINER_MODE
Alternatives
There are more automatic tests possible to check the quality of a package and to detect critical issues. E.g. 'rpmlint' or checking for orphaned directories. So using 'check-rpaths' (which is just one possible tools and can produce false positives) at buildtime is just a kludge. It would be better to create a separate system which must be passed by all built packages. There the checks will be executed and the results be told to the signing people.
This would need significantly more work than using the existing script from 'fedora-rpmdevtools'...