Package: release.debian.org
Severity: normal
Tags: bullseye
User: release.debian....@packages.debian.org
Usertags: pu

[ Reason ]
There is a path canonicalization bug in update-shells that may lead to
- insertion of duplicate entries in /etc/shells
- failure to remove obsolete entries from /etc/shells
on merged-/usr systems. This is triggered if the shell itself is a
symlink, e.g. in 9base it is managed via update-alternatives.
Furthermore the handling of /bin/sh by update-shells was inconsistent
with all other shells, e.g. update-shells didn't generate the
corresponding /usr/bin/sh entry (while usrmerge did).
Miscanonicalization could also lead to invalid (i.e. nonexistent) paths
added to /etc/shells, although that does not happen with the packages
currently in the archive.

[ Impact ]
The bad entries in /etc/shells are probably harmless for normal
operation (duplicate or stale entries), but nasty for QA tooling
checking for inconsistencies. I prefer to fix these issues properly
(where possible) instead of working around them (or ignoring them) in QA
tools.

[ Tests ]
piuparts install and upgrade tests of all packages making use of
update-shells using the fixed package in merged-/usr and unmerged-/usr
contexts. No inconsistencies in /etc/shells (missing or leftover
entries) were found after the fixed package was applied.

[ Risks ]
Low. The changes are fairly minimal.

[ Checklist ]
  [x] *all* changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in (old)stable
  [x] the issue is verified as fixed in unstable

[ Changes ]
- try to avoid creating duplicate entries in /etc/shells (using the same
  mechanism that is already used multiple times in update-shells)
  (duplicates should no longer happen with the canonicalization bug
  fixed, unless a shell is defined multiple times in shells.d, so let's
  fix these, too)
- handle /bin/sh (which is defined in /usr/share/debianutils/shells (the
  template for /etc/shells) but not in /usr/share/debianutils/shells.d/)
  like any other shell by treating the template file as if it were part
  of shells.d/
- canonicalize only the directory of the shell (not the shell itself)
  to compute the shell in an aliased location (on merged-/usr systems)
This is rebuild of the package from sid with no further changes.

[ Other info ]
With these fixes applied, my intent is to make usrmerge call
update-shells to ensure the state file of update-shells is updated after
the usrmerge conversion, too.


