The strto* family of functions may fail if the input string contains
a number which is too large for the designated data type. In such
cases, errno is set to ERANGE. Check for this error condition and if
subsequent casts would truncate the value.
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
Link: https://github.com/kmod-project/kmod/pull/357
Signed-off-by: Lucas De Marchi <lucas.de.marchi@gmail.com>
break;
}
+ errno = 0;
value = strtol(tok, &endptr, 10);
- if (endptr == tok || *endptr != '\0') {
+ if (endptr == tok || *endptr != '\0' || errno == ERANGE || value < 0) {
ERR(mod->ctx, "invalid line format at /proc/modules:%d\n", lineno);
break;
}
static int log_priority(const char *priority)
{
char *endptr;
- int prio;
+ long prio;
+ errno = 0;
prio = strtol(priority, &endptr, 10);
+ if (errno == ERANGE || prio < INT_MIN || prio > INT_MAX)
+ return 0;
if (endptr[0] == '\0' || isspace(endptr[0]))
return prio;
if (strstartswith(priority, "err"))
err = read_str_safe(fd, buf, sizeof(buf));
if (err < 0)
return err;
+ errno = 0;
v = strtol(buf, &end, base);
- if (end == buf || !isspace(*end))
+ if (end == buf || !isspace(*end) || errno == ERANGE)
return -EINVAL;
*value = v;
err = read_str_safe(fd, buf, sizeof(buf));
if (err < 0)
return err;
+ errno = 0;
v = strtoul(buf, &end, base);
- if (end == buf || !isspace(*end))
+ if (end == buf || !isspace(*end) || errno == ERANGE)
return -EINVAL;
*value = v;
return 0;
if (p == NULL)
break;
+ errno = 0;
l = strtol(p, &end, 0);
- if (end == p || *end != ':')
+ if (end == p || *end != ':' || errno == ERANGE || l < INT_MIN ||
+ l > INT_MAX)
break;
ret = (int)l;
p = end + 1;
+ errno = 0;
l = strtol(p, &end, 0);
+ if (errno == ERANGE || l < INT_MIN || l > INT_MAX)
+ break;
if (*end == ':')
p = end + 1;
else if (*end != '\0')
break;
l = strtol(p, &end, 0);
- if (end == p || *end != ':')
+ if (end == p || *end != ':' || errno == ERANGE || l < INT_MIN ||
+ l > INT_MAX)
break;
ret = (int)l;
p = end + 1;
+ errno = 0;
l = strtol(p, &end, 0);
+ if (errno == ERANGE || l < INT_MIN || l > INT_MAX)
+ break;
if (*end == ':')
p = end + 1;
else if (*end != '\0')
if (!streq(where, "vmlinux"))
continue;
+ errno = 0;
crc = strtoull(ver, &verend, 16);
- if (verend[0] != '\0') {
+ if (verend[0] != '\0' || errno == ERANGE) {
ERR("%s:%u Invalid symbol version %s: %m\n", filename, linenum,
ver);
continue;
break;
case 'w': {
char *endptr = NULL;
+ errno = 0;
wait_msec = strtoul(optarg, &endptr, 0);
- if (!*optarg || *endptr) {
+ if (!*optarg || *endptr || errno == ERANGE) {
ERR("unexpected wait value '%s'.\n", optarg);
err = -1;
goto done;