diff options
author | Lennart Poettering <lennart@poettering.net> | 2018-06-29 11:58:24 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2018-11-29 20:02:39 +0100 |
commit | de06c0cf77e2a58b4655ad5608f85ff8a6e724c7 (patch) | |
tree | 671479c459b16253b6db3ae6b0f3123c36c2d220 /src/basic | |
parent | logind: validate majors/minors we receieve via the bus (diff) | |
download | systemd-de06c0cf77e2a58b4655ad5608f85ff8a6e724c7.tar.xz systemd-de06c0cf77e2a58b4655ad5608f85ff8a6e724c7.zip |
parse-util: rework parse_dev() based on safe_atou() and DEVICE_MAJOR_VALID()/DEVICE_MINOR_VALID()
Let's be a bit more careful when parsing major/minor pairs, and filter
out more corner cases. This also means using safe_atou() rather than
sscanf() to avoid weird negative unsigned handling and such.
Diffstat (limited to 'src/basic')
-rw-r--r-- | src/basic/parse-util.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c index ce8bb12670..718357e290 100644 --- a/src/basic/parse-util.c +++ b/src/basic/parse-util.c @@ -16,6 +16,7 @@ #include "missing.h" #include "parse-util.h" #include "process-util.h" +#include "stat-util.h" #include "string-util.h" int parse_boolean(const char *v) { @@ -731,17 +732,30 @@ int parse_ip_port_range(const char *s, uint16_t *low, uint16_t *high) { } int parse_dev(const char *s, dev_t *ret) { + const char *major; unsigned x, y; - dev_t d; + size_t n; + int r; - if (sscanf(s, "%u:%u", &x, &y) != 2) + n = strspn(s, DIGITS); + if (n == 0) return -EINVAL; - - d = makedev(x, y); - if ((unsigned) major(d) != x || (unsigned) minor(d) != y) + if (s[n] != ':') return -EINVAL; - *ret = d; + major = strndupa(s, n); + r = safe_atou(major, &x); + if (r < 0) + return r; + + r = safe_atou(s + n + 1, &y); + if (r < 0) + return r; + + if (!DEVICE_MAJOR_VALID(x) || !DEVICE_MINOR_VALID(y)) + return -ERANGE; + + *ret = makedev(x, y); return 0; } |