From: Iker Pedrosa Date: Fri, 19 Dec 2025 15:27:54 +0000 (+0100) Subject: src/gpasswd.c: fix segfault in clean up callbacks X-Git-Tag: 4.19.0~19 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=16a388c644bb124bc5523839f64587669e5c171d;p=thirdparty%2Fshadow.git src/gpasswd.c: fix segfault in clean up callbacks The gpasswd utility was segfaulting when cleanup functions were called because these functions expect a pointer to `process_selinux` but was being passed NULL. This caused a NULL pointer dereference. This commits adds the pointer to `process_selinux` to clean up functions making `gpasswd` consistent with other group utilities. Reproduction steps: $ useradd tuser $ groupadd tuser $ gpasswd -a tuser tgroup Adding user tuser to group tgroup Segmentation fault (core dumped) Fixes: 4d431898bad8 (2025-10-07; "src/gpasswd.c: chroot or prefix SELinux file context") Signed-off-by: Iker Pedrosa --- diff --git a/src/gpasswd.c b/src/gpasswd.c index 0ac6837c2..14c8f4f60 100644 --- a/src/gpasswd.c +++ b/src/gpasswd.c @@ -95,7 +95,7 @@ static void catch_signals (int killed); static bool is_valid_user_list (const char *users); static void process_flags (int argc, char **argv, struct option_flags *flags); static void check_flags (int argc, int opt_index); -static void open_files (void); +static void open_files(const struct option_flags *flags); static void close_files(const struct option_flags *flags); #ifdef SHADOWGRP static void get_group(struct group *gr, struct sgrp *sg, const struct option_flags *flags); @@ -338,15 +338,19 @@ static void check_flags (int argc, int opt_index) * * It will call exit in case of error. */ -static void open_files (void) +static void open_files(const struct option_flags *flags) { + static bool process_selinux; + + process_selinux = !flags->chroot; + if (gr_lock () == 0) { fprintf (stderr, _("%s: cannot lock %s; try again later.\n"), Prog, gr_dbname ()); exit (E_NOPERM); } - add_cleanup (cleanup_unlock_group, NULL); + add_cleanup (cleanup_unlock_group, &process_selinux); #ifdef SHADOWGRP if (is_shadowgrp) { @@ -356,7 +360,7 @@ static void open_files (void) Prog, sgr_dbname ()); exit (E_NOPERM); } - add_cleanup (cleanup_unlock_gshadow, NULL); + add_cleanup (cleanup_unlock_gshadow, &process_selinux); } #endif /* SHADOWGRP */ @@ -618,7 +622,7 @@ static void close_files(const struct option_flags *flags) add_cleanup (log_gpasswd_success_group, NULL); del_cleanup (log_gpasswd_failure_group); - cleanup_unlock_group (NULL); + cleanup_unlock_group (&process_selinux); del_cleanup (cleanup_unlock_group); #ifdef SHADOWGRP @@ -631,7 +635,7 @@ static void close_files(const struct option_flags *flags) } del_cleanup (log_gpasswd_failure_gshadow); - cleanup_unlock_gshadow (NULL); + cleanup_unlock_gshadow (&process_selinux); del_cleanup (cleanup_unlock_gshadow); } #endif /* SHADOWGRP */ @@ -1107,7 +1111,7 @@ int main (int argc, char **argv) } pwd_init (); - open_files (); + open_files (&flags); #ifdef SHADOWGRP update_group (&grent, &sgent);