summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/shared/conf-parser.c35
-rw-r--r--src/shared/util.c21
-rw-r--r--src/shared/util.h2
-rw-r--r--src/test/test-util.c15
-rw-r--r--src/tmpfiles/tmpfiles.c4
5 files changed, 52 insertions, 25 deletions
diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c
index 2148a30c66..aa6a4a6395 100644
--- a/src/shared/conf-parser.c
+++ b/src/shared/conf-parser.c
@@ -759,41 +759,30 @@ int config_parse_strv(const char *unit,
return 0;
}
-int config_parse_mode(const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
+int config_parse_mode(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
mode_t *m = data;
- long l;
- char *x = NULL;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
- errno = 0;
- l = strtol(rvalue, &x, 8);
- if (!x || x == rvalue || *x || errno) {
- log_syntax(unit, LOG_ERR, filename, line, errno,
- "Failed to parse mode value, ignoring: %s", rvalue);
- return 0;
- }
-
- if (l < 0000 || l > 07777) {
- log_syntax(unit, LOG_ERR, filename, line, ERANGE,
- "Mode value out of range, ignoring: %s", rvalue);
+ if (parse_mode(rvalue, m) < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, errno, "Failed to parse mode value, ignoring: %s", rvalue);
return 0;
}
- *m = (mode_t) l;
return 0;
}
diff --git a/src/shared/util.c b/src/shared/util.c
index 8372038d4d..df5f8d1088 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -8159,3 +8159,24 @@ char *shell_maybe_quote(const char *s) {
return r;
}
+
+int parse_mode(const char *s, mode_t *ret) {
+ char *x;
+ long l;
+
+ assert(s);
+ assert(ret);
+
+ errno = 0;
+ l = strtol(s, &x, 8);
+ if (errno != 0)
+ return -errno;
+
+ if (!x || x == s || *x)
+ return -EINVAL;
+ if (l < 0 || l > 07777)
+ return -ERANGE;
+
+ *ret = (mode_t) l;
+ return 0;
+}
diff --git a/src/shared/util.h b/src/shared/util.h
index 527867ce8b..56e11c7961 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -1089,3 +1089,5 @@ void cmsg_close_all(struct msghdr *mh);
int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath);
char *shell_maybe_quote(const char *s);
+
+int parse_mode(const char *s, mode_t *ret);
diff --git a/src/test/test-util.c b/src/test/test-util.c
index 77e7400bfc..4d36eb26e5 100644
--- a/src/test/test-util.c
+++ b/src/test/test-util.c
@@ -1576,6 +1576,20 @@ static void test_shell_maybe_quote(void) {
test_shell_maybe_quote_one("foo$bar", "\"foo\\$bar\"");
}
+static void test_parse_mode(void) {
+ mode_t m;
+
+ assert_se(parse_mode("-1", &m) < 0);
+ assert_se(parse_mode("", &m) < 0);
+ assert_se(parse_mode("888", &m) < 0);
+ assert_se(parse_mode("77777", &m) < 0);
+
+ assert_se(parse_mode("544", &m) >= 0 && m == 0544);
+ assert_se(parse_mode("777", &m) >= 0 && m == 0777);
+ assert_se(parse_mode("7777", &m) >= 0 && m == 07777);
+ assert_se(parse_mode("0", &m) >= 0 && m == 0);
+}
+
int main(int argc, char *argv[]) {
log_parse_environment();
log_open();
@@ -1654,6 +1668,7 @@ int main(int argc, char *argv[]) {
test_uid_ptr();
test_sparse_write();
test_shell_maybe_quote();
+ test_parse_mode();
return 0;
}
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index d34de70e1d..ce4a10aa86 100644
--- a/src/tmpfiles/tmpfiles.c
+++ b/src/tmpfiles/tmpfiles.c
@@ -1879,9 +1879,9 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
mm++;
}
- if (sscanf(mm, "%o", &m) != 1) {
+ if (parse_mode(mm, &m) < 0) {
log_error("[%s:%u] Invalid mode '%s'.", fname, line, mode);
- return -ENOENT;
+ return -EBADMSG;
}
i.mode = m;