Blame SOURCES/0359-core-fix-rlimit-parsing.patch

17b0f1
From b53ec8d7dca8eba189c45ae29e4d5ff03e5e5556 Mon Sep 17 00:00:00 2001
17b0f1
From: Evgeny Vereshchagin <evvers@ya.ru>
17b0f1
Date: Fri, 27 Nov 2015 08:54:42 +0000
17b0f1
Subject: [PATCH] core: fix rlimit parsing
17b0f1
17b0f1
* refuse limits if soft > hard
17b0f1
* print an actual value instead of (null)
17b0f1
17b0f1
see https://github.com/systemd/systemd/pull/1994#issuecomment-159999123
17b0f1
17b0f1
Cherry-picked from: 0316f2aeebde7569d24a93ab788ac4bc1657b11b
17b0f1
Related: #1351415
17b0f1
---
17b0f1
 src/core/load-fragment.c  |  5 ++++-
17b0f1
 src/test/test-unit-file.c | 21 +++++++++++++++++++++
17b0f1
 2 files changed, 25 insertions(+), 1 deletion(-)
17b0f1
17b0f1
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
17b0f1
index d307f1c743..2f6209e053 100644
17b0f1
--- a/src/core/load-fragment.c
17b0f1
+++ b/src/core/load-fragment.c
17b0f1
@@ -1160,6 +1160,7 @@ static int parse_rlimit_range(
17b0f1
                 struct rlimit **rl,
17b0f1
                 int (*rlim_parser)(const char *, rlim_t *)) {
17b0f1
 
17b0f1
+        const char *whole_value = value;
17b0f1
         rlim_t soft, hard;
17b0f1
         _cleanup_free_ char *sword = NULL, *hword = NULL;
17b0f1
         int nwords, r;
17b0f1
@@ -1175,9 +1176,11 @@ static int parse_rlimit_range(
17b0f1
         if (r == 0 && nwords == 2)
17b0f1
                 r = rlim_parser(hword, &hard);
17b0f1
         if (r < 0) {
17b0f1
-                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse resource value, ignoring: %s", value);
17b0f1
+                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse resource value, ignoring: %s", whole_value);
17b0f1
                 return 0;
17b0f1
         }
17b0f1
+        if (nwords == 2 && soft > hard)
17b0f1
+                return log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid resource value ("RLIM_FMT" > "RLIM_FMT"), ignoring: %s", soft, hard, whole_value);
17b0f1
 
17b0f1
         if (!*rl) {
17b0f1
                 *rl = new(struct rlimit, 1);
17b0f1
diff --git a/src/test/test-unit-file.c b/src/test/test-unit-file.c
17b0f1
index 931dfeda88..8acf071ff3 100644
17b0f1
--- a/src/test/test-unit-file.c
17b0f1
+++ b/src/test/test-unit-file.c
17b0f1
@@ -570,6 +570,27 @@ static void test_config_parse_rlimit(void) {
17b0f1
         assert_se(rl[RLIMIT_NOFILE]->rlim_cur == RLIM_INFINITY);
17b0f1
         assert_se(rl[RLIMIT_NOFILE]->rlim_cur == rl[RLIMIT_NOFILE]->rlim_max);
17b0f1
 
17b0f1
+        assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "10:20:30", rl, NULL) >= 0);
17b0f1
+        assert_se(rl[RLIMIT_NOFILE]);
17b0f1
+        assert_se(rl[RLIMIT_NOFILE]->rlim_cur == 10);
17b0f1
+        assert_se(rl[RLIMIT_NOFILE]->rlim_max == 20);
17b0f1
+
17b0f1
+        /* Invalid values don't change rl */
17b0f1
+        assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "wat:wat", rl, NULL) >= 0);
17b0f1
+        assert_se(rl[RLIMIT_NOFILE]);
17b0f1
+        assert_se(rl[RLIMIT_NOFILE]->rlim_cur == 10);
17b0f1
+        assert_se(rl[RLIMIT_NOFILE]->rlim_max == 20);
17b0f1
+
17b0f1
+        assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "66:wat", rl, NULL) >= 0);
17b0f1
+        assert_se(rl[RLIMIT_NOFILE]);
17b0f1
+        assert_se(rl[RLIMIT_NOFILE]->rlim_cur == 10);
17b0f1
+        assert_se(rl[RLIMIT_NOFILE]->rlim_max == 20);
17b0f1
+
17b0f1
+        assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "200:100", rl, NULL) >= 0);
17b0f1
+        assert_se(rl[RLIMIT_NOFILE]);
17b0f1
+        assert_se(rl[RLIMIT_NOFILE]->rlim_cur == 10);
17b0f1
+        assert_se(rl[RLIMIT_NOFILE]->rlim_max == 20);
17b0f1
+
17b0f1
         free(rl[RLIMIT_NOFILE]);
17b0f1
         assert_se(config_parse_sec_limit(NULL, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU, "56", rl, NULL) >= 0);
17b0f1
         assert_se(rl[RLIMIT_CPU]);