1057 lines
34 KiB
Diff
1057 lines
34 KiB
Diff
|
|
From e84112fd7128e05a1a4a380d8242c672d1f539f9 Mon Sep 17 00:00:00 2001
|
||
|
|
From: xuxuepeng <xuxuepeng1@huawei.com>
|
||
|
|
Date: Mon, 13 Nov 2023 08:44:15 +0000
|
||
|
|
Subject: [PATCH 09/14] !2243 Refactor capbilities specs * Refactor capbilities
|
||
|
|
specs
|
||
|
|
|
||
|
|
---
|
||
|
|
src/cmd/isula/isula_host_spec.c | 1 +
|
||
|
|
src/daemon/modules/spec/specs.c | 12 +-
|
||
|
|
src/daemon/modules/spec/specs_security.c | 140 ++++----
|
||
|
|
src/utils/cutils/utils_cap.c | 119 +++++++
|
||
|
|
src/utils/cutils/utils_cap.h | 39 +++
|
||
|
|
src/utils/cutils/utils_verify.c | 81 -----
|
||
|
|
src/utils/cutils/utils_verify.h | 6 -
|
||
|
|
test/cutils/utils_verify/utils_verify_ut.cc | 14 -
|
||
|
|
.../image/oci/oci_config_merge/CMakeLists.txt | 1 +
|
||
|
|
test/image/oci/storage/images/CMakeLists.txt | 1 +
|
||
|
|
test/specs/specs/CMakeLists.txt | 1 +
|
||
|
|
test/specs/specs/oci_runtime_spec.json | 32 ++
|
||
|
|
test/specs/specs/specs_ut.cc | 315 ++++++++++++++++++
|
||
|
|
test/specs/specs_extend/CMakeLists.txt | 1 +
|
||
|
|
14 files changed, 573 insertions(+), 190 deletions(-)
|
||
|
|
create mode 100644 src/utils/cutils/utils_cap.c
|
||
|
|
create mode 100644 src/utils/cutils/utils_cap.h
|
||
|
|
|
||
|
|
diff --git a/src/cmd/isula/isula_host_spec.c b/src/cmd/isula/isula_host_spec.c
|
||
|
|
index 6f39588d..09dea271 100644
|
||
|
|
--- a/src/cmd/isula/isula_host_spec.c
|
||
|
|
+++ b/src/cmd/isula/isula_host_spec.c
|
||
|
|
@@ -36,6 +36,7 @@
|
||
|
|
#include "utils_file.h"
|
||
|
|
#include "utils_string.h"
|
||
|
|
#include "utils_verify.h"
|
||
|
|
+#include "utils_cap.h"
|
||
|
|
#include "opt_ulimit.h"
|
||
|
|
|
||
|
|
static bool parse_restart_policy(const char *policy, host_config_restart_policy **rp)
|
||
|
|
diff --git a/src/daemon/modules/spec/specs.c b/src/daemon/modules/spec/specs.c
|
||
|
|
index 95346603..cc49d85f 100644
|
||
|
|
--- a/src/daemon/modules/spec/specs.c
|
||
|
|
+++ b/src/daemon/modules/spec/specs.c
|
||
|
|
@@ -49,6 +49,7 @@
|
||
|
|
#include "utils_file.h"
|
||
|
|
#include "utils_string.h"
|
||
|
|
#include "utils_verify.h"
|
||
|
|
+#include "utils_cap.h"
|
||
|
|
|
||
|
|
#ifndef CLONE_NEWUTS
|
||
|
|
#define CLONE_NEWUTS 0x04000000
|
||
|
|
@@ -814,15 +815,16 @@ static int adapt_settings_for_privileged(oci_runtime_spec *oci_spec, bool privil
|
||
|
|
{
|
||
|
|
int ret = 0;
|
||
|
|
size_t all_caps_len = 0;
|
||
|
|
+ const char **all_caps = NULL;
|
||
|
|
|
||
|
|
if (!privileged) {
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
- all_caps_len = util_get_all_caps_len();
|
||
|
|
- if (oci_spec == NULL) {
|
||
|
|
- ret = -1;
|
||
|
|
- goto out;
|
||
|
|
+ all_caps = util_get_all_caps(&all_caps_len);
|
||
|
|
+ if (all_caps == NULL) {
|
||
|
|
+ ERROR("Failed to get all capabilities");
|
||
|
|
+ return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
clean_correlated_items(oci_spec);
|
||
|
|
@@ -838,7 +840,7 @@ static int adapt_settings_for_privileged(oci_runtime_spec *oci_spec, bool privil
|
||
|
|
goto out;
|
||
|
|
}
|
||
|
|
|
||
|
|
- ret = refill_oci_process_capabilities(&oci_spec->process->capabilities, g_all_caps, all_caps_len);
|
||
|
|
+ ret = refill_oci_process_capabilities(&oci_spec->process->capabilities, all_caps, all_caps_len);
|
||
|
|
if (ret != 0) {
|
||
|
|
ERROR("Failed to copy all capabilities");
|
||
|
|
ret = -1;
|
||
|
|
diff --git a/src/daemon/modules/spec/specs_security.c b/src/daemon/modules/spec/specs_security.c
|
||
|
|
index e78cc744..b34aec7c 100644
|
||
|
|
--- a/src/daemon/modules/spec/specs_security.c
|
||
|
|
+++ b/src/daemon/modules/spec/specs_security.c
|
||
|
|
@@ -37,6 +37,7 @@
|
||
|
|
#include "utils_array.h"
|
||
|
|
#include "utils_string.h"
|
||
|
|
#include "utils_verify.h"
|
||
|
|
+#include "utils_cap.h"
|
||
|
|
|
||
|
|
#define MAX_CAP_LEN 32
|
||
|
|
|
||
|
|
@@ -104,41 +105,31 @@ static int tweak_drops_capabilities(char ***new_caps, size_t *new_caps_len, char
|
||
|
|
size_t i = 0;
|
||
|
|
int ret = 0;
|
||
|
|
|
||
|
|
- if (util_strings_in_slice((const char **)drops, drops_len, "all")) {
|
||
|
|
- goto out;
|
||
|
|
+ if (basic_caps == NULL || basic_caps_len == 0) {
|
||
|
|
+ *new_caps = NULL;
|
||
|
|
+ *new_caps_len = 0;
|
||
|
|
+ return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
- for (i = 0; (basic_caps != NULL && i < basic_caps_len); i++) {
|
||
|
|
- // skip `all` already handled above
|
||
|
|
- if (!basic_caps[i] || !strcasecmp(basic_caps[i], "all")) {
|
||
|
|
- continue;
|
||
|
|
- }
|
||
|
|
-
|
||
|
|
- // if we don't drop `all`, add back all the non-dropped caps
|
||
|
|
+ for (i = 0; i < basic_caps_len; i++) {
|
||
|
|
if (!util_strings_in_slice((const char **)drops, drops_len, basic_caps[i] + strlen("CAP_"))) {
|
||
|
|
ret = append_capability(new_caps, new_caps_len, basic_caps[i]);
|
||
|
|
if (ret != 0) {
|
||
|
|
ERROR("Failed to append capabilities");
|
||
|
|
- ret = -1;
|
||
|
|
- goto out;
|
||
|
|
+ return -1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
-out:
|
||
|
|
- return ret;
|
||
|
|
+ return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
static int tweak_adds_capabilities(char ***new_caps, size_t *new_caps_len, const char **adds, size_t adds_len)
|
||
|
|
{
|
||
|
|
size_t i = 0;
|
||
|
|
- int ret = 0;
|
||
|
|
int nret = 0;
|
||
|
|
- size_t all_caps_len = 0;
|
||
|
|
char tmpcap[MAX_CAP_LEN] = { 0 };
|
||
|
|
|
||
|
|
- all_caps_len = util_get_all_caps_len();
|
||
|
|
-
|
||
|
|
for (i = 0; i < adds_len; i++) {
|
||
|
|
// skip `all` already handled above
|
||
|
|
if (strcasecmp(adds[i], "all") == 0) {
|
||
|
|
@@ -148,111 +139,92 @@ static int tweak_adds_capabilities(char ***new_caps, size_t *new_caps_len, const
|
||
|
|
nret = snprintf(tmpcap, sizeof(tmpcap), "CAP_%s", adds[i]);
|
||
|
|
if (nret < 0 || (size_t)nret >= sizeof(tmpcap)) {
|
||
|
|
ERROR("Failed to print string");
|
||
|
|
- ret = -1;
|
||
|
|
- goto out;
|
||
|
|
- }
|
||
|
|
- if (!util_strings_in_slice(g_all_caps, all_caps_len, tmpcap)) {
|
||
|
|
- ERROR("Unknown capability to add: '%s'", tmpcap);
|
||
|
|
- ret = -1;
|
||
|
|
- goto out;
|
||
|
|
+ return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
// add cap if not already in the list
|
||
|
|
if (!util_strings_in_slice((const char **)*new_caps, *new_caps_len, tmpcap)) {
|
||
|
|
- ret = append_capability(new_caps, new_caps_len, tmpcap);
|
||
|
|
- if (ret != 0) {
|
||
|
|
+ nret = append_capability(new_caps, new_caps_len, tmpcap);
|
||
|
|
+ if (nret != 0) {
|
||
|
|
ERROR("Failed to append capabilities");
|
||
|
|
- ret = -1;
|
||
|
|
- goto out;
|
||
|
|
+ return -1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
-out:
|
||
|
|
- return ret;
|
||
|
|
-}
|
||
|
|
-
|
||
|
|
-static bool valid_drops_cap(const char **drops, size_t drops_len)
|
||
|
|
-{
|
||
|
|
- int nret = 0;
|
||
|
|
- size_t i;
|
||
|
|
- size_t all_caps_len = 0;
|
||
|
|
- char tmpcap[MAX_CAP_LEN] = { 0 };
|
||
|
|
-
|
||
|
|
- all_caps_len = util_get_all_caps_len();
|
||
|
|
- // look for invalid cap in the drop list
|
||
|
|
- for (i = 0; i < drops_len; i++) {
|
||
|
|
- if (strcasecmp(drops[i], "all") == 0) {
|
||
|
|
- continue;
|
||
|
|
- }
|
||
|
|
-
|
||
|
|
- nret = snprintf(tmpcap, sizeof(tmpcap), "CAP_%s", drops[i]);
|
||
|
|
- if (nret < 0 || (size_t)nret >= sizeof(tmpcap)) {
|
||
|
|
- ERROR("Failed to print string");
|
||
|
|
- return false;
|
||
|
|
- }
|
||
|
|
- if (!util_strings_in_slice(g_all_caps, all_caps_len, tmpcap)) {
|
||
|
|
- ERROR("Unknown capability to drop: '%s'", drops[i]);
|
||
|
|
- return false;
|
||
|
|
- }
|
||
|
|
- }
|
||
|
|
-
|
||
|
|
- return true;
|
||
|
|
+ return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
// tweak_capabilities can tweak capabilities by adding or dropping capabilities
|
||
|
|
-// based on the basic capabilities.
|
||
|
|
+// based on the basic capabilities. The following are the priorities of the tweaks:
|
||
|
|
+// 1. if adds contains "all", then the basic capabilities will be ignored, and all capabilities will be added.
|
||
|
|
+// 2. if drops contains "all", all capabilities will be dropped.
|
||
|
|
+// 3. add individual capabilities in adds
|
||
|
|
+// 4. drop individual capabilities in drops.
|
||
|
|
+// The reason why we handle "all" first is that we can avoid the case that the individual capabilities are
|
||
|
|
+// not included by "all".
|
||
|
|
static int tweak_capabilities(char ***caps, size_t *caps_len, const char **adds, size_t adds_len, const char **drops,
|
||
|
|
size_t drops_len)
|
||
|
|
{
|
||
|
|
- size_t i;
|
||
|
|
- size_t all_caps_len = 0;
|
||
|
|
int ret = 0;
|
||
|
|
char **new_caps = NULL;
|
||
|
|
char **basic_caps = NULL;
|
||
|
|
+ const char **all_caps = NULL;
|
||
|
|
size_t new_caps_len = 0;
|
||
|
|
size_t basic_caps_len = 0;
|
||
|
|
+ size_t all_caps_len = 0;
|
||
|
|
+ bool add_all = false;
|
||
|
|
+ bool drop_all = false;
|
||
|
|
|
||
|
|
- all_caps_len = util_get_all_caps_len();
|
||
|
|
- if (!valid_drops_cap(drops, drops_len)) {
|
||
|
|
+ all_caps = util_get_all_caps(&all_caps_len);
|
||
|
|
+ if (all_caps == NULL) {
|
||
|
|
+ ERROR("Failed to get all capabilities");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
- if (util_strings_in_slice((const char **)adds, adds_len, "all")) {
|
||
|
|
- ret = copy_capabilities(&basic_caps, &basic_caps_len, g_all_caps, all_caps_len);
|
||
|
|
- } else {
|
||
|
|
+ add_all = util_strings_in_slice((const char **)adds, adds_len, "all");
|
||
|
|
+ drop_all = util_strings_in_slice((const char **)drops, drops_len, "all");
|
||
|
|
+
|
||
|
|
+
|
||
|
|
+ if (!add_all && !drop_all) {
|
||
|
|
+ // if neither add_all nor drop_all, we start with the default capabilities
|
||
|
|
ret = copy_capabilities(&basic_caps, &basic_caps_len, (const char **)*caps, *caps_len);
|
||
|
|
- }
|
||
|
|
- if (ret != 0) {
|
||
|
|
- ERROR("Failed to copy capabilities");
|
||
|
|
- ret = -1;
|
||
|
|
- goto free_out;
|
||
|
|
+ if (ret != 0) {
|
||
|
|
+ ERROR("Failed to copy capabilities");
|
||
|
|
+ ret = -1;
|
||
|
|
+ goto free_out;
|
||
|
|
+ }
|
||
|
|
+ } else if (drop_all) {
|
||
|
|
+ // if drop_all, we start with an empty set
|
||
|
|
+ basic_caps = NULL;
|
||
|
|
+ basic_caps_len = 0;
|
||
|
|
+ } else {
|
||
|
|
+ // if not drop_all but add_all, we start with all capabilities
|
||
|
|
+ ret = copy_capabilities(&basic_caps, &basic_caps_len, all_caps, all_caps_len);
|
||
|
|
+ if (ret != 0) {
|
||
|
|
+ ERROR("Failed to copy all capabilities");
|
||
|
|
+ ret = -1;
|
||
|
|
+ goto free_out;
|
||
|
|
+ }
|
||
|
|
}
|
||
|
|
|
||
|
|
- ret = tweak_drops_capabilities(&new_caps, &new_caps_len, basic_caps, basic_caps_len, drops, drops_len);
|
||
|
|
+ // Add capabilities to the basic capabilities
|
||
|
|
+ ret = tweak_adds_capabilities(&basic_caps, &basic_caps_len, adds, adds_len);
|
||
|
|
if (ret != 0) {
|
||
|
|
ret = -1;
|
||
|
|
goto free_out;
|
||
|
|
}
|
||
|
|
|
||
|
|
- ret = tweak_adds_capabilities(&new_caps, &new_caps_len, adds, adds_len);
|
||
|
|
+ // Drop capabilities from the basic capabilities
|
||
|
|
+ ret = tweak_drops_capabilities(&new_caps, &new_caps_len, basic_caps, basic_caps_len, drops, drops_len);
|
||
|
|
if (ret != 0) {
|
||
|
|
ret = -1;
|
||
|
|
goto free_out;
|
||
|
|
}
|
||
|
|
|
||
|
|
free_out:
|
||
|
|
- for (i = 0; i < basic_caps_len; i++) {
|
||
|
|
- free(basic_caps[i]);
|
||
|
|
- }
|
||
|
|
- free(basic_caps);
|
||
|
|
-
|
||
|
|
- // free old caps
|
||
|
|
- for (i = 0; i < *caps_len; i++) {
|
||
|
|
- free((*caps)[i]);
|
||
|
|
- (*caps)[i] = NULL;
|
||
|
|
- }
|
||
|
|
- free(*caps);
|
||
|
|
+ util_free_array_by_len(basic_caps, basic_caps_len);
|
||
|
|
+ util_free_array_by_len(*caps, *caps_len);
|
||
|
|
|
||
|
|
// set new caps
|
||
|
|
*caps = new_caps;
|
||
|
|
diff --git a/src/utils/cutils/utils_cap.c b/src/utils/cutils/utils_cap.c
|
||
|
|
new file mode 100644
|
||
|
|
index 00000000..6473df45
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/src/utils/cutils/utils_cap.c
|
||
|
|
@@ -0,0 +1,119 @@
|
||
|
|
+/******************************************************************************
|
||
|
|
+ * Copyright (c) Huawei Technologies Co., Ltd. 2018-2022. 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.
|
||
|
|
+ * Author: xuxuepeng
|
||
|
|
+ * Create: 2023-11-08
|
||
|
|
+ * Description: provide capbilities utils functions
|
||
|
|
+ *******************************************************************************/
|
||
|
|
+
|
||
|
|
+#define _GNU_SOURCE
|
||
|
|
+
|
||
|
|
+#include "utils_cap.h"
|
||
|
|
+
|
||
|
|
+#include <stdint.h>
|
||
|
|
+#include <stdio.h>
|
||
|
|
+#include <isula_libutils/log.h>
|
||
|
|
+
|
||
|
|
+#include "utils_string.h"
|
||
|
|
+
|
||
|
|
+const char *g_all_caps[] = {
|
||
|
|
+ "CAP_CHOWN",
|
||
|
|
+ "CAP_DAC_OVERRIDE",
|
||
|
|
+ "CAP_DAC_READ_SEARCH",
|
||
|
|
+ "CAP_FOWNER",
|
||
|
|
+ "CAP_FSETID",
|
||
|
|
+ "CAP_KILL",
|
||
|
|
+ "CAP_SETGID",
|
||
|
|
+ "CAP_SETUID",
|
||
|
|
+ "CAP_SETPCAP",
|
||
|
|
+ "CAP_LINUX_IMMUTABLE",
|
||
|
|
+ "CAP_NET_BIND_SERVICE",
|
||
|
|
+ "CAP_NET_BROADCAST",
|
||
|
|
+ "CAP_NET_ADMIN",
|
||
|
|
+ "CAP_NET_RAW",
|
||
|
|
+ "CAP_IPC_LOCK",
|
||
|
|
+ "CAP_IPC_OWNER",
|
||
|
|
+ "CAP_SYS_MODULE",
|
||
|
|
+ "CAP_SYS_RAWIO",
|
||
|
|
+ "CAP_SYS_CHROOT",
|
||
|
|
+ "CAP_SYS_PTRACE",
|
||
|
|
+ "CAP_SYS_PACCT",
|
||
|
|
+ "CAP_SYS_ADMIN",
|
||
|
|
+ "CAP_SYS_BOOT",
|
||
|
|
+ "CAP_SYS_NICE",
|
||
|
|
+ "CAP_SYS_RESOURCE",
|
||
|
|
+ "CAP_SYS_TIME",
|
||
|
|
+ "CAP_SYS_TTY_CONFIG",
|
||
|
|
+ "CAP_MKNOD",
|
||
|
|
+ "CAP_LEASE",
|
||
|
|
+#ifdef CAP_AUDIT_WRITE
|
||
|
|
+ "CAP_AUDIT_WRITE",
|
||
|
|
+#endif
|
||
|
|
+#ifdef CAP_AUDIT_CONTROL
|
||
|
|
+ "CAP_AUDIT_CONTROL",
|
||
|
|
+#endif
|
||
|
|
+ "CAP_SETFCAP",
|
||
|
|
+ "CAP_MAC_OVERRIDE",
|
||
|
|
+ "CAP_MAC_ADMIN",
|
||
|
|
+#ifdef CAP_SYSLOG
|
||
|
|
+ "CAP_SYSLOG",
|
||
|
|
+#endif
|
||
|
|
+#ifdef CAP_WAKE_ALARM
|
||
|
|
+ "CAP_WAKE_ALARM",
|
||
|
|
+#endif
|
||
|
|
+#ifdef CAP_BLOCK_SUSPEND
|
||
|
|
+ "CAP_BLOCK_SUSPEND",
|
||
|
|
+#endif
|
||
|
|
+#ifdef CAP_AUDIT_READ
|
||
|
|
+ "CAP_AUDIT_READ",
|
||
|
|
+#endif
|
||
|
|
+#ifdef CAP_PERFMON
|
||
|
|
+ "CAP_PERFMON",
|
||
|
|
+#endif
|
||
|
|
+#ifdef CAP_BPF
|
||
|
|
+ "CAP_BPF",
|
||
|
|
+#endif
|
||
|
|
+#ifdef CAP_CHECKPOINT_RESTORE
|
||
|
|
+ "CAP_CHECKPOINT_RESTORE",
|
||
|
|
+#endif
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
+static inline size_t util_get_all_caps_len()
|
||
|
|
+{
|
||
|
|
+ return sizeof(g_all_caps) / sizeof(char *);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+bool util_valid_cap(const char *cap)
|
||
|
|
+{
|
||
|
|
+ int nret = 0;
|
||
|
|
+ char tmpcap[32] = { 0 };
|
||
|
|
+ size_t all_caps_len = util_get_all_caps_len();
|
||
|
|
+
|
||
|
|
+ if (cap == NULL) {
|
||
|
|
+ return false;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ nret = snprintf(tmpcap, sizeof(tmpcap), "CAP_%s", cap);
|
||
|
|
+ if (nret < 0 || (size_t)nret >= sizeof(tmpcap)) {
|
||
|
|
+ ERROR("Failed to print string");
|
||
|
|
+ return false;
|
||
|
|
+ }
|
||
|
|
+ if (!util_strings_in_slice(g_all_caps, all_caps_len, tmpcap)) {
|
||
|
|
+ return false;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return true;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+const char **util_get_all_caps(size_t *cap_len)
|
||
|
|
+{
|
||
|
|
+ *cap_len = util_get_all_caps_len();
|
||
|
|
+ return g_all_caps;
|
||
|
|
+}
|
||
|
|
diff --git a/src/utils/cutils/utils_cap.h b/src/utils/cutils/utils_cap.h
|
||
|
|
new file mode 100644
|
||
|
|
index 00000000..de63d070
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/src/utils/cutils/utils_cap.h
|
||
|
|
@@ -0,0 +1,39 @@
|
||
|
|
+/******************************************************************************
|
||
|
|
+ * Copyright (c) Huawei Technologies Co., Ltd. 2018-2022. 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.
|
||
|
|
+ * Author: xuxuepeng
|
||
|
|
+ * Create: 2023-11-08
|
||
|
|
+ * Description: provide capbilities utils functions
|
||
|
|
+ *******************************************************************************/
|
||
|
|
+
|
||
|
|
+#ifndef UTILS_CUTILS_UTILS_CAP_H
|
||
|
|
+#define UTILS_CUTILS_UTILS_CAP_H
|
||
|
|
+
|
||
|
|
+#ifdef __cplusplus
|
||
|
|
+extern "C" {
|
||
|
|
+#endif
|
||
|
|
+
|
||
|
|
+#include <stdbool.h>
|
||
|
|
+#include <stddef.h>
|
||
|
|
+#include <linux/capability.h>
|
||
|
|
+
|
||
|
|
+bool util_valid_cap(const char *cap);
|
||
|
|
+
|
||
|
|
+/**
|
||
|
|
+ * Get all supported capabilities for linux,
|
||
|
|
+ * note that the returned strings are unmutable
|
||
|
|
+ */
|
||
|
|
+const char **util_get_all_caps(size_t *cap_len);
|
||
|
|
+
|
||
|
|
+#ifdef __cplusplus
|
||
|
|
+}
|
||
|
|
+#endif
|
||
|
|
+
|
||
|
|
+#endif // UTILS_CUTILS_UTILS_CAP_H
|
||
|
|
diff --git a/src/utils/cutils/utils_verify.c b/src/utils/cutils/utils_verify.c
|
||
|
|
index 2f10f278..f4ce3199 100644
|
||
|
|
--- a/src/utils/cutils/utils_verify.c
|
||
|
|
+++ b/src/utils/cutils/utils_verify.c
|
||
|
|
@@ -22,7 +22,6 @@
|
||
|
|
#include <sys/stat.h>
|
||
|
|
#include <errno.h>
|
||
|
|
#include <fcntl.h>
|
||
|
|
-#include <linux/capability.h>
|
||
|
|
#include <stdio.h>
|
||
|
|
#include <strings.h>
|
||
|
|
|
||
|
|
@@ -32,59 +31,6 @@
|
||
|
|
#include "utils_array.h"
|
||
|
|
#include "utils_string.h"
|
||
|
|
|
||
|
|
-const char *g_all_caps[] = {
|
||
|
|
- "CAP_CHOWN",
|
||
|
|
- "CAP_DAC_OVERRIDE",
|
||
|
|
- "CAP_DAC_READ_SEARCH",
|
||
|
|
- "CAP_FOWNER",
|
||
|
|
- "CAP_FSETID",
|
||
|
|
- "CAP_KILL",
|
||
|
|
- "CAP_SETGID",
|
||
|
|
- "CAP_SETUID",
|
||
|
|
- "CAP_SETPCAP",
|
||
|
|
- "CAP_LINUX_IMMUTABLE",
|
||
|
|
- "CAP_NET_BIND_SERVICE",
|
||
|
|
- "CAP_NET_BROADCAST",
|
||
|
|
- "CAP_NET_ADMIN",
|
||
|
|
- "CAP_NET_RAW",
|
||
|
|
- "CAP_IPC_LOCK",
|
||
|
|
- "CAP_IPC_OWNER",
|
||
|
|
- "CAP_SYS_MODULE",
|
||
|
|
- "CAP_SYS_RAWIO",
|
||
|
|
- "CAP_SYS_CHROOT",
|
||
|
|
- "CAP_SYS_PTRACE",
|
||
|
|
- "CAP_SYS_PACCT",
|
||
|
|
- "CAP_SYS_ADMIN",
|
||
|
|
- "CAP_SYS_BOOT",
|
||
|
|
- "CAP_SYS_NICE",
|
||
|
|
- "CAP_SYS_RESOURCE",
|
||
|
|
- "CAP_SYS_TIME",
|
||
|
|
- "CAP_SYS_TTY_CONFIG",
|
||
|
|
- "CAP_MKNOD",
|
||
|
|
- "CAP_LEASE",
|
||
|
|
-#ifdef CAP_AUDIT_WRITE
|
||
|
|
- "CAP_AUDIT_WRITE",
|
||
|
|
-#endif
|
||
|
|
-#ifdef CAP_AUDIT_CONTROL
|
||
|
|
- "CAP_AUDIT_CONTROL",
|
||
|
|
-#endif
|
||
|
|
- "CAP_SETFCAP",
|
||
|
|
- "CAP_MAC_OVERRIDE",
|
||
|
|
- "CAP_MAC_ADMIN",
|
||
|
|
-#ifdef CAP_SYSLOG
|
||
|
|
- "CAP_SYSLOG",
|
||
|
|
-#endif
|
||
|
|
-#ifdef CAP_WAKE_ALARM
|
||
|
|
- "CAP_WAKE_ALARM",
|
||
|
|
-#endif
|
||
|
|
-#ifdef CAP_BLOCK_SUSPEND
|
||
|
|
- "CAP_BLOCK_SUSPEND",
|
||
|
|
-#endif
|
||
|
|
-#ifdef CAP_AUDIT_READ
|
||
|
|
- "CAP_AUDIT_READ",
|
||
|
|
-#endif
|
||
|
|
-};
|
||
|
|
-
|
||
|
|
bool util_valid_cmd_arg(const char *arg)
|
||
|
|
{
|
||
|
|
return (arg != NULL) && (strchr(arg, '|') == NULL) && (strchr(arg, '`') == NULL) && (strchr(arg, '&')) == NULL &&
|
||
|
|
@@ -215,33 +161,6 @@ bool util_valid_str(const char *str)
|
||
|
|
return (str != NULL && str[0] != '\0') ? true : false;
|
||
|
|
}
|
||
|
|
|
||
|
|
-size_t util_get_all_caps_len()
|
||
|
|
-{
|
||
|
|
- return sizeof(g_all_caps) / sizeof(char *);
|
||
|
|
-}
|
||
|
|
-
|
||
|
|
-bool util_valid_cap(const char *cap)
|
||
|
|
-{
|
||
|
|
- int nret = 0;
|
||
|
|
- char tmpcap[32] = { 0 };
|
||
|
|
- size_t all_caps_len = util_get_all_caps_len();
|
||
|
|
-
|
||
|
|
- if (cap == NULL) {
|
||
|
|
- return false;
|
||
|
|
- }
|
||
|
|
-
|
||
|
|
- nret = snprintf(tmpcap, sizeof(tmpcap), "CAP_%s", cap);
|
||
|
|
- if (nret < 0 || (size_t)nret >= sizeof(tmpcap)) {
|
||
|
|
- ERROR("Failed to print string");
|
||
|
|
- return false;
|
||
|
|
- }
|
||
|
|
- if (!util_strings_in_slice(g_all_caps, all_caps_len, tmpcap)) {
|
||
|
|
- return false;
|
||
|
|
- }
|
||
|
|
-
|
||
|
|
- return true;
|
||
|
|
-}
|
||
|
|
-
|
||
|
|
bool util_valid_container_id(const char *id)
|
||
|
|
{
|
||
|
|
char *patten = "^[a-f0-9]{1,64}$";
|
||
|
|
diff --git a/src/utils/cutils/utils_verify.h b/src/utils/cutils/utils_verify.h
|
||
|
|
index ad4466ef..54d1ce71 100644
|
||
|
|
--- a/src/utils/cutils/utils_verify.h
|
||
|
|
+++ b/src/utils/cutils/utils_verify.h
|
||
|
|
@@ -38,8 +38,6 @@ extern "C" {
|
||
|
|
|
||
|
|
#define VALID_VOLUME_NAME "[a-zA-Z0-9][a-zA-Z0-9_.-]{1,63}"
|
||
|
|
|
||
|
|
-extern const char *g_all_caps[];
|
||
|
|
-
|
||
|
|
bool util_valid_cmd_arg(const char *arg);
|
||
|
|
|
||
|
|
bool util_valid_signal(int sig);
|
||
|
|
@@ -54,10 +52,6 @@ bool util_valid_device_mode(const char *mode);
|
||
|
|
|
||
|
|
bool util_valid_str(const char *str);
|
||
|
|
|
||
|
|
-size_t util_get_all_caps_len();
|
||
|
|
-
|
||
|
|
-bool util_valid_cap(const char *cap);
|
||
|
|
-
|
||
|
|
bool util_valid_time_tz(const char *time);
|
||
|
|
|
||
|
|
bool util_valid_embedded_image_name(const char *name);
|
||
|
|
diff --git a/test/cutils/utils_verify/utils_verify_ut.cc b/test/cutils/utils_verify/utils_verify_ut.cc
|
||
|
|
index 99775d09..79670ec1 100644
|
||
|
|
--- a/test/cutils/utils_verify/utils_verify_ut.cc
|
||
|
|
+++ b/test/cutils/utils_verify/utils_verify_ut.cc
|
||
|
|
@@ -98,20 +98,6 @@ TEST(utils_verify, test_util_valid_str)
|
||
|
|
ASSERT_EQ(util_valid_str(nullptr), false);
|
||
|
|
}
|
||
|
|
|
||
|
|
-TEST(utils_verify, test_util_get_all_caps_len)
|
||
|
|
-{
|
||
|
|
- ASSERT_NE(util_get_all_caps_len(), 0);
|
||
|
|
-}
|
||
|
|
-
|
||
|
|
-TEST(utils_verify, test_util_valid_cap)
|
||
|
|
-{
|
||
|
|
- ASSERT_EQ(util_valid_cap("DAC_READ_SEARCH"), true);
|
||
|
|
-
|
||
|
|
- ASSERT_EQ(util_valid_cap(nullptr), false);
|
||
|
|
- ASSERT_EQ(util_valid_cap(""), false);
|
||
|
|
- ASSERT_EQ(util_valid_cap("DA_READ_SEARCH"), false);
|
||
|
|
-}
|
||
|
|
-
|
||
|
|
TEST(utils_verify, test_util_valid_time_tz)
|
||
|
|
{
|
||
|
|
ASSERT_EQ(util_valid_time_tz("2022-10-04T18:22:45.289257759Z"), true);
|
||
|
|
diff --git a/test/image/oci/oci_config_merge/CMakeLists.txt b/test/image/oci/oci_config_merge/CMakeLists.txt
|
||
|
|
index ce4df5ba..90809080 100644
|
||
|
|
--- a/test/image/oci/oci_config_merge/CMakeLists.txt
|
||
|
|
+++ b/test/image/oci/oci_config_merge/CMakeLists.txt
|
||
|
|
@@ -14,6 +14,7 @@ add_executable(${EXE}
|
||
|
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/utils/cutils/utils_file.c
|
||
|
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/utils/cutils/utils_timestamp.c
|
||
|
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/utils/cutils/utils_fs.c
|
||
|
|
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/utils/cutils/utils_cap.c
|
||
|
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/utils/cutils/map/map.c
|
||
|
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/utils/cutils/map/rb_tree.c
|
||
|
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/utils/cutils/util_atomic.c
|
||
|
|
diff --git a/test/image/oci/storage/images/CMakeLists.txt b/test/image/oci/storage/images/CMakeLists.txt
|
||
|
|
index 8446ebba..28e0b505 100644
|
||
|
|
--- a/test/image/oci/storage/images/CMakeLists.txt
|
||
|
|
+++ b/test/image/oci/storage/images/CMakeLists.txt
|
||
|
|
@@ -11,6 +11,7 @@ add_executable(${EXE}
|
||
|
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/cutils/utils_convert.c
|
||
|
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/cutils/utils_file.c
|
||
|
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/cutils/utils_base64.c
|
||
|
|
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/cutils/utils_cap.c
|
||
|
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/cutils/util_atomic.c
|
||
|
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/sha256/sha256.c
|
||
|
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/cutils/path.c
|
||
|
|
diff --git a/test/specs/specs/CMakeLists.txt b/test/specs/specs/CMakeLists.txt
|
||
|
|
index 1d627e37..a9dbc52c 100644
|
||
|
|
--- a/test/specs/specs/CMakeLists.txt
|
||
|
|
+++ b/test/specs/specs/CMakeLists.txt
|
||
|
|
@@ -14,6 +14,7 @@ add_executable(${EXE}
|
||
|
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/util_atomic.c
|
||
|
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_mount_spec.c
|
||
|
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_fs.c
|
||
|
|
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_cap.c
|
||
|
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/sha256/sha256.c
|
||
|
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/path.c
|
||
|
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/map/map.c
|
||
|
|
diff --git a/test/specs/specs/oci_runtime_spec.json b/test/specs/specs/oci_runtime_spec.json
|
||
|
|
index 0223fd6f..efd5da35 100644
|
||
|
|
--- a/test/specs/specs/oci_runtime_spec.json
|
||
|
|
+++ b/test/specs/specs/oci_runtime_spec.json
|
||
|
|
@@ -154,6 +154,38 @@
|
||
|
|
"CAP_SYS_CHROOT",
|
||
|
|
"CAP_KILL",
|
||
|
|
"CAP_AUDIT_WRITE"
|
||
|
|
+ ],
|
||
|
|
+ "effective": [
|
||
|
|
+ "CAP_CHOWN",
|
||
|
|
+ "CAP_DAC_OVERRIDE",
|
||
|
|
+ "CAP_FSETID",
|
||
|
|
+ "CAP_FOWNER",
|
||
|
|
+ "CAP_MKNOD",
|
||
|
|
+ "CAP_NET_RAW",
|
||
|
|
+ "CAP_SETGID",
|
||
|
|
+ "CAP_SETUID",
|
||
|
|
+ "CAP_SETFCAP",
|
||
|
|
+ "CAP_SETPCAP",
|
||
|
|
+ "CAP_NET_BIND_SERVICE",
|
||
|
|
+ "CAP_SYS_CHROOT",
|
||
|
|
+ "CAP_KILL",
|
||
|
|
+ "CAP_AUDIT_WRITE"
|
||
|
|
+ ],
|
||
|
|
+ "permitted": [
|
||
|
|
+ "CAP_CHOWN",
|
||
|
|
+ "CAP_DAC_OVERRIDE",
|
||
|
|
+ "CAP_FSETID",
|
||
|
|
+ "CAP_FOWNER",
|
||
|
|
+ "CAP_MKNOD",
|
||
|
|
+ "CAP_NET_RAW",
|
||
|
|
+ "CAP_SETGID",
|
||
|
|
+ "CAP_SETUID",
|
||
|
|
+ "CAP_SETFCAP",
|
||
|
|
+ "CAP_SETPCAP",
|
||
|
|
+ "CAP_NET_BIND_SERVICE",
|
||
|
|
+ "CAP_SYS_CHROOT",
|
||
|
|
+ "CAP_KILL",
|
||
|
|
+ "CAP_AUDIT_WRITE"
|
||
|
|
]
|
||
|
|
}
|
||
|
|
},
|
||
|
|
diff --git a/test/specs/specs/specs_ut.cc b/test/specs/specs/specs_ut.cc
|
||
|
|
index 96aa1c63..ad903a3f 100644
|
||
|
|
--- a/test/specs/specs/specs_ut.cc
|
||
|
|
+++ b/test/specs/specs/specs_ut.cc
|
||
|
|
@@ -20,6 +20,7 @@
|
||
|
|
#include "isula_libutils/oci_runtime_spec.h"
|
||
|
|
#include "specs_api.h"
|
||
|
|
#include "specs_namespace.h"
|
||
|
|
+#include "specs_security.h"
|
||
|
|
#include "isula_libutils/host_config.h"
|
||
|
|
#include "isula_libutils/container_config.h"
|
||
|
|
#include "oci_ut_common.h"
|
||
|
|
@@ -27,6 +28,7 @@
|
||
|
|
#include <gmock/gmock.h>
|
||
|
|
#include "isulad_config_mock.h"
|
||
|
|
#include "utils.h"
|
||
|
|
+#include "utils_cap.h"
|
||
|
|
|
||
|
|
using ::testing::Args;
|
||
|
|
using ::testing::ByRef;
|
||
|
|
@@ -344,3 +346,316 @@ TEST_F(SpecsUnitTest, test_merge_container_cgroups_path_5)
|
||
|
|
|
||
|
|
testing::Mock::VerifyAndClearExpectations(&m_isulad_conf);
|
||
|
|
}
|
||
|
|
+
|
||
|
|
+/********************************* UT for merge caps *******************************************/
|
||
|
|
+struct capabilities_lens {
|
||
|
|
+ size_t bounding_len;
|
||
|
|
+ size_t effective_len;
|
||
|
|
+ size_t inheritable_len;
|
||
|
|
+ size_t permitted_len;
|
||
|
|
+ size_t ambient_len;
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
+void check_capabilities_len(defs_process_capabilities *cap, struct capabilities_lens *lens)
|
||
|
|
+{
|
||
|
|
+ lens->bounding_len = cap->bounding_len;
|
||
|
|
+ lens->effective_len = cap->effective_len;
|
||
|
|
+ lens->inheritable_len = cap->inheritable_len;
|
||
|
|
+ lens->permitted_len = cap->permitted_len;
|
||
|
|
+ lens->ambient_len = cap->ambient_len;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+void validate_capabilities_len(defs_process_capabilities *cap, struct capabilities_lens *lens, ssize_t len_diff)
|
||
|
|
+{
|
||
|
|
+ ASSERT_EQ((ssize_t)cap->bounding_len, (ssize_t)lens->bounding_len + len_diff);
|
||
|
|
+ ASSERT_EQ((ssize_t)cap->effective_len, (ssize_t)lens->effective_len + len_diff);
|
||
|
|
+ ASSERT_EQ((ssize_t)cap->permitted_len, (ssize_t)lens->permitted_len + len_diff);
|
||
|
|
+ // Currently we don't support inheritable and ambient capabilities
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+TEST(merge_capability_ut, test_merge_caps_without_adds_drops)
|
||
|
|
+{
|
||
|
|
+ oci_runtime_spec *oci_spec = nullptr;
|
||
|
|
+ int ret = 0;
|
||
|
|
+ char *err = nullptr;
|
||
|
|
+ struct capabilities_lens old_lens = { 0 };
|
||
|
|
+ char *oci_config_file = nullptr;
|
||
|
|
+
|
||
|
|
+ oci_config_file = json_path(OCI_RUNTIME_SPEC_FILE);
|
||
|
|
+ ASSERT_TRUE(oci_config_file != nullptr);
|
||
|
|
+
|
||
|
|
+
|
||
|
|
+ oci_spec = oci_runtime_spec_parse_file(oci_config_file, nullptr, &err);
|
||
|
|
+ ASSERT_TRUE(oci_spec != nullptr);
|
||
|
|
+ free(err);
|
||
|
|
+
|
||
|
|
+ check_capabilities_len(oci_spec->process->capabilities, &old_lens);
|
||
|
|
+
|
||
|
|
+ ret = merge_caps(oci_spec, nullptr, 0, nullptr, 0);
|
||
|
|
+ ASSERT_EQ(ret, 0);
|
||
|
|
+
|
||
|
|
+ validate_capabilities_len(oci_spec->process->capabilities, &old_lens, 0);
|
||
|
|
+
|
||
|
|
+ free_oci_runtime_spec(oci_spec);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+TEST(merge_capability_ut, test_merge_caps_adds_without_drops)
|
||
|
|
+{
|
||
|
|
+ oci_runtime_spec *oci_spec = nullptr;
|
||
|
|
+ int ret = 0;
|
||
|
|
+ char *err = nullptr;
|
||
|
|
+ struct capabilities_lens old_lens = { 0 };
|
||
|
|
+ char *oci_config_file = nullptr;
|
||
|
|
+ /* All of below capabilities are not in oci_config_file */
|
||
|
|
+ const char *adds[] = { "NET_ADMIN", "SYS_ADMIN", "SYS_TTY_CONFIG", "SYS_PTRACE" };
|
||
|
|
+ const char *drops[] = {};
|
||
|
|
+ size_t adds_len = sizeof(adds) / sizeof(adds[0]);
|
||
|
|
+ size_t drops_len = sizeof(drops) / sizeof(drops[0]);
|
||
|
|
+
|
||
|
|
+ oci_config_file = json_path(OCI_RUNTIME_SPEC_FILE);
|
||
|
|
+ ASSERT_TRUE(oci_config_file != nullptr);
|
||
|
|
+
|
||
|
|
+
|
||
|
|
+ oci_spec = oci_runtime_spec_parse_file(oci_config_file, nullptr, &err);
|
||
|
|
+ ASSERT_TRUE(oci_spec != nullptr);
|
||
|
|
+ free(err);
|
||
|
|
+
|
||
|
|
+ check_capabilities_len(oci_spec->process->capabilities, &old_lens);
|
||
|
|
+
|
||
|
|
+ ret = merge_caps(oci_spec, adds, adds_len, drops, drops_len);
|
||
|
|
+ ASSERT_EQ(ret, 0);
|
||
|
|
+
|
||
|
|
+ /* All of capabilities in adds are added */
|
||
|
|
+ validate_capabilities_len(oci_spec->process->capabilities, &old_lens, adds_len);
|
||
|
|
+
|
||
|
|
+ free_oci_runtime_spec(oci_spec);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+TEST(merge_capability_ut, test_merge_caps_adds_existing_without_drops)
|
||
|
|
+{
|
||
|
|
+ oci_runtime_spec *oci_spec = nullptr;
|
||
|
|
+ int ret = 0;
|
||
|
|
+ char *err = nullptr;
|
||
|
|
+ struct capabilities_lens old_lens = { 0 };
|
||
|
|
+ char *oci_config_file = nullptr;
|
||
|
|
+ /* CHOWN already exits in oci_config_file */
|
||
|
|
+ const char *adds[] = { "CHOWN", "SYS_ADMIN", "SYS_TTY_CONFIG", "SYS_PTRACE" };
|
||
|
|
+ const char *drops[] = {};
|
||
|
|
+ size_t adds_len = sizeof(adds) / sizeof(adds[0]);
|
||
|
|
+ size_t drops_len = sizeof(drops) / sizeof(drops[0]);
|
||
|
|
+
|
||
|
|
+ oci_config_file = json_path(OCI_RUNTIME_SPEC_FILE);
|
||
|
|
+ ASSERT_TRUE(oci_config_file != nullptr);
|
||
|
|
+
|
||
|
|
+
|
||
|
|
+ oci_spec = oci_runtime_spec_parse_file(oci_config_file, nullptr, &err);
|
||
|
|
+ ASSERT_TRUE(oci_spec != nullptr);
|
||
|
|
+ free(err);
|
||
|
|
+
|
||
|
|
+ check_capabilities_len(oci_spec->process->capabilities, &old_lens);
|
||
|
|
+
|
||
|
|
+ ret = merge_caps(oci_spec, adds, adds_len, drops, drops_len);
|
||
|
|
+ ASSERT_EQ(ret, 0);
|
||
|
|
+
|
||
|
|
+ /* CHOWN is not added, since it already exits in the default list */
|
||
|
|
+ validate_capabilities_len(oci_spec->process->capabilities, &old_lens, adds_len - 1);
|
||
|
|
+
|
||
|
|
+ free_oci_runtime_spec(oci_spec);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+TEST(merge_capability_ut, test_merge_caps_drops_without_adds)
|
||
|
|
+{
|
||
|
|
+ oci_runtime_spec *oci_spec = nullptr;
|
||
|
|
+ int ret = 0;
|
||
|
|
+ char *err = nullptr;
|
||
|
|
+ struct capabilities_lens old_lens = { 0 };
|
||
|
|
+ char *oci_config_file = nullptr;
|
||
|
|
+ const char *adds[] = {};
|
||
|
|
+ /* Below capabilities are not in the oci_config_file */
|
||
|
|
+ const char *drops[] = { "SYS_TTY_CONFIG", "SYS_PTRACE" };
|
||
|
|
+ size_t adds_len = sizeof(adds) / sizeof(adds[0]);
|
||
|
|
+ size_t drops_len = sizeof(drops) / sizeof(drops[0]);
|
||
|
|
+
|
||
|
|
+ oci_config_file = json_path(OCI_RUNTIME_SPEC_FILE);
|
||
|
|
+ ASSERT_TRUE(oci_config_file != nullptr);
|
||
|
|
+
|
||
|
|
+
|
||
|
|
+ oci_spec = oci_runtime_spec_parse_file(oci_config_file, nullptr, &err);
|
||
|
|
+ ASSERT_TRUE(oci_spec != nullptr);
|
||
|
|
+ free(err);
|
||
|
|
+
|
||
|
|
+ check_capabilities_len(oci_spec->process->capabilities, &old_lens);
|
||
|
|
+
|
||
|
|
+ ret = merge_caps(oci_spec, adds, adds_len, drops, drops_len);
|
||
|
|
+ ASSERT_EQ(ret, 0);
|
||
|
|
+
|
||
|
|
+ /* Nothing dropped */
|
||
|
|
+ validate_capabilities_len(oci_spec->process->capabilities, &old_lens, 0);
|
||
|
|
+
|
||
|
|
+ free_oci_runtime_spec(oci_spec);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+TEST(merge_capability_ut, test_merge_caps_drops_existing_without_adds)
|
||
|
|
+{
|
||
|
|
+ oci_runtime_spec *oci_spec = nullptr;
|
||
|
|
+ int ret = 0;
|
||
|
|
+ char *err = nullptr;
|
||
|
|
+ struct capabilities_lens old_lens = { 0 };
|
||
|
|
+ char *oci_config_file = nullptr;
|
||
|
|
+ const char *adds[] = {};
|
||
|
|
+ /* Below capabilities are in the oci_config_file */
|
||
|
|
+ const char *drops[] = { "CHOWN", "MKNOD" };
|
||
|
|
+ size_t adds_len = sizeof(adds) / sizeof(adds[0]);
|
||
|
|
+ size_t drops_len = sizeof(drops) / sizeof(drops[0]);
|
||
|
|
+
|
||
|
|
+ oci_config_file = json_path(OCI_RUNTIME_SPEC_FILE);
|
||
|
|
+ ASSERT_TRUE(oci_config_file != nullptr);
|
||
|
|
+
|
||
|
|
+
|
||
|
|
+ oci_spec = oci_runtime_spec_parse_file(oci_config_file, nullptr, &err);
|
||
|
|
+ ASSERT_TRUE(oci_spec != nullptr);
|
||
|
|
+ free(err);
|
||
|
|
+
|
||
|
|
+ check_capabilities_len(oci_spec->process->capabilities, &old_lens);
|
||
|
|
+
|
||
|
|
+ ret = merge_caps(oci_spec, adds, adds_len, drops, drops_len);
|
||
|
|
+ ASSERT_EQ(ret, 0);
|
||
|
|
+
|
||
|
|
+ /* All dropped */
|
||
|
|
+ validate_capabilities_len(oci_spec->process->capabilities, &old_lens, adds_len - drops_len);
|
||
|
|
+
|
||
|
|
+ free_oci_runtime_spec(oci_spec);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+TEST(merge_capability_ut, test_merge_caps_adds_drops)
|
||
|
|
+{
|
||
|
|
+ oci_runtime_spec *oci_spec = nullptr;
|
||
|
|
+ int ret = 0;
|
||
|
|
+ char *err = nullptr;
|
||
|
|
+ struct capabilities_lens old_lens = { 0 };
|
||
|
|
+ char *oci_config_file = nullptr;
|
||
|
|
+ /* All of below capabilities are not in oci_config_file */
|
||
|
|
+ const char *adds[] = { "NET_ADMIN", "SYS_ADMIN", "SYS_TTY_CONFIG", "SYS_PTRACE" };
|
||
|
|
+ const char *drops[] = { "SYS_TTY_CONFIG", "SYS_PTRACE" };
|
||
|
|
+ size_t adds_len = sizeof(adds) / sizeof(adds[0]);
|
||
|
|
+ size_t drops_len = sizeof(drops) / sizeof(drops[0]);
|
||
|
|
+
|
||
|
|
+ oci_config_file = json_path(OCI_RUNTIME_SPEC_FILE);
|
||
|
|
+ ASSERT_TRUE(oci_config_file != nullptr);
|
||
|
|
+
|
||
|
|
+
|
||
|
|
+ oci_spec = oci_runtime_spec_parse_file(oci_config_file, nullptr, &err);
|
||
|
|
+ ASSERT_TRUE(oci_spec != nullptr);
|
||
|
|
+ free(err);
|
||
|
|
+
|
||
|
|
+ check_capabilities_len(oci_spec->process->capabilities, &old_lens);
|
||
|
|
+
|
||
|
|
+ ret = merge_caps(oci_spec, adds, adds_len, drops, drops_len);
|
||
|
|
+ ASSERT_EQ(ret, 0);
|
||
|
|
+
|
||
|
|
+ validate_capabilities_len(oci_spec->process->capabilities, &old_lens, adds_len - drops_len);
|
||
|
|
+
|
||
|
|
+ free_oci_runtime_spec(oci_spec);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+TEST(merge_capability_ut, test_merge_caps_adds_all_without_drops)
|
||
|
|
+{
|
||
|
|
+ oci_runtime_spec *oci_spec = nullptr;
|
||
|
|
+ int ret = 0;
|
||
|
|
+ char *err = nullptr;
|
||
|
|
+ struct capabilities_lens old_lens = { 0 };
|
||
|
|
+ char *oci_config_file = nullptr;
|
||
|
|
+ /* NET_ADMIN is in all */
|
||
|
|
+ const char *adds[] = { "ALL", "NET_ADMIN" };
|
||
|
|
+ const char *drops[] = {};
|
||
|
|
+ size_t adds_len = sizeof(adds) / sizeof(adds[0]);
|
||
|
|
+ size_t drops_len = sizeof(drops) / sizeof(drops[0]);
|
||
|
|
+ size_t all_caps_len = 0;
|
||
|
|
+ util_get_all_caps(&all_caps_len);
|
||
|
|
+
|
||
|
|
+ oci_config_file = json_path(OCI_RUNTIME_SPEC_FILE);
|
||
|
|
+ ASSERT_TRUE(oci_config_file != nullptr);
|
||
|
|
+
|
||
|
|
+ oci_spec = oci_runtime_spec_parse_file(oci_config_file, nullptr, &err);
|
||
|
|
+ ASSERT_TRUE(oci_spec != nullptr);
|
||
|
|
+ free(err);
|
||
|
|
+
|
||
|
|
+ check_capabilities_len(oci_spec->process->capabilities, &old_lens);
|
||
|
|
+
|
||
|
|
+ ret = merge_caps(oci_spec, adds, adds_len, drops, drops_len);
|
||
|
|
+ ASSERT_EQ(ret, 0);
|
||
|
|
+
|
||
|
|
+ ASSERT_EQ(oci_spec->process->capabilities->bounding_len, all_caps_len);
|
||
|
|
+ ASSERT_EQ(oci_spec->process->capabilities->effective_len, all_caps_len);
|
||
|
|
+ ASSERT_EQ(oci_spec->process->capabilities->permitted_len, all_caps_len);
|
||
|
|
+
|
||
|
|
+ free_oci_runtime_spec(oci_spec);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+TEST(merge_capability_ut, test_merge_caps_adds_all_and_extra_without_drops)
|
||
|
|
+{
|
||
|
|
+ oci_runtime_spec *oci_spec = nullptr;
|
||
|
|
+ int ret = 0;
|
||
|
|
+ char *err = nullptr;
|
||
|
|
+ struct capabilities_lens old_lens = { 0 };
|
||
|
|
+ char *oci_config_file = nullptr;
|
||
|
|
+ /* ABC is not in all */
|
||
|
|
+ const char *adds[] = { "ALL", "ABC" };
|
||
|
|
+ const char *drops[] = {};
|
||
|
|
+ size_t adds_len = sizeof(adds) / sizeof(adds[0]);
|
||
|
|
+ size_t drops_len = sizeof(drops) / sizeof(drops[0]);
|
||
|
|
+ size_t all_caps_len = 0;
|
||
|
|
+ util_get_all_caps(&all_caps_len);
|
||
|
|
+
|
||
|
|
+ oci_config_file = json_path(OCI_RUNTIME_SPEC_FILE);
|
||
|
|
+ ASSERT_TRUE(oci_config_file != nullptr);
|
||
|
|
+
|
||
|
|
+ oci_spec = oci_runtime_spec_parse_file(oci_config_file, nullptr, &err);
|
||
|
|
+ ASSERT_TRUE(oci_spec != nullptr);
|
||
|
|
+ free(err);
|
||
|
|
+
|
||
|
|
+ check_capabilities_len(oci_spec->process->capabilities, &old_lens);
|
||
|
|
+
|
||
|
|
+ ret = merge_caps(oci_spec, adds, adds_len, drops, drops_len);
|
||
|
|
+ ASSERT_EQ(ret, 0);
|
||
|
|
+
|
||
|
|
+ ASSERT_EQ(oci_spec->process->capabilities->bounding_len, all_caps_len + 1);
|
||
|
|
+ ASSERT_EQ(oci_spec->process->capabilities->effective_len, all_caps_len + 1);
|
||
|
|
+ ASSERT_EQ(oci_spec->process->capabilities->permitted_len, all_caps_len + 1);
|
||
|
|
+
|
||
|
|
+ free_oci_runtime_spec(oci_spec);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+TEST(merge_capability_ut, test_merge_caps_adds_all_drops_all)
|
||
|
|
+{
|
||
|
|
+ oci_runtime_spec *oci_spec = nullptr;
|
||
|
|
+ int ret = 0;
|
||
|
|
+ char *err = nullptr;
|
||
|
|
+ struct capabilities_lens old_lens = { 0 };
|
||
|
|
+ char *oci_config_file = nullptr;
|
||
|
|
+ /* ABC, EFG is not in all */
|
||
|
|
+ const char *adds[] = { "ALL", "ABC", "EFG"};
|
||
|
|
+ const char *drops[] = { "ALL", "ABC" };
|
||
|
|
+ size_t adds_len = sizeof(adds) / sizeof(adds[0]);
|
||
|
|
+ size_t drops_len = sizeof(drops) / sizeof(drops[0]);
|
||
|
|
+ size_t all_caps_len = 0;
|
||
|
|
+ util_get_all_caps(&all_caps_len);
|
||
|
|
+
|
||
|
|
+ oci_config_file = json_path(OCI_RUNTIME_SPEC_FILE);
|
||
|
|
+ ASSERT_TRUE(oci_config_file != nullptr);
|
||
|
|
+
|
||
|
|
+ oci_spec = oci_runtime_spec_parse_file(oci_config_file, nullptr, &err);
|
||
|
|
+ ASSERT_TRUE(oci_spec != nullptr);
|
||
|
|
+ free(err);
|
||
|
|
+
|
||
|
|
+ check_capabilities_len(oci_spec->process->capabilities, &old_lens);
|
||
|
|
+
|
||
|
|
+ ret = merge_caps(oci_spec, adds, adds_len, drops, drops_len);
|
||
|
|
+ ASSERT_EQ(ret, 0);
|
||
|
|
+
|
||
|
|
+ ASSERT_EQ(oci_spec->process->capabilities->bounding_len, 1);
|
||
|
|
+ ASSERT_EQ(oci_spec->process->capabilities->effective_len, 1);
|
||
|
|
+ ASSERT_EQ(oci_spec->process->capabilities->permitted_len, 1);
|
||
|
|
+
|
||
|
|
+ free_oci_runtime_spec(oci_spec);
|
||
|
|
+}
|
||
|
|
diff --git a/test/specs/specs_extend/CMakeLists.txt b/test/specs/specs_extend/CMakeLists.txt
|
||
|
|
index 294690e8..bf4b378e 100644
|
||
|
|
--- a/test/specs/specs_extend/CMakeLists.txt
|
||
|
|
+++ b/test/specs/specs_extend/CMakeLists.txt
|
||
|
|
@@ -14,6 +14,7 @@ add_executable(${EXE}
|
||
|
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/util_atomic.c
|
||
|
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_mount_spec.c
|
||
|
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_fs.c
|
||
|
|
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/utils_cap.c
|
||
|
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/sha256/sha256.c
|
||
|
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/path.c
|
||
|
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/utils/cutils/map/map.c
|
||
|
|
--
|
||
|
|
2.42.0
|
||
|
|
|