taskset: fix cpuset list parser
taskset hangs when executed with badly formatted cpuset list, for example: $ taskset -c 0--1 true The current cpuset list parser is pretty weak as based on scanf() without strings verification ("-1" as input for "%u" returns unexpected number). It seems faster and better to use strtoul() and isdigit(). Addresses: https://github.com/karelzak/util-linux/issues/77 Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
parent
06c141a99a
commit
65bcbf105b
32
lib/cpuset.c
32
lib/cpuset.c
|
@ -260,6 +260,19 @@ int cpumask_parse(const char *str, cpu_set_t *set, size_t setsize)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int nextnumber(const char *str, char **end, unsigned int *result)
|
||||||
|
{
|
||||||
|
errno = 0;
|
||||||
|
if (str == NULL || *str == '\0' || !isdigit(*str))
|
||||||
|
return -EINVAL;
|
||||||
|
*result = (unsigned int) strtoul(str, end, 10);
|
||||||
|
if (errno)
|
||||||
|
return -errno;
|
||||||
|
if (str == *end)
|
||||||
|
return -EINVAL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parses string with list of CPU ranges.
|
* Parses string with list of CPU ranges.
|
||||||
* Returns 0 on success.
|
* Returns 0 on success.
|
||||||
|
@ -272,7 +285,7 @@ int cpulist_parse(const char *str, cpu_set_t *set, size_t setsize, int fail)
|
||||||
{
|
{
|
||||||
size_t max = cpuset_nbits(setsize);
|
size_t max = cpuset_nbits(setsize);
|
||||||
const char *p, *q;
|
const char *p, *q;
|
||||||
int r = 0;
|
char *end = NULL;
|
||||||
|
|
||||||
q = str;
|
q = str;
|
||||||
CPU_ZERO_S(setsize, set);
|
CPU_ZERO_S(setsize, set);
|
||||||
|
@ -282,21 +295,24 @@ int cpulist_parse(const char *str, cpu_set_t *set, size_t setsize, int fail)
|
||||||
unsigned int b; /* end of range */
|
unsigned int b; /* end of range */
|
||||||
unsigned int s; /* stride */
|
unsigned int s; /* stride */
|
||||||
const char *c1, *c2;
|
const char *c1, *c2;
|
||||||
char c;
|
|
||||||
|
|
||||||
if ((r = sscanf(p, "%u%c", &a, &c)) < 1)
|
if (nextnumber(p, &end, &a) != 0)
|
||||||
return 1;
|
return 1;
|
||||||
b = a;
|
b = a;
|
||||||
s = 1;
|
s = 1;
|
||||||
|
p = end;
|
||||||
|
|
||||||
c1 = nexttoken(p, '-');
|
c1 = nexttoken(p, '-');
|
||||||
c2 = nexttoken(p, ',');
|
c2 = nexttoken(p, ',');
|
||||||
|
|
||||||
if (c1 != NULL && (c2 == NULL || c1 < c2)) {
|
if (c1 != NULL && (c2 == NULL || c1 < c2)) {
|
||||||
if ((r = sscanf(c1, "%u%c", &b, &c)) < 1)
|
if (nextnumber(c1, &end, &b) != 0)
|
||||||
return 1;
|
return 1;
|
||||||
c1 = nexttoken(c1, ':');
|
|
||||||
|
c1 = end && *end ? nexttoken(end, ':') : NULL;
|
||||||
|
|
||||||
if (c1 != NULL && (c2 == NULL || c1 < c2)) {
|
if (c1 != NULL && (c2 == NULL || c1 < c2)) {
|
||||||
if ((r = sscanf(c1, "%u%c", &s, &c)) < 1)
|
if (nextnumber(c1, &end, &s) != 0)
|
||||||
return 1;
|
return 1;
|
||||||
if (s == 0)
|
if (s == 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -313,7 +329,7 @@ int cpulist_parse(const char *str, cpu_set_t *set, size_t setsize, int fail)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r == 2)
|
if (end && *end)
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -390,7 +406,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
usage_err:
|
usage_err:
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"usage: %s [--ncpus <num>] --mask <mask> | --range <list>",
|
"usage: %s [--ncpus <num>] --mask <mask> | --range <list>\n",
|
||||||
program_invocation_short_name);
|
program_invocation_short_name);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue