]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
seccomp: add seccomp_notify_fd_active api extension
authorChristian Brauner <christian.brauner@ubuntu.com>
Thu, 6 Aug 2020 12:38:07 +0000 (14:38 +0200)
committerChristian Brauner <christian.brauner@ubuntu.com>
Thu, 6 Aug 2020 12:40:13 +0000 (14:40 +0200)
which allows to retrieve an active seccomp notifier fd from a running
container.

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
doc/api-extensions.md
src/lxc/api_extensions.h
src/lxc/commands.c
src/lxc/commands.h
src/lxc/lxccontainer.c
src/lxc/lxccontainer.h

index 21cb55d1117c6bd437723fc8d23b3bfe97edd69b..9a716e48acebd9b1a8a3ffba1602f9e59b21b09a 100644 (file)
@@ -136,3 +136,7 @@ This adds the ability to use "denylist" and "allowlist" in seccomp v2 policies.
 
 This adds the ability to allocate a file descriptor for the devpts instance of
 the container.
+
+## seccomp\_notify\_fd\_active
+
+Retrieve the seccomp notifier fd from a running container.
index 4d975048872ee7f0f95a411491fab3ce188b1846..1b40e5d452a04d9b4cba87d2f5b70ef0fe673f13 100644 (file)
@@ -44,6 +44,7 @@ static char *api_extensions[] = {
        "time_namespace",
        "seccomp_allow_deny_syntax",
        "devpts_fd",
+       "seccomp_notify_fd_active",
 };
 
 static size_t nr_api_extensions = sizeof(api_extensions) / sizeof(*api_extensions);
index 22fbb04bb4a3abb2bfb985fd900611b31aa3a020..4ed84c3a02be6067021fa67600612398e98eb860 100644 (file)
@@ -87,6 +87,7 @@ static const char *lxc_cmd_str(lxc_cmd_t cmd)
                [LXC_CMD_GET_LIMITING_CGROUP]           = "get_limiting_cgroup",
                [LXC_CMD_GET_LIMITING_CGROUP2_FD]       = "get_limiting_cgroup2_fd",
                [LXC_CMD_GET_DEVPTS_FD]                 = "get_devpts_fd",
+               [LXC_CMD_GET_SECCOMP_NOTIFY_FD]         = "get_seccomp_notify_fd",
        };
 
        if (cmd >= LXC_CMD_MAX)
@@ -162,6 +163,11 @@ static int lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd)
                rsp->data = INT_TO_PTR(devpts_fd);
        }
 
