]> git.ipfire.org Git - thirdparty/shadow.git/commitdiff
src/gpasswd.c: fix segfault in clean up callbacks
authorIker Pedrosa <ipedrosa@redhat.com>
Fri, 19 Dec 2025 15:27:54 +0000 (16:27 +0100)
committerIker Pedrosa <ikerpedrosam@gmail.com>
Mon, 22 Dec 2025 17:55:33 +0000 (18:55 +0100)
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 <ipedrosa@redhat.com>
src/gpasswd.c

index 0ac6837c2c261adfd9e73572898c936c501f5b38..14c8f4f6091a11da75470b5ea852b6ca4d1da1b7 100644 (file)
@@ -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);