]> git.proxmox.com Git - mirror_lxc.git/blobdiff - src/lxc/attach.c
attach: don't close stdout of getent
[mirror_lxc.git] / src / lxc / attach.c
index e00584178ba41d326c1fa723d50e774a5797d42a..80c41fe263a164a9ed628fe87163c5b833f99e75 100644 (file)
@@ -126,7 +126,7 @@ static struct lxc_proc_context_info *lxc_proc_get_context_info(pid_t pid)
 static inline void lxc_proc_close_ns_fd(struct lxc_proc_context_info *ctx)
 {
        for (int i = 0; i < LXC_NS_MAX; i++) {
-               __do_close_prot_errno int fd = ctx->ns_fd[i];
+               __do_close_prot_errno int fd ATTR_UNUSED = move_fd(ctx->ns_fd[i]);
        }
 }
 
@@ -159,7 +159,6 @@ static int in_same_namespace(pid_t pid1, pid_t pid2, const char *ns)
 {
        __do_close_prot_errno int ns_fd1 = -1, ns_fd2 = -1;
        int ret = -1;
-       int saved_errno;
        struct stat ns_st1, ns_st2;
 
        ns_fd1 = lxc_preserve_ns(pid1, ns);
@@ -214,7 +213,7 @@ static int lxc_attach_to_ns(pid_t pid, struct lxc_proc_context_info *ctx)
        return 0;
 }
 
-static int lxc_attach_remount_sys_proc(void)
+int lxc_attach_remount_sys_proc(void)
 {
        int ret;
 
@@ -460,7 +459,7 @@ static char *lxc_attach_getpwshell(uid_t uid)
                        close(STDERR_FILENO);
                } else {
                        (void)dup3(fd, STDIN_FILENO, O_CLOEXEC);
-                       (void)dup3(fd, STDOUT_FILENO, O_CLOEXEC);
+                       (void)dup3(fd, STDERR_FILENO, O_CLOEXEC);
                        close(fd);
                }
 