+       if (cmd->req.cmd == LXC_CMD_GET_SECCOMP_NOTIFY_FD) {
+               int seccomp_notify_fd = move_fd(fd_rsp);
+               rsp->data = INT_TO_PTR(seccomp_notify_fd);
+       }
+
        if (rsp->datalen == 0)
                return log_debug(ret,
                                 "Response data length for command \"%s\" is 0",
@@ -490,6 +496,51 @@ static int lxc_cmd_get_devpts_fd_callback(int fd, struct lxc_cmd_req *req,
        return 0;
 }
 
+int lxc_cmd_get_seccomp_notify_fd(const char *name, const char *lxcpath)
+{
+#if HAVE_DECL_SECCOMP_NOTIFY_FD
+       int ret, stopped;
+       struct lxc_cmd_rr cmd = {
+               .req = {
+                       .cmd = LXC_CMD_GET_SECCOMP_NOTIFY_FD,
+               },
+       };
+
+       ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
+       if (ret < 0)
+               return log_debug_errno(-1, errno, "Failed to process seccomp notify fd command");
+
+       if (cmd.rsp.ret < 0)
+               return log_debug_errno(-EBADF, errno, "Failed to receive seccomp notify fd");
+
+       return PTR_TO_INT(cmd.rsp.data);
+#else
+       return ret_errno(EOPNOTSUPP);
+#endif
+}
+
+static int lxc_cmd_get_seccomp_notify_fd_callback(int fd, struct lxc_cmd_req *req,
+                                                 struct lxc_handler *handler,
+                                                 struct lxc_epoll_descr *descr)
+{
+#if HAVE_DECL_SECCOMP_NOTIFY_FD
+       struct lxc_cmd_rsp rsp = {
+               .ret = 0,
+       };
+       int ret;
+
+       if (!handler->conf || handler->conf->seccomp.notifier.notify_fd < 0)
+               rsp.ret = -EBADF;
+       ret = lxc_abstract_unix_send_fds(fd, &handler->conf->seccomp.notifier.notify_fd, 1, &rsp, sizeof(rsp));
+       if (ret < 0)
+               return log_error(LXC_CMD_REAP_CLIENT_FD, "Failed to send seccomp notify fd");
+
+       return 0;
+#else
+       return ret_errno(EOPNOTSUPP);
+#endif
+}
+
 /*
  * lxc_cmd_get_clone_flags: Get clone flags container was spawned with
  *
@@ -1549,6 +1600,7 @@ static int lxc_cmd_process(int fd, struct lxc_cmd_req *req,
                [LXC_CMD_GET_LIMITING_CGROUP]           = lxc_cmd_get_limiting_cgroup_callback,
                [LXC_CMD_GET_LIMITING_CGROUP2_FD]       = lxc_cmd_get_limiting_cgroup2_fd_callback,
                [LXC_CMD_GET_DEVPTS_FD]                 = lxc_cmd_get_devpts_fd_callback,
+               [LXC_CMD_GET_SECCOMP_NOTIFY_FD]         = lxc_cmd_get_seccomp_notify_fd_callback,
        };
 
        if (req->cmd >= LXC_CMD_MAX)
index ef545e23aed3e01bf7ebf71bdc3c13204d36e4db..c87dad4e90967d01102118b5fe904a9092163041 100644 (file)
@@ -42,6 +42,7 @@ typedef enum {
        LXC_CMD_GET_LIMITING_CGROUP,
        LXC_CMD_GET_LIMITING_CGROUP2_FD,
        LXC_CMD_GET_DEVPTS_FD,
+       LXC_CMD_GET_SECCOMP_NOTIFY_FD,
        LXC_CMD_MAX,
 } lxc_cmd_t;
 
@@ -120,6 +121,7 @@ __hidden extern int lxc_cmd_mainloop_add(const char *name, struct lxc_epoll_desc
 __hidden extern int lxc_try_cmd(const char *name, const char *lxcpath);
 __hidden extern int lxc_cmd_console_log(const char *name, const char *lxcpath,
                                        struct lxc_console_log *log);
+__hidden extern int lxc_cmd_get_seccomp_notify_fd(const char *name, const char *lxcpath);
 __hidden extern int lxc_cmd_seccomp_notify_add_listener(const char *name, const char *lxcpath, int fd,
                                                        /* unused */ unsigned int command,
                                                        /* unused */ unsigned int flags);
index 8d854aaf136ff7aa8b0161e2be2cb8b4b633235c..673cf2483d99db0363b2d9f5c7d9db24d3195a3b 100644 (file)
@@ -5240,6 +5240,16 @@ static int do_lxcapi_seccomp_notify_fd(struct lxc_container *c)
 
 WRAP_API(int, lxcapi_seccomp_notify_fd)
 
+static int do_lxcapi_seccomp_notify_fd_active(struct lxc_container *c)
+{
+       if (!c || !c->lxc_conf)
+               return ret_set_errno(-1, -EINVAL);
+
+       return lxc_cmd_get_seccomp_notify_fd(c->name, c->config_path);
+}
+
+WRAP_API(int, lxcapi_seccomp_notify_fd_active)
+
 struct lxc_container *lxc_container_new(const char *name, const char *configpath)
 {
        struct lxc_container *c;
@@ -5382,6 +5392,7 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath
        c->mount = lxcapi_mount;
        c->umount = lxcapi_umount;
        c->seccomp_notify_fd = lxcapi_seccomp_notify_fd;
+       c->seccomp_notify_fd_active = lxcapi_seccomp_notify_fd_active;
 
        return c;
 
index 3437550d7ea7865fa81dde8a9187c41024ebbecd..1229a1f3491df3cc445824a49b4e72ad33d86217 100644 (file)
@@ -857,6 +857,15 @@ struct lxc_container {
         */
        int (*seccomp_notify_fd)(struct lxc_container *c);
 
+       /*!
+        * \brief Retrieve a file descriptor for the running container's seccomp filter.
+        *
+        * \param c Container
+        *
+        * \return file descriptor for the running container's seccomp filter
+        */
+       int (*seccomp_notify_fd_active)(struct lxc_container *c);
+
        /*!
         * \brief Retrieve a pidfd for the container's init process.
         *