Andreas
diff --git a/debian/changelog b/debian/changelog
index eb37be1..b50154c 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,19 @@
+debianutils (5.7-0.5~deb12u1) bookworm; urgency=medium
+
+  * Rebuild for bookworm.
+
+ -- Andreas Beckmann <a...@debian.org>  Mon, 03 Jul 2023 13:56:27 +0200
+
+debianutils (5.7-0.5) unstable; urgency=medium
+
+  * Non-maintainer upload.
+  * update-shells: Do not create duplicate entries in /etc/shells.
+  * update-shells: Manage (/usr)/bin/sh in the state file.
+  * update-shells: Fix canonicalization of shells in aliased locations.
+    (Closes: #1035820)
+
+ -- Andreas Beckmann <a...@debian.org>  Thu, 22 Jun 2023 21:59:33 +0200
+
 debianutils (5.7-0.4) unstable; urgency=medium
 
   * Non-maintainer upload
diff --git a/debian/patches/dpkg-root b/debian/patches/dpkg-root.patch
similarity index 87%
rename from debian/patches/dpkg-root
rename to debian/patches/dpkg-root.patch
index 2641b70..ead43a1 100644
--- a/debian/patches/dpkg-root
+++ b/debian/patches/dpkg-root.patch
@@ -1,3 +1,6 @@
+Author: Johannes Schauer Marin Rodrigues <jo...@debian.org>
+Description: set the default for ROOT to $DPKG_ROOT
+
 --- a/update-shells
 +++ b/update-shells
 @@ -23,7 +23,7 @@ log() {
diff --git a/debian/patches/fix-aliased-location.patch 
b/debian/patches/fix-aliased-location.patch
new file mode 100644
index 0000000..97e1efe
--- /dev/null
+++ b/debian/patches/fix-aliased-location.patch
@@ -0,0 +1,18 @@
+Author: Andreas Beckmann <a...@debian.org>
+Description: fix detection of shells in aliased locations
+ only canonicalize the directory where the shell resides,
+ not the shell itself (which may be a symlink, e.g. managed by
+ update-alternatives)
+Bug-Debian: https://bugs.debian.org/1035820
+
+--- a/update-shells
++++ b/update-shells
+@@ -80,7 +80,7 @@ for f in "$TEMPLATE_ETC_FILE" "$PKG_DIR/
+       while IFS='#' read -r line _; do
+               [ -n "$line" ] || continue
+               PKG_SHELLS="$PKG_SHELLS$line#"
+-              realshell=$(dirname "$(dpkg-realpath --root "$ROOT" 
"$line")")/$(basename "$line")
++              realshell=$(dpkg-realpath --root "$ROOT" "$(dirname 
"$line")")/$(basename "$line")
+               if [ "$line" != "$realshell" ]; then
+                       PKG_SHELLS="$PKG_SHELLS$realshell#"
+               fi
diff --git a/debian/patches/manage-usr-bin-sh.patch 
b/debian/patches/manage-usr-bin-sh.patch
new file mode 100644
index 0000000..b9122e9
--- /dev/null
+++ b/debian/patches/manage-usr-bin-sh.patch
@@ -0,0 +1,29 @@
+Author: Andreas Beckmann <a...@debian.org>
+Description: manage (/usr)/bin/sh in the state file
+
+--- a/update-shells
++++ b/update-shells
+@@ -63,19 +63,20 @@ done
+ 
+ PKG_DIR="$ROOT/usr/share/debianutils/shells.d"
+ STATE_FILE="$ROOT/var/lib/shells.state"
++TEMPLATE_ETC_FILE="$ROOT/usr/share/debianutils/shells"
+ TARGET_ETC_FILE="$ROOT/etc/shells"
+ SOURCE_ETC_FILE="$TARGET_ETC_FILE"
+ NEW_ETC_FILE="$TARGET_ETC_FILE.tmp"
+ NEW_STATE_FILE="$STATE_FILE.tmp"
+ 
+ if ! test -e "$SOURCE_ETC_FILE"; then
+-      SOURCE_ETC_FILE="$ROOT/usr/share/debianutils/shells"
++      SOURCE_ETC_FILE="$TEMPLATE_ETC_FILE"
+ fi
+ 
+ PKG_SHELLS='#'
+ LC_COLLATE=C.UTF-8  # glob in reproducible order
+-for f in "$PKG_DIR/"*; do
+-      [ "$f" = "$PKG_DIR/*" ] && break
++for f in "$TEMPLATE_ETC_FILE" "$PKG_DIR/"*; do
++      test -f "$f" || continue
+       while IFS='#' read -r line _; do
+               [ -n "$line" ] || continue
+               PKG_SHELLS="$PKG_SHELLS$line#"
diff --git a/debian/patches/no-duplicates.patch 
b/debian/patches/no-duplicates.patch
new file mode 100644
index 0000000..2c797de
--- /dev/null
+++ b/debian/patches/no-duplicates.patch
@@ -0,0 +1,18 @@
+Author: Andreas Beckmann <a...@debian.org>
+Description: do not create duplicate entries in /etc/shells
+
+--- a/update-shells
++++ b/update-shells
+@@ -106,8 +106,10 @@ while IFS= read -r line; do
+       if [ -z "$shell" ] ||
+                       hashset_contains "$PKG_SHELLS" "$shell" ||
+                       ! hashset_contains "$STATE_SHELLS" "$shell"; then
+-              echo "$line" >> "$NEW_ETC_FILE"
+-              ETC_SHELLS="$ETC_SHELLS$shell#"
++              if [ -z "$shell" ] || ! hashset_contains "$ETC_SHELLS" 
"$shell"; then
++                      echo "$line" >> "$NEW_ETC_FILE"
++                      ETC_SHELLS="$ETC_SHELLS$shell#"
++              fi
+       else
+               log "removing shell $shell"
+       fi
diff --git a/debian/patches/series b/debian/patches/series
index fdbf332..d09aed9 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1 +1,4 @@
-dpkg-root
+dpkg-root.patch
+no-duplicates.patch
+manage-usr-bin-sh.patch
+fix-aliased-location.patch

Reply via email to