** Description changed: + [ Impact ] + + The base-files preinst refuses to install or upgrade when one of the + multilib aliasing symlinks (/lib32, /libo32, /libx32) points at a + /usr/<dir> that no longer exists: + + ``` + The base-files package cannot be installed because + /lib32 is a dangling symbolic link. + ``` + + These symlinks are optional and are created/removed on demand by the + base-files postinst (via a file trigger on /usr/<dir>). They can be + left dangling, e.g. when the last package shipping files in /usr/lib32 + is removed. Affected users cannot upgrade base-files, which breaks apt + upgrades and release upgrades in some reported cases leaving the + system unbootable (Comment #15) + + The fix makes the preinst remove a dangling multilib aliasing symlink + instead of aborting. The postinst recreates it if /usr/<dir> appears + later. Dangling /bin, /lib, /sbin (and the rtld dir, e.g. /lib64 on + amd64) are still treated as fatal. + + [ Test Plan ] + + In a fresh resolute (resp. stonking) container or VM (amd64): + + 1. Confirm the multilib dir is absent: + + ``` + $ ls -ld /usr/lib32 /usr/libo32 /usr/libx32 /lib32 /libo32 /libx32 + ``` + + All should report "No such file or directory". + + 2. Reproduce with the current version: + + ``` + $ sudo ln -s usr/lib32 /lib32 + $ sudo ln -s usr/libo32 /libo32 + $ sudo ln -s usr/libx32 /libx32 + $ sudo apt install --reinstall base-files + ``` + + Expected: dpkg fails with + `/lib32 is a dangling symbolic link ... Cannot proceed with the upgrade` + + The old preinst stops at the first problem it finds, so it reports + `/lib32` even though all three links are broken. + + 3. Enable `-proposed` and upgrade: + + ``` + $ sudo apt install -t <series>-proposed base-files + ``` + + Expected: + ``` + Removing dangling /lib32 symbolic link. + Removing dangling /libo32 symbolic link. + Removing dangling /libx32 symbolic link. + ``` + + is printed, the install succeeds, `dpkg -s base-files` shows the new + version as installed, and: + + ``` + $ ls -ld /lib32 /libo32 /libx32 + ``` + + reports "No such file or directory" for all three. + + 4. Regression check, valid symlink kept and trigger still works: + + ``` + $ sudo apt install libc6-i386 + $ ls -ld /usr/lib32 # directory exists + $ readlink /lib32 # -> usr/lib32 (created by the base-files trigger) + $ sudo apt install --reinstall base-files + ``` + + Expected: the install succeeds, NO `Removing dangling` message is + printed. + + ``` + $ readlink /lib32 # still -> usr/lib32 + $ sudo apt purge libc6-i386 && sudo apt autoremove --purge + $ ls -ld /usr/lib32 /lib32 + ``` + + Expected: both report `No such file or directory`. The trigger removes + /lib32 once /usr/lib32 is gone, so the link is never left dangling. + + [ Where problems could occur ] + + The change only affects the preinst branch where /<dir> is a symlink + to usr/<dir> and /usr/<dir> does not exist, and only for the multilib + aliasing dirs (lib32, libo32, libx32 and, on archs whose rtld dir is + not /lib64, lib64). In that state the symlink resolves to nothing, so + removing it cannot break path lookups. If something did rely on the + symlink existing (not its target), it would no longer find it. The + postinst/trigger recreates it as soon as /usr/<dir> exists again. + + A mistake in the directory list could make the preinst delete an + essential symlink such as /lib64. The list comes from the same + `USR_MERGE_MULTILIB` build variable already used by the postinst and + trigger, which excludes bin, lib, sbin and the rtld dir. + + [ Other Info ] + + The test plan is run on amd64 only. This is sufficient because the + preinst itself is architecture-independent shell code, and the only + per-arch difference is the directory list substituted for + `#USR_MERGE_MULTILIB#` at build time, which debian/rules derives from + the architecture's rtld dir: + + - amd64, ppc64el: lib32 libo32 libx32 + - arm64, armhf, riscv64, s390x, i386: lib32 lib64 libo32 libx32 + + The same list is already substituted into the postinst and used for + the file triggers, so it is not new per-arch logic introduced by this + SRU. The changes run same commands for every entry in the list (an + echo and an rm of /<dir>), so exercising them on amd64 for lib32, + libo32 and libx32 covers the code path that every architecture runs. + + [ Original Description ] + + Check on the report ProblemType: Package DistroRelease: Ubuntu 24.04 Package: base-files 13ubuntu10.2 Uname: Linux 6.16.0-061600rc6-generic x86_64 ApportVersion: 2.28.1-0ubuntu3.8 Architecture: amd64 CasperMD5CheckResult: pass Date: Fri Nov 14 12:51:22 2025 ErrorMessage: new base-files package pre-installation script subprocess returned error exit status 1 InstallationDate: Installed on 2023-08-09 (828 days ago) InstallationMedia: Ubuntu 22.04.1 LTS "Jammy Jellyfish" - Release amd64 (20220809.1) Python3Details: /usr/bin/python3.12, Python 3.12.3, python3-minimal, 3.12.3-0ubuntu2 PythonDetails: N/A RelatedPackageVersions: - dpkg 1.22.6ubuntu6.1 - apt 2.8.3 + dpkg 1.22.6ubuntu6.1 + apt 2.8.3 SourcePackage: base-files Title: package base-files 13ubuntu10.2 failed to install/upgrade: new base-files package pre-installation script subprocess returned error exit status 1 UpgradeStatus: Upgraded to noble on 2025-01-15 (303 days ago)
-- You received this bug notification because you are a member of Ubuntu Bugs, which is subscribed to Ubuntu. https://bugs.launchpad.net/bugs/2131303 Title: package base-files 13ubuntu10.2 failed to install/upgrade: new base- files package pre-installation script subprocess returned error exit status 1: /lib32 is a dangling symbolic link To manage notifications about this bug go to: https://bugs.launchpad.net/ubuntu/+source/base-files/+bug/2131303/+subscriptions -- ubuntu-bugs mailing list [email protected] https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs
