From 8e1bd51183eeb2ca2713b85afd52b12e584bc7a8 Mon Sep 17 00:00:00 2001
From: zhongtao <zhongtao17@huawei.com>
Date: Wed, 12 Apr 2023 21:19:56 +0800
Subject: [PATCH 42/46] add effective and permitted type of cap to oci spec

Signed-off-by: zhongtao <zhongtao17@huawei.com>
---
 src/contrib/config/config.json                | 28 ++++++
 .../config/systemcontainer_config.json        | 28 ++++++
 src/daemon/modules/spec/specs_security.c      | 88 ++++++++++++++-----
 3 files changed, 120 insertions(+), 24 deletions(-)

diff --git a/src/contrib/config/config.json b/src/contrib/config/config.json
index f84f3394..9070a893 100644
--- a/src/contrib/config/config.json
+++ b/src/contrib/config/config.json
@@ -36,10 +36,38 @@
 				"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"
 			],
 			"inheritable": [
 			],
 			"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"
 			],
 			"ambient": [
 			]
diff --git a/src/contrib/config/systemcontainer_config.json b/src/contrib/config/systemcontainer_config.json
index 8ebce8c6..9169956e 100644
--- a/src/contrib/config/systemcontainer_config.json
+++ b/src/contrib/config/systemcontainer_config.json
@@ -36,10 +36,38 @@
 				"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"
 			],
 			"inheritable": [
 			],
 			"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"
 			],
 			"ambient": [
 			]
diff --git a/src/daemon/modules/spec/specs_security.c b/src/daemon/modules/spec/specs_security.c
index 62f67082..d4884097 100644
--- a/src/daemon/modules/spec/specs_security.c
+++ b/src/daemon/modules/spec/specs_security.c
@@ -261,36 +261,80 @@ free_out:
     return ret;
 }
 
+// tweak_all_type_capabilities can tweak all support type capabilities by adding or dropping capabilities
+// based on the basic capabilities.
+static int tweak_all_type_capabilities(defs_process_capabilities **caps, const char **adds, size_t adds_len,
+                                       const char **drops, size_t drops_len)
+{
+    int ret = 0;
+    ret = tweak_capabilities(&((*caps)->bounding), &((*caps)->bounding_len), adds, adds_len, drops, drops_len);
+    if (ret != 0) {
+        ERROR("Failed to tweak bounding capabilities");
+        return -1;
+    }
+
+    ret = tweak_capabilities(&((*caps)->permitted), &((*caps)->permitted_len), adds, adds_len, drops, drops_len);
+    if (ret != 0) {
+        ERROR("Failed to tweak permitted capabilities");
+        return -1;
+    }
+
+    ret = tweak_capabilities(&((*caps)->effective), &((*caps)->effective_len), adds, adds_len, drops, drops_len);
+    if (ret != 0) {
+        ERROR("Failed to tweak effective capabilities");
+        return -1;
+    }
+    return ret;
+}
+
+static void clear_caps(defs_process_capabilities **caps)
+{
+    util_free_array_by_len((*caps)->bounding, (*caps)->bounding_len);
+    (*caps)->bounding_len = 0;
+    (*caps)->bounding = NULL;
+
+    util_free_array_by_len((*caps)->permitted, (*caps)->permitted_len);
+    (*caps)->permitted_len = 0;
+    (*caps)->permitted = NULL;
+
+    util_free_array_by_len((*caps)->effective, (*caps)->effective_len);
+    (*caps)->effective_len = 0;
+    (*caps)->effective = NULL;
+}
+
 int refill_oci_process_capabilities(defs_process_capabilities **caps, const char **src_caps, size_t src_caps_len)
 {
     int ret = 0;
-    size_t i = 0;
 
     if (*caps == NULL) {
         *caps = util_common_calloc_s(sizeof(defs_process_capabilities));
         if (*caps == NULL) {
-            ret = -1;
-            goto out;
+            return -1;
         }
     }
 
-    if ((*caps)->bounding != NULL) {
-        // free current capabilities
-        for (i = 0; i < ((*caps)->bounding_len); i++) {
-            free((*caps)->bounding[i]);
-            (*caps)->bounding[i] = NULL;
-        }
-        free((*caps)->bounding);
-        (*caps)->bounding = NULL;
-    }
-    (*caps)->bounding_len = 0;
+    // clear current capabilities
+    clear_caps(caps);
 
     // copy capabilities
     ret = copy_capabilities(&((*caps)->bounding), &((*caps)->bounding_len), src_caps, src_caps_len);
     if (ret != 0) {
-        ERROR("Failed to copy all capabilities");
+        ERROR("Failed to copy all bounding capabilities");
+        return -1;
     }
-out:
+
+    ret = copy_capabilities(&((*caps)->permitted), &((*caps)->permitted_len), src_caps, src_caps_len);
+    if (ret != 0) {
+        ERROR("Failed to copy all permitted capabilities");
+        return -1;
+    }
+
+    ret = copy_capabilities(&((*caps)->effective), &((*caps)->effective_len), src_caps, src_caps_len);
+    if (ret != 0) {
+        ERROR("Failed to copy all effective capabilities");
+        return -1;
+    }
+
     return ret;
 }
 
@@ -823,25 +867,21 @@ int merge_caps(oci_runtime_spec *oci_spec, const char **adds, size_t adds_len, c
 
     ret = make_sure_oci_spec_process_capabilities(oci_spec);
     if (ret < 0) {
-        goto out;
+        return ret;
     }
 
     if (adds_len > LIST_SIZE_MAX || drops_len > LIST_SIZE_MAX) {
         ERROR("Too many capabilities to add or drop, the limit is %lld", LIST_SIZE_MAX);
         isulad_set_error_message("Too many capabilities to add or drop, the limit is %d", LIST_SIZE_MAX);
-        ret = -1;
-        goto out;
+        return -1;
     }
 
-    ret = tweak_capabilities(&oci_spec->process->capabilities->bounding, &oci_spec->process->capabilities->bounding_len,
-                             adds, adds_len, drops, drops_len);
+    ret = tweak_all_type_capabilities(&oci_spec->process->capabilities, adds, adds_len, drops, drops_len);
     if (ret != 0) {
-        ERROR("Failed to tweak capabilities");
-        ret = -1;
-        goto out;
+        ERROR("Failed to tweak all type capabilities");
+        return -1;
     }
 
-out:
     return ret;
 }
 
-- 
2.25.1

