lib/, src/: Fix error handling after strto[u]l[l](3)

-  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>
This commit is contained in:
Alejandro Colomar
2023-12-01 19:31:16 +01:00
committed by Iker Pedrosa
parent f6701d3efa
commit 1c464d9a2d
12 changed files with 32 additions and 34 deletions

View 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;
}

View 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;

View 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;
}

View 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);
}

View 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;
}

View 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;
}

View 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));

View 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;
}

View 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?

View 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);

View 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))

View 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;