]> granicus.if.org Git - shadow/commitdiff
useradd: fix segfault trying to overwrite const data with mkstemp
authorTomas Mraz <tmraz@fedoraproject.org>
Fri, 12 Oct 2018 08:14:02 +0000 (10:14 +0200)
committerTomas Mraz <tmraz@fedoraproject.org>
Fri, 12 Oct 2018 08:14:02 +0000 (10:14 +0200)
Also fix memory leaks in error paths.

src/useradd.c

index ca90f076ab2f1e26de24b218a84b66a923e14fd8..85fe0ddfc0ea6019532696d68c22073dce334071 100644 (file)
@@ -343,7 +343,7 @@ static void fail_exit (int code)
 static void get_defaults (void)
 {
        FILE *fp;
-       chardefault_file = USER_DEFAULTS_FILE;
+       char *default_file = USER_DEFAULTS_FILE;
        char buf[1024];
        char *cp;
 
@@ -353,6 +353,8 @@ static void get_defaults (void)
 
                len = strlen(prefix) + strlen(USER_DEFAULTS_FILE) + 2;
                default_file = malloc(len);
+                if (default_file == NULL)
+                       return;
                wlen = snprintf(default_file, len, "%s/%s", prefix, USER_DEFAULTS_FILE);
                assert (wlen == (int) len -1);
        }
@@ -363,7 +365,7 @@ static void get_defaults (void)
 
        fp = fopen (default_file, "r");
        if (NULL == fp) {
-               return;
+               goto getdef_err;
        }
 
        /*
@@ -474,7 +476,7 @@ static void get_defaults (void)
                }
        }
        (void) fclose (fp);
-
+     getdef_err:
        if(prefix[0]) {
                free(default_file);
        }
@@ -509,8 +511,8 @@ static int set_defaults (void)
        FILE *ifp;
        FILE *ofp;
        char buf[1024];
-       char* new_file = NEW_USER_FILE;
-       chardefault_file = USER_DEFAULTS_FILE;
+       char *new_file = NULL;
+       char *default_file = USER_DEFAULTS_FILE;
        char *cp;
        int ofd;
        int wlen;
@@ -521,17 +523,30 @@ static int set_defaults (void)
        bool out_shell = false;
        bool out_skel = false;
        bool out_create_mail_spool = false;
+       size_t len;
+       int ret = -1;
 
-       if(prefix[0]) {
-               size_t len;
 
-               len = strlen(prefix) + strlen(NEW_USER_FILE) + 2;
-               new_file = malloc(len);
-               wlen = snprintf(new_file, len, "%s/%s", prefix, NEW_USER_FILE);
-               assert (wlen == (int) len -1);
+       len = strlen(prefix) + strlen(NEW_USER_FILE) + 2;
+       new_file = malloc(len);
+        if (new_file == NULL) {
+               fprintf (stderr,
+                        _("%s: cannot create new defaults file: %s\n"),
+                        Prog, strerror(errno));
+               return -1;
+        }
+       wlen = snprintf(new_file, len, "%s%s%s", prefix, prefix[0]?"/":"", NEW_USER_FILE);
+       assert (wlen <= (int) len -1);
 
+       if(prefix[0]) {
                len = strlen(prefix) + strlen(USER_DEFAULTS_FILE) + 2;
                default_file = malloc(len);
+               if (default_file == NULL) {
+                       fprintf (stderr,
+                                _("%s: cannot create new defaults file: %s\n"),
+                                Prog, strerror(errno));
+                       goto setdef_err;
+               }
                wlen = snprintf(default_file, len, "%s/%s", prefix, USER_DEFAULTS_FILE);
                assert (wlen == (int) len -1);
        }
@@ -544,7 +559,7 @@ static int set_defaults (void)
                fprintf (stderr,
                         _("%s: cannot create new defaults file\n"),
                         Prog);
-               return -1;
+               goto setdef_err;
        }
 
        ofp = fdopen (ofd, "w");
@@ -552,7 +567,7 @@ static int set_defaults (void)
                fprintf (stderr,
                         _("%s: cannot open new defaults file\n"),
                         Prog);
-               return -1;
+               goto setdef_err;
        }
 
        /*
@@ -579,7 +594,7 @@ static int set_defaults (void)
                                         _("%s: line too long in %s: %s..."),
                                         Prog, default_file, buf);
                                (void) fclose (ifp);
-                               return -1;
+                               goto setdef_err;
                        }
                }
 
@@ -643,7 +658,7 @@ static int set_defaults (void)
            || (fsync (fileno (ofp)) != 0)
            || (fclose (ofp) != 0)) {
                unlink (new_file);
-               return -1;
+               goto setdef_err;
        }
 
        /*
@@ -658,7 +673,7 @@ static int set_defaults (void)
                         _("%s: Cannot create backup file (%s): %s\n"),
                         Prog, buf, strerror (err));
                unlink (new_file);
-               return -1;
+               goto setdef_err;
        }
 
        /*
@@ -669,7 +684,7 @@ static int set_defaults (void)
                fprintf (stderr,
                         _("%s: rename: %s: %s\n"),
                         Prog, new_file, strerror (err));
-               return -1;
+               goto setdef_err;
        }
 #ifdef WITH_AUDIT
        audit_logger (AUDIT_USYS_CONFIG, Prog,
@@ -683,13 +698,14 @@ static int set_defaults (void)
                 (unsigned int) def_group, def_home, def_shell,
                 def_inactive, def_expire, def_template,
                 def_create_mail_spool));
-
+       ret = 0;
+    setdef_err:
+       free(new_file);
        if(prefix[0]) {
-               free(new_file);
                free(default_file);
        }
 
-       return 0;
+       return ret;
 }
 
 /*