]> git.ipfire.org Git - thirdparty/shadow.git/commitdiff
lib/, src/: Fix error handling after strto[u]l[l](3)
authorAlejandro Colomar <alx@kernel.org>
Fri, 1 Dec 2023 18:31:16 +0000 (19:31 +0100)
committerIker Pedrosa <ikerpedrosam@gmail.com>
Mon, 4 Dec 2023 11:21:55 +0000 (12:21 +0100)
-  Set errno = 0 before the call.  Otherwise, it may contain anything.
-  ERANGE is not the only possible errno value of these functions.  They
   can also set it to EINVAL.
-  Any errno value after these calls is bad; just compare against 0.
-  Don't check for the return value; just errno.  This function is
   guaranteed to not modify errno on success (POSIX).
-  Check endptr == str, which may or may not set EINVAL.

Suggested-by: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
12 files changed:
lib/get_gid.c
lib/get_pid.c
lib/get_uid.c
lib/getgr_nam_gid.c
lib/getlong.c
lib/getrange.c
lib/gettime.c
lib/getulong.c
lib/limits.c
lib/prefix_flag.c
src/check_subid_range.c
src/usermod.c

index a43a7d68b870536d40b66f65e4780d958eb5246d..c9dcd1d0c2d165e0791dee5df4ae21651d35ea36 100644 (file)
@@ -17,10 +17,10 @@ int get_gid (const char *gidstr, gid_t *gid)
        char *endptr;
 
        errno = 0;
-       val = strtoll (gidstr, &endptr, 10);
+       val = strtoll(gidstr, &endptr, 10);
        if (   ('\0' == *gidstr)
            || ('\0' != *endptr)
-           || (ERANGE == errno)
+           || (0 != errno)
            || (/*@+longintegral@*/val != (gid_t)val)/*@=longintegral@*/) {
                return 0;
        }
index 5eda20279385dee14550e87c57f9b074239f4d66..e473731fa66524952ce6cd8b78f82fba3222a8eb 100644 (file)
@@ -20,10 +20,10 @@ int get_pid (const char *pidstr, pid_t *pid)
        char *endptr;
 
        errno = 0;
