]> git.ipfire.org Git - thirdparty/shadow.git/commitdiff
src/useradd.c: Add fmkstemp() to fix file-descriptor leak
authorAlejandro Colomar <alx@kernel.org>
Fri, 17 May 2024 11:40:58 +0000 (13:40 +0200)
committerAlejandro Colomar <alx@kernel.org>
Fri, 17 May 2024 23:15:10 +0000 (01:15 +0200)
This function creates a temporary file, and returns a FILE pointer to
it.  This avoids dealing with both a file descriptor and a FILE pointer,
and correctly deallocating the resources on error.

The code before this patch was leaking the file descriptor if fdopen(3)
failed.

Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
src/useradd.c

index ad2676c1cc82bb6de66a0390276e2660c43e4eb3..e0238457d1096b5565d0d7ee4cee63fa44c169b9 100644 (file)
@@ -238,6 +238,9 @@ static void create_home (void);
 static void create_mail (void);
 static void check_uid_range(int rflg, uid_t user_id);
 
+static FILE *fmkstemp(char *template);
+
+
 /*
  * fail_exit - undo as much as possible
  */
@@ -524,7 +527,6 @@ static void show_defaults (void)
  */
 static int set_defaults (void)
 {
-       int   ofd;
        int   ret = -1;
        bool  out_group = false;
        bool  out_groups = false;
@@ -582,15 +584,7 @@ static int set_defaults (void)
        /*
         * Create a temporary file to copy the new output to.
         */
-       ofd = mkstemp (new_file);
-       if (-1 == ofd) {
-               fprintf (stderr,
-                        _("%s: cannot create new defaults file\n"),
-                        Prog);
-               goto err_free_def;
-       }
-
-       ofp = fdopen (ofd, "w");
+       ofp = fmkstemp(new_file);
        if (NULL == ofp) {
                fprintf (stderr,
                         _("%s: cannot open new defaults file\n"),
@@ -2752,3 +2746,23 @@ int main (int argc, char **argv)
        return E_SUCCESS;
 }
 
+
+static FILE *
+fmkstemp(char *template)
+{
+       int   fd;
+       FILE  *fp;
+
+       fd = mkstemp(template);
+       if (fd == -1)
+               return NULL;
+
+       fp = fdopen(fd, "w");
+       if (fp == NULL) {
+               close(fd);
+               unlink(template);
+               return NULL;
+       }
+
+       return fp;
+}