From 0b421290e05862e1abbb5a82654bd2de9829dd58 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Tue, 10 Apr 2018 12:08:21 +0100 Subject: [PATCH 69/74] setpriv: implement option to set parent death signal When a process uses the syscall `prctl(PR_SET_PDEATHSIG, ...)`, it will get notified with a process-defined signal as soon as its parent process dies. This is for example being used by unshare(1)'s recently added "--kill-child" option, causing the forked child to be killed as soon as unshare itself dies. Unfortunately, some LSMs will cause the parent death signal to be reset when a process changes credentials, with the most important ones being SELinux and AppArmor. The following command will thus not work as expected: unshare --fork --kill-child setpriv --reuid user As soon as setpriv changes UID, the parent death signal is cleared and the child will never get signalled when unshare gets killed. Add a new option "--pdeathsig keep|clear|". Setting this flag will cause us to either - restore the previously active parent death signal as soon as the setpriv has applied all credential changes - clear the parent death signal - set the parent death signal to "" Furthermore, print out the currently set signal when dumping process state. [kzak@redhat.com: - small changes in codding style] Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1894192 Signed-off-by: Patrick Steinhardt Signed-off-by: Karel Zak --- sys-utils/setpriv.1 | 6 ++++++ sys-utils/setpriv.c | 49 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/sys-utils/setpriv.1 b/sys-utils/setpriv.1 index b900f6e08..f989bf33c 100644 --- a/sys-utils/setpriv.1 +++ b/sys-utils/setpriv.1 @@ -139,6 +139,12 @@ is cleared by .BR execve (2) and is therefore not allowed. .TP +.BR "\-\-pdeathsig keep" | clear | +Keep, clear or set the parent death signal. Some LSMs, most notably SELinux and +AppArmor, clear the signal when the process' credentials change. Using +\fB--pdeathsig keep\fR will restore the parent death signal after changing +credentials to remedy that situation. +.TP .BI \-\-selinux\-label " label" Request a particular SELinux transition (using a transition on exec, not dyntrans). This will fail and cause diff --git a/sys-utils/setpriv.c b/sys-utils/setpriv.c index 4147978cc..0d3a3b3c9 100644 --- a/sys-utils/setpriv.c +++ b/sys-utils/setpriv.c @@ -38,6 +38,7 @@ #include "strutils.h" #include "xalloc.h" #include "pathnames.h" +#include "signames.h" #ifndef PR_SET_NO_NEW_PRIVS # define PR_SET_NO_NEW_PRIVS 38 @@ -102,6 +103,8 @@ struct privctx { /* securebits */ int securebits; + /* parent death signal (<0 clear, 0 nothing, >0 signal) */ + int pdeathsig; /* LSMs */ const char *selinux_label; @@ -135,6 +138,8 @@ static void __attribute__((__noreturn__)) usage(void) fputs(_(" --init-groups initialize supplementary groups\n"), out); fputs(_(" --groups set supplementary groups\n"), out); fputs(_(" --securebits set securebits\n"), out); + fputs(_(" --pdeathsig keep|clear|\n" + " set or clear parent death signal\n"), out); fputs(_(" --selinux-label