-       val = strtoll (pidstr, &endptr, 10);
+       val = strtoll(pidstr, &endptr, 10);
        if (   ('\0' == *pidstr)
            || ('\0' != *endptr)
-           || (ERANGE == errno)
+           || (0 != errno)
            || (val < 1)
            || (/*@+longintegral@*/val != (pid_t)val)/*@=longintegral@*/) {
                return 0;
@@ -46,10 +46,10 @@ int get_pidfd_from_fd(const char *pidfdstr)
        dev_t proc_st_dev, proc_st_rdev;
 
        errno = 0;
-       val = strtoll (pidfdstr, &endptr, 10);
+       val = strtoll(pidfdstr, &endptr, 10);
        if (   ('\0' == *pidfdstr)
            || ('\0' != *endptr)
-           || (ERANGE == errno)
+           || (0 != errno)
            || (val < 0)
            || (/*@+longintegral@*/val != (int)val)/*@=longintegral@*/) {
                return -1;
index 797b4bb917535f34c433b0adf05dbabf62b2cf54..011b0adee263397797fd9a8f6219529a67c38b1d 100644 (file)
@@ -17,10 +17,10 @@ int get_uid (const char *uidstr, uid_t *uid)
        char *endptr;
 
        errno = 0;
-       val = strtoll (uidstr, &endptr, 10);
+       val = strtoll(uidstr, &endptr, 10);
        if (   ('\0' == *uidstr)
            || ('\0' != *endptr)
-           || (ERANGE == errno)
+           || (0 != errno)
            || (/*@+longintegral@*/val != (uid_t)val)/*@=longintegral@*/) {
                return 0;
        }
index 53a9ee56ceb567750c16a639f9a6ee92936e7fd7..6d6259797b9d6d0bdeee8b96110c5140a67066e2 100644 (file)
@@ -31,10 +31,10 @@ extern /*@only@*//*@null@*/struct group *getgr_nam_gid (/*@null@*/const char *gr
        }
 
        errno = 0;
-       gid = strtoll (grname, &endptr, 10);
+       gid = strtoll(grname, &endptr, 10);
        if (   ('\0' != *grname)
            && ('\0' == *endptr)
-           && (ERANGE != errno)
+           && (0 == errno)
            && (/*@+longintegral@*/gid == (gid_t)gid)/*@=longintegral@*/) {
                return xgetgrgid (gid);
        }
index 6317bf0fa521f2d09a67f621d32b3670a6856cd4..8c8083fbc991b8c90f7a47db8571842f7fb44b26 100644 (file)
@@ -25,8 +25,8 @@ int getlong (const char *numstr, /*@out@*/long *result)
        char *endptr;
 
        errno = 0;
-       val = strtol (numstr, &endptr, 0);
-       if (('\0' == *numstr) || ('\0' != *endptr) || (ERANGE == errno)) {
+       val = strtol(numstr, &endptr, 0);
+       if (('\0' == *numstr) || ('\0' != *endptr) || (0 != errno)) {
                return 0;
        }
 
index 82f2edfa4515426de03213f541134f5ae10530b9..fcef7d677b996a3bf2cc42bfc2fe6c050936ba96 100644 (file)
@@ -42,8 +42,8 @@ int getrange (const char *range,
                        return 0;
                }
                errno = 0;
-               n = strtoul (&range[1], &endptr, 10);
-               if (('\0' != *endptr) || (ERANGE == errno)) {
+               n = strtoul(&range[1], &endptr, 10);
+               if (('\0' != *endptr) || (0 != errno)) {
                        /* invalid */
                        return 0;
                }
@@ -53,8 +53,8 @@ int getrange (const char *range,
                *max = n;
        } else {
                errno = 0;
-               n = strtoul (range, &endptr, 10);
-               if (ERANGE == errno) {
+               n = strtoul(range, &endptr, 10);
+               if (endptr == range || 0 != errno) {
                        /* invalid */
                        return 0;
                }
@@ -80,9 +80,9 @@ int getrange (const char *range,
                                        *has_min = true;
                                        *min = n;
                                        errno = 0;
-                                       n = strtoul (endptr, &endptr, 10);
+                                       n = strtoul(endptr, &endptr, 10);
                                        if (   ('\0' != *endptr)
-                                           || (ERANGE == errno)) {
+                                           || (0 != errno)) {
                                                /* invalid */
                                                return 0;
                                        }
index bb6e8443da9ea17f1ae3f82cf7ae3fc50b8e26d2..89afdbd576642bee7b3d205360cb274056c9f9e7 100644 (file)
@@ -37,9 +37,8 @@
                return fallback;
 
        errno = 0;
-       epoch = strtoull (source_date_epoch, &endptr, 10);
-       if ((errno == ERANGE && (epoch == ULLONG_MAX || epoch == 0))
-                       || (errno != 0 && epoch == 0)) {
+       epoch = strtoull(source_date_epoch, &endptr, 10);
+       if (errno != 0) {
                fprintf (shadow_logfd,
                         _("Environment variable $SOURCE_DATE_EPOCH: strtoull: %s\n"),
                         strerror(errno));
index 543fcd47a0134a0dfd0071166ac8e7f26f30a33c..03d35bf8360d6395f2138e281508917f56cf261a 100644 (file)
@@ -25,10 +25,10 @@ int getulong (const char *numstr, /*@out@*/unsigned long *result)
        char *endptr;
 
        errno = 0;
-       val = strtoul (numstr, &endptr, 0);
+       val = strtoul(numstr, &endptr, 0);
        if (    ('\0' == *numstr)
             || ('\0' != *endptr)
-            || (ERANGE == errno)
+            || (0 != errno)
           ) {
                return 0;
        }
index 1da228ca69531c3b9822443489fa834bb3363688..1aa4dc296697bee17fccdc8a25b9e3cf05e23040 100644 (file)
@@ -62,14 +62,12 @@ static int setrlimit_value (unsigned int resource,
                 * Also, we are limited to base 10 here (hex numbers will not
                 * work with the limit string parser as is anyway)
                 */
+               errno = 0;
                l = strtol(value, &endptr, 10);
 
-               if (value == endptr) {
-                       /* No argument at all. No-op.
-                        * FIXME: We could instead throw an error, though.
-                        */
-                       return 0;
-               }
+               if (value == endptr || errno != 0)
+                       return 0;  // FIXME: We could instead throw an error, though.
+
                if (__builtin_mul_overflow(l, multiplier, &limit)) {
                        /* FIXME: Again, silent error handling...
                         * Wouldn't screaming make more sense?
index 7c2afe626d50667bf6eb21f5b5a76a14a951b962..8360a4ab4d6322ed3889ed18dfbdc0ba429395f9 100644 (file)
@@ -352,7 +352,7 @@ extern struct group *prefix_getgr_nam_gid(const char *grname)
        gid = strtoll(grname, &endptr, 10);
        if (   ('\0' != *grname)
            && ('\0' == *endptr)
-           && (ERANGE != errno)
+           && (0 == errno)
            && (gid == (gid_t)gid))
        {
                return prefix_getgrgid(gid);
index 38703b60301cabb8d183ff303cfa1bbf71aec985..160df728fba049ae6aa903d5571507e31bba66f8 100644 (file)
@@ -34,11 +34,12 @@ int main(int argc, char **argv)
 
        owner = argv[1];
        check_uids = argv[2][0] == 'u';
+       errno = 0;
        start = strtoul(argv[3], NULL, 10);
-       if (start == ULONG_MAX && errno == ERANGE)
+       if (errno != 0)
                exit(1);
        count = strtoul(argv[4], NULL, 10);
-       if (count == ULONG_MAX && errno == ERANGE)
+       if (errno != 0)
                exit(1);
        if (check_uids) {
                if (have_sub_uids(owner, start, count))
index 06fe931cb65bfa61cde7eefe4b975262027bfc0a..4fe52c8ac4b80f3164d2d88aef22be5cd21915b5 100644 (file)
@@ -318,13 +318,13 @@ static struct ulong_range getulong_range(const char *str)
 
        errno = 0;
        first = strtoll(str, &pos, 10);
-       if (('\0' == *str) || ('-' != *pos ) || (ERANGE == errno) ||
+       if (('\0' == *str) || ('-' != *pos ) || (0 != errno) ||
            (first != (unsigned long)first))
                goto out;
 
        errno = 0;
        last = strtoll(pos + 1, &pos, 10);
-       if (('\0' != *pos ) || (ERANGE == errno) ||
+       if (('\0' != *pos ) || (0 != errno) ||
            (last != (unsigned long)last))
                goto out;