From 4986f27c25ac3d6b20df78f6b137a0b3839dbe3f Mon Sep 17 00:00:00 2001 From: Leah Neukirchen Date: Mon, 23 Sep 2019 11:26:29 +0200 Subject: add -x to set PR_SET_NO_NEW_PRIVS for the children --- README | 11 +++++++---- reap.1 | 14 +++++++++----- reap.c | 14 ++++++++++---- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/README b/README index d5c6af4..15b891f 100644 --- a/README +++ b/README @@ -4,7 +4,7 @@ NAME reap – run process until all its spawned processes are dead SYNOPSIS - reap [-vw] command line ... + reap [-vwx] command line ... DESCRIPTION The reap utility executes the given command line and ensures all spawned @@ -19,9 +19,12 @@ DESCRIPTION The options are as follows: + -v Verbose mode, report what reap is doing. + -w Wait for all spawned processes to finish. - -v Verbose mode, report what reap is doing. + -x Forbid execution of binaries we cannot kill (using + PR_SET_NO_NEW_PRIVS). EXIT STATUS The reap utility exits with the exit status of the spawned command. @@ -34,7 +37,7 @@ ASSUMPTIONS enabled. reap can only work reliably when it has permission to kill all spawned - processes and they respect SIGTERM. + processes and they respect SIGTERM (see also -x). RATIONALE Keeping track of all spawned process is traditionally a hard problem on @@ -55,4 +58,4 @@ LICENSE http://creativecommons.org/publicdomain/zero/1.0/ -Void Linux August 13, 2019 Void Linux +Void Linux September 23, 2019 Void Linux diff --git a/reap.1 b/reap.1 index 86cd2c9..fe51f96 100644 --- a/reap.1 +++ b/reap.1 @@ -1,4 +1,4 @@ -.Dd August 13, 2019 +.Dd September 23, 2019 .Dt REAP 1 .Os .Sh NAME @@ -6,7 +6,7 @@ .Nd run process until all its spawned processes are dead .Sh SYNOPSIS .Nm -.Op Fl vw +.Op Fl vwx .Ar command\ line ... .Sh DESCRIPTION The @@ -31,12 +31,15 @@ will start slaying all children immediately. .Pp The options are as follows: .Bl -tag -width Ds -.It Fl w -Wait for all spawned processes to finish. .It Fl v Verbose mode, report what .Nm is doing. +.It Fl w +Wait for all spawned processes to finish. +.It Fl x +Forbid execution of binaries we cannot kill (using +.Dv PR_SET_NO_NEW_PRIVS ) . .El .Sh EXIT STATUS The @@ -57,7 +60,8 @@ is enabled. .Nm can only work reliably when it has permission to kill all spawned processes and they respect -.Dv SIGTERM . +.Dv SIGTERM +.Pq see also Fl x . .Sh RATIONALE Keeping track of all spawned process is traditionally a hard problem on Unix systems, mainly due to daemonization by forking twice. diff --git a/reap.c b/reap.c index ce3016c..3700a29 100644 --- a/reap.c +++ b/reap.c @@ -24,6 +24,7 @@ sig_atomic_t do_slay; int do_wait; int verbose; +int no_new_privs; #define E(str, ...) do { fprintf(stderr, "reap: " str ": %s\n", ## __VA_ARGS__, strerror(errno)); } while (0) #define F(str, ...) do { E(str, ## __VA_ARGS__); exit(111); } while (0) @@ -86,15 +87,17 @@ int main(int argc, char *argv[]) { int c; - while ((c = getopt(argc, argv, "+vw")) != -1) { + while ((c = getopt(argc, argv, "+vwx")) != -1) { switch (c) { - case 'w': do_wait = 1; break; case 'v': verbose = 1; break; + case 'w': do_wait = 1; break; + case 'x': no_new_privs = 1; break; default: fprintf(stderr, -"Usage: %s [-wv] COMMAND...\n" +"Usage: %s [-vwx] COMMAND...\n" +"\t-v\tverbose\n" "\t-w\twait for main command to finish (default: start reaping)\n" -"\t-v\tverbose\n", +"\t-x\tforbid execution of binaries we cannot kill\n", argv[0]); exit(1); } @@ -115,6 +118,9 @@ main(int argc, char *argv[]) { pid = fork(); if (pid == 0) { // in child close(pipefd[0]); + if (no_new_privs) + if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) != 0) + F("failed to SET_NO_NEW_PRIVS"); execvp(argv[optind], argv+optind); unsigned char err = errno; write(pipefd[1], &err, 1); -- cgit 1.4.1