From: Tobias Stoeckmann Date: Tue, 16 Dec 2025 13:00:54 +0000 (+0100) Subject: passwd: Fix TOCTOU race condition (no PAM) X-Git-Tag: 4.19.0~34 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f787a0c7d59a91e62bc58ff826956d3f067e3a89;p=thirdparty%2Fshadow.git passwd: Fix TOCTOU race condition (no PAM) The passwd tool checks if the password of a user may be changed before locking the passwd/shadow files. This leaves a time window to perform the same action twice (e.g. circumventing PASS_MIN_DAYS limit) or to circumvent a locked password by an administrator. Perform the check after the lock again. This keeps the behavior as it is today for a user and also prevents the race condition. Reviewed-by: Alejandro Colomar Signed-off-by: Tobias Stoeckmann --- diff --git a/src/passwd.c b/src/passwd.c index fe6ae6683..17cda7745 100644 --- a/src/passwd.c +++ b/src/passwd.c @@ -649,6 +649,7 @@ static void update_noshadow(bool process_selinux) Prog, name, pw_dbname ()); fail_exit (E_NOPERM, process_selinux); } + check_password(pw, pwd_to_spwd(pw), process_selinux); npw = __pw_dup (pw); if (NULL == npw) { oom (process_selinux); @@ -664,6 +665,7 @@ static void update_noshadow(bool process_selinux) static void update_shadow(bool process_selinux) { + const struct passwd pw = { .pw_passwd = SHADOW_PASSWD_STRING }; const struct spwd *sp; struct spwd *nsp; @@ -673,6 +675,7 @@ static void update_shadow(bool process_selinux) update_noshadow (process_selinux); return; } + check_password(&pw, sp, process_selinux); nsp = __spw_dup (sp); if (NULL == nsp) { oom (process_selinux);