diff --git a/0005-refactor-patch-code-of-attach-and-seccomp.patch b/0005-refactor-patch-code-of-attach-and-seccomp.patch new file mode 100644 index 0000000000000000000000000000000000000000..46c3e2bbdd08a6d951abe830e3b417094560e8db --- /dev/null +++ b/0005-refactor-patch-code-of-attach-and-seccomp.patch @@ -0,0 +1,1517 @@ +From ad33756d6190df4f1aad9b6468b0b59086e916b5 Mon Sep 17 00:00:00 2001 +From: zhangxiaoyu +Date: Tue, 19 Jul 2022 15:23:34 +0800 +Subject: [PATCH] refactor patch code of attach and seccomp + +Signed-off-by: zhangxiaoyu +--- + src/lxc/attach.c | 517 +++++++++++++++++++++++++++++++++++++++ + src/lxc/lsm/nop.c | 14 ++ + src/lxc/seccomp.c | 555 ++++++++++++++++++++++++++++++++++++++++++ + src/lxc/storage/zfs.c | 9 + + 4 files changed, 1095 insertions(+) + +diff --git a/src/lxc/attach.c b/src/lxc/attach.c +index 38e16f2..8a2c52a 100644 +--- a/src/lxc/attach.c ++++ b/src/lxc/attach.c +@@ -49,6 +49,25 @@ + #include + #endif + ++#ifdef HAVE_ISULAD ++#include "exec_commands.h" ++ ++typedef enum { ++ ATTACH_INIT, ++ ATTACH_TIMEOUT, ++ ATTACH_MAX, ++} attach_timeout_t; ++ ++static volatile attach_timeout_t g_attach_timeout_state = ATTACH_INIT; ++ ++struct attach_timeout_conf { ++ int64_t timeout; ++ unsigned long long start_time; ++ pid_t pid; ++}; ++ ++#endif ++ + lxc_log_define(attach, lxc); + + /* Define default options if no options are supplied by the user. */ +@@ -630,6 +649,9 @@ struct attach_clone_payload { + struct lxc_proc_context_info *init_ctx; + lxc_attach_exec_t exec_function; + void *exec_payload; ++#ifdef HAVE_ISULAD ++ struct lxc_terminal *terminal; ++#endif + }; + + static void lxc_put_attach_clone_payload(struct attach_clone_payload *p) +@@ -642,6 +664,48 @@ static void lxc_put_attach_clone_payload(struct attach_clone_payload *p) + } + } + ++#ifdef HAVE_ISULAD ++static int isulad_set_attach_pipes(struct lxc_terminal *terminal) ++{ ++ int ret = 0; ++ if (terminal->pipes[0][1] >= 0) { ++ close(terminal->pipes[0][1]); ++ terminal->pipes[0][1] = -1; ++ } ++ ++ if (terminal->pipes[0][0] >= 0) { ++ ret = dup2(terminal->pipes[0][0], STDIN_FILENO); ++ if (ret < 0) ++ goto out; ++ } ++ ++ if (terminal->pipes[1][0] >= 0) { ++ close(terminal->pipes[1][0]); ++ terminal->pipes[1][0] = -1; ++ } ++ ++ if (terminal->pipes[1][1] >= 0) { ++ ret = dup2(terminal->pipes[1][1], STDOUT_FILENO); ++ if (ret < 0) ++ goto out; ++ } ++ if (terminal->pipes[2][0] >= 0) { ++ close(terminal->pipes[2][0]); ++ terminal->pipes[2][0] = -1; ++ } ++ ++ if (terminal->pipes[2][1] >= 0) { ++ ret = dup2(terminal->pipes[2][1], STDERR_FILENO); ++ if (ret < 0) ++ goto out; ++ } ++ ++ setsid(); ++out: ++ return ret; ++} ++#endif ++ + static int attach_child_main(struct attach_clone_payload *payload) + { + int lsm_fd, ret; +@@ -654,6 +718,31 @@ static int attach_child_main(struct attach_clone_payload *payload) + bool needs_lsm = (options->namespaces & CLONE_NEWNS) && + (options->attach_flags & LXC_ATTACH_LSM) && + init_ctx->lsm_label; ++#ifdef HAVE_ISULAD ++ int msg_fd = -1; ++ sigset_t mask; ++ ++ /*isulad: record errpipe fd*/ ++ msg_fd = init_ctx->container->lxc_conf->errpipe[1]; ++ init_ctx->container->lxc_conf->errpipe[1] = -1; ++ /*isulad: set system umask */ ++ umask(init_ctx->container->lxc_conf->umask); ++ ++ /*isulad: restore default signal handlers and unblock all signals*/ ++ for (int i = 1; i < NSIG; i++) ++ signal(i, SIG_DFL); ++ ++ ret = sigfillset(&mask); ++ if (ret < 0) { ++ SYSERROR("Failed to fill signal mask"); ++ goto on_error;; ++ } ++ ret = sigprocmask(SIG_UNBLOCK, &mask, NULL); ++ if (ret < 0) { ++ SYSERROR("Failed to set signal mask"); ++ goto on_error; ++ } ++#endif + + /* A description of the purpose of this functionality is provided in the + * lxc-attach(1) manual page. We have to remount here and not in the +@@ -695,6 +784,28 @@ static int attach_child_main(struct attach_clone_payload *payload) + TRACE("Dropped capabilities"); + } + ++#ifdef HAVE_ISULAD ++ /* isulad: set workdir */ ++ if (options->initial_cwd || init_ctx->container->lxc_conf->init_cwd) { ++ char *init_cwd; ++ init_cwd = options->initial_cwd ? options->initial_cwd : init_ctx->container->lxc_conf->init_cwd; ++ /* try to create workdir if not exist */ ++ struct stat st; ++ if (stat(init_cwd, &st) < 0 && mkdir_p(init_cwd, 0750) < 0) { ++ SYSERROR("Try to create directory \"%s\" as workdir failed when attach", init_cwd); ++ lxc_write_error_message(msg_fd, "Try to create directory \"%s\" as workdir failed when attach: %s", ++ init_cwd, strerror(errno)); ++ goto on_error; ++ } ++ if (chdir(init_cwd)) { ++ SYSERROR("Could not change directory to \"%s\" when attach", init_cwd); ++ lxc_write_error_message(msg_fd, "Could not change directory to \"%s\" when attach: %s", ++ init_cwd, strerror(errno)); ++ goto on_error; ++ } ++ } ++#endif ++ + /* Always set the environment (specify (LXC_ATTACH_KEEP_ENV, NULL, NULL) + * if you want this to be a no-op). + */ +@@ -736,8 +847,10 @@ static int attach_child_main(struct attach_clone_payload *payload) + goto on_error; + } + ++#ifndef HAVE_ISULAD + if (!lxc_setgroups(0, NULL) && errno != EPERM) + goto on_error; ++#endif + + if (options->namespaces & CLONE_NEWUSER) { + /* Check whether nsuid 0 has a mapping. */ +@@ -770,6 +883,13 @@ static int attach_child_main(struct attach_clone_payload *payload) + else + new_gid = ns_root_gid; + ++#ifdef HAVE_ISULAD ++ // isulad: set env home in container ++ if (lxc_setup_env_home(new_uid) < 0) { ++ goto on_error; ++ } ++#endif ++ + if ((init_ctx->container && init_ctx->container->lxc_conf && + init_ctx->container->lxc_conf->no_new_privs) || + (options->attach_flags & LXC_ATTACH_NO_NEW_PRIVS)) { +@@ -810,10 +930,12 @@ static int attach_child_main(struct attach_clone_payload *payload) + goto on_error; + } + ++#ifndef HAVE_ISULAD + close(payload->ipc_socket); + payload->ipc_socket = -EBADF; + lxc_proc_put_context_info(init_ctx); + payload->init_ctx = NULL; ++#endif + + /* The following is done after the communication socket is shut down. + * That way, all errors that might (though unlikely) occur up until this +@@ -856,6 +978,24 @@ static int attach_child_main(struct attach_clone_payload *payload) + } + + if (options->attach_flags & LXC_ATTACH_TERMINAL) { ++#ifdef HAVE_ISULAD ++ /* isulad: dup2 pipe[0][0] to container stdin, pipe[1][1] to container stdout, pipe[2][1] to container stderr */ ++ if (payload->terminal->disable_pty) { ++ ret = isulad_set_attach_pipes(payload->terminal); ++ if (ret < 0) { ++ SYSERROR("Failed to prepare terminal file pipes"); ++ goto on_error; ++ } ++ } ++ ++ if(!payload->terminal->disable_pty && payload->terminal_pts_fd >= 0) { ++ ret = lxc_terminal_prepare_login(payload->terminal_pts_fd); ++ if (ret < 0) { ++ SYSERROR("Failed to prepare terminal file descriptor %d", payload->terminal_pts_fd); ++ goto on_error; ++ } ++ } ++#else + ret = lxc_terminal_prepare_login(payload->terminal_pts_fd); + if (ret < 0) { + SYSERROR("Failed to prepare terminal file descriptor %d", payload->terminal_pts_fd); +@@ -863,6 +1003,7 @@ static int attach_child_main(struct attach_clone_payload *payload) + } + + TRACE("Prepared terminal file descriptor %d", payload->terminal_pts_fd); ++#endif + } + + /* Avoid unnecessary syscalls. */ +@@ -872,6 +1013,17 @@ static int attach_child_main(struct attach_clone_payload *payload) + if (new_gid == ns_root_gid) + new_gid = LXC_INVALID_GID; + ++#ifdef HAVE_ISULAD ++ if (prctl(PR_SET_KEEPCAPS, 1) < 0) { ++ SYSERROR("Failed to keep permitted capabilities"); ++ goto on_error; ++ } ++ ++ if (!lxc_setgroups(init_ctx->container->lxc_conf->init_groups_len, ++ init_ctx->container->lxc_conf->init_groups)) ++ goto on_error; ++#endif ++ + /* Make sure that the processes STDIO is correctly owned by the user that we are switching to */ + ret = fix_stdio_permissions(new_uid); + if (ret) +@@ -880,21 +1032,63 @@ static int attach_child_main(struct attach_clone_payload *payload) + if (!lxc_switch_uid_gid(new_uid, new_gid)) + goto on_error; + ++#ifdef HAVE_ISULAD ++ if (prctl(PR_SET_KEEPCAPS, 0) < 0) { ++ SYSERROR("Failed to clear permitted capabilities"); ++ goto on_error; ++ } ++ ++ if (lxc_drop_caps(init_ctx->container->lxc_conf) != 0) { ++ ERROR("Failed to drop caps."); ++ goto on_error; ++ } ++ ++ close(payload->ipc_socket); ++ payload->ipc_socket = -EBADF; ++ lxc_proc_put_context_info(init_ctx); ++ payload->init_ctx = NULL; ++ _exit(payload->exec_function(payload->exec_payload, msg_fd)); ++#else + /* We're done, so we can now do whatever the user intended us to do. */ + _exit(payload->exec_function(payload->exec_payload)); ++#endif + + on_error: + lxc_put_attach_clone_payload(payload); + _exit(EXIT_FAILURE); + } + ++#ifdef HAVE_ISULAD ++static int lxc_attach_terminal(struct lxc_conf *conf, ++ struct lxc_terminal *terminal, lxc_attach_options_t *options) ++#else + static int lxc_attach_terminal(struct lxc_conf *conf, + struct lxc_terminal *terminal) ++#endif + { + int ret; + + lxc_terminal_init(terminal); + ++#ifdef HAVE_ISULAD ++ /* isulad: if we pass fifo in option, use them as init fifos */ ++ if (options->init_fifo[0]) { ++ free(terminal->init_fifo[0]); ++ terminal->init_fifo[0] = safe_strdup(options->init_fifo[0]); ++ } ++ if (options->init_fifo[1]) { ++ free(terminal->init_fifo[1]); ++ terminal->init_fifo[1] = safe_strdup(options->init_fifo[1]); ++ } ++ if (options->init_fifo[2]) { ++ free(terminal->init_fifo[2]); ++ terminal->init_fifo[2] = safe_strdup(options->init_fifo[2]); ++ } ++ ++ terminal->disable_pty = options->disable_pty; ++ terminal->open_stdin = options->open_stdin; ++#endif ++ + ret = lxc_terminal_create(terminal); + if (ret < 0) + return log_error(-1, "Failed to create terminal"); +@@ -952,9 +1146,126 @@ static inline void lxc_attach_terminal_close_log(struct lxc_terminal *terminal) + close_prot_errno_disarm(terminal->log_fd); + } + ++#ifdef HAVE_ISULAD ++/* isulad: attach timeout thread function */ ++static void* wait_attach_timeout(void *arg) ++{ ++ struct attach_timeout_conf *conf = (struct attach_timeout_conf *)arg; ++ ++ if (!conf || conf->timeout < 1) ++ goto out; ++ sleep(conf->timeout); ++ if (lxc_process_alive(conf->pid, conf->start_time)) { ++ g_attach_timeout_state = ATTACH_TIMEOUT; ++ if (kill(conf->pid, SIGKILL) < 0) { ++ ERROR("Failed to send signal %d to pid %d", SIGKILL, conf->pid); ++ } ++ } ++ ++out: ++ free(conf); ++ return ((void *)0); ++} ++ ++/* isulad: create attach timeout thread */ ++static int create_attach_timeout_thread(int64_t attach_timeout, pid_t pid) ++{ ++ int ret = 0; ++ pthread_t ptid; ++ pthread_attr_t attr; ++ struct attach_timeout_conf *timeout_conf = NULL; ++ ++ timeout_conf = malloc(sizeof(struct attach_timeout_conf)); ++ if (timeout_conf == NULL) { ++ ERROR("Failed to malloc attach timeout conf"); ++ ret = -1; ++ goto out; ++ } ++ ++ memset(timeout_conf, 0, sizeof(struct attach_timeout_conf)); ++ timeout_conf->timeout = attach_timeout; ++ timeout_conf->pid = pid; ++ timeout_conf->start_time = lxc_get_process_startat(pid); ++ ++ pthread_attr_init(&attr); ++ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); ++ ret = pthread_create(&ptid, &attr, wait_attach_timeout, timeout_conf); ++ pthread_attr_destroy(&attr); ++ if (ret != 0) { ++ ERROR("Create attach wait timeout thread failed"); ++ free(timeout_conf); ++ goto out; ++ } ++ ++out: ++ return ret; ++} ++ ++static int attach_signal_handler(int fd, uint32_t events, void *data, ++ struct lxc_epoll_descr *descr) ++{ ++ int ret; ++ siginfo_t info; ++ struct signalfd_siginfo siginfo; ++ pid_t *pid = data; ++ ++ ret = lxc_read_nointr(fd, &siginfo, sizeof(siginfo)); ++ if (ret < 0) ++ return log_error(LXC_MAINLOOP_ERROR, "Failed to read signal info from signal file descriptor %d", fd); ++ ++ if (ret != sizeof(siginfo)) ++ return log_error(LXC_MAINLOOP_ERROR, "Unexpected size for struct signalfd_siginfo"); ++ ++ /* Check whether init is running. */ ++ info.si_pid = 0; ++ ret = waitid(P_PID, *pid, &info, WEXITED | WNOWAIT | WNOHANG); ++ if (ret == 0 && info.si_pid == *pid) { ++ return log_warn(LXC_MAINLOOP_CLOSE, "Container attach init process %d exited", *pid); ++ } ++ ++ return LXC_MAINLOOP_CONTINUE; ++} ++ ++static int isulad_setup_signal_fd(sigset_t *oldmask) ++{ ++ int ret; ++ sigset_t mask; ++ const int signals[] = {SIGBUS, SIGILL, SIGSEGV, SIGWINCH, SIGTERM}; ++ ++ /* Block everything except serious error signals. */ ++ ret = sigfillset(&mask); ++ if (ret < 0) ++ return -EBADF; ++ ++ for (int sig = 0; sig < (sizeof(signals) / sizeof(signals[0])); sig++) { ++ ret = sigdelset(&mask, signals[sig]); ++ if (ret < 0) ++ return -EBADF; ++ } ++ ++ ret = pthread_sigmask(SIG_BLOCK, &mask, oldmask); ++ if (ret < 0) ++ return log_error_errno(-EBADF, errno, ++ "Failed to set signal mask"); ++ ++ ret = signalfd(-1, &mask, SFD_CLOEXEC); ++ if (ret < 0) ++ return log_error_errno(-EBADF, ++ errno, "Failed to create signal file descriptor"); ++ ++ TRACE("Created signal file descriptor %d", ret); ++ ++ return ret; ++} ++ ++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, char **err_msg) ++#else + 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) ++#endif + { + int i, ret, status; + int ipc_sockets[2]; +@@ -966,6 +1277,13 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + struct lxc_conf *conf; + char *name, *lxcpath; + struct attach_clone_payload payload = {0}; ++#ifdef HAVE_ISULAD ++ struct lxc_exec_command_handler exec_command; ++ const char *suffix = options->suffix; ++ ++ exec_command.maincmd_fd = -1; ++ exec_command.terminal = &terminal; ++#endif + + ret = access("/proc/self/ns", X_OK); + if (ret) +@@ -1017,6 +1335,14 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + if (!conf) + return log_error_errno(-EINVAL, EINVAL, "Missing container confifg"); + ++#ifdef HAVE_ISULAD ++ // always switch uid and gid for attach ++ if (options->uid == -1) ++ options->uid = init_ctx->container->lxc_conf->init_uid; ++ if (options->gid == -1) ++ options->gid = init_ctx->container->lxc_conf->init_gid; ++#endif ++ + if (!fetch_seccomp(init_ctx->container, options)) + WARN("Failed to get seccomp policy"); + +@@ -1090,7 +1416,11 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + } + + if (options->attach_flags & LXC_ATTACH_TERMINAL) { ++#ifdef HAVE_ISULAD ++ ret = lxc_attach_terminal(conf, &terminal, options); ++#else + ret = lxc_attach_terminal(conf, &terminal); ++#endif + if (ret < 0) { + ERROR("Failed to setup new terminal"); + free(cwd); +@@ -1099,6 +1429,12 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + } + + terminal.log_fd = options->log_fd; ++#ifdef HAVE_ISULAD ++ if (suffix != NULL) { ++ exec_command.maincmd_fd = lxc_exec_cmd_init(name, lxcpath, suffix); ++ exec_command.terminal = &terminal; ++ } ++#endif + } else { + lxc_terminal_init(&terminal); + } +@@ -1139,10 +1475,40 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + ret = socketpair(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets); + if (ret < 0) { + SYSERROR("Could not set up required IPC mechanism for attaching"); ++#ifdef HAVE_ISULAD ++ if (options->attach_flags & LXC_ATTACH_TERMINAL) { ++ lxc_terminal_delete(&terminal); ++ lxc_terminal_conf_free(&terminal); ++ if (exec_command.maincmd_fd != -1) { ++ close(exec_command.maincmd_fd); ++ } ++ lxc_exec_unix_sock_delete(name, suffix); ++ } ++#endif ++ free(cwd); ++ lxc_proc_put_context_info(init_ctx); ++ return -1; ++ } ++ ++#ifdef HAVE_ISULAD ++ /* isulad: pipdfd for get error message of child or grandchild process. */ ++ if (pipe2(conf->errpipe, O_CLOEXEC) != 0) { ++ SYSERROR("Failed to init errpipe"); ++ if (options->attach_flags & LXC_ATTACH_TERMINAL) { ++ lxc_terminal_delete(&terminal); ++ lxc_terminal_conf_free(&terminal); ++ if (exec_command.maincmd_fd != -1) { ++ close(exec_command.maincmd_fd); ++ } ++ lxc_exec_unix_sock_delete(name, suffix); ++ } ++ close(ipc_sockets[0]); ++ close(ipc_sockets[1]); + free(cwd); + lxc_proc_put_context_info(init_ctx); + return -1; + } ++#endif + + /* Create intermediate subprocess, two reasons: + * 1. We can't setns() in the child itself, since we want to make +@@ -1154,6 +1520,18 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + pid = fork(); + if (pid < 0) { + SYSERROR("Failed to create first subprocess"); ++#ifdef HAVE_ISULAD ++ if (options->attach_flags & LXC_ATTACH_TERMINAL) { ++ lxc_terminal_delete(&terminal); ++ lxc_terminal_conf_free(&terminal); ++ if (exec_command.maincmd_fd != -1) { ++ close(exec_command.maincmd_fd); ++ } ++ lxc_exec_unix_sock_delete(name, suffix); ++ } ++ close(ipc_sockets[0]); ++ close(ipc_sockets[1]); ++#endif + free(cwd); + lxc_proc_put_context_info(init_ctx); + return -1; +@@ -1163,10 +1541,35 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + int ret_parent = -1; + pid_t to_cleanup_pid = pid; + struct lxc_epoll_descr descr = {0}; ++#ifdef HAVE_ISULAD ++ int isulad_sigfd; ++ sigset_t isulad_oldmask; ++ struct lxc_epoll_descr isulad_descr = {0}; ++#endif + + /* close unneeded file descriptors */ + close(ipc_sockets[1]); + free(cwd); ++#ifdef HAVE_ISULAD ++ /* isulad: close errpipe */ ++ close(conf->errpipe[1]); ++ conf->errpipe[1] = -1; ++ /* isulad: close pipe after clone */ ++ if (terminal.pipes[0][0] >= 0) { ++ close(terminal.pipes[0][0]); ++ terminal.pipes[0][0] = -1; ++ } ++ ++ if (terminal.pipes[1][1] >= 0) { ++ close(terminal.pipes[1][1]); ++ terminal.pipes[1][1] = -1; ++ } ++ ++ if (terminal.pipes[2][1] >= 0) { ++ close(terminal.pipes[2][1]); ++ terminal.pipes[2][1] = -1; ++ } ++#endif + lxc_proc_close_ns_fd(init_ctx); + if (options->attach_flags & LXC_ATTACH_TERMINAL) + lxc_attach_terminal_close_pts(&terminal); +@@ -1200,7 +1603,11 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + + /* Setup resource limits */ + if (!lxc_list_empty(&conf->limits)) { ++#ifdef HAVE_ISULAD ++ ret = setup_resource_limits(&conf->limits, pid, -1); ++#else + ret = setup_resource_limits(&conf->limits, pid); ++#endif + if (ret < 0) + goto on_error; + } +@@ -1210,9 +1617,28 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + if (ret < 0) + goto on_error; + ++#ifdef HAVE_ISULAD ++ ret = lxc_attach_terminal_mainloop_init(&terminal, &isulad_descr); ++ if (ret < 0) ++ goto on_error; ++ ++ if (suffix != NULL) { ++ (void)lxc_exec_cmd_mainloop_add(&descr, &exec_command); ++ } ++#endif + TRACE("Initialized terminal mainloop"); + } + ++#ifdef HAVE_ISULAD ++ /* The signal fd has to be created before forking otherwise if the child ++ * process exits before we setup the signal fd, the event will be lost ++ * and the command will be stuck. ++ */ ++ isulad_sigfd = isulad_setup_signal_fd(&isulad_oldmask); ++ if (isulad_sigfd < 0) ++ goto close_mainloop; ++#endif ++ + /* Let the child process know to go ahead. */ + status = 0; + ret = lxc_write_nointr(ipc_sockets[0], &status, sizeof(status)); +@@ -1290,6 +1716,34 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + + *attached_process = attached_pid; + ++#ifdef HAVE_ISULAD ++ if (options->timeout > 0) { ++ ret = create_attach_timeout_thread(options->timeout, *attached_process); ++ if (ret) { ++ ERROR("Failed to create attach timeout thread for container."); ++ goto close_mainloop; ++ } ++ } ++ /* isulad: read error msg from pipe */ ++ ssize_t size_read; ++ char errbuf[BUFSIZ + 1] = {0}; ++ pid_t tmp_pid = *attached_process; ++ ++ size_read = read(conf->errpipe[0], errbuf, BUFSIZ); ++ if (size_read > 0) { ++ if (err_msg) ++ *err_msg = safe_strdup(errbuf); ++ goto close_mainloop; ++ } ++ if (options->attach_flags & LXC_ATTACH_TERMINAL) { ++ ret = lxc_mainloop_add_handler(&descr, isulad_sigfd, attach_signal_handler, &tmp_pid); ++ if (ret < 0) { ++ ERROR("Failed to add signal handler for %d to mainloop", tmp_pid); ++ goto close_mainloop; ++ } ++ } ++#endif ++ + /* Now shut down communication with child, we're done. */ + shutdown(ipc_sockets[0], SHUT_RDWR); + close(ipc_sockets[0]); +@@ -1298,17 +1752,44 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + ret_parent = 0; + to_cleanup_pid = -1; + ++#ifdef HAVE_ISULAD ++ // iSulad: close stdin pipe if we do not want open_stdin with container stdin ++ if (!terminal.open_stdin) { ++ if (terminal.pipes[0][1] > 0) { ++ close(terminal.pipes[0][1]); ++ terminal.pipes[0][1] = -1; ++ } ++ } ++#endif + if (options->attach_flags & LXC_ATTACH_TERMINAL) { ++#ifdef HAVE_ISULAD ++ ret = isulad_safe_mainloop(&descr, -1); ++#else + ret = lxc_mainloop(&descr, -1); ++#endif + if (ret < 0) { + ret_parent = -1; + to_cleanup_pid = attached_pid; + } + } + ++#ifdef HAVE_ISULAD ++ // do lxc_mainloop to make sure we do not lose any output ++ (void)isulad_safe_mainloop(&isulad_descr, 100); ++ if (g_attach_timeout_state == ATTACH_TIMEOUT && err_msg != NULL && *err_msg == NULL) { ++ *err_msg = safe_strdup("Attach exceeded timeout"); ++ } ++#endif + close_mainloop: ++#ifdef HAVE_ISULAD ++ if (options->attach_flags & LXC_ATTACH_TERMINAL) { ++ lxc_mainloop_close(&isulad_descr); ++ lxc_mainloop_close(&descr); ++ } ++#else + if (options->attach_flags & LXC_ATTACH_TERMINAL) + lxc_mainloop_close(&descr); ++#endif + + on_error: + if (ipc_sockets[0] >= 0) { +@@ -1322,6 +1803,12 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + if (options->attach_flags & LXC_ATTACH_TERMINAL) { + lxc_terminal_delete(&terminal); + lxc_terminal_conf_free(&terminal); ++#ifdef HAVE_ISULAD ++ if (exec_command.maincmd_fd != -1) { ++ close(exec_command.maincmd_fd); ++ } ++ lxc_exec_unix_sock_delete(name, suffix); ++#endif + } + + lxc_proc_put_context_info(init_ctx); +@@ -1331,10 +1818,21 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + /* close unneeded file descriptors */ + close_prot_errno_disarm(ipc_sockets[0]); + ++#ifdef HAVE_ISULAD ++ /* isulad: close errpipe */ ++ close(conf->errpipe[0]); ++ conf->errpipe[0] = -1; ++#endif ++ + if (options->attach_flags & LXC_ATTACH_TERMINAL) { + lxc_attach_terminal_close_ptmx(&terminal); + lxc_attach_terminal_close_peer(&terminal); + lxc_attach_terminal_close_log(&terminal); ++#ifdef HAVE_ISULAD ++ if (exec_command.maincmd_fd != -1) { ++ close(exec_command.maincmd_fd); ++ } ++#endif + } + + /* Wait for the parent to have setup cgroups. */ +@@ -1380,6 +1878,9 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + payload.terminal_pts_fd = terminal.pts; + payload.exec_function = exec_function; + payload.exec_payload = exec_payload; ++#ifdef HAVE_ISULAD ++ payload.terminal = &terminal; ++#endif + + pid = lxc_raw_clone(CLONE_PARENT, NULL); + if (pid < 0) { +@@ -1390,7 +1891,11 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + } + + if (pid == 0) { ++#ifdef HAVE_ISULAD ++ if (options->attach_flags & LXC_ATTACH_TERMINAL && terminal.tty_state) { ++#else + if (options->attach_flags & LXC_ATTACH_TERMINAL) { ++#endif + ret = pthread_sigmask(SIG_SETMASK, + &terminal.tty_state->oldmask, NULL); + if (ret < 0) { +@@ -1430,7 +1935,11 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + _exit(EXIT_SUCCESS); + } + ++#ifdef HAVE_ISULAD ++int lxc_attach_run_command(void *payload, int msg_fd) ++#else + int lxc_attach_run_command(void *payload) ++#endif + { + int ret = -1; + lxc_attach_command_t *cmd = payload; +@@ -1446,11 +1955,19 @@ int lxc_attach_run_command(void *payload) + break; + } + } ++#ifdef HAVE_ISULAD ++ /* isulad: write error messages */ ++ lxc_write_error_message(msg_fd, "exec: \"%s\": %s.", cmd->program, strerror(errno)); ++#endif + + return log_error_errno(ret, errno, "Failed to exec \"%s\"", cmd->program); + } + ++#ifdef HAVE_ISULAD ++int lxc_attach_run_shell(void* payload, int msg_fd) ++#else + int lxc_attach_run_shell(void* payload) ++#endif + { + __do_free char *buf = NULL; + uid_t uid; +diff --git a/src/lxc/lsm/nop.c b/src/lxc/lsm/nop.c +index 5b345b9..188945d 100644 +--- a/src/lxc/lsm/nop.c ++++ b/src/lxc/lsm/nop.c +@@ -24,11 +24,25 @@ static int nop_enabled(void) + return 0; + } + ++#ifdef HAVE_ISULAD ++static int nop_file_label_set(const char *path, const char *label) { ++ return 0; ++} ++ ++static int nop_relabel(const char *path, const char *label, bool shared) { ++ return 0; ++} ++#endif ++ + static struct lsm_drv nop_drv = { + .name = "nop", + .enabled = nop_enabled, + .process_label_get = nop_process_label_get, + .process_label_set = nop_process_label_set, ++#ifdef HAVE_ISULAD ++ .file_label_set = nop_file_label_set, ++ .relabel = nop_relabel, ++#endif + }; + + struct lsm_drv *lsm_nop_drv_init(void) +diff --git a/src/lxc/seccomp.c b/src/lxc/seccomp.c +index 7820db8..a6e6d42 100644 +--- a/src/lxc/seccomp.c ++++ b/src/lxc/seccomp.c +@@ -351,8 +351,13 @@ int get_hostarch(void) + return lxc_seccomp_arch_unknown; + } + ++#ifdef HAVE_ISULAD ++scmp_filter_ctx get_new_ctx(enum lxc_hostarch_t n_arch, ++ uint32_t default_policy_action, uint32_t *architectures) ++#else + scmp_filter_ctx get_new_ctx(enum lxc_hostarch_t n_arch, + uint32_t default_policy_action, bool *needs_merge) ++#endif + { + int ret; + uint32_t arch; +@@ -476,9 +481,17 @@ scmp_filter_ctx get_new_ctx(enum lxc_hostarch_t n_arch, + } + TRACE("Removed native arch from main seccomp context"); + ++#ifdef HAVE_ISULAD ++ *architectures = arch; ++#else + *needs_merge = true; ++#endif + } else { ++#ifdef HAVE_ISULAD ++ *architectures = SCMP_ARCH_NATIVE; ++#else + *needs_merge = false; ++#endif + TRACE("Arch %d already present in main seccomp context", (int)n_arch); + } + +@@ -510,7 +523,11 @@ bool do_resolve_add_rule(uint32_t arch, char *line, scmp_filter_ctx ctx, + if (ret < 0) { + errno = -ret; + SYSERROR("Failed loading rule to reject force umount"); ++#ifdef HAVE_ISULAD ++ return true; ++#else + return false; ++#endif + } + + INFO("Set seccomp rule to reject force umounts"); +@@ -519,24 +536,42 @@ bool do_resolve_add_rule(uint32_t arch, char *line, scmp_filter_ctx ctx, + + nr = seccomp_syscall_resolve_name(line); + if (nr == __NR_SCMP_ERROR) { ++#ifdef HAVE_ISULAD ++ DEBUG("Failed to resolve syscall \"%s\"", line); ++ DEBUG("This syscall will NOT be handled by seccomp"); ++#else + WARN("Failed to resolve syscall \"%s\"", line); + WARN("This syscall will NOT be handled by seccomp"); ++#endif + return true; + } + + if (nr < 0) { ++#ifdef HAVE_ISULAD ++ DEBUG("Got negative return value %d for syscall \"%s\"", nr, line); ++ DEBUG("This syscall will NOT be handled by seccomp"); ++#else + WARN("Got negative return value %d for syscall \"%s\"", nr, line); + WARN("This syscall will NOT be handled by seccomp"); ++#endif + return true; + } + + memset(&arg_cmp, 0, sizeof(arg_cmp)); + for (i = 0; i < rule->args_num; i++) { ++#ifdef HAVE_ISULAD ++ DEBUG("arg_cmp[%d]: SCMP_CMP(%u, %llu, %llu, %llu)", i, ++ rule->args_value[i].index, ++ (long long unsigned int)rule->args_value[i].op, ++ (long long unsigned int)rule->args_value[i].mask, ++ (long long unsigned int)rule->args_value[i].value); ++#else + INFO("arg_cmp[%d]: SCMP_CMP(%u, %llu, %llu, %llu)", i, + rule->args_value[i].index, + (long long unsigned int)rule->args_value[i].op, + (long long unsigned int)rule->args_value[i].mask, + (long long unsigned int)rule->args_value[i].value); ++#endif + + if (SCMP_CMP_MASKED_EQ == rule->args_value[i].op) + arg_cmp[i] = SCMP_CMP(rule->args_value[i].index, +@@ -553,14 +588,43 @@ bool do_resolve_add_rule(uint32_t arch, char *line, scmp_filter_ctx ctx, + rule->args_num, arg_cmp); + if (ret < 0) { + errno = -ret; ++#ifdef HAVE_ISULAD ++ DEBUG("Failed loading rule for %s (nr %d action %d (%s))", ++ line, nr, rule->action, get_action_name(rule->action)); ++ return true; ++#else + SYSERROR("Failed loading rule for %s (nr %d action %d (%s))", + line, nr, rule->action, get_action_name(rule->action)); + return false; ++#endif + } + + return true; + } + ++#ifdef HAVE_ISULAD ++#define SCMP_ARCH_INDEX_MAX 3 ++ ++struct scmp_ctx_info { ++ uint32_t architectures[SCMP_ARCH_INDEX_MAX]; ++ enum lxc_hostarch_t lxc_arch[SCMP_ARCH_INDEX_MAX]; ++ scmp_filter_ctx contexts[SCMP_ARCH_INDEX_MAX]; ++ bool needs_merge[SCMP_ARCH_INDEX_MAX]; ++}; ++ ++static int get_arch_index(enum lxc_hostarch_t arch, struct scmp_ctx_info *ctx) ++{ ++ int i; ++ ++ for (i = 0; i < SCMP_ARCH_INDEX_MAX; i++) { ++ if (ctx->lxc_arch[i] == arch) ++ return i; ++ } ++ ++ return -1; ++} ++#endif ++ + /* + * v2 consists of + * [x86] +@@ -575,6 +639,494 @@ bool do_resolve_add_rule(uint32_t arch, char *line, scmp_filter_ctx ctx, + * write + * close + */ ++#ifdef HAVE_ISULAD ++static int parse_config_v2(FILE *f, char *line, size_t *line_bufsz, struct lxc_conf *conf) ++{ ++ int ret; ++ char *p; ++ enum lxc_hostarch_t cur_rule_arch, native_arch; ++ bool blacklist = false; ++ uint32_t default_policy_action = -1, default_rule_action = -1; ++ struct seccomp_v2_rule rule; ++ struct scmp_ctx_info ctx; ++ ++ if (strncmp(line, "blacklist", 9) == 0) ++ blacklist = true; ++ else if (strncmp(line, "whitelist", 9) != 0) { ++ ERROR("Bad seccomp policy style \"%s\"", line); ++ return -1; ++ } ++ ++ p = strchr(line, ' '); ++ if (p) { ++ default_policy_action = get_v2_default_action(p + 1); ++ if (default_policy_action == -2) ++ return -1; ++ } ++ ++ /* for blacklist, allow any syscall which has no rule */ ++ if (blacklist) { ++ if (default_policy_action == -1) ++ default_policy_action = SCMP_ACT_ALLOW; ++ ++ if (default_rule_action == -1) ++ default_rule_action = SCMP_ACT_KILL; ++ } else { ++ if (default_policy_action == -1) ++ default_policy_action = SCMP_ACT_KILL; ++ ++ if (default_rule_action == -1) ++ default_rule_action = SCMP_ACT_ALLOW; ++ } ++ ++ memset(&ctx, 0, sizeof(ctx)); ++ ctx.architectures[0] = SCMP_ARCH_NATIVE; ++ ctx.architectures[1] = SCMP_ARCH_NATIVE; ++ ctx.architectures[2] = SCMP_ARCH_NATIVE; ++ native_arch = get_hostarch(); ++ cur_rule_arch = native_arch; ++ if (native_arch == lxc_seccomp_arch_amd64) { ++ cur_rule_arch = lxc_seccomp_arch_all; ++ ++ ctx.lxc_arch[0] = lxc_seccomp_arch_i386; ++ ctx.contexts[0] = get_new_ctx(lxc_seccomp_arch_i386, ++ default_policy_action, &ctx.architectures[0]); ++ if (!ctx.contexts[0]) ++ goto bad; ++ ++ ctx.lxc_arch[1] = lxc_seccomp_arch_x32; ++ ctx.contexts[1] = get_new_ctx(lxc_seccomp_arch_x32, ++ default_policy_action, &ctx.architectures[1]); ++ if (!ctx.contexts[1]) ++ goto bad; ++ ++ ctx.lxc_arch[2] = lxc_seccomp_arch_amd64; ++ ctx.contexts[2] = get_new_ctx(lxc_seccomp_arch_amd64, ++ default_policy_action, &ctx.architectures[2]); ++ if (!ctx.contexts[2]) ++ goto bad; ++#ifdef SCMP_ARCH_PPC ++ } else if (native_arch == lxc_seccomp_arch_ppc64) { ++ cur_rule_arch = lxc_seccomp_arch_all; ++ ++ ctx.lxc_arch[0] = lxc_seccomp_arch_ppc; ++ ctx.contexts[0] = get_new_ctx(lxc_seccomp_arch_ppc, ++ default_policy_action, &ctx.architectures[0]); ++ if (!ctx.contexts[0]) ++ goto bad; ++ ++ ctx.lxc_arch[1] = lxc_seccomp_arch_ppc64; ++ ctx.contexts[1] = get_new_ctx(lxc_seccomp_arch_ppc64, ++ default_policy_action, &ctx.architectures[1]); ++ if (!ctx.contexts[1]) ++ goto bad; ++#endif ++#ifdef SCMP_ARCH_ARM ++ } else if (native_arch == lxc_seccomp_arch_arm64) { ++ cur_rule_arch = lxc_seccomp_arch_all; ++ ++ ctx.lxc_arch[0] = lxc_seccomp_arch_arm; ++ ctx.contexts[0] = get_new_ctx(lxc_seccomp_arch_arm, ++ default_policy_action, &ctx.architectures[0]); ++ if (!ctx.contexts[0]) ++ goto bad; ++ ++#ifdef SCMP_ARCH_AARCH64 ++ ctx.lxc_arch[1] = lxc_seccomp_arch_arm64; ++ ctx.contexts[1] = get_new_ctx(lxc_seccomp_arch_arm64, ++ default_policy_action, &ctx.architectures[1]); ++ if (!ctx.contexts[1]) ++ goto bad; ++#endif ++#endif ++#ifdef SCMP_ARCH_MIPS ++ } else if (native_arch == lxc_seccomp_arch_mips64) { ++ cur_rule_arch = lxc_seccomp_arch_all; ++ ++ ctx.lxc_arch[0] = lxc_seccomp_arch_mips; ++ ctx.contexts[0] = get_new_ctx(lxc_seccomp_arch_mips, ++ default_policy_action, &ctx.architectures[0]); ++ if (!ctx.contexts[0]) ++ goto bad; ++ ++ ctx.lxc_arch[1] = lxc_seccomp_arch_mips64n32; ++ ctx.contexts[1] = get_new_ctx(lxc_seccomp_arch_mips64n32, ++ default_policy_action, &ctx.architectures[1]); ++ if (!ctx.contexts[1]) ++ goto bad; ++ ++ ctx.lxc_arch[2] = lxc_seccomp_arch_mips64; ++ ctx.contexts[2] = get_new_ctx(lxc_seccomp_arch_mips64, ++ default_policy_action, &ctx.architectures[2]); ++ if (!ctx.contexts[2]) ++ goto bad; ++ } else if (native_arch == lxc_seccomp_arch_mipsel64) { ++ cur_rule_arch = lxc_seccomp_arch_all; ++ ctx.lxc_arch[0] = lxc_seccomp_arch_mipsel; ++ ctx.contexts[0] = get_new_ctx(lxc_seccomp_arch_mipsel, ++ default_policy_action, &ctx.architectures[0]); ++ if (!ctx.contexts[0]) ++ goto bad; ++ ++ ctx.lxc_arch[1] = lxc_seccomp_arch_mipsel64n32; ++ ctx.contexts[1] = get_new_ctx(lxc_seccomp_arch_mipsel64n32, ++ default_policy_action, &ctx.architectures[1]); ++ if (!ctx.contexts[1]) ++ goto bad; ++ ++ ctx.lxc_arch[2] = lxc_seccomp_arch_mipsel64; ++ ctx.contexts[2] = get_new_ctx(lxc_seccomp_arch_mipsel64, ++ default_policy_action, &ctx.architectures[2]); ++ if (!ctx.contexts[2]) ++ goto bad; ++#endif ++ } ++ ++ if (default_policy_action != SCMP_ACT_KILL) { ++ ret = seccomp_reset(conf->seccomp.seccomp_ctx, default_policy_action); ++ if (ret != 0) { ++ ERROR("Error re-initializing Seccomp"); ++ return -1; ++ } ++ ++ ret = seccomp_attr_set(conf->seccomp.seccomp_ctx, SCMP_FLTATR_CTL_NNP, 0); ++ if (ret < 0) { ++ errno = -ret; ++ SYSERROR("Failed to turn off no-new-privs"); ++ return -1; ++ } ++ ++#ifdef SCMP_FLTATR_ATL_TSKIP ++ ret = seccomp_attr_set(conf->seccomp.seccomp_ctx, SCMP_FLTATR_ATL_TSKIP, 1); ++ if (ret < 0) { ++ errno = -ret; ++ SYSWARN("Failed to turn on seccomp nop-skip, continuing"); ++ } ++#endif ++ } ++ ++ while (getline(&line, line_bufsz, f) != -1) { ++ if (line[0] == '#') ++ continue; ++ ++ if (line[0] == '\0') ++ continue; ++ ++ remove_trailing_newlines(line); ++ ++ DEBUG("Processing \"%s\"", line); ++ ++ if (line[0] == '[') { ++ /* Read the architecture for next set of rules. */ ++ if (strcmp(line, "[x86]") == 0 || ++ strcmp(line, "[X86]") == 0) { ++ if (native_arch != lxc_seccomp_arch_i386 && ++ native_arch != lxc_seccomp_arch_amd64) { ++ cur_rule_arch = lxc_seccomp_arch_unknown; ++ continue; ++ } ++ ++ cur_rule_arch = lxc_seccomp_arch_i386; ++ } else if (strcmp(line, "[x32]") == 0 || ++ strcmp(line, "[X32]") == 0) { ++ if (native_arch != lxc_seccomp_arch_amd64) { ++ cur_rule_arch = lxc_seccomp_arch_unknown; ++ continue; ++ } ++ ++ cur_rule_arch = lxc_seccomp_arch_x32; ++ } else if (strcmp(line, "[X86_64]") == 0 || ++ strcmp(line, "[x86_64]") == 0) { ++ if (native_arch != lxc_seccomp_arch_amd64) { ++ cur_rule_arch = lxc_seccomp_arch_unknown; ++ continue; ++ } ++ ++ cur_rule_arch = lxc_seccomp_arch_amd64; ++ } else if (strcmp(line, "[all]") == 0 || ++ strcmp(line, "[ALL]") == 0) { ++ cur_rule_arch = lxc_seccomp_arch_all; ++ } ++#ifdef SCMP_ARCH_ARM ++ else if (strcmp(line, "[arm]") == 0 || ++ strcmp(line, "[ARM]") == 0) { ++ if (native_arch != lxc_seccomp_arch_arm && ++ native_arch != lxc_seccomp_arch_arm64) { ++ cur_rule_arch = lxc_seccomp_arch_unknown; ++ continue; ++ } ++ ++ cur_rule_arch = lxc_seccomp_arch_arm; ++ } ++#endif ++#ifdef SCMP_ARCH_AARCH64 ++ else if (strcmp(line, "[arm64]") == 0 || ++ strcmp(line, "[ARM64]") == 0) { ++ if (native_arch != lxc_seccomp_arch_arm64) { ++ cur_rule_arch = lxc_seccomp_arch_unknown; ++ continue; ++ } ++ ++ cur_rule_arch = lxc_seccomp_arch_arm64; ++ } ++#endif ++#ifdef SCMP_ARCH_PPC64LE ++ else if (strcmp(line, "[ppc64le]") == 0 || ++ strcmp(line, "[PPC64LE]") == 0) { ++ if (native_arch != lxc_seccomp_arch_ppc64le) { ++ cur_rule_arch = lxc_seccomp_arch_unknown; ++ continue; ++ } ++ ++ cur_rule_arch = lxc_seccomp_arch_ppc64le; ++ } ++#endif ++#ifdef SCMP_ARCH_PPC64 ++ else if (strcmp(line, "[ppc64]") == 0 || ++ strcmp(line, "[PPC64]") == 0) { ++ if (native_arch != lxc_seccomp_arch_ppc64) { ++ cur_rule_arch = lxc_seccomp_arch_unknown; ++ continue; ++ } ++ ++ cur_rule_arch = lxc_seccomp_arch_ppc64; ++ } ++#endif ++#ifdef SCMP_ARCH_PPC ++ else if (strcmp(line, "[ppc]") == 0 || ++ strcmp(line, "[PPC]") == 0) { ++ if (native_arch != lxc_seccomp_arch_ppc && ++ native_arch != lxc_seccomp_arch_ppc64) { ++ cur_rule_arch = lxc_seccomp_arch_unknown; ++ continue; ++ } ++ ++ cur_rule_arch = lxc_seccomp_arch_ppc; ++ } ++#endif ++#ifdef SCMP_ARCH_MIPS ++ else if (strcmp(line, "[mips64]") == 0 || ++ strcmp(line, "[MIPS64]") == 0) { ++ if (native_arch != lxc_seccomp_arch_mips64) { ++ cur_rule_arch = lxc_seccomp_arch_unknown; ++ continue; ++ } ++ ++ cur_rule_arch = lxc_seccomp_arch_mips64; ++ } else if (strcmp(line, "[mips64n32]") == 0 || ++ strcmp(line, "[MIPS64N32]") == 0) { ++ if (native_arch != lxc_seccomp_arch_mips64) { ++ cur_rule_arch = lxc_seccomp_arch_unknown; ++ continue; ++ } ++ ++ cur_rule_arch = lxc_seccomp_arch_mips64n32; ++ } else if (strcmp(line, "[mips]") == 0 || ++ strcmp(line, "[MIPS]") == 0) { ++ if (native_arch != lxc_seccomp_arch_mips && ++ native_arch != lxc_seccomp_arch_mips64) { ++ cur_rule_arch = lxc_seccomp_arch_unknown; ++ continue; ++ } ++ ++ cur_rule_arch = lxc_seccomp_arch_mips; ++ } else if (strcmp(line, "[mipsel64]") == 0 || ++ strcmp(line, "[MIPSEL64]") == 0) { ++ if (native_arch != lxc_seccomp_arch_mipsel64) { ++ cur_rule_arch = lxc_seccomp_arch_unknown; ++ continue; ++ } ++ ++ cur_rule_arch = lxc_seccomp_arch_mipsel64; ++ } else if (strcmp(line, "[mipsel64n32]") == 0 || ++ strcmp(line, "[MIPSEL64N32]") == 0) { ++ if (native_arch != lxc_seccomp_arch_mipsel64) { ++ cur_rule_arch = lxc_seccomp_arch_unknown; ++ continue; ++ } ++ ++ cur_rule_arch = lxc_seccomp_arch_mipsel64n32; ++ } else if (strcmp(line, "[mipsel]") == 0 || ++ strcmp(line, "[MIPSEL]") == 0) { ++ if (native_arch != lxc_seccomp_arch_mipsel && ++ native_arch != lxc_seccomp_arch_mipsel64) { ++ cur_rule_arch = lxc_seccomp_arch_unknown; ++ continue; ++ } ++ ++ cur_rule_arch = lxc_seccomp_arch_mipsel; ++ } ++#endif ++#ifdef SCMP_ARCH_S390X ++ else if (strcmp(line, "[s390x]") == 0 || ++ strcmp(line, "[S390X]") == 0) { ++ if (native_arch != lxc_seccomp_arch_s390x) { ++ cur_rule_arch = lxc_seccomp_arch_unknown; ++ continue; ++ } ++ ++ cur_rule_arch = lxc_seccomp_arch_s390x; ++ } ++#endif ++ else { ++ goto bad_arch; ++ } ++ ++ continue; ++ } ++ ++ /* irrelevant arch - i.e. arm on i386 */ ++ if (cur_rule_arch == lxc_seccomp_arch_unknown) ++ continue; ++ ++ memset(&rule, 0, sizeof(rule)); ++ /* read optional action which follows the syscall */ ++ ret = parse_v2_rules(line, default_rule_action, &rule); ++ if (ret != 0) { ++ ERROR("Failed to interpret seccomp rule"); ++ goto bad_rule; ++ } ++ ++ if (cur_rule_arch == native_arch) { ++ /* add for native arch */ ++ if (!do_resolve_add_rule(SCMP_ARCH_NATIVE, line, ++ conf->seccomp.seccomp_ctx, &rule)) ++ goto bad_rule; ++ ++ DEBUG("Added native rule for arch %d for %s action %d(%s)", ++ SCMP_ARCH_NATIVE, line, rule.action, ++ get_action_name(rule.action)); ++ } else if (cur_rule_arch != lxc_seccomp_arch_all) { ++ /* add for compat specified arch */ ++ int arch_index = get_arch_index(cur_rule_arch, &ctx); ++ if (arch_index < 0) ++ goto bad_arch; ++ ++ if (!do_resolve_add_rule(ctx.architectures[arch_index], line, ++ ctx.contexts[arch_index], &rule)) ++ goto bad_rule; ++ ++ DEBUG("Added compat rule for arch %d for %s action %d(%s)", ++ ctx.architectures[arch_index], line, rule.action, ++ get_action_name(rule.action)); ++ ctx.needs_merge[arch_index] = true; ++ } else { ++ /* add for all compat archs */ ++ if (!do_resolve_add_rule(SCMP_ARCH_NATIVE, line, ++ conf->seccomp.seccomp_ctx, &rule)) ++ goto bad_rule; ++ ++ DEBUG("Added native rule for arch %d for %s action %d(%s)", ++ SCMP_ARCH_NATIVE, line, rule.action, ++ get_action_name(rule.action)); ++ ++ if (ctx.architectures[0] != SCMP_ARCH_NATIVE) { ++ if (!do_resolve_add_rule(ctx.architectures[0], line, ++ ctx.contexts[0], &rule)) ++ goto bad_rule; ++ ++ DEBUG("Added compat rule for arch %d for %s action %d(%s)", ++ ctx.architectures[0], line, rule.action, ++ get_action_name(rule.action)); ++ ctx.needs_merge[0] = true; ++ } ++ ++ if (ctx.architectures[1] != SCMP_ARCH_NATIVE) { ++ if (!do_resolve_add_rule(ctx.architectures[1], line, ++ ctx.contexts[1], &rule)) ++ goto bad_rule; ++ ++ DEBUG("Added compat rule for arch %d for %s action %d(%s)", ++ ctx.architectures[1], line, rule.action, ++ get_action_name(rule.action)); ++ ctx.needs_merge[1] = true; ++ } ++ ++ if (ctx.architectures[2] != SCMP_ARCH_NATIVE) { ++ if (!do_resolve_add_rule(ctx.architectures[2], line, ++ ctx.contexts[2], &rule)) ++ goto bad_rule; ++ ++ DEBUG("Added native rule for arch %d for %s action %d(%s)", ++ ctx.architectures[2], line, rule.action, ++ get_action_name(rule.action)); ++ ctx.needs_merge[2] = true; ++ } ++ } ++ ++ } ++ ++ INFO("Merging compat seccomp contexts into main context"); ++ if (ctx.contexts[0]) { ++ if (ctx.needs_merge[0]) { ++ ret = seccomp_merge(conf->seccomp.seccomp_ctx, ctx.contexts[0]); ++ if (ret < 0) { ++ ERROR("%s - Failed to merge first compat seccomp " ++ "context into main context", strerror(-ret)); ++ goto bad; ++ } ++ ++ TRACE("Merged first compat seccomp context into main context"); ++ } else { ++ seccomp_release(ctx.contexts[0]); ++ ctx.contexts[0] = NULL; ++ } ++ } ++ ++ if (ctx.contexts[1]) { ++ if (ctx.needs_merge[1]) { ++ ret = seccomp_merge(conf->seccomp.seccomp_ctx, ctx.contexts[1]); ++ if (ret < 0) { ++ ERROR("%s - Failed to merge second compat seccomp " ++ "context into main context", strerror(-ret)); ++ goto bad; ++ } ++ ++ TRACE("Merged second compat seccomp context into main context"); ++ } else { ++ seccomp_release(ctx.contexts[1]); ++ ctx.contexts[1] = NULL; ++ } ++ } ++ ++ if (ctx.contexts[2]) { ++ if (ctx.needs_merge[2]) { ++ ret = seccomp_merge(conf->seccomp.seccomp_ctx, ctx.contexts[2]); ++ if (ret < 0) { ++ ERROR("%s - Failed to merge third compat seccomp " ++ "context into main context", strerror(-ret)); ++ goto bad; ++ } ++ ++ TRACE("Merged third compat seccomp context into main context"); ++ } else { ++ seccomp_release(ctx.contexts[2]); ++ ctx.contexts[2] = NULL; ++ } ++ } ++ ++ free(line); ++ return 0; ++ ++bad_arch: ++ ERROR("Unsupported architecture \"%s\"", line); ++ ++bad_rule: ++bad: ++ if (ctx.contexts[0]) ++ seccomp_release(ctx.contexts[0]); ++ ++ if (ctx.contexts[1]) ++ seccomp_release(ctx.contexts[1]); ++ ++ if (ctx.contexts[2]) ++ seccomp_release(ctx.contexts[2]); ++ ++ free(line); ++ ++ return -1; ++} ++#else + static int parse_config_v2(FILE *f, char *line, size_t *line_bufsz, struct lxc_conf *conf) + { + int ret; +@@ -1067,6 +1619,7 @@ bad: + + return -1; + } ++#endif + #else /* HAVE_DECL_SECCOMP_SYSCALL_RESOLVE_NAME_ARCH */ + static int parse_config_v2(FILE *f, char *line, struct lxc_conf *conf) + { +@@ -1288,6 +1841,7 @@ void lxc_seccomp_free(struct lxc_seccomp *seccomp) + seccomp_notify_free(seccomp->notifier.req_buf, seccomp->notifier.rsp_buf); + seccomp->notifier.req_buf = NULL; + seccomp->notifier.rsp_buf = NULL; ++ free_disarm(seccomp->notifier.cookie); + #endif + } + +@@ -1498,6 +2052,7 @@ void seccomp_conf_init(struct lxc_conf *conf) + sizeof(conf->seccomp.notifier.proxy_addr)); + conf->seccomp.notifier.req_buf = NULL; + conf->seccomp.notifier.rsp_buf = NULL; ++ conf->seccomp.notifier.cookie = NULL; + #endif + } + +diff --git a/src/lxc/storage/zfs.c b/src/lxc/storage/zfs.c +index ee9e32d..903937a 100644 +--- a/src/lxc/storage/zfs.c ++++ b/src/lxc/storage/zfs.c +@@ -167,13 +167,22 @@ int zfs_mount(struct lxc_storage *bdev) + const char *src; + char cmd_output[PATH_MAX] = {0}; + ++#ifdef HAVE_ISULAD ++ unsigned long pflags = 0; ++#endif ++ + if (strcmp(bdev->type, "zfs")) + return -22; + + if (!bdev->src || !bdev->dest) + return -22; + ++#ifdef HAVE_ISULAD ++ ret = parse_mntopts(bdev->mntopts, &mntflags, &pflags, &mntdata); ++#else + ret = parse_mntopts(bdev->mntopts, &mntflags, &mntdata); ++#endif ++ + if (ret < 0) { + ERROR("Failed to parse mount options"); + return -22; +-- +2.25.1 + diff --git a/lxc.spec b/lxc.spec index 8e01cc0e9353c4feb641ca6963bd63726bba3123..c083b6c52fb94e4d56b0cf7fdd9263eb57b29d9c 100644 --- a/lxc.spec +++ b/lxc.spec @@ -1,4 +1,4 @@ -%global _release 2022071901 +%global _release 2022071903 Name: lxc Version: 4.0.3 @@ -12,6 +12,7 @@ Patch0001: 0001-refactor-patch-code-of-utils-commands-and-so-on.patch Patch0002: 0002-refactor-patch-code-of-isulad-for-conf-exec-attach.patch Patch0003: 0003-refactor-patch-code-of-isulad-for-selinux-attach.patch Patch0004: 0004-refactor-patch-code-of-lxccontianer-and-so-on.patch +Patch0005: 0005-refactor-patch-code-of-attach-and-seccomp.patch BuildRequires: systemd-units git libtool graphviz docbook2X doxygen chrpath BuildRequires: pkgconfig(libseccomp) @@ -183,7 +184,13 @@ make check %{_mandir}/*/man7/%{name}* %changelog -* Tue Jul 19 2022 wangfengtu - 4.0.3-2022071901 +* Thu Jul 19 2022 zhangxiaoyu - 4.0.3-2022071903 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC: refactor patch code of attach and seccomp + +* Tue Jul 19 2022 wangfengtu - 4.0.3-2022071902 - Type:bugfix - ID:NA - SUG:NA