提交 32c9572a 编写于 作者: L lifeng68

selinux: support selinux mount label in image

Signed-off-by: Nlifeng68 <lifeng68@huawei.com>
上级 e881e53c
......@@ -34,10 +34,6 @@ function isula_pull()
isula rm -f `isula ps -a -q`
isula rmi centos
isula pull centos &
isula pull centos
fn_check_eq "$?" "0" "isula pull centos"
isula pull hub-mirror.c.163.com/library/busybox
fn_check_eq "$?" "0" "isula pull hub-mirror.c.163.com/library/busybox"
......
......@@ -1071,3 +1071,94 @@ int get_disable_security_opt(char ***labels, size_t *labels_len)
return 0;
}
#define MOUNT_CONTEXT "context="
static char *fill_selinux_label_with_src(const char *src, const char *mount_label)
{
int nret = 0;
char *result = NULL;
size_t data_size = 0;
if (strlen(mount_label) >= (INT_MAX - strlen(src) - strlen(MOUNT_CONTEXT) - 4)) {
ERROR("mount_label string too large");
goto err_out;
}
data_size = strlen(src) + 1 + strlen(MOUNT_CONTEXT) + 2 + strlen(mount_label) + 1;
result = util_common_calloc_s(data_size);
if (result == NULL) {
ERROR("Memory out");
goto err_out;
}
nret = snprintf(result, data_size, "%s,%s\"%s\"", src, MOUNT_CONTEXT, mount_label);
if (nret < 0 || (size_t)nret >= data_size) {
ERROR("failed to snprintf selinux label");
goto err_out;
}
goto out;
err_out:
free(result);
result = NULL;
out:
return result;
}
static char *fill_selinux_label_without_src(const char *mount_label)
{
int nret = 0;
char *result = NULL;
size_t data_size = 0;
if (strlen(mount_label) >= (INT_MAX - strlen(MOUNT_CONTEXT) - 3)) {
ERROR("mount_label string too large");
goto err_out;
}
data_size = strlen(MOUNT_CONTEXT) + strlen(mount_label) + 3;
result = util_common_calloc_s(data_size);
if (result == NULL) {
ERROR("Memory out");
goto err_out;
}
nret = snprintf(result, data_size, "%s\"%s\"", MOUNT_CONTEXT, mount_label);
if (nret < 0 || (size_t)nret >= data_size) {
ERROR("failed to snprintf selinux label");
goto err_out;
}
goto out;
err_out:
free(result);
result = NULL;
out:
return result;
}
char *selinux_format_mountlabel(const char *src, const char *mount_label)
{
char *result = NULL;
if (src == NULL && mount_label == NULL) {
return NULL;
}
if (src != NULL && mount_label != NULL) {
result = fill_selinux_label_with_src(src, mount_label);
} else if (src == NULL) {
result = fill_selinux_label_without_src(mount_label);
} else {
result = util_strdup_s(src);
}
return result;
}
\ No newline at end of file
......@@ -30,6 +30,7 @@ int init_label(const char **label_opts, size_t label_opts_len, char **process_la
int relabel(const char *path, const char *file_label, bool shared);
int get_disable_security_opt(char ***labels, size_t *labels_len);
int dup_security_opt(const char *src, char ***dst, size_t *len);
char *selinux_format_mountlabel(const char *src, const char *mount_label);
#ifdef __cplusplus
}
......
......@@ -189,6 +189,7 @@ typedef struct {
char *image_name;
char *container_id;
char *rootfs; // only used for external image type
char *mount_label; // mount label for selinux
json_map_string_string *storage_opt;
} im_prepare_request;
......
......@@ -65,6 +65,7 @@ add_library(${LIB_ISULAD_IMG} ${LIBTYPE}
${CMAKE_SOURCE_DIR}/src/utils/cutils/map/rb_tree.c
${CMAKE_SOURCE_DIR}/src/utils/sha256/sha256.c
${CMAKE_SOURCE_DIR}/src/daemon/common/err_msg.c
${CMAKE_SOURCE_DIR}/src/daemon/common/selinux_label.c
${CMAKE_SOURCE_DIR}/src/daemon/config/isulad_config.c
${CMAKE_SOURCE_DIR}/src/daemon/config/daemon_arguments.c
${CMAKE_SOURCE_DIR}/src/daemon/common/sysinfo.c
......@@ -93,6 +94,7 @@ target_link_libraries(${LIB_ISULAD_IMG}
${ISULA_LIBUTILS_LIBRARY}
${DEVMAPPER_LIBRARY}
${LIBTAR_LIBRARY}
${SELINUX_LIBRARY}
-lpthread -lcrypto -larchive -lz libhttpclient)
install(TARGETS ${LIB_ISULAD_IMG}
......
......@@ -453,6 +453,9 @@ void free_im_prepare_request(im_prepare_request *request)
free(request->image_type);
request->image_type = NULL;
free(request->mount_label);
request->mount_label = NULL;
free_json_map_string_string(request->storage_opt);
request->storage_opt = NULL;
......
......@@ -161,7 +161,8 @@ int oci_prepare_rf(const im_prepare_request *request, char **real_rootfs)
return -1;
}
if (storage_rootfs_create(request->container_id, request->image_name, request->storage_opt, real_rootfs) != 0) {
if (storage_rootfs_create(request->container_id, request->image_name, request->mount_label, request->storage_opt,
real_rootfs) != 0) {
ERROR("Failed to create container rootfs:%s", request->container_id);
isulad_set_error_message("Failed to create container rootfs:%s", request->container_id);
ret = -1;
......
......@@ -46,6 +46,7 @@
#include "utils_fs.h"
#include "utils_string.h"
#include "utils_verify.h"
#include "selinux_label.h"
#define DM_LOG_FATAL 2
#define DM_LOG_DEBUG 7
......@@ -2810,6 +2811,7 @@ static char *generate_mount_options(const struct driver_mount_opts *moptions, co
char *res_str = NULL;
char *options = NULL;
bool add_nouuid = false;
char *tmp = NULL;
options = util_strdup_s(dev_options);
if (moptions != NULL && moptions->options_len > 0) {
......@@ -2823,6 +2825,23 @@ static char *generate_mount_options(const struct driver_mount_opts *moptions, co
append_mount_options(&res_str, options);
if (moptions != NULL && moptions->mount_label != NULL) {
tmp = selinux_format_mountlabel(res_str, moptions->mount_label);
if (tmp == NULL) {
goto error_out;
}
free(res_str);
res_str = tmp;
tmp = NULL;
}
goto out;
error_out:
free(res_str);
res_str = NULL;
out:
free(options);
return res_str;
}
......
......@@ -39,6 +39,7 @@
#include "utils_fs.h"
#include "utils_string.h"
#include "utils_timestamp.h"
#include "selinux_label.h"
struct io_read_wrapper;
......@@ -622,6 +623,11 @@ static char *get_lower(const char *parent, const char *driver_home)
}
lower = util_common_calloc_s(lower_len);
if (lower == NULL) {
ERROR("Memory out");
goto err_out;
}
if (parent_lowers != NULL) {
nret = snprintf(lower, lower_len, "%s/%s:%s", OVERLAY_LINK_DIR, parent_link, parent_lowers);
} else {
......@@ -1118,6 +1124,10 @@ static char *get_mount_opt_data_with_custom_option(size_t cur_size, const char *
data_size = cur_size + strlen(custom_opts) + 1;
mount_data = util_common_calloc_s(data_size);
if (mount_data == NULL) {
ERROR("Memory out");
goto error_out;
}
nret = snprintf(mount_data, data_size, "%s,%s", custom_opts, cur_opts);
if (nret < 0 || (size_t)nret >= data_size) {
......@@ -1149,6 +1159,10 @@ static char *get_mount_opt_data_with_driver_option(size_t cur_size, const char *
data_size = cur_size + strlen(mount_opts) + 1;
mount_data = util_common_calloc_s(data_size);
if (mount_data == NULL) {
ERROR("Memory out");
goto error_out;
}
nret = snprintf(mount_data, data_size, "%s,%s", mount_opts, cur_opts);
if (nret < 0 || (size_t)nret >= data_size) {
......@@ -1197,6 +1211,10 @@ static char *get_abs_mount_opt_data(const char *layer_dir, const char *abs_lower
strlen(",workdir=") + strlen(work_dir) + 1;
mount_data = util_common_calloc_s(data_size);
if (mount_data == NULL) {
ERROR("Memory out");
goto error_out;
}
nret = snprintf(mount_data, data_size, "lowerdir=%s,upperdir=%s,workdir=%s", abs_lower_dir, upper_dir, work_dir);
if (nret < 0 || (size_t)nret >= data_size) {
......@@ -1211,6 +1229,7 @@ static char *get_abs_mount_opt_data(const char *layer_dir, const char *abs_lower
}
free(mount_data);
mount_data = tmp;
tmp = NULL;
} else if (driver->overlay_opts->mount_options != NULL) {
tmp = get_mount_opt_data_with_driver_option(data_size, mount_data, driver->overlay_opts->mount_options);
if (tmp == NULL) {
......@@ -1218,6 +1237,17 @@ static char *get_abs_mount_opt_data(const char *layer_dir, const char *abs_lower
}
free(mount_data);
mount_data = tmp;
tmp = NULL;
}
if (mount_opts != NULL && mount_opts->mount_label != NULL) {
tmp = selinux_format_mountlabel(mount_data, mount_opts->mount_label);
if (tmp == NULL) {
goto error_out;
}
free(mount_data);
mount_data = tmp;
tmp = NULL;
}
goto out;
......@@ -1263,6 +1293,10 @@ static char *get_rel_mount_opt_data(const char *id, const char *rel_lower_dir, c
strlen(",workdir=") + strlen(work_dir) + 1;
mount_data = util_common_calloc_s(data_size);
if (mount_data == NULL) {
ERROR("Memory out");
goto error_out;
}
nret = snprintf(mount_data, data_size, "lowerdir=%s,upperdir=%s,workdir=%s", rel_lower_dir, upper_dir, work_dir);
if (nret < 0 || (size_t)nret >= data_size) {
......@@ -1277,6 +1311,7 @@ static char *get_rel_mount_opt_data(const char *id, const char *rel_lower_dir, c
}
free(mount_data);
mount_data = tmp;
tmp = NULL;
} else if (driver->overlay_opts->mount_options != NULL) {
tmp = get_mount_opt_data_with_driver_option(data_size, mount_data, driver->overlay_opts->mount_options);
if (tmp == NULL) {
......@@ -1284,6 +1319,17 @@ static char *get_rel_mount_opt_data(const char *id, const char *rel_lower_dir, c
}
free(mount_data);
mount_data = tmp;
tmp = NULL;
}
if (mount_opts != NULL && mount_opts->mount_label != NULL) {
tmp = selinux_format_mountlabel(mount_data, mount_opts->mount_label);
if (tmp == NULL) {
goto error_out;
}
free(mount_data);
mount_data = tmp;
tmp = NULL;
}
goto out;
......
......@@ -129,7 +129,7 @@ out:
return ret;
}
static struct layer_opts *fill_create_layer_opts(storage_layer_create_opts_t *copts)
static struct layer_opts *fill_create_layer_opts(storage_layer_create_opts_t *copts, const char *mount_label)
{
struct layer_opts *opts = NULL;
......@@ -144,12 +144,15 @@ static struct layer_opts *fill_create_layer_opts(storage_layer_create_opts_t *co
opts->compressed_digest = util_strdup_s(copts->compressed_digest);
opts->writable = copts->writable;
opts->opts = util_common_calloc_s(sizeof(struct layer_store_mount_opts));
if (opts->opts == NULL) {
ERROR("Memory out");
goto err_out;
}
opts->opts->mount_label = util_strdup_s(mount_label);
if (copts->storage_opts != NULL) {
opts->opts = util_common_calloc_s(sizeof(struct layer_store_mount_opts));
if (opts->opts == NULL) {
ERROR("Memory out");
goto err_out;
}
opts->opts->mount_opts = util_common_calloc_s(sizeof(json_map_string_string));
if (opts->opts->mount_opts == NULL) {
ERROR("Memory out");
......@@ -194,7 +197,7 @@ int storage_layer_create(const char *layer_id, storage_layer_create_opts_t *copt
goto out;
}
opts = fill_create_layer_opts(copts);
opts = fill_create_layer_opts(copts, NULL);
if (opts == NULL) {
ERROR("Failed to fill create ro layer options");
ret = -1;
......@@ -984,7 +987,7 @@ void free_layer_list(struct layer_list *ptr)
free(ptr);
}
static int do_create_container_rw_layer(const char *container_id, const char *image_top_layer,
static int do_create_container_rw_layer(const char *container_id, const char *image_top_layer, const char *mount_label,
json_map_string_string *storage_opts)
{
int ret = 0;
......@@ -996,7 +999,7 @@ static int do_create_container_rw_layer(const char *container_id, const char *im
.storage_opts = storage_opts,
};
opts = fill_create_layer_opts(&copts);
opts = fill_create_layer_opts(&copts, mount_label);
if (opts == NULL) {
ERROR("Failed to fill create opts");
ret = -1;
......@@ -1014,7 +1017,8 @@ out:
return ret;
}
int storage_rootfs_create(const char *container_id, const char *image, json_map_string_string *storage_opts,
int storage_rootfs_create(const char *container_id, const char *image, const char *mount_label,
json_map_string_string *storage_opts,
char **mountpoint)
{
int ret = 0;
......@@ -1042,7 +1046,7 @@ int storage_rootfs_create(const char *container_id, const char *image, json_map_
}
// note: we use container id as the layer id of the container
if (do_create_container_rw_layer(container_id, image_info->top_layer, storage_opts) != 0) {
if (do_create_container_rw_layer(container_id, image_info->top_layer, mount_label, storage_opts) != 0) {
ERROR("Failed to do create rootfs layer");
ret = -1;
goto unlock_out;
......
......@@ -161,7 +161,8 @@ void free_layer(struct layer *l);
void free_layer_list(struct layer_list *ptr);
/* container rootfs operations */
int storage_rootfs_create(const char *container_id, const char *image, json_map_string_string *storage_opts,
int storage_rootfs_create(const char *container_id, const char *image, const char *mount_label,
json_map_string_string *storage_opts,
char **mountpoint);
int storage_rootfs_delete(const char *container_id);
......
......@@ -20,6 +20,7 @@ add_executable(${DRIVER_EXE}
${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/tar/util_archive.c
${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/sha256/sha256.c
${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/common/err_msg.c
${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/common/selinux_label.c
${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/layer_store/graphdriver/driver.c
${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/layer_store/graphdriver/devmapper/deviceset.c
${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/layer_store/graphdriver/devmapper/driver_devmapper.c
......@@ -58,7 +59,7 @@ target_link_libraries(${DRIVER_EXE}
${CMAKE_THREAD_LIBS_INIT}
${ISULA_LIBUTILS_LIBRARY}
${LIBTAR_LIBRARY}
-lwebsockets -lcrypto -lyajl -larchive -ldevmapper -lz)
-lwebsockets -lcrypto -lyajl -larchive ${SELINUX_LIBRARY} -ldevmapper -lz)
add_test(NAME ${DRIVER_EXE} COMMAND ${DRIVER_EXE})
......@@ -132,5 +133,5 @@ target_link_libraries(${EXE}
${GMOCK_LIBRARY}
${GMOCK_MAIN_LIBRARY}
${CMAKE_THREAD_LIBS_INIT}
-lwebsockets -lcrypto -lyajl -larchive -ldevmapper -lz)
-lwebsockets -lcrypto -lyajl -larchive ${SELINUX_LIBRARY} -ldevmapper -lz)
]]
......@@ -202,7 +202,6 @@ TEST_F(StorageDriverUnitTest, test_graphdriver_mount_layer)
mount_opts = (struct driver_mount_opts *)malloc(sizeof(struct driver_mount_opts));
ASSERT_NE(mount_opts, nullptr);
mount_opts->mount_label = strdup("mount_label");
mount_opts->options = (char **)malloc(1 * sizeof(char *));
mount_opts->options[0] = strdup("ro");
mount_opts->options_len = 1;
......
......@@ -17,7 +17,7 @@ add_executable(${EXE}
${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/utils/cutils/map/rb_tree.c
${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/common/err_msg.c
${CMAKE_CURRENT_SOURCE_DIR}/../../../mocks/namespace_mock.cc
${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/spec//selinux_label.c
${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/common/selinux_label.c
selinux_label_ut.cpp)
add_executable(${MOCK_EXE}
......@@ -36,7 +36,7 @@ add_executable(${MOCK_EXE}
${CMAKE_CURRENT_SOURCE_DIR}/../../../mocks/namespace_mock.cc
${CMAKE_CURRENT_SOURCE_DIR}/../../../mocks/syscall_mock.cc
${CMAKE_CURRENT_SOURCE_DIR}/../../../mocks/selinux_mock.cc
${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/spec//selinux_label.c
${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/common/selinux_label.c
selinux_label_mock_ut.cpp)
target_include_directories(${EXE} PUBLIC
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册