Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 908613 - <sys-apps/shadow-4.13-r4: possible password leak during passwd(1) change
Summary: <sys-apps/shadow-4.13-r4: possible password leak during passwd(1) change
Alias: None
Product: Gentoo Security
Classification: Unclassified
Component: Vulnerabilities (show other bugs)
Hardware: All Linux
: Normal minor (vote)
Assignee: Gentoo Security
Whiteboard: B3 [glsa? cleanup]
Depends on: 909740
  Show dependency tree
Reported: 2023-06-17 02:29 UTC by Sam James
Modified: 2023-12-12 07:34 UTC (History)
1 user (show)

See Also:
Package list:
Runtime testing required: ---


Note You need to log in before you can comment on or make changes to this bug.
Description Sam James archtester Gentoo Infrastructure gentoo-dev Security 2023-06-17 02:29:11 UTC
The commit message describes it in detail (

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

-  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

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 /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
> 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

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.
Comment 1 Larry the Git Cow gentoo-dev 2023-06-17 02:40:22 UTC
The bug has been referenced in the following commit(s):

commit 16921604a6bd3ec292570577a472d18aebe60389
Author:     Sam James <>
AuthorDate: 2023-06-17 02:29:25 +0000
Commit:     Sam James <>
CommitDate: 2023-06-17 02:32:11 +0000

    sys-apps/shadow: backport password leak fix, backport usermod gid --prefix fix
    Signed-off-by: Sam James <>

 .../shadow/files/shadow-4.13-password-leak.patch   | 135 +++++++++++
 .../files/shadow-4.13-usermod-prefix-gid.patch     |  33 +++
 sys-apps/shadow/shadow-4.13-r4.ebuild              | 268 +++++++++++++++++++++
 3 files changed, 436 insertions(+)
Comment 2 Sam James archtester Gentoo Infrastructure gentoo-dev Security 2023-06-19 02:56:32 UTC
fwiw I went for B as it's supposedly not particularly easy to exploit, but A is fine as well
Comment 3 John Helmert III archtester Gentoo Infrastructure gentoo-dev Security 2023-06-19 03:15:51 UTC
Ah, you're right, we can treat it that way despite not quite being a "configuration". One day we'll make a better rating system...