From: Daniel Golle Date: Wed, 29 Jul 2020 12:49:38 +0000 (+0100) Subject: service: add method to query available container features X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=47a9f0d652678a0994595095de6e15f980cb37d3;p=project%2Fprocd.git service: add method to query available container features Signed-off-by: Daniel Golle --- diff --git a/service/service.c b/service/service.c index c2d072b..cabc69c 100644 --- a/service/service.c +++ b/service/service.c @@ -14,7 +14,12 @@ #include #include +#include +#include +#include + #include +#include #include #include @@ -297,6 +302,97 @@ static inline bool is_container_obj(struct ubus_object *obj) return (obj && (strcmp(obj->name, "container") == 0)); } +static inline void put_namespace(struct blob_buf *b, char *name) +{ + char nsfname[32]; + struct stat statbuf; + + snprintf(nsfname, sizeof(nsfname), "/proc/self/ns/%s", name); + + if (!stat(nsfname, &statbuf)) + blobmsg_add_string(b, NULL, name); +} + +static void put_cgroups(struct blob_buf *b) +{ + int fd, ret; + static char buf[512] = ""; + char *t, *z; + + fd = open("/sys/fs/cgroup/cgroup.controllers", O_RDONLY); + if (fd == -1) + return; + + ret = read(fd, &buf, sizeof(buf)); + close(fd); + + if (ret < 2) + return; + + t = buf; + while(t) { + z = t; + /* replace space with \0 and direct next entry */ + t = strchr(z, ' '); + if (t) { + *(t++) = '\0'; + } else { /* replace trailing new-line with \0 */ + t = strchr(z, '\n'); + if (!t) /* shouldn't happen, but don't segfault if it does */ + break; + + *t = '\0'; + t = NULL; + } + blobmsg_add_string(b, NULL, z); + } +} + +static int +container_handle_features(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct utsname utsbuf; + struct stat statbuf; + void *nsarray, *cgarray; + + if (stat("/sbin/ujail", &statbuf)) + return UBUS_STATUS_NOT_SUPPORTED; + + if (uname(&utsbuf) < 0) + return UBUS_STATUS_UNKNOWN_ERROR; + + blob_buf_init(&b, 0); + blobmsg_add_string(&b, "machine", utsbuf.machine); + +#ifdef SECCOMP_SUPPORT + blobmsg_add_u8(&b, "seccomp", true); +#else + blobmsg_add_u8(&b, "seccomp", false); +#endif + + cgarray = blobmsg_open_array(&b, "cgroup"); + put_cgroups(&b); + blobmsg_close_array(&b, cgarray); + + nsarray = blobmsg_open_array(&b, "namespaces"); + put_namespace(&b, "cgroup"); + put_namespace(&b, "ipc"); + put_namespace(&b, "mnt"); + put_namespace(&b, "net"); + put_namespace(&b, "pid"); +#ifdef CLONE_NEWTIME + put_namespace(&b, "time"); +#endif + put_namespace(&b, "user"); + put_namespace(&b, "uts"); + blobmsg_close_array(&b, nsarray); + ubus_send_reply(ctx, req, b.head); + + return UBUS_STATUS_OK; +} + static int service_handle_set(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, @@ -936,6 +1032,7 @@ static struct ubus_method container_object_methods[] = { UBUS_METHOD("list", service_handle_list, service_list_attrs), UBUS_METHOD("delete", service_handle_delete, service_del_attrs), UBUS_METHOD("state", service_handle_state, service_state_attrs), + UBUS_METHOD_NOARG("get_features", container_handle_features), UBUS_METHOD("console_set", container_handle_console, container_console_policy), UBUS_METHOD("console_attach", container_handle_console, container_console_policy), };