Blame SOURCES/0758-service-relax-PID-file-symlink-chain-checks-a-bit-81.patch

17b0f1
From ce87ed7b47c61e649a0f9da39d272631b9524740 Mon Sep 17 00:00:00 2001
17b0f1
From: Lennart Poettering <lennart@poettering.net>
17b0f1
Date: Fri, 9 Feb 2018 17:05:17 +0100
17b0f1
Subject: [PATCH] service: relax PID file symlink chain checks a bit (#8133)
17b0f1
17b0f1
Let's read the PID file after all if there's a potentially unsafe
17b0f1
symlink chain in place. But if we do, then refuse taking the PID if its
17b0f1
outside of the cgroup.
17b0f1
17b0f1
Fixes: #8085
17b0f1
(cherry picked from commit 73969ab61c39357e6892747e43307fbf07cafbed)
17b0f1
17b0f1
Resolves: #1724420
17b0f1
---
17b0f1
 src/core/service.c | 15 +++++++++++++--
17b0f1
 1 file changed, 13 insertions(+), 2 deletions(-)
17b0f1
17b0f1
diff --git a/src/core/service.c b/src/core/service.c
17b0f1
index eaa588863f..6b61ccac18 100644
17b0f1
--- a/src/core/service.c
17b0f1
+++ b/src/core/service.c
17b0f1
@@ -736,6 +736,7 @@ static int service_is_suitable_main_pid(Service *s, pid_t pid, int prio) {
17b0f1
 
17b0f1
 static int service_load_pid_file(Service *s, bool may_warn) {
17b0f1
         char procfs[sizeof("/proc/self/fd/") - 1 + DECIMAL_STR_MAX(int)];
17b0f1
+        bool questionable_pid_file = false;
17b0f1
         _cleanup_free_ char *k = NULL;
17b0f1
         _cleanup_close_ int fd = -1;
17b0f1
         int r, prio;
17b0f1
@@ -749,8 +750,13 @@ static int service_load_pid_file(Service *s, bool may_warn) {
17b0f1
         prio = may_warn ? LOG_INFO : LOG_DEBUG;
17b0f1
 
17b0f1
         fd = chase_symlinks(s->pid_file, NULL, CHASE_OPEN|CHASE_SAFE, NULL);
17b0f1
-        if (fd == -EPERM)
17b0f1
-                return log_unit_full_errno(UNIT(s)->id, prio, fd, "Permission denied while opening PID file or unsafe symlink chain: %s", s->pid_file);
17b0f1
+        if (fd == -EPERM) {
17b0f1
+                log_unit_full(UNIT(s)->id, LOG_DEBUG, "Permission denied while opening PID file or potentially unsafe symlink chain, will now retry with relaxed checks: %s", s->pid_file);
17b0f1
+
17b0f1
+                questionable_pid_file = true;
17b0f1
+
17b0f1
+                fd = chase_symlinks(s->pid_file, NULL, CHASE_OPEN, NULL);
17b0f1
+        }
17b0f1
         if (fd < 0)
17b0f1
                 return log_unit_full_errno(UNIT(s)->id, prio, fd, "Can't open PID file %s (yet?) after %s: %m", s->pid_file, service_state_to_string(s->state));
17b0f1
 
17b0f1
@@ -773,6 +779,11 @@ static int service_load_pid_file(Service *s, bool may_warn) {
17b0f1
         if (r == 0) {
17b0f1
                 struct stat st;
17b0f1
 
17b0f1
+                if (questionable_pid_file) {
17b0f1
+                        log_unit_error(UNIT(s)->id, "Refusing to accept PID outside of service control group, acquired through unsafe symlink chain: %s", s->pid_file);
17b0f1
+                        return -EPERM;
17b0f1
+                }
17b0f1
+
17b0f1
                 /* Hmm, it's not clear if the new main PID is safe. Let's allow this if the PID file is owned by root */
17b0f1
 
17b0f1
                 if (fstat(fd, &st) < 0)