** 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.
  
+ For ubuntu-release-upgrader testing:
+ 
+ Danging symlink case
+ 
+ * lxc launch ubuntu:r urutest
+ * lxc shell urutest
+ * Check /libx32 does not exist
+ * sudo ln -s usr/libx32 /libx32 # makes a broken symlink
+ * sudo do-release-upgrade
+ * Note that upgrade does not attempt to remove symlink (terminate early)
+ * sudo do-release-upgrade --proposed
+ * Note that dangling symlink is removed and upgrade proceeds
+ 
+ Unexpected symlink case
+ 
+ * lxc launch ubuntu:r urutest
+ * lxc shell urutest
+ * Check /libx32 does not exist
+ * sudo mkdir /foo
+ * sudo ln -s foo /libx32
+ * sudo do-release-upgrade
+ * Note that upgrade does not complain and starts successfully (terminate 
early)
+ * sudo do-release-upgrade --proposed
+ * Upgrader should produce error and refuse to proceed
+ 
+ Not-a-symlink case
+ 
+ * lxc launch ubuntu:r urutest
+ * lxc shell urutest
+ * Check /libx32 does not exist
+ * sudo mkdir /libx32 /usr/libx32
+ * sudo do-release-upgrade
+ * Note that upgrade does not complain and starts successfully (terminate 
early)
+ * sudo do-release-upgrade --proposed
+ * Upgrader should produce error and refuse to proceed
+ 
  [ 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
  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:
  [SRU] 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

Reply via email to