aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Oberhollenzer <goliath@infraroot.at>2020-05-08 02:44:33 +0200
committerDavid Oberhollenzer <goliath@infraroot.at>2020-05-08 02:51:20 +0200
commitf6ef5b8dd3f1b8d6af104304a9988ff1f8edd182 (patch)
treebf29526bf2c57870d79546ca2823044f9e927844
parent62133a68b7a1aecf65765f7137ef8d6e0eed913e (diff)
Implement a "subreaper" service flag
For particularly hostile daemons. Signed-off-by: David Oberhollenzer <goliath@infraroot.at>
-rw-r--r--initd/init.h1
-rw-r--r--initd/runsvc.c15
-rw-r--r--lib/include/service.h2
-rw-r--r--lib/init/rdsvc.c17
4 files changed, 32 insertions, 3 deletions
diff --git a/initd/init.h b/initd/init.h
index 9e18b96..b1287ee 100644
--- a/initd/init.h
+++ b/initd/init.h
@@ -16,6 +16,7 @@
#include <linux/reboot.h>
#include <sys/reboot.h>
+#include <sys/prctl.h>
#include <stdbool.h>
#include <signal.h>
diff --git a/initd/runsvc.c b/initd/runsvc.c
index b30e8e3..144490b 100644
--- a/initd/runsvc.c
+++ b/initd/runsvc.c
@@ -132,13 +132,13 @@ static __attribute__((noreturn)) void argv_exec(exec_t *e)
exit(EXIT_FAILURE);
}
-static int run_sequentially(exec_t *list)
+static int run_sequentially(exec_t *list, bool direct_exec_last)
{
pid_t ret, pid;
int status;
for (; list != NULL; list = list->next) {
- if (list->next == NULL)
+ if (list->next == NULL && direct_exec_last)
argv_exec(list);
pid = fork();
@@ -169,6 +169,7 @@ pid_t runsvc(service_t *svc)
{
sigset_t mask;
pid_t pid;
+ int ret;
pid = fork();
@@ -190,7 +191,15 @@ pid_t runsvc(service_t *svc)
exit(EXIT_FAILURE);
}
- exit(run_sequentially(svc->exec));
+ if (svc->flags & SVC_FLAG_SUB_REAPER) {
+ prctl(PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0);
+
+ ret = run_sequentially(svc->exec, false);
+ } else {
+ ret = run_sequentially(svc->exec, true);
+ }
+
+ exit(ret);
}
return pid;
diff --git a/lib/include/service.h b/lib/include/service.h
index 0fbf018..05ab8de 100644
--- a/lib/include/service.h
+++ b/lib/include/service.h
@@ -39,6 +39,8 @@ enum {
/* truncate stdout */
SVC_FLAG_TRUNCATE_OUT = 0x01,
+ SVC_FLAG_SUB_REAPER = 0x08,
+
SVC_FLAG_HAS_EXEC = 0x10,
};
diff --git a/lib/init/rdsvc.c b/lib/init/rdsvc.c
index 09ed156..c461d98 100644
--- a/lib/init/rdsvc.c
+++ b/lib/init/rdsvc.c
@@ -204,6 +204,22 @@ static int svc_target(void *user, char *arg, rdline_t *rd)
return 0;
}
+static int svc_subreaper(void *user, char *arg, rdline_t *rd)
+{
+ service_t *svc = user;
+
+ if (try_unescape(arg, rd))
+ return -1;
+
+ if (strcmp(arg, "yes") == 0 || strcmp(arg, "on") == 0 ||
+ strcmp(arg, "true") == 0) {
+ svc->flags |= SVC_FLAG_SUB_REAPER;
+ } else {
+ svc->flags &= ~SVC_FLAG_SUB_REAPER;
+ }
+ return 0;
+}
+
static const cfg_param_t svc_params[] = {
{ "description", 0, svc_desc },
{ "exec", 1, svc_exec },
@@ -212,6 +228,7 @@ static const cfg_param_t svc_params[] = {
{ "tty", 0, svc_tty },
{ "before", 0, svc_before },
{ "after", 0, svc_after },
+ { "subreaper", 0, svc_subreaper },
};
service_t *rdsvc(int dirfd, const char *filename)