]> git.ipfire.org Git - thirdparty/shadow.git/commitdiff
src/: Make line number overflows less likely
authorTobias Stoeckmann <tobias@stoeckmann.org>
Sun, 12 Jan 2025 18:19:39 +0000 (19:19 +0100)
committerAlejandro Colomar <alx@kernel.org>
Wed, 15 Jan 2025 23:46:40 +0000 (00:46 +0100)
Huge files could trigger signed integer overflows if enough lines are
within the file. Use intmax_t which is at least 64 bit to move this
event far into the future.

Reviewed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
src/chgpasswd.c
src/chpasswd.c
src/login_nopam.c
src/newusers.c
src/suauth.c

index 2d50337e6490e8918ebbf86d081ee62ac911f7ca..807ef15d3415edff96c741bbdd07c44989e0c649 100644 (file)
@@ -14,6 +14,7 @@
 #include <fcntl.h>
 #include <getopt.h>
 #include <pwd.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 
@@ -426,7 +427,7 @@ int main (int argc, char **argv)
        const struct group *gr;
        struct group newgr;
        int errors = 0;
-       int line = 0;
+       intmax_t line = 0;
 
        log_set_progname(Prog);
        log_set_logfd(stderr);
@@ -463,7 +464,7 @@ int main (int argc, char **argv)
        while (fgets (buf, (int) sizeof buf, stdin) != NULL) {
                line++;
                if (stpsep(buf, "\n") == NULL) {
-                       fprintf (stderr, _("%s: line %d: line too long\n"),
+                       fprintf (stderr, _("%s: line %jd: line too long\n"),
                                 Prog, line);
                        errors++;
                        continue;
@@ -482,7 +483,7 @@ int main (int argc, char **argv)
                cp = stpsep(name, ":");
                if (cp == NULL) {
                        fprintf (stderr,
-                                _("%s: line %d: missing new password\n"),
+                                _("%s: line %jd: missing new password\n"),
                                 Prog, line);
                        errors++;
                        continue;
@@ -533,7 +534,7 @@ int main (int argc, char **argv)
                gr = gr_locate (name);
                if (NULL == gr) {
                        fprintf (stderr,
-                                _("%s: line %d: group '%s' does not exist\n"), Prog,
+                                _("%s: line %jd: group '%s' does not exist\n"), Prog,
                                 line, name);
                        errors++;
                        continue;
@@ -593,7 +594,7 @@ int main (int argc, char **argv)
                if (NULL != sg) {
                        if (sgr_update (&newsg) == 0) {
                                fprintf (stderr,
-                                        _("%s: line %d: failed to prepare the new %s entry '%s'\n"),
+                                        _("%s: line %jd: failed to prepare the new %s entry '%s'\n"),
                                         Prog, line, sgr_dbname (), newsg.sg_name);
                                errors++;
                                continue;
@@ -605,7 +606,7 @@ int main (int argc, char **argv)
                {
                        if (gr_update (&newgr) == 0) {
                                fprintf (stderr,
-                                        _("%s: line %d: failed to prepare the new %s entry '%s'\n"),
+                                        _("%s: line %jd: failed to prepare the new %s entry '%s'\n"),
                                         Prog, line, gr_dbname (), newgr.gr_name);
                                errors++;
                                continue;
index dfe5074097eedbc0f19123320cbc27256cb22301..0ac7d38b3a049703e77112b21332cc9b3c8fb5dd 100644 (file)
@@ -14,6 +14,7 @@
 #include <fcntl.h>
 #include <getopt.h>
 #include <pwd.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 
@@ -453,7 +454,7 @@ int main (int argc, char **argv)
 #endif                         /* USE_PAM */
 
        int errors = 0;
-       int line = 0;
+       intmax_t line = 0;
 
        log_set_progname(Prog);
        log_set_logfd(stderr);
@@ -514,7 +515,7 @@ int main (int argc, char **argv)
                                }
 
                                fprintf (stderr,
-                                        _("%s: line %d: line too long\n"),
+                                        _("%s: line %jd: line too long\n"),
                                         Prog, line);
                                errors++;
                                continue;
@@ -534,7 +535,7 @@ int main (int argc, char **argv)
                cp = stpsep(name, ":");
                if (cp == NULL) {
                        fprintf (stderr,
-                                _("%s: line %d: missing new password\n"),
+                                _("%s: line %jd: missing new password\n"),
                                 Prog, line);
                        errors++;
                        continue;
@@ -545,7 +546,7 @@ int main (int argc, char **argv)
                if (use_pam) {
                        if (do_pam_passwd_non_interactive (Prog, name, newpwd) != 0) {
                                fprintf (stderr,
-                                        _("%s: (line %d, user %s) password not changed\n"),
+                                        _("%s: (line %jd, user %s) password not changed\n"),
                                         Prog, line, name);
                                errors++;
                        }
@@ -574,7 +575,7 @@ int main (int argc, char **argv)
                pw = pw_locate (name);
                if (NULL == pw) {
                        fprintf (stderr,
-                                _("%s: line %d: user '%s' does not exist\n"), Prog,
+                                _("%s: line %jd: user '%s' does not exist\n"), Prog,
                                 line, name);
                        errors++;
                        continue;
@@ -640,7 +641,7 @@ int main (int argc, char **argv)
                if (NULL != sp) {
                        if (spw_update (&newsp) == 0) {
                                fprintf (stderr,
-                                        _("%s: line %d: failed to prepare the new %s entry '%s'\n"),
+                                        _("%s: line %jd: failed to prepare the new %s entry '%s'\n"),
                                         Prog, line, spw_dbname (), newsp.sp_namp);
                                errors++;
                                continue;
@@ -650,7 +651,7 @@ int main (int argc, char **argv)
                    || !streq(pw->pw_passwd, SHADOW_PASSWD_STRING)) {
                        if (pw_update (&newpw) == 0) {
                                fprintf (stderr,
-                                        _("%s: line %d: failed to prepare the new %s entry '%s'\n"),
+                                        _("%s: line %jd: failed to prepare the new %s entry '%s'\n"),
                                         Prog, line, pw_dbname (), newpw.pw_name);
                                errors++;
                                continue;
index de9513554c62d6a00cfc45948dc699b0822748f6..a9be91d3ba64452c32e7ad15c3269238329be6ca 100644 (file)
@@ -47,6 +47,7 @@
 #include <pwd.h>
 #endif
 #include <stddef.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -94,7 +95,7 @@ login_access(const char *user, const char *from)
         */
        fp = fopen (TABLE, "r");
        if (NULL != fp) {
-               int lineno = 0; /* for diagnostics */
+               intmax_t lineno = 0;    /* for diagnostics */
                while (   !match
                       && (fgets (line, sizeof (line), fp) == line))
                {
@@ -103,7 +104,7 @@ login_access(const char *user, const char *from)
                        lineno++;
                        if (stpsep(line, "\n") == NULL) {
                                SYSLOG ((LOG_ERR,
-                                        "%s: line %d: missing newline or line too long",
+                                        "%s: line %jd: missing newline or line too long",
                                         TABLE, lineno));
                                continue;
                        }
@@ -120,13 +121,13 @@ login_access(const char *user, const char *from)
                        froms = strsep(&p, ":");
                        if (froms == NULL || p != NULL) {
                                SYSLOG ((LOG_ERR,
-                                        "%s: line %d: bad field count",
+                                        "%s: line %jd: bad field count",
                                         TABLE, lineno));
                                continue;
                        }
                        if (perm[0] != '+' && perm[0] != '-') {
                                SYSLOG ((LOG_ERR,
-                                        "%s: line %d: bad first field",
+                                        "%s: line %jd: bad first field",
                                         TABLE, lineno));
                                continue;
                        }
index 5e78dd9760679190f4546e7dfa042ccab1b3d511..2d99ccfe0e5bdfe19d961d350f64ae19653b673e 100644 (file)
@@ -28,6 +28,7 @@
 #include <getopt.h>
 #include <ctype.h>
 #include <errno.h>
+#include <stdint.h>
 #include <string.h>
 
 #include "alloc/reallocf.h"
@@ -1062,11 +1063,11 @@ int main (int argc, char **argv)
        char *cp;
        const struct passwd *pw;
        struct passwd newpw;
-       int line = 0;
+       intmax_t line = 0;
        uid_t uid;
        gid_t gid;
 #ifdef USE_PAM
-       int *lines = NULL;
+       intmax_t *lines = NULL;
        char **usernames = NULL;
        char **passwords = NULL;
        unsigned int nusers = 0;
@@ -1112,7 +1113,7 @@ int main (int argc, char **argv)
        while (fgets (buf, sizeof buf, stdin) != NULL) {
                line++;
                if (stpsep(buf, "\n") == NULL && feof(stdin) == 0) {
-                       fprintf (stderr, _("%s: line %d: line too long\n"),
+                       fprintf (stderr, _("%s: line %jd: line too long\n"),
                                 Prog, line);
                        fail_exit (EXIT_FAILURE);
                }
@@ -1128,7 +1129,7 @@ int main (int argc, char **argv)
                                break;
                }
                if (nfields != 6) {
-                       fprintf (stderr, _("%s: line %d: invalid line\n"),
+                       fprintf (stderr, _("%s: line %jd: invalid line\n"),
                                 Prog, line);
                        fail_exit (EXIT_FAILURE);
                }
@@ -1147,7 +1148,7 @@ int main (int argc, char **argv)
 
                if (NULL == pw && get_user_id(fields[2], &uid) != 0) {
                        fprintf (stderr,
-                                _("%s: line %d: can't create user\n"),
+                                _("%s: line %jd: can't create user\n"),
                                 Prog, line);
                        fail_exit (EXIT_FAILURE);
                }
@@ -1167,7 +1168,7 @@ int main (int argc, char **argv)
                if (   (NULL == pw)
                    && (add_group (fields[0], fields[3], &gid, uid) != 0)) {
                        fprintf (stderr,
-                                _("%s: line %d: can't create group\n"),
+                                _("%s: line %jd: can't create group\n"),
                                 Prog, line);
                        fail_exit (EXIT_FAILURE);
                }
@@ -1182,7 +1183,7 @@ int main (int argc, char **argv)
                if (   (NULL == pw)
                    && (add_user (fields[0], uid, gid) != 0)) {
                        fprintf (stderr,
-                                _("%s: line %d: can't create user\n"),
+                                _("%s: line %jd: can't create user\n"),
                                 Prog, line);
                        fail_exit (EXIT_FAILURE);
                }
@@ -1194,7 +1195,7 @@ int main (int argc, char **argv)
                pw = pw_locate (fields[0]);
                if (NULL == pw) {
                        fprintf (stderr,
-                                _("%s: line %d: user '%s' does not exist in %s\n"),
+                                _("%s: line %jd: user '%s' does not exist in %s\n"),
                                 Prog, line, fields[0], pw_dbname ());
                        fail_exit (EXIT_FAILURE);
                }
@@ -1203,12 +1204,12 @@ int main (int argc, char **argv)
 #ifdef USE_PAM
                /* keep the list of user/password for later update by PAM */
                nusers++;
-               lines     = REALLOCF(lines, nusers, int);
+               lines     = REALLOCF(lines, nusers, intmax_t);
                usernames = REALLOCF(usernames, nusers, char *);
                passwords = REALLOCF(passwords, nusers, char *);
                if (lines == NULL || usernames == NULL || passwords == NULL) {
                        fprintf (stderr,
-                                _("%s: line %d: %s\n"),
+                                _("%s: line %jd: %s\n"),
                                 Prog, line, strerror(errno));
                        fail_exit (EXIT_FAILURE);
                }
@@ -1218,7 +1219,7 @@ int main (int argc, char **argv)
 #endif                         /* USE_PAM */
                if (add_passwd (&newpw, fields[1]) != 0) {
                        fprintf (stderr,
-                                _("%s: line %d: can't update password\n"),
+                                _("%s: line %jd: can't update password\n"),
                                 Prog, line);
                        fail_exit (EXIT_FAILURE);
                }
@@ -1241,13 +1242,13 @@ int main (int argc, char **argv)
                                                  0777 & ~getdef_num ("UMASK", GETDEF_DEFAULT_UMASK));
                        if (newpw.pw_dir[0] != '/') {
                                fprintf(stderr,
-                                       _("%s: line %d: homedir must be an absolute path\n"),
+                                       _("%s: line %jd: homedir must be an absolute path\n"),
                                        Prog, line);
                                fail_exit (EXIT_FAILURE);
                        }
                        if (mkdir (newpw.pw_dir, mode) != 0) {
                                fprintf (stderr,
-                                        _("%s: line %d: mkdir %s failed: %s\n"),
+                                        _("%s: line %jd: mkdir %s failed: %s\n"),
                                         Prog, line, newpw.pw_dir,
                                         strerror (errno));
                                if (errno != EEXIST) {
@@ -1257,7 +1258,7 @@ int main (int argc, char **argv)
                        if (chown(newpw.pw_dir, newpw.pw_uid, newpw.pw_gid) != 0)
                        {
                                fprintf (stderr,
-                                        _("%s: line %d: chown %s failed: %s\n"),
+                                        _("%s: line %jd: chown %s failed: %s\n"),
                                         Prog, line, newpw.pw_dir,
                                         strerror (errno));
                                fail_exit (EXIT_FAILURE);
@@ -1269,7 +1270,7 @@ int main (int argc, char **argv)
                 */
                if (pw_update (&newpw) == 0) {
                        fprintf (stderr,
-                                _("%s: line %d: can't update entry\n"),
+                                _("%s: line %jd: can't update entry\n"),
                                 Prog, line);
                        fail_exit (EXIT_FAILURE);
                }
@@ -1338,7 +1339,7 @@ int main (int argc, char **argv)
        for (i = 0; i < nusers; i++) {
                if (do_pam_passwd_non_interactive ("newusers", usernames[i], passwords[i]) != 0) {
                        fprintf (stderr,
-                                _("%s: (line %d, user %s) password not changed\n"),
+                                _("%s: (line %jd, user %s) password not changed\n"),
                                 Prog, lines[i], usernames[i]);
                        exit (EXIT_FAILURE);
                }
index 8d961fd5b2fed3a27e5716cbbaa46c9779b1d19b..aab7e986715fc51d1e3b3c519a89fbe3f7b6b20a 100644 (file)
@@ -12,6 +12,7 @@
 #include <errno.h>
 #include <grp.h>
 #include <pwd.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <string.h>
 #include <sys/types.h>
@@ -42,7 +43,7 @@ static int applies (const char *, char *);
 
 static int isgrp (const char *, const char *);
 
-static int lines = 0;
+static intmax_t lines = 0;
 
 
 int
@@ -78,7 +79,7 @@ check_su_auth(const char *actual_id, const char *wanted_id, bool su_to_root)
 
                if (stpsep(temp, "\n") == NULL) {
                        SYSLOG ((LOG_ERR,
-                                "%s, line %d: line too long or missing newline",
+                                "%s, line %jd: line too long or missing newline",
                                 SUAUTHFILE, lines));
                        continue;
                }
@@ -94,7 +95,7 @@ check_su_auth(const char *actual_id, const char *wanted_id, bool su_to_root)
                action = strsep(&p, ":");
                if (action == NULL || p != NULL) {
                        SYSLOG ((LOG_ERR,
-                                "%s, line %d. Bad number of fields.\n",
+                                "%s, line %jd. Bad number of fields.\n",
                                 SUAUTHFILE, lines));
                        continue;
                }
@@ -128,7 +129,7 @@ check_su_auth(const char *actual_id, const char *wanted_id, bool su_to_root)
                        return OWNPWORD;
                } else {
                        SYSLOG ((LOG_ERR,
-                                "%s, line %d: unrecognized action!\n",
+                                "%s, line %jd: unrecognized action!\n",
                                 SUAUTHFILE, lines));
                }
        }
@@ -148,7 +149,7 @@ applies(const char *single, char *list)
                if (streq(tok, "ALL")) {
                        if (state != 0) {
                                SYSLOG ((LOG_ERR,
-                                        "%s, line %d: ALL in bad place\n",
+                                        "%s, line %jd: ALL in bad place\n",
                                         SUAUTHFILE, lines));
                                return 0;
                        }
@@ -156,7 +157,7 @@ applies(const char *single, char *list)
                } else if (streq(tok, "EXCEPT")) {
                        if (state != 1) {
                                SYSLOG ((LOG_ERR,
-                                        "%s, line %d: EXCEPT in bas place\n",
+                                        "%s, line %jd: EXCEPT in bas place\n",
                                         SUAUTHFILE, lines));
                                return 0;
                        }
@@ -164,7 +165,7 @@ applies(const char *single, char *list)
                } else if (streq(tok, "GROUP")) {
                        if ((state != 0) && (state != 2)) {
                                SYSLOG ((LOG_ERR,
-                                        "%s, line %d: GROUP in bad place\n",
+                                        "%s, line %jd: GROUP in bad place\n",
                                         SUAUTHFILE, lines));
                                return 0;
                        }
@@ -177,7 +178,7 @@ applies(const char *single, char *list)
                                break;
                        case 1: /* An all */
                                SYSLOG ((LOG_ERR,
-                                        "%s, line %d: expect another token after ALL\n",
+                                        "%s, line %jd: expect another token after ALL\n",
                                         SUAUTHFILE, lines));
                                return 0;
                        case 2: /* All except */