[Pkg-shadow-devel] Bug#1102139: bookworm-pu: package shadow/4.13+dfsg1-2

Chris Hofstaedtler zeha at debian.org
Sat Apr 5 16:22:41 BST 2025


Package: release.debian.org
Severity: normal
Tags: bookworm
User: release.debian.org at packages.debian.org
Usertags: pu
X-Debbugs-Cc: shadow at packages.debian.org, team at security.debian.org
Control: affects -1 + src:shadow

[ Reason ]

Fixes two security issues, long fixed in unstable.

CVE-2023-4641 and CVE-2023-29383 

[ Impact ]

gpasswd and chfn utilities are the targets of the fixes.

[ Tests ]

For CVE-2023-29383 I've performed a manual test showing that the issue 
is fixed. For CVE-2023-4641 I'm not sure how to trigger that.

[ Risks ]

Both CVEs have upstream fixes, which got cherry-picked into unstable in 
1:4.13+dfsg1-2 and 1:4.13+dfsg1-3. The patches are not very long.



[ 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 ]

Two patches to fix the security issues and a regression fix for the 
second fix are cherry picked from upstream. We had these in 
1:4.13+dfsg1-3 for a long time.

I've also updated the Uploaders: field to match unstable.

[ Other info ]

Nothing I'm aware of.
-------------- next part --------------
diff -Nru shadow-4.13+dfsg1/debian/changelog shadow-4.13+dfsg1/debian/changelog
--- shadow-4.13+dfsg1/debian/changelog	2022-11-11 09:28:15.000000000 +0100
+++ shadow-4.13+dfsg1/debian/changelog	2025-04-05 17:02:05.000000000 +0200
@@ -1,3 +1,17 @@
+shadow (1:4.13+dfsg1-2) bookworm; urgency=medium
+
+  [ Balint Reczey ]
+  * Cherry-pick upstream patch to fix gpasswd passwd leak (Closes: #1051062)
+    CVE-2023-4641
+  * Cherry-pick upstream patch to fix chfn vulnerability (Closes: #1034482)
+    CVE-2023-29383
+  * Fix valid_field() that regressed in upstream's chfn fix
+
+  [ Chris Hofstaedtler ]
+  * Update Uploaders: field from unstable
+
+ -- Chris Hofstaedtler <zeha at debian.org>  Sat, 05 Apr 2025 17:02:05 +0200
+
 shadow (1:4.13+dfsg1-1) unstable; urgency=medium
 
   [ Balint Reczey ]
diff -Nru shadow-4.13+dfsg1/debian/control shadow-4.13+dfsg1/debian/control
--- shadow-4.13+dfsg1/debian/control	2022-11-11 09:28:15.000000000 +0100
+++ shadow-4.13+dfsg1/debian/control	2025-04-05 17:01:47.000000000 +0200
@@ -1,7 +1,8 @@
 Source: shadow
 Maintainer: Shadow package maintainers <pkg-shadow-devel at lists.alioth.debian.org>
-Uploaders: Balint Reczey <balint at balintreczey.hu>,
-           Serge Hallyn <serge at hallyn.com>
+Uploaders:
+ Serge Hallyn <serge at hallyn.com>,
+ Chris Hofstaedtler <zeha at debian.org>
 Section: admin
 Priority: required
 Build-Depends: debhelper-compat (= 13),
diff -Nru shadow-4.13+dfsg1/debian/patches/0001-gpasswd-1-Fix-password-leak.patch shadow-4.13+dfsg1/debian/patches/0001-gpasswd-1-Fix-password-leak.patch
--- shadow-4.13+dfsg1/debian/patches/0001-gpasswd-1-Fix-password-leak.patch	1970-01-01 01:00:00.000000000 +0100
+++ shadow-4.13+dfsg1/debian/patches/0001-gpasswd-1-Fix-password-leak.patch	2025-04-05 17:01:40.000000000 +0200
@@ -0,0 +1,137 @@
+From 65c88a43a23c2391dcc90c0abda3e839e9c57904 Mon Sep 17 00:00:00 2001
+From: Alejandro Colomar <alx at kernel.org>
+Date: Sat, 10 Jun 2023 16:20:05 +0200
+Subject: [PATCH] gpasswd(1): Fix password leak
+
+How to trigger this password leak?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When gpasswd(1) asks for the new password, it asks twice (as is usual
+for confirming the new password).  Each of those 2 password prompts
+uses agetpass() to get the password.  If the second agetpass() fails,
+the first password, which has been copied into the 'static' buffer
+'pass' via STRFCPY(), wasn't being zeroed.
+
+agetpass() is defined in <./libmisc/agetpass.c> (around line 91), and
+can fail for any of the following reasons:
+
+-  malloc(3) or readpassphrase(3) failure.
+
+   These are going to be difficult to trigger.  Maybe getting the system
+   to the limits of memory utilization at that exact point, so that the
+   next malloc(3) gets ENOMEM, and possibly even the OOM is triggered.
+   About readpassphrase(3), ENFILE and EINTR seem the only plausible
+   ones, and EINTR probably requires privilege or being the same user;
+   but I wouldn't discard ENFILE so easily, if a process starts opening
+   files.
+
+-  The password is longer than PASS_MAX.
+
+   The is plausible with physical access.  However, at that point, a
+   keylogger will be a much simpler attack.
+
+And, the attacker must be able to know when the second password is being
+introduced, which is not going to be easy.
+
+How to read the password after the leak?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Provoking the leak yourself at the right point by entering a very long
+password is easy, and inspecting the process stack at that point should
+be doable.  Try to find some consistent patterns.
+
+Then, search for those patterns in free memory, right after the victim
+leaks their password.
+
+Once you get the leak, a program should read all the free memory
+searching for patterns that gpasswd(1) leaves nearby the leaked
+password.
+
+On 6/10/23 03:14, Seth Arnold wrote:
+> An attacker process wouldn't be able to use malloc(3) for this task.
+> There's a handful of tools available for userspace to allocate memory:
+>
+> -  brk / sbrk
+> -  mmap MAP_ANONYMOUS
+> -  mmap /dev/zero
+> -  mmap some other file
+> -  shm_open
+> -  shmget
+>
+> Most of these return only pages of zeros to a process.  Using mmap of an
+> existing file, you can get some of the contents of the file demand-loaded
+> into the memory space on the first use.
+>
+> The MAP_UNINITIALIZED flag only works if the kernel was compiled with
+> CONFIG_MMAP_ALLOW_UNINITIALIZED.  This is rare.
+>
+> malloc(3) doesn't zero memory, to our collective frustration, but all the
+> garbage in the allocations is from previous allocations in the current
+> process.  It isn't leftover from other processes.
+>
+> The avenues available for reading the memory:
+> -  /dev/mem and /dev/kmem (requires root, not available with Secure Boot)
+> -  /proc/pid/mem (requires ptrace privileges, mediated by YAMA)
+> -  ptrace (requires ptrace privileges, mediated by YAMA)
+> -  causing memory to be swapped to disk, and then inspecting the swap
+>
+> These all require a certain amount of privileges.
+
+How to fix it?
+~~~~~~~~~~~~~~
+
+memzero(), which internally calls explicit_bzero(3), or whatever
+alternative the system provides with a slightly different name, will
+make sure that the buffer is zeroed in memory, and optimizations are not
+allowed to impede this zeroing.
+
+This is not really 100% effective, since compilers may place copies of
+the string somewhere hidden in the stack.  Those copies won't get zeroed
+by explicit_bzero(3).  However, that's arguably a compiler bug, since
+compilers should make everything possible to avoid optimizing strings
+that are later passed to explicit_bzero(3).  But we all know that
+sometimes it's impossible to have perfect knowledge in the compiler, so
+this is plausible.  Nevertheless, there's nothing we can do against such
+issues, except minimizing the time such passwords are stored in plain
+text.
+
+Security concerns
+~~~~~~~~~~~~~~~~~
+
+We believe this isn't easy to exploit.  Nevertheless, and since the fix
+is trivial, this fix should probably be applied soon, and backported to
+all supported distributions, to prevent someone else having more
+imagination than us to find a way.
+
+Affected versions
+~~~~~~~~~~~~~~~~~
+
+All.  Bug introduced in shadow 19990709.  That's the second commit in
+the git history.
+
+Fixes: 45c6603cc86c ("[svn-upgrade] Integrating new upstream version, shadow (19990709)")
+Reported-by: Alejandro Colomar <alx at kernel.org>
+Cc: Serge Hallyn <serge at hallyn.com>
+Cc: Iker Pedrosa <ipedrosa at redhat.com>
+Cc: Seth Arnold <seth.arnold at canonical.com>
+Cc: Christian Brauner <christian at brauner.io>
+Cc: Balint Reczey <rbalint at debian.org>
+Cc: Sam James <sam at gentoo.org>
+Cc: David Runge <dvzrv at archlinux.org>
+Cc: Andreas Jaeger <aj at suse.de>
+Cc: <~hallyn/shadow at lists.sr.ht>
+Signed-off-by: Alejandro Colomar <alx at kernel.org>
+---
+ src/gpasswd.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/src/gpasswd.c
++++ b/src/gpasswd.c
+@@ -896,6 +896,7 @@
+ 		strzero (cp);
+ 		cp = getpass (_("Re-enter new password: "));
+ 		if (NULL == cp) {
++			memzero (pass, sizeof pass);
+ 			exit (1);
+ 		}
+ 
diff -Nru shadow-4.13+dfsg1/debian/patches/0002-Added-control-character-check.patch shadow-4.13+dfsg1/debian/patches/0002-Added-control-character-check.patch
--- shadow-4.13+dfsg1/debian/patches/0002-Added-control-character-check.patch	1970-01-01 01:00:00.000000000 +0100
+++ shadow-4.13+dfsg1/debian/patches/0002-Added-control-character-check.patch	2025-04-05 17:01:40.000000000 +0200
@@ -0,0 +1,45 @@
+From e5905c4b84d4fb90aefcd96ee618411ebfac663d Mon Sep 17 00:00:00 2001
+From: tomspiderlabs <128755403+tomspiderlabs at users.noreply.github.com>
+Date: Thu, 23 Mar 2023 23:39:38 +0000
+Subject: [PATCH] Added control character check
+
+Added control character check, returning -1 (to "err") if control characters are present.
+---
+ lib/fields.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/lib/fields.c b/lib/fields.c
+index 640be931..fb51b582 100644
+--- a/lib/fields.c
++++ b/lib/fields.c
+@@ -21,9 +21,9 @@
+  *
+  * The supplied field is scanned for non-printable and other illegal
+  * characters.
+- *  + -1 is returned if an illegal character is present.
+- *  +  1 is returned if no illegal characters are present, but the field
+- *       contains a non-printable character.
++ *  + -1 is returned if an illegal or control character is present.
++ *  +  1 is returned if no illegal or control characters are present,
++ *       but the field contains a non-printable character.
+  *  +  0 is returned otherwise.
+  */
+ int valid_field (const char *field, const char *illegal)
+@@ -45,10 +45,13 @@ int valid_field (const char *field, const char *illegal)
+ 	}
+ 
+ 	if (0 == err) {
+-		/* Search if there are some non-printable characters */
++		/* Search if there are non-printable or control characters */
+ 		for (cp = field; '\0' != *cp; cp++) {
+ 			if (!isprint (*cp)) {
+ 				err = 1;
++			}
++			if (!iscntrl (*cp)) {
++				err = -1;
+ 				break;
+ 			}
+ 		}
+-- 
+2.34.1
+
diff -Nru shadow-4.13+dfsg1/debian/patches/0003-Overhaul-valid_field.patch shadow-4.13+dfsg1/debian/patches/0003-Overhaul-valid_field.patch
--- shadow-4.13+dfsg1/debian/patches/0003-Overhaul-valid_field.patch	1970-01-01 01:00:00.000000000 +0100
+++ shadow-4.13+dfsg1/debian/patches/0003-Overhaul-valid_field.patch	2025-04-05 17:01:40.000000000 +0200
@@ -0,0 +1,61 @@
+From 2eaea70111f65b16d55998386e4ceb4273c19eb4 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones at googlemail.com>
+Date: Fri, 31 Mar 2023 14:46:50 +0200
+Subject: [PATCH] Overhaul valid_field()
+
+e5905c4b ("Added control character check") introduced checking for
+control characters but had the logic inverted, so it rejects all
+characters that are not control ones.
+
+Cast the character to `unsigned char` before passing to the character
+checking functions to avoid UB.
+
+Use strpbrk(3) for the illegal character test and return early.
+---
+ lib/fields.c | 24 ++++++++++--------------
+ 1 file changed, 10 insertions(+), 14 deletions(-)
+
+diff --git a/lib/fields.c b/lib/fields.c
+index fb51b582..53929248 100644
+--- a/lib/fields.c
++++ b/lib/fields.c
+@@ -37,26 +37,22 @@ int valid_field (const char *field, const char *illegal)
+ 
+ 	/* For each character of field, search if it appears in the list
+ 	 * of illegal characters. */
++	if (illegal && NULL != strpbrk (field, illegal)) {
++		return -1;
++	}
++
++	/* Search if there are non-printable or control characters */
+ 	for (cp = field; '\0' != *cp; cp++) {
+-		if (strchr (illegal, *cp) != NULL) {
++		unsigned char c = *cp;
++		if (!isprint (c)) {
++			err = 1;
++		}
++		if (iscntrl (c)) {
+ 			err = -1;
+ 			break;
+ 		}
+ 	}
+ 
+-	if (0 == err) {
+-		/* Search if there are non-printable or control characters */
+-		for (cp = field; '\0' != *cp; cp++) {
+-			if (!isprint (*cp)) {
+-				err = 1;
+-			}
+-			if (!iscntrl (*cp)) {
+-				err = -1;
+-				break;
+-			}
+-		}
+-	}
+-
+ 	return err;
+ }
+ 
+-- 
+2.34.1
+
diff -Nru shadow-4.13+dfsg1/debian/patches/series shadow-4.13+dfsg1/debian/patches/series
--- shadow-4.13+dfsg1/debian/patches/series	2022-11-11 09:28:15.000000000 +0100
+++ shadow-4.13+dfsg1/debian/patches/series	2025-04-05 17:01:40.000000000 +0200
@@ -1,3 +1,10 @@
+# CVE-2023-4641
+0001-gpasswd-1-Fix-password-leak.patch
+
+# CVE-2023-29383
+0002-Added-control-character-check.patch
+0003-Overhaul-valid_field.patch
+
 # These patches are only for the testsuite:
 #900_testsuite_groupmems
 #901_testsuite_gcov


More information about the Pkg-shadow-devel mailing list