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:
committed by
Iker Pedrosa
parent
f6701d3efa
commit
1c464d9a2d
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
10
lib/limits.c
10
lib/limits.c
@@ -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?
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user