From 35e00a818c7ce1033e844076e7d1ea1a50b4b0c7 Mon Sep 17 00:00:00 2001 From: wujing Date: Mon, 7 Dec 2020 16:57:16 +0800 Subject: [PATCH] af_unix: use path based unix domain sockets instead of abstract namespace sockets to improve container security Signed-off-by: wujing --- ...nix-domain-sockets-instead-of-abstra.patch | 401 ++++++++++++++++++ lxc.spec | 9 +- 2 files changed, 409 insertions(+), 1 deletion(-) create mode 100644 0013-use-path-based-unix-domain-sockets-instead-of-abstra.patch diff --git a/0013-use-path-based-unix-domain-sockets-instead-of-abstra.patch b/0013-use-path-based-unix-domain-sockets-instead-of-abstra.patch new file mode 100644 index 0000000..71d2e29 --- /dev/null +++ b/0013-use-path-based-unix-domain-sockets-instead-of-abstra.patch @@ -0,0 +1,401 @@ +From f0af10aef5b21b6bf19dce0d2657f645355a42ac Mon Sep 17 00:00:00 2001 +From: wujing +Date: Fri, 4 Dec 2020 10:04:30 +0800 +Subject: [PATCH] use path based unix domain sockets instead of abstract + namespace sockets to improve container security + +Signed-off-by: wujing +--- + src/lxc/af_unix.c | 50 ++++++++++++++++++++++++++++++++++-- + src/lxc/af_unix.h | 4 ++- + src/lxc/attach.c | 4 +++ + src/lxc/commands.c | 39 ++++++++++++++++++++++++++++ + src/lxc/commands_utils.c | 51 +++++++++++++++++++++++++++++++++++++ + src/lxc/commands_utils.h | 6 +++++ + src/lxc/exec_commands.c | 55 ++++++++++++++++++++++++++++++++++++++++ + src/lxc/exec_commands.h | 4 +++ + src/lxc/lxccontainer.c | 18 +++++++++++++ + 9 files changed, 228 insertions(+), 3 deletions(-) + +diff --git a/src/lxc/af_unix.c b/src/lxc/af_unix.c +index 9f268be6..090465b4 100644 +--- a/src/lxc/af_unix.c ++++ b/src/lxc/af_unix.c +@@ -372,12 +372,58 @@ int lxc_unix_connect_type(struct sockaddr_un *addr, int type) + ret = connect(fd, (struct sockaddr *)addr, + offsetof(struct sockaddr_un, sun_path) + len); + if (ret < 0) +- return log_error_errno(-1, errno, +- "Failed to bind new AF_UNIX socket"); ++ return log_warn_errno(-1, errno, ++ "Failed to connect new AF_UNIX socket"); ++ ++ return move_fd(fd); ++} ++ ++#ifdef HAVE_ISULAD ++int lxc_named_unix_open(const char *path, int type, int flags) ++{ ++ __do_close int fd = -EBADF; ++ int ret; ++ ssize_t len; ++ struct sockaddr_un addr; ++ ++ fd = socket(PF_UNIX, type | SOCK_CLOEXEC, 0); ++ if (fd < 0) ++ return -1; ++ ++ if (!path) ++ return move_fd(fd); ++ ++ len = lxc_unix_sockaddr(&addr, path); ++ if (len < 0) ++ return -1; ++ ++ ret = bind(fd, (struct sockaddr *)&addr, len); ++ if (ret < 0) ++ return -1; ++ ++ if (chmod(path, 0600) < 0) ++ return -1; ++ ++ if (type == SOCK_STREAM) { ++ ret = listen(fd, 100); ++ if (ret < 0) ++ return -1; ++ } + + return move_fd(fd); + } + ++int lxc_named_unix_connect(const char *path) ++{ ++ struct sockaddr_un addr; ++ ++ if (lxc_unix_sockaddr(&addr, path) < 0) ++ return -1; ++ ++ return lxc_unix_connect_type(&addr, SOCK_STREAM); ++} ++#endif ++ + int lxc_unix_connect(struct sockaddr_un *addr, int type) + { + return lxc_unix_connect_type(addr, SOCK_STREAM); +diff --git a/src/lxc/af_unix.h b/src/lxc/af_unix.h +index 6943a61e..a511330a 100644 +--- a/src/lxc/af_unix.h ++++ b/src/lxc/af_unix.h +@@ -28,7 +28,9 @@ extern int lxc_unix_connect(struct sockaddr_un *addr); + extern int lxc_unix_connect_type(struct sockaddr_un *addr, int type); + extern int lxc_socket_set_timeout(int fd, int rcv_timeout, int snd_timeout); + #ifdef HAVE_ISULAD +-int lxc_abstract_unix_recv_fds_timeout(int fd, int *recvfds, int num_recvfds, ++extern int lxc_abstract_unix_recv_fds_timeout(int fd, int *recvfds, int num_recvfds, + void *data, size_t size, unsigned int timeout); ++extern int lxc_named_unix_open(const char *path, int type, int flags); ++extern int lxc_named_unix_connect(const char *path); + #endif + #endif /* __LXC_AF_UNIX_H */ +diff --git a/src/lxc/attach.c b/src/lxc/attach.c +index 72b3055c..87e23c22 100644 +--- a/src/lxc/attach.c ++++ b/src/lxc/attach.c +@@ -1474,6 +1474,7 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + if (exec_command.maincmd_fd != -1) { + close(exec_command.maincmd_fd); + } ++ lxc_exec_unix_sock_delete(name, suffix); + } + #endif + free(cwd); +@@ -1491,6 +1492,7 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + 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]); +@@ -1517,6 +1519,7 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + 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]); +@@ -1789,6 +1792,7 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, + if (exec_command.maincmd_fd != -1) { + close(exec_command.maincmd_fd); + } ++ lxc_exec_unix_sock_delete(name, suffix); + #endif + } + +diff --git a/src/lxc/commands.c b/src/lxc/commands.c +index 37354e87..70c56579 100644 +--- a/src/lxc/commands.c ++++ b/src/lxc/commands.c +@@ -1691,6 +1691,44 @@ static int lxc_cmd_accept(int fd, uint32_t events, void *data, + return ret; + } + ++#ifdef HAVE_ISULAD ++int lxc_cmd_init(const char *name, const char *lxcpath, const char *suffix) ++{ ++ __do_close int fd = -EBADF; ++ int ret; ++ char path[LXC_AUDS_ADDR_LEN] = {0}; ++ __do_free char *runtime_sock_dir = NULL; ++ ++ runtime_sock_dir = generate_named_unix_sock_dir(name); ++ if (runtime_sock_dir == NULL) ++ return -1; ++ ++ if (mkdir_p(runtime_sock_dir, 0600) < 0) ++ return log_error_errno(-1, errno, "Failed to create container runtime unix sock directory %s", path); ++ ++ if (generate_named_unix_sock_path(name, suffix, path, sizeof(path)) != 0) ++ return -1; ++ ++ fd = lxc_named_unix_open(path, SOCK_STREAM, 0); ++ if (fd < 0) { ++ if (errno == EADDRINUSE) { ++ WARN("Container \"%s\" appears to be already running", name); ++ (void)unlink(path); ++ ++ fd = lxc_named_unix_open(path, SOCK_STREAM, 0); ++ if (fd < 0) ++ return log_error_errno(-1, errno, "Failed to create command socket %s", path); ++ } else ++ return log_error_errno(-1, errno, "Failed to create command socket %s", path); ++ } ++ ++ ret = fcntl(fd, F_SETFD, FD_CLOEXEC); ++ if (ret < 0) ++ return log_error_errno(-1, errno, "Failed to set FD_CLOEXEC on command socket file descriptor"); ++ ++ return log_trace(move_fd(fd), "Created unix socket \"%s\"", path); ++} ++#else + int lxc_cmd_init(const char *name, const char *lxcpath, const char *suffix) + { + __do_close int fd = -EBADF; +@@ -1715,6 +1753,7 @@ int lxc_cmd_init(const char *name, const char *lxcpath, const char *suffix) + + return log_trace(move_fd(fd), "Created abstract unix socket \"%s\"", &path[1]); + } ++#endif + + int lxc_cmd_mainloop_add(const char *name, struct lxc_epoll_descr *descr, + struct lxc_handler *handler) +diff --git a/src/lxc/commands_utils.c b/src/lxc/commands_utils.c +index 2f2670d7..7dfefa5c 100644 +--- a/src/lxc/commands_utils.c ++++ b/src/lxc/commands_utils.c +@@ -137,12 +137,63 @@ int lxc_make_abstract_socket_name(char *path, size_t pathlen, + return 0; + } + ++#ifdef HAVE_ISULAD ++char *generate_named_unix_sock_dir(const char *name) ++{ ++ __do_free char *exec_sock_dir = NULL; ++ ++ if (asprintf(&exec_sock_dir, "/var/run/lxc/%s", name) < 0) ++ return log_error_errno(NULL, errno, "Failed to allocate memory"); ++ ++ return move_ptr(exec_sock_dir); ++} ++ ++int generate_named_unix_sock_path(const char *container_name, const char *sock_name, ++ char *out_path, size_t len) ++{ ++#define MAX_SOCK_NAME_LENGTH 12 ++ int ret; ++ __do_free char *sock_dir = NULL; ++ __do_free char *short_sock_name = NULL; ++ ++ if (container_name == NULL || sock_name == NULL) ++ return -1; ++ ++ sock_dir = generate_named_unix_sock_dir(container_name); ++ if (sock_dir == NULL) ++ return -1; ++ ++ short_sock_name = strdup(sock_name); ++ if (strlen(short_sock_name) > MAX_SOCK_NAME_LENGTH) ++ short_sock_name[MAX_SOCK_NAME_LENGTH] = '\0'; ++ ++ ret = snprintf(out_path, len, "%s/%s.sock", sock_dir, short_sock_name); ++ if (ret < 0 || (size_t)ret >= len) ++ return log_error_errno(-1, errno, "Failed to allocate memory"); ++ ++ return 0; ++} ++#endif ++ + int lxc_cmd_connect(const char *name, const char *lxcpath, + const char *hashed_sock_name, const char *suffix) + { + int ret, client_fd; + char path[LXC_AUDS_ADDR_LEN] = {0}; + ++#ifdef HAVE_ISULAD ++ if (generate_named_unix_sock_path(name, suffix, path, sizeof(path)) != 0) ++ return -1; ++ ++ if (file_exists(path)) { ++ client_fd = lxc_named_unix_connect(path); ++ if (client_fd < 0) ++ return -1; ++ ++ return client_fd; ++ } ++#endif ++ + ret = lxc_make_abstract_socket_name(path, sizeof(path), name, lxcpath, + hashed_sock_name, suffix); + if (ret < 0) +diff --git a/src/lxc/commands_utils.h b/src/lxc/commands_utils.h +index 3ef7920c..c836ead8 100644 +--- a/src/lxc/commands_utils.h ++++ b/src/lxc/commands_utils.h +@@ -65,4 +65,10 @@ extern int lxc_add_state_client(int state_client_fd, + extern int lxc_cmd_connect(const char *name, const char *lxcpath, + const char *hashed_sock_name, const char *suffix); + ++#ifdef HAVE_ISULAD ++extern char *generate_named_unix_sock_dir(const char *name); ++extern int generate_named_unix_sock_path(const char *container_name, ++ const char *sock_name, char *out_path, size_t len); ++#endif ++ + #endif /* __LXC_COMMANDS_UTILS_H */ +diff --git a/src/lxc/exec_commands.c b/src/lxc/exec_commands.c +index 00129cb0..50246fa4 100644 +--- a/src/lxc/exec_commands.c ++++ b/src/lxc/exec_commands.c +@@ -371,7 +371,61 @@ out_close: + close(connection); + goto out; + } ++#ifdef HAVE_ISULAD ++int lxc_exec_unix_sock_delete(const char *name, const char *suffix) ++{ ++ char path[LXC_AUDS_ADDR_LEN] = {0}; ++ ++ if (name == NULL || suffix == NULL) ++ return -1; ++ ++ if (generate_named_unix_sock_path(name, suffix, path, sizeof(path)) != 0) ++ return -1; ++ ++ (void)unlink(path); ++ ++ return 0; ++} ++ ++int lxc_exec_cmd_init(const char *name, const char *lxcpath, const char *suffix) ++{ ++ __do_close int fd = -EBADF; ++ int ret; ++ char path[LXC_AUDS_ADDR_LEN] = {0}; ++ __do_free char *exec_sock_dir = NULL; + ++ exec_sock_dir = generate_named_unix_sock_dir(name); ++ if (exec_sock_dir == NULL) ++ return -1; ++ ++ if (mkdir_p(exec_sock_dir, 0600) < 0) ++ return log_error_errno(-1, errno, "Failed to create exec sock directory %s", path); ++ ++ if (generate_named_unix_sock_path(name, suffix, path, sizeof(path)) != 0) ++ return -1; ++ ++ TRACE("Creating unix socket \"%s\"", path); ++ ++ fd = lxc_named_unix_open(path, SOCK_STREAM, 0); ++ if (fd < 0) { ++ if (errno == EADDRINUSE) { ++ WARN("Container \"%s\" exec unix sock is occupied", name); ++ (void)unlink(path); ++ fd = lxc_named_unix_open(path, SOCK_STREAM, 0); ++ if (fd < 0) ++ return log_error_errno(-1, errno, "Failed to create command socket %s", path); ++ } else { ++ return log_error_errno(-1, errno, "Failed to create command socket %s", path); ++ } ++ } ++ ++ ret = fcntl(fd, F_SETFD, FD_CLOEXEC); ++ if (ret < 0) ++ return log_error_errno(-1, errno, "Failed to set FD_CLOEXEC on command socket file descriptor"); ++ ++ return log_trace(move_fd(fd), "Created unix socket \"%s\"", path); ++} ++#else + int lxc_exec_cmd_init(const char *name, const char *lxcpath, const char *suffix) + { + int fd, ret; +@@ -400,6 +454,7 @@ int lxc_exec_cmd_init(const char *name, const char *lxcpath, const char *suffix) + + return fd; + } ++#endif + + int lxc_exec_cmd_mainloop_add(struct lxc_epoll_descr *descr, struct lxc_exec_command_handler *handler) + { +diff --git a/src/lxc/exec_commands.h b/src/lxc/exec_commands.h +index 2581ee90..3ec2a226 100644 +--- a/src/lxc/exec_commands.h ++++ b/src/lxc/exec_commands.h +@@ -70,4 +70,8 @@ extern int lxc_exec_cmd_init(const char *name, const char *lxcpath, const char * + extern int lxc_exec_cmd_mainloop_add(struct lxc_epoll_descr *descr, struct lxc_exec_command_handler *handler); + extern int lxc_exec_cmd_set_terminal_winch(const char *name, const char *lxcpath, const char *suffix, unsigned int height, unsigned int width); + ++#ifdef HAVE_ISULAD ++extern int lxc_exec_unix_sock_delete(const char *name, const char *suffix); ++#endif ++ + #endif /* __exec_commands_h */ +diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c +index eef98df6..cbb67f32 100644 +--- a/src/lxc/lxccontainer.c ++++ b/src/lxc/lxccontainer.c +@@ -3189,6 +3189,21 @@ static int lxc_unlink_exec_wrapper(void *data) + return unlink(arg); + } + ++#ifdef HAVE_ISULAD ++static void container_sock_dir_delete(const char *name) ++{ ++ __do_free char *sock_dir = NULL; ++ ++ sock_dir = generate_named_unix_sock_dir(name); ++ if (sock_dir == NULL) { ++ ERROR("Failed to generate exec unix sock dir"); ++ return; ++ } ++ ++ (void)lxc_rmdir_onedev(sock_dir, NULL); ++} ++#endif ++ + static bool container_destroy(struct lxc_container *c, + struct lxc_storage *storage) + { +@@ -3342,6 +3357,9 @@ static bool container_destroy(struct lxc_container *c, + #endif + goto out; + } ++#ifdef HAVE_ISULAD ++ container_sock_dir_delete(c->name); ++#endif + INFO("Destroyed directory \"%s\" for \"%s\"", path, c->name); + + on_success: +-- +2.25.1 + diff --git a/lxc.spec b/lxc.spec index 7e27b61..924fece 100644 --- a/lxc.spec +++ b/lxc.spec @@ -1,4 +1,4 @@ -%global _release 2020112701 +%global _release 2020120701 Name: lxc Version: 4.0.3 @@ -20,6 +20,7 @@ Patch0009: 0009-cgroup-refact-cgroup-manager-to-single-file.patch Patch0010: 0010-cgfsng-adjust-log-level-from-error-to-warn.patch Patch0011: 0011-rootfs-add-make-private-for-root.path-parent.patch Patch0012: 0012-mount-make-possible-to-bind-mount-proc-and-sys-fs.patch +Patch0013: 0013-use-path-based-unix-domain-sockets-instead-of-abstra.patch BuildRequires: systemd-units git libtool graphviz docbook2X doxygen chrpath BuildRequires: pkgconfig(libseccomp) @@ -191,6 +192,12 @@ make check %{_mandir}/*/man7/%{name}* %changelog +* Mon Dec 07 2020 wujing - 4.0.3-2020120701 +- Type:enhancement +- ID:NA +- SUG:NA +- DESC: use path based unix domain sockets instead of abstract namespace sockets + * Fri Nov 27 2020 lifeng - 4.0.3-2020112701 - Type:enhancement - ID:NA -- Gitee