From 602b8fa14a973de3a164ee3200ed1f80688303b7 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Wed, 28 Oct 2020 00:09:51 +0000 Subject: [PATCH] jail: add option for pidfile Signed-off-by: Daniel Golle --- jail/jail.c | 35 ++++++++++++++++++++++++++++++++++- service/instance.c | 19 +++++++++++++++++++ service/instance.h | 1 + 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/jail/jail.c b/jail/jail.c index 757f6cf..77315d2 100644 --- a/jail/jail.c +++ b/jail/jail.c @@ -67,7 +67,7 @@ #endif #define STACK_SIZE (1024 * 1024) -#define OPT_ARGS "S:C:n:h:r:w:d:psulocU:G:NR:fFO:T:EyJ:i" +#define OPT_ARGS "S:C:n:h:r:w:d:psulocU:G:NR:fFO:T:EyJ:iP:" #define OCI_VERSION_STRING "1.0.2" @@ -108,6 +108,7 @@ static struct { char **envp; char *uidmap; char *gidmap; + char *pidfile; struct sysctl_val **sysctl; int no_new_privs; int namespace; @@ -276,6 +277,7 @@ static void free_opts(bool parent) { free(opts.gidmap); free(opts.annotations); free(opts.ocibundle); + free(opts.pidfile); free_hooklist(opts.hooks.createRuntime); free_hooklist(opts.hooks.createContainer); free_hooklist(opts.hooks.startContainer); @@ -958,6 +960,7 @@ static void usage(void) fprintf(stderr, " -y\t\tprovide jail console\n"); fprintf(stderr, " -J \tcreate container from OCI bundle\n"); fprintf(stderr, " -j\t\tstart container immediately\n"); + fprintf(stderr, " -P \tcreate \n"); fprintf(stderr, "\nWarning: by default root inside the jail is the same\n\ and he has the same powers as root outside the jail,\n\ thus he can escape the jail and/or break stuff.\n\ @@ -2353,6 +2356,29 @@ container_handle_kill(struct ubus_context *ctx, struct ubus_object *obj, return UBUS_STATUS_UNKNOWN_ERROR; } +static int +jail_writepid(pid_t pid) +{ + FILE *_pidfile; + + if (!opts.pidfile) + return 0; + + _pidfile = fopen(opts.pidfile, "w"); + if (_pidfile == NULL) + return errno; + + if (fprintf(_pidfile, "%d\n", pid) < 0) { + fclose(_pidfile); + return errno; + } + + if (fclose(_pidfile)) + return errno; + + return 0; +} + static struct ubus_method container_methods[] = { UBUS_METHOD_NOARG("start", handle_start), UBUS_METHOD_NOARG("state", handle_state), @@ -2480,6 +2506,9 @@ int main(int argc, char **argv) case 'i': opts.immediately = true; break; + case 'P': + opts.pidfile = strdup(optarg); + break; } } @@ -2751,6 +2780,10 @@ static void post_main(struct uloop_timeout *t) netns_fd = ns_open_pid("net", jail_process.pid); netns_updown(jail_process.pid, true); } + if (jail_writepid(jail_process.pid)) { + ERROR("failed to write pidfile: %m\n"); + exit(-1); + } } else if (jail_process.pid == 0) { /* fork child process */ exit(exec_jail(NULL)); diff --git a/service/instance.c b/service/instance.c index a57fe30..f1242d6 100644 --- a/service/instance.c +++ b/service/instance.c @@ -119,6 +119,7 @@ enum { JAIL_ATTR_CONSOLE, JAIL_ATTR_REQUIREJAIL, JAIL_ATTR_IMMEDIATELY, + JAIL_ATTR_PIDFILE, __JAIL_ATTR_MAX, }; @@ -137,6 +138,7 @@ static const struct blobmsg_policy jail_attr[__JAIL_ATTR_MAX] = { [JAIL_ATTR_CONSOLE] = { "console", BLOBMSG_TYPE_BOOL }, [JAIL_ATTR_REQUIREJAIL] = { "requirejail", BLOBMSG_TYPE_BOOL }, [JAIL_ATTR_IMMEDIATELY] = { "immediately", BLOBMSG_TYPE_BOOL }, + [JAIL_ATTR_PIDFILE] = { "pidfile", BLOBMSG_TYPE_STRING }, }; struct instance_netdev { @@ -311,6 +313,11 @@ jail_run(struct service_instance *in, char **argv) if (in->immediately) argv[argc++] = "-i"; + if (jail->pidfile) { + argv[argc++] = "-P"; + argv[argc++] = jail->pidfile; + } + if (in->bundle) { argv[argc++] = "-J"; argv[argc++] = in->bundle; @@ -928,6 +935,9 @@ instance_config_changed(struct service_instance *in, struct service_instance *in if (string_changed(in->jail.hostname, in_new->jail.hostname)) return true; + if (string_changed(in->jail.pidfile, in_new->jail.pidfile)) + return true; + if (in->jail.procfs != in_new->jail.procfs) return true; @@ -1117,6 +1127,10 @@ instance_jail_parse(struct service_instance *in, struct blob_attr *attr) jail->console = true; jail->argc++; } + if (tb[JAIL_ATTR_PIDFILE]) { + jail->pidfile = strdup(blobmsg_get_string(tb[JAIL_ATTR_PIDFILE])); + jail->argc += 2; + } if (tb[JAIL_ATTR_MOUNT]) { struct blob_attr *cur; @@ -1447,6 +1461,7 @@ instance_config_move(struct service_instance *in, struct service_instance *in_sr instance_config_move_strdup(&in->group, in_src->group); instance_config_move_strdup(&in->jail.name, in_src->jail.name); instance_config_move_strdup(&in->jail.hostname, in_src->jail.hostname); + instance_config_move_strdup(&in->jail.pidfile, in_src->jail.pidfile); free(in->config); in->config = in_src->config; @@ -1490,6 +1505,7 @@ instance_free(struct service_instance *in) free(in->bundle); free(in->jail.name); free(in->jail.hostname); + free(in->jail.pidfile); free(in->seccomp); free(in->capabilities); free(in->pidfile); @@ -1640,6 +1656,9 @@ void instance_dump(struct blob_buf *b, struct service_instance *in, int verbose) blobmsg_add_u8(b, "userns", in->jail.userns); blobmsg_add_u8(b, "cgroupsns", in->jail.cgroupsns); } else { + if (in->jail.pidfile) + blobmsg_add_string(b, "pidfile", in->jail.pidfile); + blobmsg_add_u8(b, "immediately", in->immediately); } blobmsg_add_u8(b, "console", (in->console.fd.fd > -1)); diff --git a/service/instance.h b/service/instance.h index 09fbb5d..bbd943c 100644 --- a/service/instance.h +++ b/service/instance.h @@ -35,6 +35,7 @@ struct jail { bool console; char *name; char *hostname; + char *pidfile; struct blobmsg_list mount; int argc; }; -- 2.30.2