From 00d9ef8560c252d8504be99cb38d1a54d35a9144 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 1 Aug 2016 19:24:40 +0200 Subject: core: add RemoveIPC= setting This adds the boolean RemoveIPC= setting to service, socket, mount and swap units (i.e. all unit types that may invoke processes). if turned on, and the unit's user/group is not root, all IPC objects of the user/group are removed when the service is shut down. The life-cycle of the IPC objects is hence bound to the unit life-cycle. This is particularly relevant for units with dynamic users, as it is essential that no objects owned by the dynamic users survive the service exiting. In fact, this patch adds code to imply RemoveIPC= if DynamicUser= is set. In order to communicate the UID/GID of an executed process back to PID 1 this adds a new "user lookup" socket pair, that is inherited into the forked processes, and closed before the exec(). This is needed since we cannot do NSS from PID 1 due to deadlock risks, However need to know the used UID/GID in order to clean up IPC owned by it if the unit shuts down. --- src/login/logind-user.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src/login') diff --git a/src/login/logind-user.c b/src/login/logind-user.c index 63363035e7..11951aca5b 100644 --- a/src/login/logind-user.c +++ b/src/login/logind-user.c @@ -612,9 +612,14 @@ int user_finalize(User *u) { if (k < 0) r = k; - /* Clean SysV + POSIX IPC objects */ - if (u->manager->remove_ipc) { - k = clean_ipc(u->uid); + /* Clean SysV + POSIX IPC objects, but only if this is not a system user. Background: in many setups cronjobs + * are run in full PAM and thus logind sessions, even if the code run doesn't belong to actual users but to + * system components. Since enable RemoveIPC= globally for all users, we need to be a bit careful with such + * cases, as we shouldn't accidentally remove a system service's IPC objects while it is running, just because + * a cronjob running as the same user just finished. Hence: exclude system users generally from IPC clean-up, + * and do it only for normal users. */ + if (u->manager->remove_ipc && u->uid > SYSTEM_UID_MAX) { + k = clean_ipc_by_uid(u->uid); if (k < 0) r = k; } -- cgit v1.2.3-54-g00ecf