summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEvgeny Vereshchagin <evvers@ya.ru>2015-11-27 08:54:42 +0000
committerEvgeny Vereshchagin <evvers@ya.ru>2015-11-27 11:26:37 +0000
commit0316f2aeebde7569d24a93ab788ac4bc1657b11b (patch)
tree0b9a3d09993a8d2e234e7c46afbb71f9e0284c91 /src
parente0d8c8015a089e9a8e971be5ebe2139bb714c10a (diff)
core: fix rlimit parsing
* refuse limits if soft > hard * print an actual value instead of (null) see https://github.com/systemd/systemd/pull/1994#issuecomment-159999123
Diffstat (limited to 'src')
-rw-r--r--src/core/load-fragment.c5
-rw-r--r--src/test/test-unit-file.c21
2 files changed, 25 insertions, 1 deletions
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index 8847578bd7..3c124495b6 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -1173,6 +1173,7 @@ static int parse_rlimit_range(
struct rlimit **rl,
int (*rlim_parser)(const char *, rlim_t *)) {
+ const char *whole_value = value;
rlim_t soft, hard;
_cleanup_free_ char *sword = NULL, *hword = NULL;
int nwords, r;
@@ -1188,9 +1189,11 @@ static int parse_rlimit_range(
if (r == 0 && nwords == 2)
r = rlim_parser(hword, &hard);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse resource value, ignoring: %s", value);
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse resource value, ignoring: %s", whole_value);
return 0;
}
+ if (nwords == 2 && soft > hard)
+ return log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid resource value ("RLIM_FMT" > "RLIM_FMT"), ignoring: %s", soft, hard, whole_value);
if (!*rl) {
*rl = new(struct rlimit, 1);
diff --git a/src/test/test-unit-file.c b/src/test/test-unit-file.c
index 854f60be80..0b3630f77c 100644
--- a/src/test/test-unit-file.c
+++ b/src/test/test-unit-file.c
@@ -695,6 +695,27 @@ static void test_config_parse_rlimit(void) {
assert_se(rl[RLIMIT_NOFILE]->rlim_cur == RLIM_INFINITY);
assert_se(rl[RLIMIT_NOFILE]->rlim_cur == rl[RLIMIT_NOFILE]->rlim_max);
+ assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "10:20:30", rl, NULL) >= 0);
+ assert_se(rl[RLIMIT_NOFILE]);
+ assert_se(rl[RLIMIT_NOFILE]->rlim_cur == 10);
+ assert_se(rl[RLIMIT_NOFILE]->rlim_max == 20);
+
+ /* Invalid values don't change rl */
+ assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "wat:wat", rl, NULL) >= 0);
+ assert_se(rl[RLIMIT_NOFILE]);
+ assert_se(rl[RLIMIT_NOFILE]->rlim_cur == 10);
+ assert_se(rl[RLIMIT_NOFILE]->rlim_max == 20);
+
+ assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "66:wat", rl, NULL) >= 0);
+ assert_se(rl[RLIMIT_NOFILE]);
+ assert_se(rl[RLIMIT_NOFILE]->rlim_cur == 10);
+ assert_se(rl[RLIMIT_NOFILE]->rlim_max == 20);
+
+ assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "200:100", rl, NULL) >= 0);
+ assert_se(rl[RLIMIT_NOFILE]);
+ assert_se(rl[RLIMIT_NOFILE]->rlim_cur == 10);
+ assert_se(rl[RLIMIT_NOFILE]->rlim_max == 20);
+
rl[RLIMIT_NOFILE] = mfree(rl[RLIMIT_NOFILE]);
assert_se(config_parse_sec_limit(NULL, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU, "56", rl, NULL) >= 0);