From 879e8e26506cda1650aed469781dd68d56f289b2 Mon Sep 17 00:00:00 2001 From: gaohuatao Date: Tue, 31 Mar 2020 04:41:58 -0400 Subject: [PATCH 142/142] lxc: fix non-root user cannot write /dev/stdout Signed-off-by: gaohuatao --- src/lxc/attach.c | 2 ++ src/lxc/conf.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ src/lxc/conf.h | 1 + src/lxc/start.c | 2 ++ src/lxc/utils.c | 1 - 5 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/lxc/attach.c b/src/lxc/attach.c index 2061b960..b1bbaeba 100644 --- a/src/lxc/attach.c +++ b/src/lxc/attach.c @@ -1031,6 +1031,8 @@ static int attach_child_main(struct attach_clone_payload *payload) init_ctx->container->lxc_conf->init_groups)) goto on_error; + fix_stdio_permissions(new_uid); + if (!lxc_switch_uid_gid(new_uid, new_gid)) goto on_error; diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 65b33ea5..b67e138d 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -5262,6 +5262,57 @@ int lxc_clear_namespace(struct lxc_conf *c) return 0; } +void fix_stdio_permissions(uid_t uid) +{ + int std_fds[3] = {STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO}; + int devnull_fd = -1; + int ret = 0; + int i = 0; + struct stat st; + struct stat null_st; + + devnull_fd = open_devnull(); + if (devnull_fd < 0) { + WARN("Using /dev/null from the host for container " + "init's standard file descriptors. Migration will " + "not work"); + goto out; + } + + ret = fstat(devnull_fd, &null_st); + if (ret != 0) { + ERROR("Failed to get /dev/null stat"); + goto out; + } + + for (; i < 3; i++) { + ret = fstat(std_fds[i], &st); + if (ret != 0) { + ERROR("Failed to get fd %d stat", std_fds[i]); + continue; + } + + if (st.st_rdev == null_st.st_rdev) { + continue; + } + + ret = fchown(std_fds[i], uid, st.st_gid); + if (ret != 0) { + ERROR("Failed to change fd %d owner", std_fds[i]); + } + + ret = fchmod(std_fds[i], 0700); + if (ret != 0) { + ERROR("Failed to change fd %d mode", std_fds[i]); + } + } + +out: + if (devnull_fd >= 0) { + close(devnull_fd); + } +} + int lxc_clear_groups(struct lxc_conf *c) { struct lxc_list *it, *next; diff --git a/src/lxc/conf.h b/src/lxc/conf.h index e4bfc48f..d67ca31b 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h @@ -500,6 +500,7 @@ extern int lxc_clear_sysctls(struct lxc_conf *c, const char *key); extern int setup_proc_filesystem(struct lxc_list *procs, pid_t pid); extern int lxc_clear_procs(struct lxc_conf *c, const char *key); extern int lxc_clear_namespace(struct lxc_conf *c); +extern void fix_stdio_permissions(uid_t uid); /* isulad add begin */ int lxc_clear_init_args(struct lxc_conf *lxc_conf); diff --git a/src/lxc/start.c b/src/lxc/start.c index 0af2e926..1977ccd2 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -1679,6 +1679,8 @@ static int do_start(void *data) if (lxc_setup_env_home(new_uid) < 0) goto out_warn_father; + fix_stdio_permissions(new_uid); + /* If we are in a new user namespace we already dropped all groups when * we switched to root in the new user namespace further above. Only * drop groups if we can, so ensure that we have necessary privilege. diff --git a/src/lxc/utils.c b/src/lxc/utils.c index 31bcac71..f2b3a4f9 100644 --- a/src/lxc/utils.c +++ b/src/lxc/utils.c @@ -1909,7 +1909,6 @@ set_env: return 0; } - /* isulad: read file to buffer */ int lxc_file2str(const char *filename, char ret[], int cap) { -- 2.19.1