From 23413b0d6374846c646b18b760ca75603941fdce Mon Sep 17 00:00:00 2001 From: WangFengTu Date: Wed, 2 Mar 2022 14:20:12 +0800 Subject: [PATCH] iSulad: Add the function of isolating the user namespaces Signed-off-by: WangFengTu --- ...unction-of-isolating-the-user-namesp.patch | 1231 +++++++++++++++++ ...ot-path-configable-when-userns-remap.patch | 93 ++ iSulad.spec | 11 +- 3 files changed, 1334 insertions(+), 1 deletion(-) create mode 100644 0001-iSulad-Add-the-function-of-isolating-the-user-namesp.patch create mode 100644 0002-let-isulad-root-path-configable-when-userns-remap.patch diff --git a/0001-iSulad-Add-the-function-of-isolating-the-user-namesp.patch b/0001-iSulad-Add-the-function-of-isolating-the-user-namesp.patch new file mode 100644 index 0000000..711a5f0 --- /dev/null +++ b/0001-iSulad-Add-the-function-of-isolating-the-user-namesp.patch @@ -0,0 +1,1231 @@ +From 0667ccb27829d58dd63110d6cb3460a958d28427 Mon Sep 17 00:00:00 2001 +From: HumbleHunger <2495970924@qq.com> +Date: Tue, 3 Aug 2021 17:30:00 +0800 +Subject: [PATCH 1/2] iSulad: Add the function of isolating the user namespaces + +Signed-off-by: HumbleHunger <2495970924@qq.com> +--- + CI/test_cases/container_cases/userns_remap.sh | 256 ++++++++++++++++++ + src/cmd/isula/base/create.c | 10 + + src/cmd/isula/base/create.h | 7 + + src/cmd/isulad/isulad_commands.h | 9 +- + src/cmd/isulad/main.c | 71 +++++ + src/daemon/config/isulad_config.c | 23 ++ + src/daemon/config/isulad_config.h | 1 + + .../executor/container_cb/execution_create.c | 8 + + .../executor/container_cb/execution_network.c | 33 ++- + .../graphdriver/overlay2/driver_overlay2.c | 81 +++++- + .../graphdriver/overlay2/driver_overlay2.h | 2 +- + .../modules/image/oci/storage/storage.c | 9 + + src/daemon/modules/runtime/engines/engine.c | 33 ++- + src/daemon/modules/spec/specs.c | 34 ++- + src/daemon/modules/spec/specs_mount.c | 36 ++- + src/daemon/modules/volume/local.c | 10 +- + src/utils/cutils/utils_file.c | 25 ++ + src/utils/cutils/utils_file.h | 1 + + src/utils/tar/util_archive.c | 3 + + src/utils/tar/util_archive.h | 2 + + 20 files changed, 624 insertions(+), 30 deletions(-) + create mode 100755 CI/test_cases/container_cases/userns_remap.sh + +diff --git a/CI/test_cases/container_cases/userns_remap.sh b/CI/test_cases/container_cases/userns_remap.sh +new file mode 100755 +index 00000000..21496941 +--- /dev/null ++++ b/CI/test_cases/container_cases/userns_remap.sh +@@ -0,0 +1,256 @@ ++#!/bin/bash ++ ++####################################################################### ++##- @Copyright (C) Huawei Technologies., Ltd. 2021. All rights reserved. ++# - iSulad licensed under the Mulan PSL v2. ++# - You can use this software according to the terms and conditions of the Mulan PSL v2. ++# - You may obtain a copy of Mulan PSL v2 at: ++# - http://license.coscl.org.cn/MulanPSL2 ++# - THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++# - IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++# - PURPOSE. ++# - See the Mulan PSL v2 for more details. ++##- @Description:CI ++##- @Author: liuyuji ++##- @Create: 2021-08-20 ++####################################################################### ++ ++source ../helpers.sh ++ ++ISULAD_ROOT_PATH="/var/lib/isulad/100000.100000" ++LCR_ROOT_PATH="/var/lib/isulad/100000.100000/engines/lcr" ++CONTAINER_PATH="/var/lib/isulad/100000.100000/storage/overlay" ++IDMAP="100000:100000" ++ROOT="0:0" ++ ++function check_idmap_of_file() ++{ ++ local ret=0 ++ ++ idmap=$(stat -c"%u:%g" ${1}) ++ [[ "${idmap}" != "${IDMAP}" ]] && msg_err "${2}" && ((ret++)) ++ ++ return ${ret} ++} ++ ++function check_idmap_of_file_in_container() ++{ ++ local ret=0 ++ ++ idmap=$(isula exec -it ${1} stat -c"%u:%g" ${2}) ++ # delete \r of iamap ++ idmap=$(echo ${idmap} | sed -e 's/\r//g') ++ ++ [[ "${idmap}" != "${ROOT}" ]] && msg_err "${3}" && ((ret++)) ++ ++ return ${ret} ++} ++ ++function start_isulad_with_userns_remap() ++{ ++ local test="start_isulad_with_userns_remap with userns-remap = 100000:100000:65535 => (${FUNCNAME[@]})" ++ ++ msg_info "${test} starting..." ++ ++ check_valgrind_log ++ [[ $? != 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - memory leak before current testcase, please check...." && return ${FAILURE} ++ ++ start_isulad_with_valgrind --userns-remap="100000:100000:65535" ++} ++ ++function check_the_management_directory_for_userns_remap() ++{ ++ local ret=0 ++ local test="check_the_management_directory_for_userns_remap => (${FUNCNAME[@]})" ++ ++ msg_info "${test} starting..." ++ ++ check_idmap_of_file ${ISULAD_ROOT_PATH}/engines "${FUNCNAME[0]}:${LINENO} - The idmap of the storage directory is not correctly mapped" ++ [[ $? != 0 ]] && ((ret++)) ++ ++ check_idmap_of_file ${ISULAD_ROOT_PATH}/storage "${FUNCNAME[0]}:${LINENO} - The idmap of the storage directory is not correctly mapped" ++ [[ $? != 0 ]] && ((ret++)) ++ ++ check_idmap_of_file ${ISULAD_ROOT_PATH}/volumes "${FUNCNAME[0]}:${LINENO} - The idmap of the volumes directory is not correctly mapped" ++ [[ $? != 0 ]] && ((ret++)) ++ ++ mod=$(stat -c"%a" ${ISULAD_ROOT_PATH}/mnt) ++ [[ $mod != 751 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - The permissions of the mnt directory are not set correctly" && ((ret++)) ++ ++ mod=$(stat -c"%a" ${ISULAD_ROOT_PATH}/mnt/rootfs) ++ [[ $mod != 751 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - The permissions of the rootfs directory are not set correctly" && ((ret++)) ++ ++ msg_info "${test} finished with return ${ret}..." ++ return ${ret} ++} ++ ++function test_userns_remap_with_pull_image() ++{ ++ local ret=0 ++ local image="busybox" ++ local test="test_userns_remap_with_pull_image => (${FUNCNAME[@]})" ++ ++ msg_info "${test} starting..." ++ ++ isula pull ${image} ++ [[ $? != 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - failed to pull image: ${image}" && return ${FAILURE} ++ ++ isula images | grep busybox ++ [[ $? != 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - missing list image: ${image}" && ((ret++)) ++ ++ layer_id=$(isula inspect -f '{{.image.top_layer}}' ${image}) ++ ++ check_idmap_of_file ${CONTAINER_PATH}/${layer_id}/diff "${FUNCNAME[0]}:${LINENO} - The idmap of the engines directory is not correctly mapped" ++ [[ $? != 0 ]] && ((ret++)) ++ ++ check_idmap_of_file ${ISULAD_ROOT_PATH}/storage "${FUNCNAME[0]}:${LINENO} - The idmap of the storage directory is not correctly mapped" ++ [[ $? != 0 ]] && ((ret++)) ++ ++ for file in ${CONTAINER_PATH}/${layer_id}/diff/* ++ do ++ check_idmap_of_file ${file} "${FUNCNAME[0]}:${LINENO} - The idmap of the image is not correctly mapped" ++ [[ $? != 0 ]] && ((ret++)) ++ done ++ ++ msg_info "${test} finished with return ${ret}..." ++ return ${ret} ++} ++ ++function test_userns_remap_with_create_container() ++{ ++ local ret=0 ++ local image="busybox" ++ local test="test_userns_remap_with_create_container => (${FUNCNAME[@]})" ++ ++ msg_info "${test} starting..." ++ ++ CID=$(isula create -it busybox) ++ [[ $? != 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - Failed to create container" && ((ret++)) ++ ++ check_idmap_of_file ${CONTAINER_PATH}/${CID}/diff "${FUNCNAME[0]}:${LINENO} - The idmap of the diff directory is not correctly mapped" ++ [[ $? != 0 ]] && ((ret++)) ++ ++ check_idmap_of_file ${CONTAINER_PATH}/${CID}/merged "${FUNCNAME[0]}:${LINENO} - The idmap of the merged directory is not correctly mapped" ++ [[ $? != 0 ]] && ((ret++)) ++ ++ check_idmap_of_file ${CONTAINER_PATH}/${CID}/work "${FUNCNAME[0]}:${LINENO} - The idmap of the work directory is not correctly mapped" ++ [[ $? != 0 ]] && ((ret++)) ++ ++ check_idmap_of_file ${LCR_ROOT_PATH}/${CID}/hostname "${FUNCNAME[0]}:${LINENO} - The idmap of the hostname is not correctly mapped" ++ [[ $? != 0 ]] && ((ret++)) ++ ++ check_idmap_of_file ${LCR_ROOT_PATH}/${CID}/hosts "${FUNCNAME[0]}:${LINENO} - The idmap of the hosts is not correctly mapped" ++ [[ $? != 0 ]] && ((ret++)) ++ ++ check_idmap_of_file ${LCR_ROOT_PATH}/${CID}/mounts "${FUNCNAME[0]}:${LINENO} - The idmap of the mounts is not correctly mapped" ++ [[ $? != 0 ]] && ((ret++)) ++ ++ check_idmap_of_file ${LCR_ROOT_PATH}/${CID}/resolv.conf "${FUNCNAME[0]}:${LINENO} - The idmap of the resolv.conf is not correctly mapped" ++ [[ $? != 0 ]] && ((ret++)) ++ ++ isula start ${CID} ++ [[ $? != 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - Failed to start container" && ((ret++)) ++ testcontainer ${CID} running ++ ++ isula rm -f ${CID} ++ [[ $? != 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - Failed to rm container" && ((ret++)) ++ ++ msg_info "${test} finished with return ${ret}..." ++ return ${ret} ++} ++ ++function check_lcr_config() ++{ ++ local ret=0 ++ local image="busybox" ++ local test="check_lcr_config => (${FUNCNAME[@]})" ++ ++ msg_info "${test} starting..." ++ CID=`isula run -itd ${image}` ++ [[ $? != 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - Failed to create container" && ((ret++)) ++ testcontainer ${CID} running ++ ++ cat "${LCR_ROOT_PATH}/${CID}/config" | grep "lxc.idmap = u 0 100000 65535" ++ [[ $? != 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - Failed to find uidmap in lcr config" && ((ret++)) ++ ++ cat "${LCR_ROOT_PATH}/${CID}/config" | grep "lxc.idmap = g 0 100000 65535" ++ [[ $? != 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - Failed to find gidmap in lcr config" && ((ret++)) ++ ++ isula rm -f ${CID} ++ [[ $? != 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - Failed to rm container" && ((ret++)) ++ ++ return ${ret} ++} ++ ++function test_userns_remap_with_create_file_in_container() ++{ ++ local ret=0 ++ local image="busybox" ++ local test="test_userns_remap_with_create_file_in_container => (${FUNCNAME[@]})" ++ local filename="test" ++ ++ msg_info "${test} starting..." ++ ++ CID=$(isula run -itd ${image}) ++ isula exec -it ${CID} touch ${filename} ++ [[ $? != 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - Failed to create file in container" && ((ret++)) ++ ++ check_idmap_of_file_in_container ${CID} ${filename} "${FUNCNAME[0]}:${LINENO} - The idmap is not correctly mapped" ++ [[ $? != 0 ]] && ((ret++)) ++ ++ check_idmap_of_file ${CONTAINER_PATH}/${CID}/diff/${filename} "${FUNCNAME[0]}:${LINENO} - The idmap is not correctly mapped" ++ [[ $? != 0 ]] && ((ret++)) ++ ++ isula rm -f $CID ++ [[ $? != 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - Failed to rm container" && ((ret++)) ++ ++ msg_info "${test} finished with return ${ret}..." ++ return ${ret} ++} ++ ++test_cancel_userns_remap() ++{ ++ local ret=0 ++ local image="busybox" ++ local test="tess_cancel_userns_remap => (${FUNCNAME[@]})" ++ local filename="test" ++ ++ msg_info "${test} starting..." ++ ++ CID=$(isula run -itd --userns=host ${image}) ++ isula exec -it ${CID} touch ${filename} ++ [[ $? != 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - Failed to create file in container" && ((ret++)) ++ ++ check_idmap_of_file_in_container ${CID} ${filename} "${FUNCNAME[0]}:${LINENO} - The idmap is not correctly mapped" ++ [[ $? != 0 ]] && ((ret++)) ++ ++ idmap=$(stat -c"%u:%g" ${CONTAINER_PATH}/${CID}/diff/${filename}) ++ [[ "${idmap}" != "${ROOT}" ]] && msg_err "${FUNCNAME[0]}:${LINENO} - The idmap is not correctly mapped" && ((ret++)) ++ ++ cat "${LCR_ROOT_PATH}/${CID}/config" | grep "lxc.idmap = u 0 100000 65535" ++ [[ $? == 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - Uidmap should not exist in lcr config" && ((ret++)) ++ ++ cat "${LCR_ROOT_PATH}/${CID}/config" | grep "lxc.idmap = g 0 100000 65535" ++ [[ $? == 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - Gidmap should not exist in lcr config" && ((ret++)) ++ ++ isula rm -f $CID ++ [[ $? != 0 ]] && msg_err "${FUNCNAME[0]}:${LINENO} - Failed to rm container" && ((ret++)) ++ ++ msg_info "${test} finished with return ${ret}..." ++ return ${ret} ++} ++ ++declare -i ans=0 ++ ++start_isulad_with_userns_remap || ((ans++)) ++check_the_management_directory_for_userns_remap || ((ans++)) ++test_userns_remap_with_pull_image || ((ans++)) ++test_userns_remap_with_create_container || ((ans++)) ++check_lcr_config || ((ans++)) ++test_userns_remap_with_create_file_in_container || ((ans++)) ++test_cancel_userns_remap || ((ans++)) ++ ++check_valgrind_log ++start_isulad_without_valgrind ++ ++show_result ${ans} "user namespaces remap" +diff --git a/src/cmd/isula/base/create.c b/src/cmd/isula/base/create.c +index 0b4a43a4..53fa7dc8 100644 +--- a/src/cmd/isula/base/create.c ++++ b/src/cmd/isula/base/create.c +@@ -1974,6 +1974,7 @@ static int create_namespaces_checker(const struct client_arguments *args) + { + int ret = 0; + const char *net_mode = args->custom_conf.share_ns[NAMESPACE_NET]; ++ const char *user_mode = args->custom_conf.share_ns[NAMESPACE_USER]; + + if (args->custom_conf.share_ns[NAMESPACE_NET]) { + if (!namespace_is_host(net_mode) && !namespace_is_container(net_mode) && !namespace_is_none(net_mode)) { +@@ -1982,6 +1983,15 @@ static int create_namespaces_checker(const struct client_arguments *args) + goto out; + } + } ++ ++ if (args->custom_conf.share_ns[NAMESPACE_USER]) { ++ if (!namespace_is_host(user_mode) && !namespace_is_none(user_mode)) { ++ COMMAND_ERROR("Unsupported user mode %s", user_mode); ++ ret = -1; ++ goto out; ++ } ++ } ++ + out: + return ret; + } +diff --git a/src/cmd/isula/base/create.h b/src/cmd/isula/base/create.h +index 610a289f..a638e1ca 100644 +--- a/src/cmd/isula/base/create.h ++++ b/src/cmd/isula/base/create.h +@@ -484,6 +484,13 @@ extern "C" { + 0, \ + &(cmdargs).custom_conf.stop_signal, \ + "Signal to stop a container (default \"SIGTERM\")", \ ++ NULL }, \ ++ { CMD_OPT_TYPE_STRING_DUP, \ ++ false, \ ++ "userns", \ ++ 0, \ ++ &(cmdargs).custom_conf.share_ns[NAMESPACE_USER], \ ++ "Set the usernamespace mode for the container when `userns-remap` option is enabled.", \ + NULL }, + + #define CREATE_EXTEND_OPTIONS(cmdargs) \ +diff --git a/src/cmd/isulad/isulad_commands.h b/src/cmd/isulad/isulad_commands.h +index 02007f3c..23f87e0e 100644 +--- a/src/cmd/isulad/isulad_commands.h ++++ b/src/cmd/isulad/isulad_commands.h +@@ -266,7 +266,14 @@ int command_default_ulimit_append(command_option_t *option, const char *arg); + { CMD_OPT_TYPE_BOOL, \ + false, "selinux-enabled", 0, &(cmdargs)->json_confs->selinux_enabled, \ + "Enable selinux support", NULL \ +- } ++ }, \ ++ { CMD_OPT_TYPE_STRING_DUP, \ ++ false, \ ++ "userns-remap", \ ++ 0, \ ++ &(cmdargs)->json_confs->userns_remap, \ ++ "User/Group setting for user namespaces", \ ++ NULL } + + #ifdef __cplusplus + } +diff --git a/src/cmd/isulad/main.c b/src/cmd/isulad/main.c +index 4917a3d1..b6132e12 100644 +--- a/src/cmd/isulad/main.c ++++ b/src/cmd/isulad/main.c +@@ -117,6 +117,7 @@ static int mount_rootfs_mnt_dir(const char *mountdir) + char *rootfsdir = NULL; + mountinfo_t **minfos = NULL; + mountinfo_t *info = NULL; ++ char *userns_remap = conf_get_isulad_userns_remap(); + + if (mountdir == NULL) { + ERROR("parent mount path is NULL"); +@@ -131,6 +132,14 @@ static int mount_rootfs_mnt_dir(const char *mountdir) + goto out; + } + ++ if (userns_remap != NULL) { ++ ret = chmod(rootfsdir, USER_REMAP_DIRECTORY_MODE); ++ if (ret != 0) { ++ ERROR("Failed to chmod mount dir '%s' for user remap", rootfsdir); ++ goto out; ++ } ++ } ++ + // find parent directory + p = strrchr(rootfsdir, '/'); + if (p == NULL) { +@@ -139,6 +148,14 @@ static int mount_rootfs_mnt_dir(const char *mountdir) + } + *p = '\0'; + ++ if (userns_remap != NULL) { ++ ret = chmod(rootfsdir, USER_REMAP_DIRECTORY_MODE); ++ if (ret != 0) { ++ ERROR("Failed to chmod mount dir '%s' for user remap", rootfsdir); ++ goto out; ++ } ++ } ++ + minfos = getmountsinfo(); + if (minfos == NULL) { + ERROR("Failed to get mounts info"); +@@ -157,6 +174,7 @@ static int mount_rootfs_mnt_dir(const char *mountdir) + + out: + free(rootfsdir); ++ free(userns_remap); + free_mounts_info(minfos); + return ret; + } +@@ -658,6 +676,38 @@ out: + return ret; + } + ++static int update_graph_for_userns_remap(struct service_arguments *args) ++{ ++ int ret = 0; ++ int nret = 0; ++ char graph[PATH_MAX] = { 0 }; ++ uid_t host_uid = 0; ++ gid_t host_gid = 0; ++ unsigned int size = 0; ++ ++ if (args->json_confs->userns_remap == NULL) { ++ goto out; ++ } ++ ++ if (util_parse_user_remap(args->json_confs->userns_remap, &host_uid, &host_gid, &size)) { ++ ERROR("Failed to split string '%s'.", args->json_confs->userns_remap); ++ ret = -1; ++ goto out; ++ } ++ ++ nret = snprintf(graph, sizeof(graph), "%s/%d.%d", ISULAD_ROOT_PATH, host_uid, host_gid); ++ if (nret < 0 || (size_t)nret >= sizeof(graph)) { ++ ERROR("Path is too long"); ++ ret = -1; ++ goto out; ++ } ++ ++ free(args->json_confs->graph); ++ args->json_confs->graph = util_strdup_s(graph); ++ ++out: ++ return ret; ++} + // update values for options after flag parsing is complete + static int update_tls_options(struct service_arguments *args) + { +@@ -901,6 +951,11 @@ static int update_server_args(struct service_arguments *args) + { + int ret = 0; + ++ if (update_graph_for_userns_remap(args) != 0) { ++ ret = -1; ++ goto out; ++ } ++ + if (update_tls_options(args)) { + ret = -1; + goto out; +@@ -1098,6 +1153,7 @@ static int isulad_server_pre_init(const struct service_arguments *args, const ch + const char *fifo_full_path) + { + int ret = 0; ++ char* userns_remap = conf_get_isulad_userns_remap(); + + if (check_and_save_pid(args->json_confs->pidfile) != 0) { + ERROR("Failed to save pid"); +@@ -1122,6 +1178,20 @@ static int isulad_server_pre_init(const struct service_arguments *args, const ch + goto out; + } + ++ if (userns_remap != NULL) { ++ if (chmod(ISULAD_ROOT_PATH, USER_REMAP_DIRECTORY_MODE) != 0) { ++ ERROR("Failed to chmod isulad root dir '%s' for user remap", ISULAD_ROOT_PATH); ++ ret = -1; ++ goto out; ++ } ++ ++ if (set_file_owner_for_userns_remap(args->json_confs->graph, userns_remap) != 0) { ++ ERROR("Unable to change root directory %s owner for user remap.", args->json_confs->graph); ++ ret = -1; ++ goto out; ++ } ++ } ++ + if (mount_rootfs_mnt_dir(args->json_confs->rootfsmntdir)) { + ERROR("Create and mount parent directory failed"); + ret = -1; +@@ -1135,6 +1205,7 @@ static int isulad_server_pre_init(const struct service_arguments *args, const ch + } + + out: ++ free(userns_remap); + return ret; + } + +diff --git a/src/daemon/config/isulad_config.c b/src/daemon/config/isulad_config.c +index f70b4575..539d30d2 100644 +--- a/src/daemon/config/isulad_config.c ++++ b/src/daemon/config/isulad_config.c +@@ -1157,6 +1157,28 @@ out: + return plugins; + } + ++char *conf_get_isulad_userns_remap() ++{ ++ struct service_arguments *conf = NULL; ++ char *userns_remap = NULL; ++ ++ if (isulad_server_conf_rdlock() != 0) { ++ ERROR("BUG conf_rdlock failed"); ++ return NULL; ++ } ++ ++ conf = conf_get_server_conf(); ++ if (conf == NULL || conf->json_confs == NULL || conf->json_confs->userns_remap == NULL) { ++ goto out; ++ } ++ ++ userns_remap = util_strdup_s(conf->json_confs->userns_remap); ++ ++out: ++ (void)isulad_server_conf_unlock(); ++ return userns_remap; ++} ++ + /* conf get websocket server listening port */ + int32_t conf_get_websocket_server_listening_port() + { +@@ -1510,6 +1532,7 @@ int merge_json_confs_into_global(struct service_arguments *args) + override_string_value(&args->json_confs->engine, &tmp_json_confs->engine); + override_string_value(&args->json_confs->hook_spec, &tmp_json_confs->hook_spec); + override_string_value(&args->json_confs->enable_plugins, &tmp_json_confs->enable_plugins); ++ override_string_value(&args->json_confs->userns_remap, &tmp_json_confs->userns_remap); + override_string_value(&args->json_confs->native_umask, &tmp_json_confs->native_umask); + override_string_value(&args->json_confs->cgroup_parent, &tmp_json_confs->cgroup_parent); + override_string_value(&args->json_confs->rootfsmntdir, &tmp_json_confs->rootfsmntdir); +diff --git a/src/daemon/config/isulad_config.h b/src/daemon/config/isulad_config.h +index 2b0ed349..5a9672a8 100644 +--- a/src/daemon/config/isulad_config.h ++++ b/src/daemon/config/isulad_config.h +@@ -56,6 +56,7 @@ int conf_get_container_log_opts(isulad_daemon_configs_container_log **opts); + char *conf_get_isulad_log_file(); + char *conf_get_engine_log_file(); + char *conf_get_enable_plugins(); ++char *conf_get_isulad_userns_remap(); + int32_t conf_get_websocket_server_listening_port(); + + int save_args_to_conf(struct service_arguments *args); +diff --git a/src/daemon/executor/container_cb/execution_create.c b/src/daemon/executor/container_cb/execution_create.c +index 114d2193..ac6b303a 100644 +--- a/src/daemon/executor/container_cb/execution_create.c ++++ b/src/daemon/executor/container_cb/execution_create.c +@@ -880,6 +880,7 @@ static int create_container_root_dir(const char *id, const char *runtime_root) + int nret; + char container_root[PATH_MAX] = { 0x00 }; + mode_t mask = umask(S_IWOTH); ++ char* userns_remap = conf_get_isulad_userns_remap(); + + nret = snprintf(container_root, sizeof(container_root), "%s/%s", runtime_root, id); + if ((size_t)nret >= sizeof(container_root) || nret < 0) { +@@ -894,8 +895,15 @@ static int create_container_root_dir(const char *id, const char *runtime_root) + goto out; + } + ++ if (set_file_owner_for_userns_remap(container_root, userns_remap) != 0) { ++ ERROR("Unable to change directory %s owner for user remap.", container_root); ++ ret = -1; ++ goto out; ++ } ++ + out: + umask(mask); ++ free(userns_remap); + return ret; + } + +diff --git a/src/daemon/executor/container_cb/execution_network.c b/src/daemon/executor/container_cb/execution_network.c +index 5532e3fc..d0a19c19 100644 +--- a/src/daemon/executor/container_cb/execution_network.c ++++ b/src/daemon/executor/container_cb/execution_network.c +@@ -26,6 +26,7 @@ + #include + + #include "isula_libutils/log.h" ++#include "isulad_config.h" + #include "utils.h" + #include "container_api.h" + #include "namespace.h" +@@ -707,24 +708,48 @@ static int merge_network_for_universal_container(const host_config *host_spec, c + int ret = 0; + int nret = 0; + char root_path[PATH_MAX] = { 0x00 }; ++ char *userns_remap = conf_get_isulad_userns_remap(); + + if (runtime_root == NULL || id == NULL) { + ERROR("empty runtime root or id"); +- return -1; ++ ret = -1; ++ goto out; + } + + nret = snprintf(root_path, PATH_MAX, "%s/%s", runtime_root, id); + if (nret < 0 || nret >= PATH_MAX) { + ERROR("Failed to print string"); +- return -1; ++ ret = -1; ++ goto out; ++ } ++ ++ ret = chown_network(userns_remap, root_path, "/hostname"); ++ if (ret) { ++ ret = -1; ++ goto out; ++ } ++ ++ ret = chown_network(userns_remap, root_path, "/hosts"); ++ if (ret) { ++ ret = -1; ++ goto out; + } + + ret = merge_resolv(host_spec, root_path, "/resolv.conf"); + if (ret) { +- return -1; ++ ret = -1; ++ goto out; + } + +- return 0; ++ ret = chown_network(userns_remap, root_path, "/resolv.conf"); ++ if (ret) { ++ ret = -1; ++ goto out; ++ } ++ ++out: ++ free(userns_remap); ++ return ret; + } + + static int merge_network_for_syscontainer(const host_config *host_spec, const char *rootfs, const char *hostname) +diff --git a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2/driver_overlay2.c b/src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2/driver_overlay2.c +index 659d9d52..32add2b4 100644 +--- a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2/driver_overlay2.c ++++ b/src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2/driver_overlay2.c +@@ -26,6 +26,7 @@ + #include + + #include "isula_libutils/log.h" ++#include "isulad_config.h" + #include "path.h" + #include "utils.h" + #include "util_archive.h" +@@ -268,13 +269,14 @@ out: + return ret; + } + +-int overlay2_init(struct graphdriver *driver, const char *drvier_home, const char **options, size_t len) ++int overlay2_init(struct graphdriver *driver, const char *driver_home, const char **options, size_t len) + { + int ret = 0; + char *link_dir = NULL; + char *root_dir = NULL; ++ char *userns_remap = NULL; + +- if (driver == NULL || drvier_home == NULL) { ++ if (driver == NULL || driver_home == NULL) { + ERROR("Invalid input arguments"); + return -1; + } +@@ -291,9 +293,9 @@ int overlay2_init(struct graphdriver *driver, const char *drvier_home, const cha + goto out; + } + +- link_dir = util_path_join(drvier_home, OVERLAY_LINK_DIR); ++ link_dir = util_path_join(driver_home, OVERLAY_LINK_DIR); + if (link_dir == NULL) { +- ERROR("Unable to create driver link directory %s.", drvier_home); ++ ERROR("Unable to create driver link directory %s.", driver_home); + ret = -1; + goto out; + } +@@ -306,11 +308,26 @@ int overlay2_init(struct graphdriver *driver, const char *drvier_home, const cha + + rm_invalid_symlink(link_dir); + +- driver->home = util_strdup_s(drvier_home); ++ userns_remap = conf_get_isulad_userns_remap(); ++ if (userns_remap != NULL) { ++ if (set_file_owner_for_userns_remap(link_dir, userns_remap) != 0) { ++ ERROR("Unable to change directory %s owner for user remap.", link_dir); ++ ret = -1; ++ goto out; ++ } ++ ++ if (set_file_owner_for_userns_remap(driver_home, userns_remap) != 0) { ++ ERROR("Unable to change directory %s owner for user remap.", driver_home); ++ ret = -1; ++ goto out; ++ } ++ } + +- root_dir = util_path_dir(drvier_home); ++ driver->home = util_strdup_s(driver_home); ++ ++ root_dir = util_path_dir(driver_home); + if (root_dir == NULL) { +- ERROR("Unable to get driver root home directory %s.", drvier_home); ++ ERROR("Unable to get driver root home directory %s.", driver_home); + ret = -1; + goto out; + } +@@ -328,7 +345,7 @@ int overlay2_init(struct graphdriver *driver, const char *drvier_home, const cha + goto out; + } + +- if (!util_support_d_type(drvier_home)) { ++ if (!util_support_d_type(driver_home)) { + ERROR("The backing %s filesystem is formatted without d_type support, which leads to incorrect behavior.", + driver->backing_fs); + ret = -1; +@@ -337,7 +354,7 @@ int overlay2_init(struct graphdriver *driver, const char *drvier_home, const cha + driver->support_dtype = true; + + if (!driver->overlay_opts->skip_mount_home) { +- if (util_ensure_mounted_as(drvier_home, "private") != 0) { ++ if (util_ensure_mounted_as(driver_home, "private") != 0) { + ret = -1; + goto out; + } +@@ -351,6 +368,7 @@ int overlay2_init(struct graphdriver *driver, const char *drvier_home, const cha + out: + free(link_dir); + free(root_dir); ++ free(userns_remap); + return ret; + } + +@@ -387,6 +405,7 @@ static int mk_diff_directory(const char *layer_dir) + { + int ret = 0; + char *diff_dir = NULL; ++ char* userns_remap = conf_get_isulad_userns_remap(); + + diff_dir = util_path_join(layer_dir, OVERLAY_LAYER_DIFF); + if (diff_dir == NULL) { +@@ -401,8 +420,15 @@ static int mk_diff_directory(const char *layer_dir) + goto out; + } + ++ if (set_file_owner_for_userns_remap(diff_dir, userns_remap) != 0) { ++ ERROR("Unable to change directory %s owner for user remap.", diff_dir); ++ ret = -1; ++ goto out; ++ } ++ + out: + free(diff_dir); ++ free(userns_remap); + return ret; + } + +@@ -488,6 +514,7 @@ static int mk_work_directory(const char *layer_dir) + { + int ret = 0; + char *work_dir = NULL; ++ char* userns_remap = conf_get_isulad_userns_remap(); + + work_dir = util_path_join(layer_dir, OVERLAY_LAYER_WORK); + if (work_dir == NULL) { +@@ -502,8 +529,15 @@ static int mk_work_directory(const char *layer_dir) + goto out; + } + ++ if (set_file_owner_for_userns_remap(work_dir, userns_remap) != 0) { ++ ERROR("Unable to change directory %s owner for user remap.", work_dir); ++ ret = -1; ++ goto out; ++ } ++ + out: + free(work_dir); ++ free(userns_remap); + return ret; + } + +@@ -511,6 +545,7 @@ static int mk_merged_directory(const char *layer_dir) + { + int ret = 0; + char *merged_dir = NULL; ++ char* userns_remap = conf_get_isulad_userns_remap(); + + merged_dir = util_path_join(layer_dir, OVERLAY_LAYER_MERGED); + if (merged_dir == NULL) { +@@ -525,8 +560,15 @@ static int mk_merged_directory(const char *layer_dir) + goto out; + } + ++ if (set_file_owner_for_userns_remap(merged_dir, userns_remap) != 0) { ++ ERROR("Unable to change directory %s owner for user remap.", merged_dir); ++ ret = -1; ++ goto out; ++ } ++ + out: + free(merged_dir); ++ free(userns_remap); + return ret; + } + +@@ -780,6 +822,7 @@ static int do_create(const char *id, const char *parent, const struct graphdrive + { + int ret = 0; + char *layer_dir = NULL; ++ char* userns_remap = conf_get_isulad_userns_remap(); + + layer_dir = util_path_join(driver->home, id); + if (layer_dir == NULL) { +@@ -799,6 +842,12 @@ static int do_create(const char *id, const char *parent, const struct graphdrive + goto out; + } + ++ if (set_file_owner_for_userns_remap(layer_dir, userns_remap) != 0) { ++ ERROR("Unable to change directory %s owner for user remap.", layer_dir); ++ ret = -1; ++ goto out; ++ } ++ + if (create_opts->storage_opt != NULL && create_opts->storage_opt->len != 0) { + if (set_layer_quota(layer_dir, create_opts->storage_opt, driver) != 0) { + ERROR("Unable to set layer quota %s", layer_dir); +@@ -821,6 +870,7 @@ err_out: + + out: + free(layer_dir); ++ free(userns_remap); + return ret; + } + +@@ -1654,6 +1704,10 @@ out: + int overlay2_apply_diff(const char *id, const struct graphdriver *driver, const struct io_read_wrapper *content) + { + int ret = 0; ++ ++ unsigned int size = 0; ++ char* userns_remap = conf_get_isulad_userns_remap(); ++ + char *layer_dir = NULL; + char *layer_diff = NULL; + struct archive_options options = { 0 }; +@@ -1681,6 +1735,14 @@ int overlay2_apply_diff(const char *id, const struct graphdriver *driver, const + + options.whiteout_format = OVERLAY_WHITEOUT_FORMATE; + ++ if (userns_remap != NULL) { ++ if (util_parse_user_remap(userns_remap, &options.uid, &options.gid, &size)) { ++ ERROR("Failed to split string '%s'.", userns_remap); ++ ret = -1; ++ goto out; ++ } ++ } ++ + ret = archive_unpack(content, layer_diff, &options, &err); + if (ret != 0) { + ERROR("Failed to unpack to %s: %s", layer_diff, err); +@@ -1692,6 +1754,7 @@ out: + free(err); + free(layer_dir); + free(layer_diff); ++ free(userns_remap); + return ret; + } + +diff --git a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2/driver_overlay2.h b/src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2/driver_overlay2.h +index 5f3228f0..e14271b1 100644 +--- a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2/driver_overlay2.h ++++ b/src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2/driver_overlay2.h +@@ -33,7 +33,7 @@ struct io_read_wrapper; + extern "C" { + #endif + +-int overlay2_init(struct graphdriver *driver, const char *drvier_home, const char **options, size_t len); ++int overlay2_init(struct graphdriver *driver, const char *driver_home, const char **options, size_t len); + + bool overlay2_is_quota_options(struct graphdriver *driver, const char *option); + +diff --git a/src/daemon/modules/image/oci/storage/storage.c b/src/daemon/modules/image/oci/storage/storage.c +index 40fc15a8..87aad4de 100644 +--- a/src/daemon/modules/image/oci/storage/storage.c ++++ b/src/daemon/modules/image/oci/storage/storage.c +@@ -29,6 +29,7 @@ + #include "utils.h" + #include "utils_images.h" + #include "isula_libutils/log.h" ++#include "isulad_config.h" + #include "layer_store.h" + #include "image_store.h" + #include "rootfs_store.h" +@@ -939,6 +940,7 @@ static int check_module_init_opt(struct storage_module_init_options *opts) + static int make_storage_directory(struct storage_module_init_options *opts) + { + int ret = 0; ++ char* userns_remap = conf_get_isulad_userns_remap(); + + if (util_mkdir_p(opts->storage_root, IMAGE_STORE_PATH_MODE) != 0) { + SYSERROR("Failed to make %s", opts->storage_root); +@@ -946,6 +948,12 @@ static int make_storage_directory(struct storage_module_init_options *opts) + goto out; + } + ++ if (set_file_owner_for_userns_remap(opts->storage_root, userns_remap) != 0) { ++ ERROR("Unable to change directory %s owner for user remap.", opts->storage_root); ++ ret = -1; ++ goto out; ++ } ++ + if (util_mkdir_p(opts->storage_run_root, IMAGE_STORE_PATH_MODE) != 0) { + SYSERROR("Failed to make %s", opts->storage_run_root); + ret = -1; +@@ -953,6 +961,7 @@ static int make_storage_directory(struct storage_module_init_options *opts) + } + + out: ++ free(userns_remap); + return ret; + } + +diff --git a/src/daemon/modules/runtime/engines/engine.c b/src/daemon/modules/runtime/engines/engine.c +index 0f27db12..ff010dff 100644 +--- a/src/daemon/modules/runtime/engines/engine.c ++++ b/src/daemon/modules/runtime/engines/engine.c +@@ -121,6 +121,9 @@ void engine_operation_free(struct engine_operation *eop) + static int create_engine_root_path(const char *path) + { + int ret = -1; ++ char *tmp_path = NULL; ++ char *p = NULL; ++ char *userns_remap = NULL; + + if (path == NULL) { + return ret; +@@ -130,12 +133,38 @@ static int create_engine_root_path(const char *path) + ret = 0; + goto out; + } +- ret = util_mkdir_p(path, CONFIG_DIRECTORY_MODE); +- if (ret != 0) { ++ ++ if (util_mkdir_p(path, CONFIG_DIRECTORY_MODE) != 0) { + ERROR("Unable to create engine root path: %s", path); ++ goto out; ++ } ++ ++ userns_remap = conf_get_isulad_userns_remap(); ++ if (userns_remap != NULL) { ++ if (set_file_owner_for_userns_remap(path, userns_remap) != 0) { ++ ERROR("Unable to change directory %s owner for user remap.", path); ++ goto out; ++ } ++ ++ // find parent directory ++ tmp_path = util_strdup_s(path); ++ p = strrchr(tmp_path, '/'); ++ if (p == NULL) { ++ ERROR("Failed to find parent directory for %s", tmp_path); ++ goto out; ++ } ++ *p = '\0'; ++ ++ if (set_file_owner_for_userns_remap(tmp_path, userns_remap) != 0) { ++ ERROR("Unable to change directory %s owner for user remap.", tmp_path); ++ goto out; ++ } + } ++ ret = 0; + + out: ++ free(tmp_path); ++ free(userns_remap); + return ret; + } + +diff --git a/src/daemon/modules/spec/specs.c b/src/daemon/modules/spec/specs.c +index fc53bd14..6cd00121 100644 +--- a/src/daemon/modules/spec/specs.c ++++ b/src/daemon/modules/spec/specs.c +@@ -1483,6 +1483,14 @@ static int merge_share_network_namespace(oci_runtime_spec *oci_spec, const host_ + return ret; + } + ++static bool userns_remap_is_enabled(const oci_runtime_spec *oci_spec) ++{ ++ if (oci_spec->linux->uid_mappings != NULL && oci_spec->linux->gid_mappings != NULL) { ++ return true; ++ } ++ return false; ++} ++ + int merge_share_namespace(oci_runtime_spec *oci_spec, const host_config *host_spec, + const container_config_v2_common_config_network_settings *network_settings) + { +@@ -1497,13 +1505,7 @@ int merge_share_namespace(oci_runtime_spec *oci_spec, const host_config *host_sp + } + + // user +- if (merge_share_single_namespace(oci_spec, host_spec->userns_mode, TYPE_NAMESPACE_USER) != 0) { +- ret = -1; +- goto out; +- } +- +- // user remap +- if (host_spec->user_remap != NULL && merge_share_single_namespace(oci_spec, "user", TYPE_NAMESPACE_USER) != 0) { ++ if (userns_remap_is_enabled(oci_spec) && merge_share_single_namespace(oci_spec, "user", TYPE_NAMESPACE_USER) != 0) { + ret = -1; + goto out; + } +@@ -2076,6 +2078,7 @@ int merge_all_specs(host_config *host_spec, const char *real_rootfs, container_c + oci_runtime_spec *oci_spec) + { + int ret = 0; ++ char *userns_remap = conf_get_isulad_userns_remap(); + + ret = merge_root(oci_spec, real_rootfs, host_spec); + if (ret != 0) { +@@ -2133,10 +2136,18 @@ int merge_all_specs(host_config *host_spec, const char *real_rootfs, container_c + goto out; + } + +- ret = make_userns_remap(oci_spec, host_spec->user_remap); +- if (ret != 0) { +- ERROR("Failed to make user remap for container"); +- goto out; ++ if (!host_spec->system_container && !namespace_is_host(host_spec->userns_mode)) { ++ ret = make_userns_remap(oci_spec, userns_remap); ++ if (ret != 0) { ++ ERROR("Failed to make user remap for container"); ++ goto out; ++ } ++ } else { ++ ret = make_userns_remap(oci_spec, host_spec->user_remap); ++ if (ret != 0) { ++ ERROR("Failed to make user remap for container"); ++ goto out; ++ } + } + + ret = merge_oci_cgroups_path(v2_spec->id, oci_spec, host_spec); +@@ -2146,6 +2157,7 @@ int merge_all_specs(host_config *host_spec, const char *real_rootfs, container_c + } + + out: ++ free(userns_remap); + return ret; + } + +diff --git a/src/daemon/modules/spec/specs_mount.c b/src/daemon/modules/spec/specs_mount.c +index 6b6ac87d..f589bc3b 100644 +--- a/src/daemon/modules/spec/specs_mount.c ++++ b/src/daemon/modules/spec/specs_mount.c +@@ -2588,7 +2588,9 @@ static int prepare_share_shm(host_config *host_spec, container_config_v2_common_ + int nret = 0; + bool has_mount = false; + char *spath = NULL; +- ++ char *tmp_path = NULL; ++ char *p = NULL; ++ char *userns_remap = NULL; + // has mount for /dev/shm + if (has_mount_shm(host_spec, v2_spec)) { + return 0; +@@ -2623,6 +2625,36 @@ static int prepare_share_shm(host_config *host_spec, container_config_v2_common_ + } + + v2_spec->shm_path = spath; ++ userns_remap = conf_get_isulad_userns_remap(); ++ ++ if (host_spec->user_remap == NULL && userns_remap != NULL) { ++ // find parent directory ++ tmp_path = util_strdup_s(spath); ++ p = strrchr(tmp_path, '/'); ++ if (p == NULL) { ++ ERROR("Failed to find parent directory for %s", tmp_path); ++ goto out; ++ } ++ *p = '\0'; ++ ++ if (set_file_owner_for_userns_remap(tmp_path, userns_remap) != 0) { ++ ERROR("Unable to change directory %s owner for user remap.", tmp_path); ++ goto out; ++ } ++ ++ p = strrchr(tmp_path, '/'); ++ if (p == NULL) { ++ ERROR("Failed to find parent directory for %s", tmp_path); ++ goto out; ++ } ++ *p = '\0'; ++ ++ if (set_file_owner_for_userns_remap(tmp_path, userns_remap) != 0) { ++ ERROR("Unable to change directory %s owner for user remap.", tmp_path); ++ goto out; ++ } ++ } ++ + spath = NULL; + ret = 0; + out: +@@ -2630,6 +2662,8 @@ out: + (void)umount(spath); + } + free(spath); ++ free(tmp_path); ++ free(userns_remap); + return ret; + } + +diff --git a/src/daemon/modules/volume/local.c b/src/daemon/modules/volume/local.c +index a80a5eca..def2623d 100644 +--- a/src/daemon/modules/volume/local.c ++++ b/src/daemon/modules/volume/local.c +@@ -23,6 +23,7 @@ + #include + + #include "isula_libutils/log.h" ++#include "isulad_config.h" + #include "volume_api.h" + #include "utils.h" + #include "map.h" +@@ -156,6 +157,7 @@ out: + static int init_volume_root_dir(struct volumes_info *vols_info, char *root_dir) + { + int ret = 0; ++ char *userns_remap = conf_get_isulad_userns_remap(); + + ret = util_mkdir_p(root_dir, LOCAL_VOLUME_ROOT_DIR_MODE); + if (ret != 0) { +@@ -163,10 +165,16 @@ static int init_volume_root_dir(struct volumes_info *vols_info, char *root_dir) + goto out; + } + ++ if (set_file_owner_for_userns_remap(root_dir, userns_remap) != 0) { ++ ERROR("Unable to change directory %s owner for user remap.", root_dir); ++ ret = -1; ++ goto out; ++ } ++ + vols_info->root_dir = util_strdup_s(root_dir); + + out: +- ++ free(userns_remap); + return ret; + } + +diff --git a/src/utils/cutils/utils_file.c b/src/utils/cutils/utils_file.c +index dbdd70f2..e087d92f 100644 +--- a/src/utils/cutils/utils_file.c ++++ b/src/utils/cutils/utils_file.c +@@ -2096,3 +2096,28 @@ out: + + return ret; + } ++ ++int set_file_owner_for_userns_remap(const char *filename, const char *userns_remap) ++{ ++ int ret = 0; ++ uid_t host_uid = 0; ++ gid_t host_gid = 0; ++ unsigned int size = 0; ++ ++ if (filename == NULL || userns_remap == NULL) { ++ goto out; ++ } ++ ++ if (util_parse_user_remap(userns_remap, &host_uid, &host_gid, &size)) { ++ ERROR("Failed to split string '%s'.", userns_remap); ++ ret = -1; ++ goto out; ++ } ++ if (chown(filename, host_uid, host_gid) != 0) { ++ ERROR("Failed to chown host path '%s'.", filename); ++ ret = -1; ++ } ++ ++out: ++ return ret; ++} +\ No newline at end of file +diff --git a/src/utils/cutils/utils_file.h b/src/utils/cutils/utils_file.h +index 1465ca7e..7b8c3ab4 100644 +--- a/src/utils/cutils/utils_file.h ++++ b/src/utils/cutils/utils_file.h +@@ -120,6 +120,7 @@ int util_list_all_entries(const char *directory, char ***out); + // 2. If fifo or socket exist in source, this function will return failure. + int util_copy_dir_recursive(char *copy_dst, char *copy_src); + ++int set_file_owner_for_userns_remap(const char *filename, const char *userns_remap); + #ifdef __cplusplus + } + #endif +diff --git a/src/utils/tar/util_archive.c b/src/utils/tar/util_archive.c +index 7d64e3aa..afb84a37 100644 +--- a/src/utils/tar/util_archive.c ++++ b/src/utils/tar/util_archive.c +@@ -524,6 +524,9 @@ int archive_unpack_handler(const struct io_read_wrapper *content, const struct a + + try_to_replace_exited_dst(dst_path, entry); + ++ archive_entry_set_uid(entry, options->uid); ++ archive_entry_set_gid(entry, options->gid); ++ + ret = archive_write_header(ext, entry); + if (ret != ARCHIVE_OK) { + ERROR("Fail to handle tar header: %s", archive_error_string(ext)); +diff --git a/src/utils/tar/util_archive.h b/src/utils/tar/util_archive.h +index 55fd7683..09fad03a 100644 +--- a/src/utils/tar/util_archive.h ++++ b/src/utils/tar/util_archive.h +@@ -41,6 +41,8 @@ typedef enum { + struct archive_options { + whiteout_format_type whiteout_format; + ++ uid_t uid; ++ gid_t gid; + // rename archive entry's name from src_base to dst_base + const char *src_base; + const char *dst_base; +-- +2.25.1 + diff --git a/0002-let-isulad-root-path-configable-when-userns-remap.patch b/0002-let-isulad-root-path-configable-when-userns-remap.patch new file mode 100644 index 0000000..9f5a2ae --- /dev/null +++ b/0002-let-isulad-root-path-configable-when-userns-remap.patch @@ -0,0 +1,93 @@ +From 479c9aa76830236abb135558b57363f8226dba2e Mon Sep 17 00:00:00 2001 +From: WangFengTu +Date: Sat, 26 Feb 2022 08:55:51 +0800 +Subject: [PATCH 2/2] let isulad root path configable when userns-remap + +Signed-off-by: WangFengTu +--- + src/cmd/isulad/main.c | 16 ++++++++-------- + src/daemon/modules/runtime/engines/engine.c | 10 +++++++--- + 2 files changed, 15 insertions(+), 11 deletions(-) + +diff --git a/src/cmd/isulad/main.c b/src/cmd/isulad/main.c +index b6132e12..b4e25988 100644 +--- a/src/cmd/isulad/main.c ++++ b/src/cmd/isulad/main.c +@@ -695,7 +695,7 @@ static int update_graph_for_userns_remap(struct service_arguments *args) + goto out; + } + +- nret = snprintf(graph, sizeof(graph), "%s/%d.%d", ISULAD_ROOT_PATH, host_uid, host_gid); ++ nret = snprintf(graph, sizeof(graph), "%s/%d.%d", args->json_confs->graph, host_uid, host_gid); + if (nret < 0 || (size_t)nret >= sizeof(graph)) { + ERROR("Path is too long"); + ret = -1; +@@ -1154,6 +1154,7 @@ static int isulad_server_pre_init(const struct service_arguments *args, const ch + { + int ret = 0; + char* userns_remap = conf_get_isulad_userns_remap(); ++ mode_t mode = CONFIG_DIRECTORY_MODE; + + if (check_and_save_pid(args->json_confs->pidfile) != 0) { + ERROR("Failed to save pid"); +@@ -1172,19 +1173,18 @@ static int isulad_server_pre_init(const struct service_arguments *args, const ch + goto out; + } + +- if (util_mkdir_p(args->json_confs->graph, CONFIG_DIRECTORY_MODE) != 0) { ++ if (userns_remap != NULL) { ++ mode = USER_REMAP_DIRECTORY_MODE; ++ } ++ ++ ret = util_mkdir_p(args->json_confs->graph, mode); ++ if (ret != 0) { + ERROR("Unable to create root directory %s.", args->json_confs->graph); + ret = -1; + goto out; + } + + if (userns_remap != NULL) { +- if (chmod(ISULAD_ROOT_PATH, USER_REMAP_DIRECTORY_MODE) != 0) { +- ERROR("Failed to chmod isulad root dir '%s' for user remap", ISULAD_ROOT_PATH); +- ret = -1; +- goto out; +- } +- + if (set_file_owner_for_userns_remap(args->json_confs->graph, userns_remap) != 0) { + ERROR("Unable to change root directory %s owner for user remap.", args->json_confs->graph); + ret = -1; +diff --git a/src/daemon/modules/runtime/engines/engine.c b/src/daemon/modules/runtime/engines/engine.c +index ff010dff..648711eb 100644 +--- a/src/daemon/modules/runtime/engines/engine.c ++++ b/src/daemon/modules/runtime/engines/engine.c +@@ -123,7 +123,8 @@ static int create_engine_root_path(const char *path) + int ret = -1; + char *tmp_path = NULL; + char *p = NULL; +- char *userns_remap = NULL; ++ char *userns_remap = conf_get_isulad_userns_remap(); ++ mode_t mode = CONFIG_DIRECTORY_MODE; + + if (path == NULL) { + return ret; +@@ -134,12 +135,15 @@ static int create_engine_root_path(const char *path) + goto out; + } + +- if (util_mkdir_p(path, CONFIG_DIRECTORY_MODE) != 0) { ++ if (userns_remap != NULL) { ++ mode = USER_REMAP_DIRECTORY_MODE; ++ } ++ ++ if (util_mkdir_p(path, mode) != 0) { + ERROR("Unable to create engine root path: %s", path); + goto out; + } + +- userns_remap = conf_get_isulad_userns_remap(); + if (userns_remap != NULL) { + if (set_file_owner_for_userns_remap(path, userns_remap) != 0) { + ERROR("Unable to change directory %s owner for user remap.", path); +-- +2.25.1 + diff --git a/iSulad.spec b/iSulad.spec index d53c2c0..2e638c9 100644 --- a/iSulad.spec +++ b/iSulad.spec @@ -1,5 +1,5 @@ %global _version 2.0.11 -%global _release 2 +%global _release 3 %global is_systemd 1 %global enable_shimv2 1 %global is_embedded 1 @@ -13,6 +13,9 @@ URL: https://gitee.com/openeuler/iSulad Source: https://gitee.com/openeuler/iSulad/repository/archive/v%{version}.tar.gz BuildRoot: {_tmppath}/iSulad-%{version} +Patch0001: 0001-iSulad-Add-the-function-of-isolating-the-user-namesp.patch +Patch0002: 0002-let-isulad-root-path-configable-when-userns-remap.patch + %ifarch x86_64 aarch64 Provides: libhttpclient.so()(64bit) Provides: libisula.so()(64bit) @@ -238,6 +241,12 @@ fi %endif %changelog +* Thu Mar 03 2022 wangfengtu - 2.0.11-3 +- Type: enhancement +- ID: NA +- SUG: NA +- DESC: Add the function of isolating the user namespaces + * Thu Mar 03 2022 wangfengtu - 2.0.11-2 - Type: enhancement - ID: NA