1232 lines
44 KiB
Diff
1232 lines
44 KiB
Diff
|
|
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 <string.h>
|
||
|
|
|
||
|
|
#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 <strings.h>
|
||
|
|
|
||
|
|
#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 <sys/stat.h>
|
||
|
|
|
||
|
|
#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
|
||
|
|
|