Control: tags -1 + patch

Added Md to Cc to have him review the sanity checks.

On Fri, Jul 19, 2024 at 08:20:05AM +0200, Helmut Grohne wrote:
> thanks for the extra information. Especially the history.log contains
> most of the versions at play. I have given it some attempts to reproduce
> the problem (in particular going to bookworm, upgrading to your dpkg
> version and then completing the dist upgrade to unstable), but I was
> entirely unsuccessful reproducing the failure thus far. I must be
> missing something relevant still. I need to attempt reproducing your
> full package set next, but cannot do so right now.

I believe I managed to figure out what is going on thanks to the
extensive feedback provided. The clue that lib64 was pointing to lib was
important and that is key to reproducing the issue.

mmdebstrap bookworm /dev/null http://deb.debian.org/debian --variant=apt 
--include=busybox-static --chrooted-customize-hook='busybox mv lib64/* lib/ && 
busybox rm lib64 && busybox ln -s lib lib64 && ls -la && sed -i -e 
s/bookworm/sid/ etc/apt/sources.list && apt-get update && apt-get install 
base-files'

A bit of explanations are probably in order. I explicitly pass a mirror
to avoid automatically including a security archive which would make
upgrading more difficult. I install busybox-static as the hook
temporarily breaks the dynamic loader. The resulting output is quite
close to what you reported:

| I: running --chrooted-customize-hook in shell: sh -c 'busybox mv lib64/* lib/ 
&& busybox rm lib64 && busybox ln -s lib lib64 && ls -la && sed -i -e 
s/bookworm/sid/ etc/apt/sources.list && apt-get update && apt-get install 
base-files'
| total 0
| drwxr-xr-x  17 root   root     420 Jul 25 15:19 .
| drwxr-xr-x  17 root   root     420 Jul 25 15:19 ..
| lrwxrwxrwx   1 root   root       7 Jul 25 15:19 bin -> usr/bin
| drwxr-xr-x   2 root   root      40 Mar 29 17:20 boot
| drwxr-xr-x   4 root   root     320 Jul 25 15:19 dev
| drwxr-xr-x  29 root   root    1280 Jul 25 15:19 etc
| drwxr-xr-x   2 root   root      40 Mar 29 17:20 home
| lrwxrwxrwx   1 root   root       7 Jul 25 15:19 lib -> usr/lib
| lrwxrwxrwx   1 root   root       3 Jul 25 15:19 lib64 -> lib
| drwxr-xr-x   2 root   root      40 Jul 25 15:19 media
| drwxr-xr-x   2 root   root      40 Jul 25 15:19 mnt
| drwxr-xr-x   2 root   root      40 Jul 25 15:19 opt
| dr-xr-xr-x 381 nobody nogroup    0 Jul 25 15:19 proc
| drwx------   2 root   root      80 Jul 25 15:19 root
| drwxr-xr-x   3 root   root      60 Jul 25 15:19 run
| lrwxrwxrwx   1 root   root       8 Jul 25 15:19 sbin -> usr/sbin
| drwxr-xr-x   2 root   root      40 Jul 25 15:19 srv
| drwxr-xr-x   2 root   root      40 Mar 29 17:20 sys
| drwxrwxrwt   2 root   root      60 Jul 25 15:19 tmp
| drwxr-xr-x  12 root   root     240 Jul 25 15:19 usr
| drwxr-xr-x  11 root   root     260 Jul 25 15:19 var
| Get:1 http://deb.debian.org/debian sid InRelease [198 kB]
| Get:2 http://deb.debian.org/debian sid/main amd64 Packages [10.0 MB]
| Fetched 10.2 MB in 1s (8851 kB/s)
| Reading package lists... Done
| Reading package lists... Done
| Building dependency tree... Done
| Reading state information... Done
| The following packages will be upgraded:
|   base-files
| 1 upgraded, 0 newly installed, 0 to remove and 79 not upgraded.
| Need to get 72.3 kB of archives.
| After this operation, 7168 B of additional disk space will be used.
| Get:1 http://deb.debian.org/debian sid/main amd64 base-files amd64 13.3 [72.3 
kB]
| Fetched 72.3 kB in 0s (7001 kB/s)
| debconf: delaying package configuration, since apt-utils is not installed
| (Reading database ... 6713 files and directories currently installed.)
| Preparing to unpack .../base-files_13.3_amd64.deb ...
| Unpacking base-files (13.3) over (12.4+deb12u6) ...
| dpkg: error processing archive 
/var/cache/apt/archives/base-files_13.3_amd64.deb (--unpack):
|  trying to overwrite '/lib64', which is also in package libc6:amd64 
2.36-9+deb12u7
| Errors were encountered while processing:
|  /var/cache/apt/archives/base-files_13.3_amd64.deb
| E: Sub-process /usr/bin/dpkg returned an error code (1)

