Delete Downgraded Libraries

It is common practice for large commerical applications to ship with all the libraries that they need, but on most Linux systems, this introduces compatiblity problems when the libraries are older than the equivalents that are already installed.

What do the applications do?

When installing an application, they be installed into any directory, depending on what the system administrator chooses. There can be many good reasons not to choose a default.

The installer then wraps the application with a shell script that sets LD_LIBRARY_PATH to add the application's library directory onto the library search path.

What goes wrong?

LD_LIBRARY_PATH is a very blunt tool. Once set, it affects all programs (apart from setuid/setgid), including programs that are not shipped with the application. For example, an application might call a shell script, which in turn calls grep, awk, sed etc. and the LD_LIBRARY_PATH applies to all of them.

The effect is that system programs use the libraries from the application in preference to the correct library already installed on the system. If the application library is too old, it might not provide features required by the system program; the system program will fail to start.

How can we fix it?

A long time ago, rpath, the setting in an application that said where to find its libraries, was a list of absolute path, which couldn't be modified later. Using LD_LIBRARY_PATH was a workaround for this limitation.

Two things have changed since then. The first is that patchelf lets you make retrospective changes to the rpath. The other is that $ORIGIN lets you specify a relative rpath.

A typical application, which has programs in /bin and libraries in /lib64, can use $ORIGIN/../lib64 as an rpath.

This fixes a lot of problems, but it is not enough to fix all programs.

What else goes wrong?

Nearly every program dynamically loads some libraries after main() has been called, typically to do nss lookups. Modern graphics programs so the same when loading X11 client-side drivers, especially for OpenGL.

What makes these special is that the driver runs in the same address space as the program, and therefore shares the same loaded libraries.

It is common for X11 drivers to use libstdc++, using whatever version of that library is normally present on the system.

When applications ship their own libstdc++, this is loaded before the graphics driver, which won't be loaded until much later. The application's own libstc++ will be loaded, whether it is by rpath or LD_LIBRARY_PATH.

When the graphics driver is loaded, it will fail in dlopen(); the program will either use software rendering or fail altogether.

An alternative fix

Rather than playing games with paths, we should try to get closer to what a program would do if it was packages by a distribution package maintainer. Generally speaking, the system libraries wouldn't be included in the package; instead the package would have a dependency on the package providing the library. All applications on the system would then be using the same library, and there would be no version problems.

That doesn't quite work for us because the application libraries might be newer, in which case we'd like to leave them alone. The rest of the applications libraries can go. Most of them aren't helping, and some of them are hindering us.

The algorithm will be:

The program provided does just that.

Download

delete_downgraded_libraries.zip

Preparation

unzip delete_downgraded_libraries.zip
cd delete_downgraded_libraries
python3 -mvenv .venv
. .venv/bin/activate
pip install -r requirements.txt
./delete_downgraded_libraries.py --help

Usage

Produce a report

./delete_downgraded_libraries.py /path/to/commerical/application

List what would be deleted

./delete_downgraded_libraries.py /path/to/commerical/application --delete --dryrun

Actually delete the files

./delete_downgraded_libraries.py /path/to/commerical/application --delete

Peter Benie <peterb@chiark.greenend.org.uk>
Linux