Following a recent thread discussing a reproducible failure caused by
mismatched library interfaces, I proposed a change to the RPM ELF
dependency generator. After discussion in the PR, I've provided an
implementation suggested by keszybz@ which would use libtool-style
versions collected from library filenames to provide versioned library
requirements. Before merging that feature, RPM's maintainers are
interested in feedback from a wider audience.
Links to the earlier thread and to the PR, as well as details in the
form of a mostly-complete change proposal in wiki format follow:
https://lists.fedoraproject.org/archives/list/devel@xxxxxxxxxxxxxxxxxxxxxxx/message/WE5UTPZ6EIMTSNUX6ILODAHRYNH6J6TM/
https://github.com/rpm-software-management/rpm/pull/2372
= Enable RPM's fallback version generator for ELF dependencies =
{{Change_Proposal_Banner}}
== Summary ==
This change will, over the course of two releases, enable a new feature
in RPM's dependency generator which provides a version number for ELF
shared objects which provide a libtool-style version, but don't provide
versioned symbols. This additional information may cause dependencies
to update when a package that depends on them is installed or updated.
== Detailed Description ==
The current ELF dependency generator examines ELF binaries and prints a
list of virtual packages that represent the libraries required in order
to run the binary. For libraries that use versioned symbols, the
dependency generator provides information about the symbol versions
required, ensuring that all of the required interfaces are present in
dependencies during package installation. However, for libraries that
do not provide versioned symbols, the resulting dependencies express
effectively only the major version of the interface. That limitation
can result in rpm installing a package set that meets all of the rpm
dependencies of each package, but attempts to run the installed binaries
will fail.
For example, Fedora 37 was released with libnghttp2-1.49.0, and later
updated to libnghttp2-1.51.0. The latter release introduced a new
interface and increased its libtool version appropriately. After that
update, libsoup3 was rebuilt, and gained a dependency on the new
interface. However, because the soname was the same, rpm had no way to
represent the new dependency, so both the old and new build of libsoup3
required "libnghttp2.so.14()(64bit)". One way this could cause a
reproducible failure is to construct a system from the Fedora 37 release
media (or start a Fedora 37 container). libnghttp2 is installed by
default, as a dependency of curl, but libsoup3 is not. If you then
install any package that uses libsoup3 (e.g. chezdav), the binaries
provided by that package will fail to start, because the runtime linker
cannot resolve all symbols.
The curl package appears to have had this problem more than once, and
addresses it by querying the package version of selected dependencies
and creating additional dependency statements based on their package
version. However, the versioned dependency on libnghttp2 was added
after the release of Fedora 37.
Another failure case, and one that affected real users, was to install
Fedora 37 Workstation and enable the node14 modular repo. That repo
provided a build of libnghttp2 of its own which wasn't updated when
Fedora updated its primary libnghttp2 package to 1.51.0. Because
modular repos filter their package sets out of other repos, updating the
system as a whole would not update libnghttp2, but would update
libsoup3. That update would break gdm, leaving users unable to log in
to the graphical interface.
This change would make manual, selected versioned dependencies
unnecessary by generating them automatically for any package that
provides libtool-style versioned shared objects. (Though, again,
objects that provide versioned symbols are excluded, because versioned
symbols are already handled properly, and are the preferred mechanism.)
== Feedback ==
== Benefit to Fedora ==
This change will make package updates and installation more reliable,
reducing the risk that selectively installing an update (as in the case
of users who use "dnf update --security") or installing a single new
package will result in binaries that do not work. It will also make the
use of modular repos more reliable, by preventing packages from updating
if one of their dependencies is likely to lack symbols needed by
packages which are not provided by a modular repo.
== Scope ==
* Proposal owners:
In order to complete this change, the "_elf_provide_fallback_versions"
macro must be enabled, and all packages must be rebuilt in order to
"provide" versioned libraries. In a subsequent release, the
"_elf_require_fallback_versions" macro must be enabled, and all packages
must be rebuilt in order to "require" versioned libraries.
* Other developers:
Other developers are not expected to make any specific changes, though
if any package is manually creating versioned dependencies (as the curl
package is), they can remove those and rely on the internal dependency
generator when the change is complete.
A mass rebuild is required for this feature.
== Upgrade/compatibility impact ==
Packages built on a system where the _elf_require_fallback_versions
macro was enabled would not be usable on a system that was built without
the _elf_provide_fallback_versions macro enabled.
Packages built on a system without the _elf_provide_fallback_versions
could not be used on Fedora as replacements or alternatives to Fedora
dependencies, after the _elf_require_fallback_versions macro was enabled
in Fedora.
== How To Test ==
Ensure that system installations work as expected. Ensure that new
packages can be installed. Ensure that updates can be applied.
Test that there are no unexpected old packages, which might have been
skipped in an update due to unsatisfied dependencies.
== User Experience ==
Most users will not notice this change, though they may see a dependency
resolution error if they attempt to install a package whose binary
dependencies aren't met.
== Dependencies ==
Because this change may affect compatibility with third party repos,
Fedora should notify any known repos of this change, so that they can
enable those macros in the same release as Fedora. Repos that provide
only leaf packages or leaf packages and their own dependencies would not
be affected, but any repo that provides a package meant to serve as an
alternative to a Fedora package would be affected. In particular,
rpmfusion would need to enable the _elf_provide_fallback_versions macro
in order to provide packages that would be usable on a Fedora system.
== Contingency Plan ==
* Contingency mechanism: Reverting the change would require disabling
the macro and a mass rebuild.
* Contingency deadline: Beta freeze.
* Blocks release? Yes
== Documentation ==
Some documentation regarding the feature is included in the
docs/manual/more_dependencies.md file in the PR.
== Release Notes ==
Fedora has begun to improve rpm dependency information to make it more
detailed. Libraries that make use of versioned symbols are already well
supported in rpm, and reliably ensure that a library offers the
interfaces that packages that depend on it actually require in order to
run. For the large body of libraries that do not provide versioned
symbols, rpm will begin making use of the libtool-style version encoded
in the filename to ensure that packages that provide ELF binaries
indicate a minimum version of their library dependencies which matches
the versions present in its build environment.
_______________________________________________
devel mailing list -- devel@xxxxxxxxxxxxxxxxxxxxxxx
To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxxxxxxxx
Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: https://lists.fedoraproject.org/archives/list/devel@xxxxxxxxxxxxxxxxxxxxxxx
Do not reply to spam, report it: https://pagure.io/fedora-infrastructure/new_issue