Change Proposal Name
Enable RPATH detection during rpmbuild.
Enable RPATH detection during rpmbuild. This will make the build fail in the case a hard-coded RPATH was detected within a binary or a shared library file.
- Name: Charalampos Stratakis
- Email: cstratak AT redhat.com
- Targeted release: Fedora Linux 35
- Last updated: 2021-05-03
- FESCo issue: <will be assigned by the Wrangler>
- Tracker bug: <will be assigned by the Wrangler>
- Release notes tracker: <will be assigned by the Wrangler>
The dynamic linker and loader (ld.so) is responsible for resolving runtime dependencies of executables and shared library files through a search hierarchy. However some packages (usually through their upstream buildsystems) contain a hard-coded path within their binaries or .so files, by using the -R or -rpath flag during compilation, which is referred to as RPATH. By utilizing RPATH, ELF files can point to directories to be included in the search path, on runtime, to resolve their dependencies.
While RPATH can be used for non-standard directories, such as a place containing private libraries of the project, when it points to a value already provided by the search path of ld.so it changes the hierarchy of the search, by placing the system defaults first.
(a) DT_RPATH -> (b) LD_LIBRARY_PATH -> (c) DT_RUNPATH -> (d) cache (/etc/ld.so.cache) -> (e) system defaults
This could present a variety of issues, such as LD_LIBRARY_PATH overrides not working, incomplete dependency resolution, loading of wrong libraries etc. In general changing the default search hierarchy could lead to unforeseen bugs and issues (In a similar manner as as adding /usr/lib64 to LD_LIBRARY_PATH).
Another problem of a hardcoded RPATH is security. When an ELF object contains an RPATH pointed to a directory not managed by the system, where some malicious actor has write permissions to, it's relatively easy to execute arbitrary code.
Performance can be affected as well, since probing explicitly e.g. /usr/lib64 through RPATH adds extra open/openat system calls to the process startup.
In Fedora the use of RPATH is forbidden, but it was never enforced. This change intends to ratify that by running /usr/lib/rpm/check-rpaths during rpmbuild, after %install, and fail the build if an RPATH entry was detected.
The change has been proposed a long time ago through FPC and the general consensus is that it needs to be done, along with an overhaul of the Fedora documentation in regards to RPATH.
An email thread was also started on Fedora devel regarding this change.
As for other distributions, Debian discourages the use of RPATH, openSUSE forbids it by running the check from rpmlint after every package build and Arch and Gentoo point out to possible insecure usage at their respective documentation pages.
Benefit to Fedora
Improved performance, security, compliance with the guidelines, reducing of RPATH related bugs.
- Proposal owners: Merge the PR to redhat-rpm-config to enable running the check-rpaths script after %install.
- Other developers: After merging the changes to redhat-rpm-config the affected package maintainers that will see their packages' builds fail, will need to review their usage of RPATH and either remove it or workaround the issue. The packages currently failing to build due to RPATH issues, so far, are listed bellow:
- Release engineering: #Releng issue number This change doesn't require coordination with rel-eng, as any issues will be caught during the regular mass rebuild of packages.
- Policies and guidelines: The guidelines will be overhauled to take into account accepted usage or RPATH, clarification of the policy and ways to opt-out
- Trademark approval: N/A (not needed for this Change)
There will be no visible impact to non-packagers. Packagers will need to fix their packages if an invalid RPATH entry was detected, as an invalid RPATH will make the rpmbuild fail either in koji or locally.
How To Test
- Mock build testing:
Initiate a Fedora rawhide mock chroot and install the modified redhat-rpm-config:
mock -r fedora-rawhide-x86_64 --install https://download.copr.fedorainfracloud.org/results/cstratak/rpath/fedora-rawhide-x86_64/02160930-redhat-rpm-config/redhat-rpm-config-190-1.fc35.noarch.rpm
Build your package with the --no-clean option:
mock -r fedora-rawhide-x86_64 --no-clean <srpm>
- rpmlint test: The binary-or-shlib-defines-rpath test from the BinariesCheck module will reveal RPATH usage.
rpmlint -c BinariesCheck <binary rpm>
e.g.: rpmlint -c BinariesCheck -v audiofile-0.3.6-27.fc34.x86_64.rpm audiofile.x86_64: I: checking audiofile.x86_64: E: binary-or-shlib-defines-rpath /usr/bin/sfconvert ['/usr/lib64'] audiofile.x86_64: E: binary-or-shlib-defines-rpath /usr/bin/sfinfo ['/usr/lib64'] 1 packages and 0 specfiles checked; 2 errors, 0 warnings.
Packagers will have
Merge the PR to redhat-rpm-config
- Contingency mechanism: (What to do? Who will do it?) N/A (not a System Wide Change)
- Contingency deadline: N/A (not a System Wide Change)
- Blocks release? N/A (not a System Wide Change), Yes/No
Revert the change
N/A (not a System Wide Change)