I believe that this settles the question of what is going on here.

I also argue that setting up /lib64 in this way is unsupportable in
Debian. We may still consider improving the diagnostics though.

The usr-is-merged.preinst actually reads the symbolic links and verifies
their link targets:

|    [ "$(readlink -f "$DPKG_ROOT$dir")" = "$DPKG_ROOT/usr$dir" ] || return 1

There are two forms of links in the wild, absolute and relative with
relative being the standard way. This check will accept both absolute
and relative ones when $DPKG_ROOT is empty and accept relative ones only
when $DPKG_ROOT is non-empty. I'm not sure whether we consider absolute
ones supported in any way, but usrmerge, debootstrap and base-files all
agree to create them as relative and base-files will fail to unpack in
the same way when they're not relative.

This suggests that base-files.preinst should use stronger checks and
decline unpacking unless the aliasing symlinks are all verified and pose
a more useful error message.

I am attaching a patch for base-files that improves the diagnostics for
this situation. With the patch it fails this way:

| (Reading database ... 6713 files and directories currently installed.)
| Preparing to unpack b.deb ...
| 
| 
| ******************************************************************************
| *
| * The base-files package cannot be installed because
| * /lib64 is a symbolic link and not pointing at usr/lib64 exactly.
| *
| * This is an unexpected situation. Cannot proceed with the upgrade.
| *
| * For more information please read https://wiki.debian.org/UsrMerge.
| *
| ******************************************************************************
| 
| 
| dpkg: error processing archive b.deb (--install):
|  new base-files package pre-installation script subprocess returned error 
exit status 1
| Errors were encountered while processing:
|  b.deb

For comparison, upgrading a split-/usr bookwork would fail like this:

| (Reading database ... 4675 files and directories currently installed.)
| Preparing to unpack b.deb ...
| 
| 
| ******************************************************************************
| *
| * The base-files package cannot be installed because
| * /bin is a directory, but should be a symbolic link.
| *
| * Please install the usrmerge package to convert this system to merged-/usr.
| *
| * For more information please read https://wiki.debian.org/UsrMerge.
| *
| ******************************************************************************
| 
| 
| dpkg: error processing archive b.deb (--install):
|  new base-files package pre-installation script subprocess returned error 
exit status 1
| Errors were encountered while processing:
|  b.deb

Helmut
diff --minimal -Nru base-files-13.3/debian/changelog 
base-files-13.3+nmu1/debian/changelog
--- base-files-13.3/debian/changelog    2024-06-05 15:14:03.000000000 +0200
+++ base-files-13.3+nmu1/debian/changelog       2024-07-25 17:47:46.000000000 
+0200
@@ -1,3 +1,10 @@
+base-files (13.3+nmu1) UNRELEASED; urgency=medium
+
+  * Non-maintainer upload.
+  * Tighten the merged-/usr preinst check. Closes: #1076491.
+
+ -- Helmut Grohne <[email protected]>  Thu, 25 Jul 2024 17:47:46 +0200
+
 base-files (13.3) unstable; urgency=medium
 
   [ Helmut Grohne ]
diff --minimal -Nru base-files-13.3/debian/preinst 
base-files-13.3+nmu1/debian/preinst
--- base-files-13.3/debian/preinst      2024-06-05 15:14:03.000000000 +0200
+++ base-files-13.3+nmu1/debian/preinst 2024-07-25 17:47:46.000000000 +0200
@@ -2,17 +2,29 @@
 set -e
 
 if [ "$1" = "install" ] || [ "$1" = "upgrade" ]; then
+  msg=
   for d in bin lib lib32 lib64 libo32 lib64 sbin; do
-    if [ -d "$DPKG_ROOT/$d" ] && [ ! -L "$DPKG_ROOT/$d" ]; then
+    if [ -L "$DPKG_ROOT/$d" ]; then
+      if [ "$(readlink "$DPKG_ROOT/$d")" != "usr/$d" ]; then
+        msg="/$d is a symbolic link and not pointing at usr/$d exactly"
+      elif [ ! -d "$DPKG_ROOT/usr/$d" ]; then
+        msg="/$d is a dangling symbolic link"
+      fi
+      msg2="This is an unexpected situation. Cannot proceed with the upgrade"
+    elif [ -d "$DPKG_ROOT/$d" ]; then
+      msg="/$d is a directory, but should be a symbolic link"
+      msg2="Please install the usrmerge package to convert this system to 
merged-/usr"
+    fi
+    if [ -n "$msg" ]; then
       cat <<EOF
 
 
 ******************************************************************************
 *
-* The base-files package cannot be installed because this system has a
-* split /usr.
+* The base-files package cannot be installed because
+* $msg.
 *
-* Please install the usrmerge package to convert this system to merged-/usr.
+* $msg2.
 *
 * For more information please read https://wiki.debian.org/UsrMerge.
 *

Reply via email to