X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fprocd.git;a=blobdiff_plain;f=service%2Finstance.c;h=26faa9a5e930398c8d78cc16ee2f9c650095cf55;hp=f5b61fa42c626bde52c11d80455235b9d47a44b1;hb=81e1ace59ec86842bb6f30dc0e44afc00cd7f79f;hpb=91da63d3d3fd680c805dd1a1b78df5b8731a8173 diff --git a/service/instance.c b/service/instance.c index f5b61fa..26faa9a 100644 --- a/service/instance.c +++ b/service/instance.c @@ -12,6 +12,7 @@ * GNU General Public License for more details. */ +#define _GNU_SOURCE #include #include #include @@ -19,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -75,22 +77,22 @@ static const struct blobmsg_policy instance_attr[__INSTANCE_ATTR_MAX] = { enum { JAIL_ATTR_NAME, - JAIL_ATTR_ROOT, JAIL_ATTR_PROCFS, JAIL_ATTR_SYSFS, JAIL_ATTR_UBUS, JAIL_ATTR_LOG, + JAIL_ATTR_RONLY, JAIL_ATTR_MOUNT, __JAIL_ATTR_MAX, }; static const struct blobmsg_policy jail_attr[__JAIL_ATTR_MAX] = { [JAIL_ATTR_NAME] = { "name", BLOBMSG_TYPE_STRING }, - [JAIL_ATTR_ROOT] = { "root", BLOBMSG_TYPE_STRING }, [JAIL_ATTR_PROCFS] = { "procfs", BLOBMSG_TYPE_BOOL }, [JAIL_ATTR_SYSFS] = { "sysfs", BLOBMSG_TYPE_BOOL }, [JAIL_ATTR_UBUS] = { "ubus", BLOBMSG_TYPE_BOOL }, [JAIL_ATTR_LOG] = { "log", BLOBMSG_TYPE_BOOL }, + [JAIL_ATTR_RONLY] = { "ronly", BLOBMSG_TYPE_BOOL }, [JAIL_ATTR_MOUNT] = { "mount", BLOBMSG_TYPE_TABLE }, }; @@ -181,11 +183,6 @@ jail_run(struct service_instance *in, char **argv) argv[argc++] = jail->name; } - if (jail->root) { - argv[argc++] = "-P"; - argv[argc++] = jail->root; - } - if (in->seccomp) { argv[argc++] = "-S"; argv[argc++] = in->seccomp; @@ -203,6 +200,9 @@ jail_run(struct service_instance *in, char **argv) if (jail->log) argv[argc++] = "-l"; + if (jail->ronly) + argv[argc++] = "-o"; + blobmsg_list_for_each(&jail->mount, var) { const char *type = blobmsg_data(var->data); @@ -224,8 +224,11 @@ instance_run(struct service_instance *in, int _stdout, int _stderr) struct blobmsg_list_node *var; struct blob_attr *cur; char **argv; + char *ld_preload; int argc = 1; /* NULL terminated */ int rem, _stdin; + bool seccomp = !in->trace && !in->has_jail && in->seccomp; + bool setlbf = _stdout >= 0; if (in->nice) setpriority(PRIO_PROCESS, 0, in->nice); @@ -236,10 +239,14 @@ instance_run(struct service_instance *in, int _stdout, int _stderr) blobmsg_list_for_each(&in->env, var) setenv(blobmsg_name(var->data), blobmsg_data(var->data), 1); - if (!in->trace && !in->has_jail && in->seccomp) { + if (seccomp) setenv("SECCOMP_FILE", in->seccomp, 1); - setenv("LD_PRELOAD", "/lib/libpreload-seccomp.so", 1); - } + + if ((seccomp || setlbf) && asprintf(&ld_preload, "LD_PRELOAD=%s%s%s", + seccomp ? "/lib/libpreload-seccomp.so" : "", + seccomp && setlbf ? ":" : "", + setlbf ? "/lib/libsetlbf.so" : "") > 0) + putenv(ld_preload); blobmsg_list_for_each(&in->limits, var) instance_limits(blobmsg_name(var->data), blobmsg_data(var->data)); @@ -282,16 +289,35 @@ instance_run(struct service_instance *in, int _stdout, int _stderr) closefd(_stderr); } - if (in->uid || in->gid) { - if (setuid(in->uid) || setgid(in->gid)) { - ERROR("failed to set uid:%d, gid:%d\n", in->uid, in->gid); - exit(127); - } + if (in->gid && setgid(in->gid)) { + ERROR("failed to set group id %d: %d (%s)\n", in->gid, errno, strerror(errno)); + exit(127); } + if (in->uid && setuid(in->uid)) { + ERROR("failed to set user id %d: %d (%s)\n", in->uid, errno, strerror(errno)); + exit(127); + } + execvp(argv[0], argv); exit(127); } +static void +instance_free_stdio(struct service_instance *in) +{ + if (in->_stdout.fd.fd > -1) { + ustream_free(&in->_stdout.stream); + close(in->_stdout.fd.fd); + in->_stdout.fd.fd = -1; + } + + if (in->_stderr.fd.fd > -1) { + ustream_free(&in->_stderr.stream); + close(in->_stderr.fd.fd); + in->_stderr.fd.fd = -1; + } +} + void instance_start(struct service_instance *in) { @@ -307,6 +333,7 @@ instance_start(struct service_instance *in) if (in->proc.pending) return; + instance_free_stdio(in); if (in->_stdout.fd.fd > -2) { if (pipe(opipe)) { ULOG_WARN("pipe() failed: %d (%s)\n", errno, strerror(errno)); @@ -363,6 +390,10 @@ instance_stdio(struct ustream *s, int prio, struct service_instance *in) char *newline, *str, *arg0, ident[32]; int len; + arg0 = basename(blobmsg_data(blobmsg_data(in->command))); + snprintf(ident, sizeof(ident), "%s[%d]", arg0, in->proc.pid); + ulog_open(ULOG_SYSLOG, LOG_DAEMON, ident); + do { str = ustream_get_read_buf(s, NULL); if (!str) @@ -373,17 +404,13 @@ instance_stdio(struct ustream *s, int prio, struct service_instance *in) break; *newline = 0; - len = newline + 1 - str; - - arg0 = basename(blobmsg_data(blobmsg_data(in->command))); - snprintf(ident, sizeof(ident), "%s[%d]", arg0, in->proc.pid); - - ulog_open(ULOG_SYSLOG, LOG_DAEMON, ident); ulog(prio, "%s\n", str); - ulog_open(ULOG_SYSLOG, LOG_DAEMON, "procd"); + len = newline + 1 - str; ustream_consume(s, len); } while (1); + + ulog_open(ULOG_SYSLOG, LOG_DAEMON, "procd"); } static void @@ -617,10 +644,6 @@ instance_jail_parse(struct service_instance *in, struct blob_attr *attr) jail->name = blobmsg_get_string(tb[JAIL_ATTR_NAME]); jail->argc += 2; } - if (tb[JAIL_ATTR_ROOT]) { - jail->root = blobmsg_get_string(tb[JAIL_ATTR_ROOT]); - jail->argc += 2; - } if (tb[JAIL_ATTR_PROCFS]) { jail->procfs = blobmsg_get_bool(tb[JAIL_ATTR_PROCFS]); jail->argc++; @@ -637,6 +660,10 @@ instance_jail_parse(struct service_instance *in, struct blob_attr *attr) jail->log = blobmsg_get_bool(tb[JAIL_ATTR_LOG]); jail->argc++; } + if (tb[JAIL_ATTR_RONLY]) { + jail->ronly = blobmsg_get_bool(tb[JAIL_ATTR_RONLY]); + jail->argc++; + } if (tb[JAIL_ATTR_MOUNT]) { struct blob_attr *cur; int rem; @@ -820,16 +847,7 @@ instance_update(struct service_instance *in, struct service_instance *in_new) void instance_free(struct service_instance *in) { - if (in->_stdout.fd.fd > -1) { - ustream_free(&in->_stdout.stream); - close(in->_stdout.fd.fd); - } - - if (in->_stderr.fd.fd > -1) { - ustream_free(&in->_stderr.stream); - close(in->_stderr.fd.fd); - } - + instance_free_stdio(in); uloop_process_delete(&in->proc); uloop_timeout_cancel(&in->timeout); trigger_del(in); @@ -871,6 +889,9 @@ void instance_dump(struct blob_buf *b, struct service_instance *in, int verbose) { void *i; + if (!in->valid) + return; + i = blobmsg_open_table(b, in->name); blobmsg_add_u8(b, "running", in->proc.pending); if (in->proc.pending) @@ -911,8 +932,8 @@ void instance_dump(struct blob_buf *b, struct service_instance *in, int verbose) if (in->respawn) { void *r = blobmsg_open_table(b, "respawn"); - blobmsg_add_u32(b, "timeout", in->respawn_timeout); blobmsg_add_u32(b, "threshold", in->respawn_threshold); + blobmsg_add_u32(b, "timeout", in->respawn_timeout); blobmsg_add_u32(b, "retry", in->respawn_retry); blobmsg_close_table(b, r); } @@ -927,12 +948,11 @@ void instance_dump(struct blob_buf *b, struct service_instance *in, int verbose) void *r = blobmsg_open_table(b, "jail"); if (in->jail.name) blobmsg_add_string(b, "name", in->jail.name); - if (in->jail.root) - blobmsg_add_string(b, "root", in->jail.root); blobmsg_add_u8(b, "procfs", in->jail.procfs); blobmsg_add_u8(b, "sysfs", in->jail.sysfs); blobmsg_add_u8(b, "ubus", in->jail.ubus); blobmsg_add_u8(b, "log", in->jail.log); + blobmsg_add_u8(b, "ronly", in->jail.ronly); blobmsg_close_table(b, r); if (!avl_is_empty(&in->jail.mount.avl)) { struct blobmsg_list_node *var;