summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/cgroup.c41
-rw-r--r--src/core/cgroup.h1
-rw-r--r--src/core/killall.c6
-rw-r--r--src/core/manager.c12
-rw-r--r--src/core/unit.c20
5 files changed, 48 insertions, 32 deletions
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
index 1e78f871c7..9a025cf929 100644
--- a/src/core/cgroup.c
+++ b/src/core/cgroup.c
@@ -507,15 +507,20 @@ CGroupMask unit_get_own_mask(Unit *u) {
return 0;
/* If delegation is turned on, then turn on all cgroups,
- * unless the process we fork into it is known to drop
- * privileges anyway, and shouldn't get access to the
- * controllers anyway. */
+ * unless we are on the legacy hierarchy and the process we
+ * fork into it is known to drop privileges, and hence
+ * shouldn't get access to the controllers.
+ *
+ * Note that on the unified hierarchy it is safe to delegate
+ * controllers to unprivileged services. */
if (c->delegate) {
ExecContext *e;
e = unit_get_exec_context(u);
- if (!e || exec_context_maintains_privileges(e))
+ if (!e ||
+ exec_context_maintains_privileges(e) ||
+ cg_unified() > 0)
return _CGROUP_MASK_ALL;
}
@@ -1378,9 +1383,8 @@ Unit* manager_get_unit_by_cgroup(Manager *m, const char *cgroup) {
}
}
-Unit *manager_get_unit_by_pid(Manager *m, pid_t pid) {
+Unit *manager_get_unit_by_pid_cgroup(Manager *m, pid_t pid) {
_cleanup_free_ char *cgroup = NULL;
- Unit *u;
int r;
assert(m);
@@ -1388,22 +1392,33 @@ Unit *manager_get_unit_by_pid(Manager *m, pid_t pid) {
if (pid <= 0)
return NULL;
+ r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &cgroup);
+ if (r < 0)
+ return NULL;
+
+ return manager_get_unit_by_cgroup(m, cgroup);
+}
+
+Unit *manager_get_unit_by_pid(Manager *m, pid_t pid) {
+ Unit *u;
+
+ assert(m);
+
+ if (pid <= 0)
+ return NULL;
+
if (pid == 1)
return hashmap_get(m->units, SPECIAL_INIT_SCOPE);
- u = hashmap_get(m->watch_pids1, LONG_TO_PTR(pid));
+ u = hashmap_get(m->watch_pids1, PID_TO_PTR(pid));
if (u)
return u;
- u = hashmap_get(m->watch_pids2, LONG_TO_PTR(pid));
+ u = hashmap_get(m->watch_pids2, PID_TO_PTR(pid));
if (u)
return u;
- r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &cgroup);
- if (r < 0)
- return NULL;
-
- return manager_get_unit_by_cgroup(m, cgroup);
+ return manager_get_unit_by_pid_cgroup(m, pid);
}
int manager_notify_cgroup_empty(Manager *m, const char *cgroup) {
diff --git a/src/core/cgroup.h b/src/core/cgroup.h
index 1ce21f43f2..438f5bf50f 100644
--- a/src/core/cgroup.h
+++ b/src/core/cgroup.h
@@ -130,6 +130,7 @@ void manager_shutdown_cgroup(Manager *m, bool delete);
unsigned manager_dispatch_cgroup_queue(Manager *m);
Unit *manager_get_unit_by_cgroup(Manager *m, const char *cgroup);
+Unit *manager_get_unit_by_pid_cgroup(Manager *m, pid_t pid);
Unit* manager_get_unit_by_pid(Manager *m, pid_t pid);
int unit_search_main_pid(Unit *u, pid_t *ret);
diff --git a/src/core/killall.c b/src/core/killall.c
index 2a9d72c901..ee5d388560 100644
--- a/src/core/killall.c
+++ b/src/core/killall.c
@@ -108,7 +108,7 @@ static void wait_for_children(Set *pids, sigset_t *mask) {
return;
}
- set_remove(pids, ULONG_TO_PTR(pid));
+ (void) set_remove(pids, PID_TO_PTR(pid));
}
/* Now explicitly check who might be remaining, who
@@ -117,7 +117,7 @@ static void wait_for_children(Set *pids, sigset_t *mask) {
/* We misuse getpgid as a check whether a
* process still exists. */
- if (getpgid((pid_t) PTR_TO_ULONG(p)) >= 0)
+ if (getpgid(PTR_TO_PID(p)) >= 0)
continue;
if (errno != ESRCH)
@@ -179,7 +179,7 @@ static int killall(int sig, Set *pids, bool send_sighup) {
if (kill(pid, sig) >= 0) {
if (pids) {
- r = set_put(pids, ULONG_TO_PTR(pid));
+ r = set_put(pids, PID_TO_PTR(pid));
if (r < 0)
log_oom();
}
diff --git a/src/core/manager.c b/src/core/manager.c
index c3327e37f5..fc10ddb5d9 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -1585,19 +1585,19 @@ static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t
/* Notify every unit that might be interested, but try
* to avoid notifying the same one multiple times. */
- u1 = manager_get_unit_by_pid(m, ucred->pid);
+ u1 = manager_get_unit_by_pid_cgroup(m, ucred->pid);
if (u1) {
manager_invoke_notify_message(m, u1, ucred->pid, buf, n, fds);
found = true;
}
- u2 = hashmap_get(m->watch_pids1, LONG_TO_PTR(ucred->pid));
+ u2 = hashmap_get(m->watch_pids1, PID_TO_PTR(ucred->pid));
if (u2 && u2 != u1) {
manager_invoke_notify_message(m, u2, ucred->pid, buf, n, fds);
found = true;
}
- u3 = hashmap_get(m->watch_pids2, LONG_TO_PTR(ucred->pid));
+ u3 = hashmap_get(m->watch_pids2, PID_TO_PTR(ucred->pid));
if (u3 && u3 != u2 && u3 != u1) {
manager_invoke_notify_message(m, u3, ucred->pid, buf, n, fds);
found = true;
@@ -1663,13 +1663,13 @@ static int manager_dispatch_sigchld(Manager *m) {
/* And now figure out the unit this belongs
* to, it might be multiple... */
- u1 = manager_get_unit_by_pid(m, si.si_pid);
+ u1 = manager_get_unit_by_pid_cgroup(m, si.si_pid);
if (u1)
invoke_sigchld_event(m, u1, &si);
- u2 = hashmap_get(m->watch_pids1, LONG_TO_PTR(si.si_pid));
+ u2 = hashmap_get(m->watch_pids1, PID_TO_PTR(si.si_pid));
if (u2 && u2 != u1)
invoke_sigchld_event(m, u2, &si);
- u3 = hashmap_get(m->watch_pids2, LONG_TO_PTR(si.si_pid));
+ u3 = hashmap_get(m->watch_pids2, PID_TO_PTR(si.si_pid));
if (u3 && u3 != u2 && u3 != u1)
invoke_sigchld_event(m, u3, &si);
}
diff --git a/src/core/unit.c b/src/core/unit.c
index 8c07c6140d..a5714adf38 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -1995,16 +1995,16 @@ int unit_watch_pid(Unit *u, pid_t pid) {
if (r < 0)
return r;
- r = hashmap_put(u->manager->watch_pids1, LONG_TO_PTR(pid), u);
+ r = hashmap_put(u->manager->watch_pids1, PID_TO_PTR(pid), u);
if (r == -EEXIST) {
r = hashmap_ensure_allocated(&u->manager->watch_pids2, NULL);
if (r < 0)
return r;
- r = hashmap_put(u->manager->watch_pids2, LONG_TO_PTR(pid), u);
+ r = hashmap_put(u->manager->watch_pids2, PID_TO_PTR(pid), u);
}
- q = set_put(u->pids, LONG_TO_PTR(pid));
+ q = set_put(u->pids, PID_TO_PTR(pid));
if (q < 0)
return q;
@@ -2015,16 +2015,16 @@ void unit_unwatch_pid(Unit *u, pid_t pid) {
assert(u);
assert(pid >= 1);
- (void) hashmap_remove_value(u->manager->watch_pids1, LONG_TO_PTR(pid), u);
- (void) hashmap_remove_value(u->manager->watch_pids2, LONG_TO_PTR(pid), u);
- (void) set_remove(u->pids, LONG_TO_PTR(pid));
+ (void) hashmap_remove_value(u->manager->watch_pids1, PID_TO_PTR(pid), u);
+ (void) hashmap_remove_value(u->manager->watch_pids2, PID_TO_PTR(pid), u);
+ (void) set_remove(u->pids, PID_TO_PTR(pid));
}
void unit_unwatch_all_pids(Unit *u) {
assert(u);
while (!set_isempty(u->pids))
- unit_unwatch_pid(u, PTR_TO_LONG(set_first(u->pids)));
+ unit_unwatch_pid(u, PTR_TO_PID(set_first(u->pids)));
u->pids = set_free(u->pids);
}
@@ -2038,7 +2038,7 @@ void unit_tidy_watch_pids(Unit *u, pid_t except1, pid_t except2) {
/* Cleans dead PIDs from our list */
SET_FOREACH(e, u->pids, i) {
- pid_t pid = PTR_TO_LONG(e);
+ pid_t pid = PTR_TO_PID(e);
if (pid == except1 || pid == except2)
continue;
@@ -2993,13 +2993,13 @@ static Set *unit_pid_set(pid_t main_pid, pid_t control_pid) {
/* Exclude the main/control pids from being killed via the cgroup */
if (main_pid > 0) {
- r = set_put(pid_set, LONG_TO_PTR(main_pid));
+ r = set_put(pid_set, PID_TO_PTR(main_pid));
if (r < 0)
goto fail;
}
if (control_pid > 0) {
- r = set_put(pid_set, LONG_TO_PTR(control_pid));
+ r = set_put(pid_set, PID_TO_PTR(control_pid));
if (r < 0)
goto fail;
}