You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
59 lines
2.6 KiB
59 lines
2.6 KiB
From 625b30e09d0090f81722aa8f02e7057839dfcf4f Mon Sep 17 00:00:00 2001 |
|
From: Lennart Poettering <lennart@poettering.net> |
|
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 |
|
|
|
(cherry picked from commit 73969ab61c39357e6892747e43307fbf07cafbed) |
|
(cherry picked from commit ce87ed7b47c61e649a0f9da39d272631b9524740) |
|
|
|
Resolves: #1729414 |
|
--- |
|
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 eaa588863f..6b61ccac18 100644 |
|
--- a/src/core/service.c |
|
+++ b/src/core/service.c |
|
@@ -736,6 +736,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[sizeof("/proc/self/fd/") - 1 + DECIMAL_STR_MAX(int)]; |
|
+ bool questionable_pid_file = false; |
|
_cleanup_free_ char *k = NULL; |
|
_cleanup_close_ int fd = -1; |
|
int r, prio; |
|
@@ -749,8 +750,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_errno(UNIT(s)->id, prio, fd, "Permission denied while opening PID file or unsafe symlink chain: %s", s->pid_file); |
|
+ if (fd == -EPERM) { |
|
+ 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); |
|
+ |
|
+ questionable_pid_file = true; |
|
+ |
|
+ fd = chase_symlinks(s->pid_file, NULL, CHASE_OPEN, NULL); |
|
+ } |
|
if (fd < 0) |
|
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)); |
|
|
|
@@ -773,6 +779,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)->id, "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)
|
|
|