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