@@ -609,8 +608,8 @@ static bool fetch_seccomp(struct lxc_container *c, lxc_attach_options_t *options
 
        if (!(options->namespaces & CLONE_NEWNS) ||
            !(options->attach_flags & LXC_ATTACH_LSM)) {
-               free(c->lxc_conf->seccomp);
-               c->lxc_conf->seccomp = NULL;
+               free(c->lxc_conf->seccomp.seccomp);
+               c->lxc_conf->seccomp.seccomp = NULL;
                return true;
        }
 
@@ -670,7 +669,7 @@ static bool no_new_privs(struct lxc_container *c, lxc_attach_options_t *options)
 
 static signed long get_personality(const char *name, const char *lxcpath)
 {
-       __do_free char *p;
+       __do_free char *p = NULL;
 
        p = lxc_cmd_get_config_item(name, "lxc.arch", lxcpath);
        if (!p)
@@ -690,8 +689,8 @@ struct attach_clone_payload {
 
 static void lxc_put_attach_clone_payload(struct attach_clone_payload *p)
 {
-       __do_close_prot_errno int ipc_socket = p->ipc_socket;
-       __do_close_prot_errno int terminal_slave_fd = p->terminal_slave_fd;
+       __do_close_prot_errno int ipc_socket ATTR_UNUSED = p->ipc_socket;
+       __do_close_prot_errno int terminal_slave_fd ATTR_UNUSED = p->terminal_slave_fd;
 
        if (p->init_ctx) {
                lxc_proc_put_context_info(p->init_ctx);
@@ -701,7 +700,7 @@ static void lxc_put_attach_clone_payload(struct attach_clone_payload *p)
 
 static int attach_child_main(struct attach_clone_payload *payload)
 {
-       int fd, lsm_fd, ret;
+       int lsm_fd, ret;
        uid_t new_uid;
        gid_t new_gid;
        uid_t ns_root_uid = 0;
@@ -853,12 +852,18 @@ static int attach_child_main(struct attach_clone_payload *payload)
        }
 
        if (init_ctx->container && init_ctx->container->lxc_conf &&
-           init_ctx->container->lxc_conf->seccomp) {
-               ret = lxc_seccomp_load(init_ctx->container->lxc_conf);
+           init_ctx->container->lxc_conf->seccomp.seccomp) {
+               struct lxc_conf *conf = init_ctx->container->lxc_conf;
+
+               ret = lxc_seccomp_load(conf);
                if (ret < 0)
                        goto on_error;
 
                TRACE("Loaded seccomp profile");
+
+               ret = lxc_seccomp_send_notifier_fd(&conf->seccomp, payload->ipc_socket);
+               if (ret < 0)
+                       goto on_error;
        }
 
        close(payload->ipc_socket);
@@ -894,10 +899,11 @@ static int attach_child_main(struct attach_clone_payload *payload)
        if (options->stderr_fd > STDERR_FILENO)
                close(options->stderr_fd);
 
-       /* Try to remove FD_CLOEXEC flag from stdin/stdout/stderr, but also
+       /*
+        * Try to remove FD_CLOEXEC flag from stdin/stdout/stderr, but also
         * here, ignore errors.
         */
-       for (fd = STDIN_FILENO; fd <= STDERR_FILENO; fd++) {
+       for (int fd = STDIN_FILENO; fd <= STDERR_FILENO; fd++) {
                ret = fd_cloexec(fd, false);
                if (ret < 0) {
                        SYSERROR("Failed to clear FD_CLOEXEC from file descriptor %d", fd);
@@ -1002,9 +1008,9 @@ static inline void lxc_attach_terminal_close_log(struct lxc_terminal *terminal)
        close_prot_errno_disarm(terminal->log_fd);
 }
 
-int lxc_attach(const char *name, const char *lxcpath,
-              lxc_attach_exec_t exec_function, void *exec_payload,
-              lxc_attach_options_t *options, pid_t *attached_process)
+int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function,
+              void *exec_payload, lxc_attach_options_t *options,
+              pid_t *attached_process)
 {
        int i, ret, status;
        int ipc_sockets[2];
@@ -1014,6 +1020,7 @@ int lxc_attach(const char *name, const char *lxcpath,
        struct lxc_proc_context_info *init_ctx;
        struct lxc_terminal terminal;
        struct lxc_conf *conf;
+       char *name, *lxcpath;
        struct attach_clone_payload payload = {0};
 
        ret = access("/proc/self/ns", X_OK);
@@ -1022,21 +1029,34 @@ int lxc_attach(const char *name, const char *lxcpath,
                return -1;
        }
 
+       if (!container)
+               return minus_one_set_errno(EINVAL);
+
+       if (!lxc_container_get(container))
+               return minus_one_set_errno(EINVAL);
+
+       name = container->name;
+       lxcpath = container->config_path;
+
        if (!options)
                options = &attach_static_default_options;
 
        init_pid = lxc_cmd_get_init_pid(name, lxcpath);
        if (init_pid < 0) {
                ERROR("Failed to get init pid");
+               lxc_container_put(container);
                return -1;
        }
 
        init_ctx = lxc_proc_get_context_info(init_pid);
        if (!init_ctx) {
                ERROR("Failed to get context of init process: %ld", (long)init_pid);
+               lxc_container_put(container);
                return -1;
        }
 
+       init_ctx->container = container;
+
        personality = get_personality(name, lxcpath);
        if (init_ctx->personality < 0) {
                ERROR("Failed to get personality of the container");
@@ -1045,12 +1065,6 @@ int lxc_attach(const char *name, const char *lxcpath,
        }
        init_ctx->personality = personality;
 
-       init_ctx->container = lxc_container_new(name, lxcpath);
-       if (!init_ctx->container) {
-               lxc_proc_put_context_info(init_ctx);
-               return -1;
-       }
-
        if (!init_ctx->container->lxc_conf) {
                init_ctx->container->lxc_conf = lxc_conf_init();
                if (!init_ctx->container->lxc_conf) {
@@ -1311,6 +1325,16 @@ int lxc_attach(const char *name, const char *lxcpath,
                        TRACE("Sent LSM label file descriptor %d to child", labelfd);
                }
 
+               if (conf && conf->seccomp.seccomp) {
+                       ret = lxc_seccomp_recv_notifier_fd(&conf->seccomp, ipc_sockets[0]);
+                       if (ret < 0)
+                               goto close_mainloop;
+
+                       ret = lxc_seccomp_add_notifier(name, lxcpath, &conf->seccomp);
+                       if (ret < 0)
+                               goto close_mainloop;
+               }
+
                /* We're done, the child process should now execute whatever it
                 * is that the user requested. The parent can now track it with
                 * waitpid() or similar.
@@ -1410,7 +1434,7 @@ int lxc_attach(const char *name, const char *lxcpath,
        payload.exec_function = exec_function;
        payload.exec_payload = exec_payload;
 
-       pid = lxc_raw_clone(CLONE_PARENT);
+       pid = lxc_raw_clone(CLONE_PARENT, NULL);
        if (pid < 0) {
                SYSERROR("Failed to clone attached process");
                shutdown(ipc_sockets[1], SHUT_RDWR);