summaryrefslogtreecommitdiffstats
path: root/src/basic
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2018-06-29 11:58:24 +0200
committerLennart Poettering <lennart@poettering.net>2018-11-29 20:02:39 +0100
commitde06c0cf77e2a58b4655ad5608f85ff8a6e724c7 (patch)
tree671479c459b16253b6db3ae6b0f3123c36c2d220 /src/basic
parentlogind: validate majors/minors we receieve via the bus (diff)
downloadsystemd-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.c26
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;
}