From 0ff87bf37a5f47d4bcc26911a9bd2818a8b8d866 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Sun, 14 Dec 2025 00:51:34 +0100 Subject: [PATCH] lib/, src/: Some empty lists have 0 elements, not 1 empty string In general, empty fields in a CSV are errors. However, in some cases, we want to allow passing empty lists, and the way to encode that is as an empty string. This was accidentally broken in 4.17.0, when we switched from using strtok(3) to strsep(3), without remembering to special-case an empty CSV. The bug affected directly groupadd(8) and groupmod(8). The bug also affected the library function add_groups(). In systems using PAM, that function is unused. On systems without PAM, it is called by the library function setup_uid_gid(), with the contents of the "CONSOLE_GROUPS" configuration (login.defs) CSV string. setup_uid_gid() is directly called by su(1) and login(1) on systems without PAM. setup_uid_gid() is also called by the library function expire(). expire() is directly called by expiry(1), su(1), and login(1). This bug is a regression introduced in the release 4.17.0, and present in the releases 4.17.{0..4} and 4.18.0. Fixes: 90afe61003ef (2024-12-05; "lib/, src/: Use strsep(3) instead of strtok(3)") Link: Reported-by: Osark Vieira Signed-off-by: Alejandro Colomar --- lib/addgrps.c | 3 ++- src/groupadd.c | 3 ++- src/groupmod.c | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/addgrps.c b/lib/addgrps.c index da7843f23..7768f1325 100644 --- a/lib/addgrps.c +++ b/lib/addgrps.c @@ -24,6 +24,7 @@ #include "shadow/grp/agetgroups.h" #include "shadowlog.h" #include "string/strchr/strchrscnt.h" +#include "string/strcmp/streq.h" #include "string/strerrno.h" @@ -52,7 +53,7 @@ add_groups(const char *list) if (dup == NULL) goto free_gids; - { + if (!streq(dup, "")) { while (NULL != (g = strsep(&p, ",:"))) { struct group *grp; diff --git a/src/groupadd.c b/src/groupadd.c index 7bb946b3c..fab8111b4 100644 --- a/src/groupadd.c +++ b/src/groupadd.c @@ -40,6 +40,7 @@ #include "shadow/gshadow/sgrp.h" #include "shadowlog.h" #include "string/memset/memzero.h" +#include "string/strcmp/streq.h" #include "string/strerrno.h" #include "string/strtok/stpsep.h" @@ -217,7 +218,7 @@ grp_update(void) } #endif /* SHADOWGRP */ - if (user_list) { + if (user_list && !streq(user_list, "")) { char *u, *ul; ul = user_list; diff --git a/src/groupmod.c b/src/groupmod.c index 4f9c9ea5f..5b90c2342 100644 --- a/src/groupmod.c +++ b/src/groupmod.c @@ -282,7 +282,7 @@ grp_update(void) } #endif /* SHADOWGRP */ - { + if (!streq(user_list, "")) { ul = user_list; while (NULL != (u = strsep(&ul, ","))) { if (prefix_getpwnam(u) == NULL) { -- 2.47.3