2019-12-25 15:57:42 +08:00
|
|
|
From d891502489641740373c74e761e3b615845e11a0 Mon Sep 17 00:00:00 2001
|
2019-09-30 11:03:07 -04:00
|
|
|
From: LiFeng <lifeng68@huawei.com>
|
|
|
|
|
Date: Tue, 15 Jan 2019 22:55:06 -0500
|
2019-12-25 15:57:42 +08:00
|
|
|
Subject: [PATCH 036/131] drop_caps: add drop caps of current process
|
2019-09-30 11:03:07 -04:00
|
|
|
|
|
|
|
|
Signed-off-by: LiFeng <lifeng68@huawei.com>
|
|
|
|
|
---
|
2019-12-25 15:57:42 +08:00
|
|
|
src/lxc/attach.c | 26 ++++++++++---
|
|
|
|
|
src/lxc/cgroups/cgfsng.c | 35 +++++++++---------
|
|
|
|
|
src/lxc/conf.c | 79 ++++++++++++++++++++++++++++++++++++++++
|
2019-09-30 11:03:07 -04:00
|
|
|
src/lxc/conf.h | 1 +
|
2019-12-25 15:57:42 +08:00
|
|
|
src/lxc/start.c | 16 ++++++++
|
2019-09-30 11:03:07 -04:00
|
|
|
5 files changed, 135 insertions(+), 22 deletions(-)
|
|
|
|
|
|
|
|
|
|
diff --git a/src/lxc/attach.c b/src/lxc/attach.c
|
2019-12-25 15:57:42 +08:00
|
|
|
index 8cbbf962..3f60fe10 100644
|
2019-09-30 11:03:07 -04:00
|
|
|
--- a/src/lxc/attach.c
|
|
|
|
|
+++ b/src/lxc/attach.c
|
|
|
|
|
@@ -936,11 +936,6 @@ static int attach_child_main(struct attach_clone_payload *payload)
|
|
|
|
|
TRACE("Loaded seccomp profile");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- close(payload->ipc_socket);
|
|
|
|
|
- payload->ipc_socket = -EBADF;
|
|
|
|
|
- lxc_proc_put_context_info(init_ctx);
|
|
|
|
|
- payload->init_ctx = NULL;
|
|
|
|
|
-
|
|
|
|
|
/* The following is done after the communication socket is shut down.
|
|
|
|
|
* That way, all errors that might (though unlikely) occur up until this
|
|
|
|
|
* point will have their messages printed to the original stderr (if
|
|
|
|
|
@@ -997,9 +992,30 @@ static int attach_child_main(struct attach_clone_payload *payload)
|
|
|
|
|
if (new_gid == ns_root_gid)
|
|
|
|
|
new_gid = LXC_INVALID_GID;
|
|
|
|
|
|
|
|
|
|
+ if (prctl(PR_SET_KEEPCAPS, 1) < 0) {
|
|
|
|
|
+ SYSERROR("Failed to keep permitted capabilities");
|
|
|
|
|
+ goto on_error;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
if (!lxc_switch_uid_gid(new_uid, new_gid))
|
|
|
|
|
goto on_error;
|
|
|
|
|
|
|
|
|
|
+ if (prctl(PR_SET_KEEPCAPS, 0) < 0) {
|
|
|
|
|
+ SYSERROR("Failed to clear permitted capabilities");
|
|
|
|
|
+ goto on_error;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (init_ctx->container && init_ctx->container->lxc_conf &&
|
|
|
|
|
+ lxc_drop_caps(init_ctx->container->lxc_conf) != 0) {
|
|
|
|
|
+ ERROR("Failed to drop caps.");
|
|
|
|
|
+ goto on_error;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ close(payload->ipc_socket);
|
|
|
|
|
+ payload->ipc_socket = -EBADF;
|
|
|
|
|
+ lxc_proc_put_context_info(init_ctx);
|
|
|
|
|
+ payload->init_ctx = NULL;
|
|
|
|
|
+
|
|
|
|
|
/* We're done, so we can now do whatever the user intended us to do. */
|
|
|
|
|
_exit(payload->exec_function(payload->exec_payload, msg_fd));
|
|
|
|
|
|
|
|
|
|
diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c
|
2019-12-25 15:57:42 +08:00
|
|
|
index 8b913a6b..bc1481d4 100644
|
2019-09-30 11:03:07 -04:00
|
|
|
--- a/src/lxc/cgroups/cgfsng.c
|
|
|
|
|
+++ b/src/lxc/cgroups/cgfsng.c
|
|
|
|
|
@@ -2664,11 +2664,11 @@ __cgfsng_ops static bool cgfsng_data_init(struct cgroup_ops *ops, struct lxc_han
|
|
|
|
|
{
|
|
|
|
|
const char *cgroup_pattern;
|
|
|
|
|
char *container_cgroup, *tmp;
|
|
|
|
|
- struct lxc_conf *conf = handler->conf;
|
|
|
|
|
+ struct lxc_conf *conf = NULL;
|
|
|
|
|
size_t len;
|
|
|
|
|
|
|
|
|
|
- if (!conf)
|
|
|
|
|
- return false;
|
|
|
|
|
+ if (handler)
|
|
|
|
|
+ conf = handler->conf;
|
|
|
|
|
|
|
|
|
|
/* copy system-wide cgroup information */
|
|
|
|
|
cgroup_pattern = lxc_global_config_value("lxc.cgroup.pattern");
|
|
|
|
|
@@ -2680,21 +2680,22 @@ __cgfsng_ops static bool cgfsng_data_init(struct cgroup_ops *ops, struct lxc_han
|
|
|
|
|
ops->cgroup_pattern = must_copy_string(cgroup_pattern);
|
|
|
|
|
|
|
|
|
|
/* isulad: init ops->container_cgroup here instead of in cgfsng_payload_create*/
|
|
|
|
|
- if (conf->cgroup_meta.dir)
|
|
|
|
|
- tmp = lxc_string_join("/", (const char *[]){conf->cgroup_meta.dir, handler->name, NULL}, false);
|
|
|
|
|
- else
|
|
|
|
|
- tmp = lxc_string_replace("%n", handler->name, ops->cgroup_pattern);
|
|
|
|
|
- if (!tmp) {
|
|
|
|
|
- ERROR("Failed expanding cgroup name pattern");
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- len = strlen(tmp) + 1;
|
|
|
|
|
- container_cgroup = must_realloc(NULL, len);
|
|
|
|
|
- (void)strlcpy(container_cgroup, tmp, len);
|
|
|
|
|
- free(tmp);
|
|
|
|
|
- ops->container_cgroup = container_cgroup;
|
|
|
|
|
+ if (conf) {
|
|
|
|
|
+ if (conf->cgroup_meta.dir)
|
|
|
|
|
+ tmp = lxc_string_join("/", (const char *[]){conf->cgroup_meta.dir, handler->name, NULL}, false);
|
|
|
|
|
+ else
|
|
|
|
|
+ tmp = lxc_string_replace("%n", handler->name, ops->cgroup_pattern);
|
|
|
|
|
+ if (!tmp) {
|
|
|
|
|
+ ERROR("Failed expanding cgroup name pattern");
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
+ len = strlen(tmp) + 1;
|
|
|
|
|
+ container_cgroup = must_realloc(NULL, len);
|
|
|
|
|
+ (void)strlcpy(container_cgroup, tmp, len);
|
|
|
|
|
+ free(tmp);
|
|
|
|
|
+ ops->container_cgroup = container_cgroup;
|
|
|
|
|
+ }
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
|
2019-12-25 15:57:42 +08:00
|
|
|
index fea0f592..6134ed3b 100644
|
2019-09-30 11:03:07 -04:00
|
|
|
--- a/src/lxc/conf.c
|
|
|
|
|
+++ b/src/lxc/conf.c
|
|
|
|
|
@@ -4220,6 +4220,85 @@ int lxc_setup(struct lxc_handler *handler)
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
+/* isulad drop caps for container*/
|
|
|
|
|
+int lxc_drop_caps(struct lxc_conf *conf)
|
|
|
|
|
+{
|
|
|
|
|
+#define __DEF_CAP_TO_MASK(x) (1U << ((x) & 31))
|
|
|
|
|
+#if HAVE_LIBCAP
|
|
|
|
|
+ struct lxc_list *iterator;
|
|
|
|
|
+ char *keep_entry;
|
|
|
|
|
+ int i, capid;
|
|
|
|
|
+ int numcaps = lxc_caps_last_cap() + 1;
|
|
|
|
|
+ struct lxc_list *caps = NULL;
|
|
|
|
|
+
|
|
|
|
|
+ if (lxc_list_empty(&conf->keepcaps))
|
|
|
|
|
+ return 0;
|
|
|
|
|
+
|
|
|
|
|
+ caps = &conf->keepcaps;
|
|
|
|
|
+
|
|
|
|
|
+ if (numcaps <= 0 || numcaps > 200)
|
|
|
|
|
+ return -1;
|
|
|
|
|
+
|
|
|
|
|
+ // caplist[i] is 1 if we keep capability i
|
|
|
|
|
+ int *caplist = alloca(numcaps * sizeof(int));
|
|
|
|
|
+ memset(caplist, 0, numcaps * sizeof(int));
|
|
|
|
|
+
|
|
|
|
|
+ lxc_list_for_each(iterator, caps) {
|
|
|
|
|
+
|
|
|
|
|
+ keep_entry = iterator->elem;
|
|
|
|
|
+ /* isulad: Do not keep any cap*/
|
|
|
|
|
+ if (strcmp(keep_entry, "ISULAD_KEEP_NONE") == 0) {
|
|
|
|
|
+ DEBUG("Do not keep any capability");
|
|
|
|
|
+ for(i = 0; i < numcaps; i++) {
|
|
|
|
|
+ caplist[i] = 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ capid = parse_cap(keep_entry);
|
|
|
|
|
+
|
|
|
|
|
+ if (capid == -2)
|
|
|
|
|
+ continue;
|
|
|
|
|
+
|
|
|
|
|
+ if (capid < 0) {
|
|
|
|
|
+ ERROR("unknown capability %s", keep_entry);
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ DEBUG("keep capability '%s' (%d)", keep_entry, capid);
|
|
|
|
|
+
|
|
|
|
|
+ caplist[capid] = 1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ struct __user_cap_header_struct cap_header_data;
|
|
|
|
|
+ struct __user_cap_data_struct cap_data_data[2];
|
|
|
|
|
+
|
|
|
|
|
+ cap_user_header_t cap_header = &cap_header_data;
|
|
|
|
|
+ cap_user_data_t cap_data = &cap_data_data[0];
|
|
|
|
|
+
|
|
|
|
|
+ memset(cap_header, 0 ,sizeof(struct __user_cap_header_struct));
|
|
|
|
|
+ memset(cap_data, 0, sizeof(struct __user_cap_data_struct) * 2);
|
|
|
|
|
+
|
|
|
|
|
+ cap_header->pid = 0;
|
|
|
|
|
+ cap_header->version = _LINUX_CAPABILITY_VERSION;
|
|
|
|
|
+
|
|
|
|
|
+ for (i = 0; i < numcaps; i++) {
|
|
|
|
|
+ if (caplist[i]) {
|
|
|
|
|
+ cap_data[CAP_TO_INDEX(i)].effective = cap_data[CAP_TO_INDEX(i)].effective | __DEF_CAP_TO_MASK(i);
|
|
|
|
|
+ cap_data[CAP_TO_INDEX(i)].permitted = cap_data[CAP_TO_INDEX(i)].permitted | __DEF_CAP_TO_MASK(i);
|
|
|
|
|
+ cap_data[CAP_TO_INDEX(i)].inheritable = cap_data[CAP_TO_INDEX(i)].inheritable | __DEF_CAP_TO_MASK(i);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (capset(cap_header, cap_data)) {
|
|
|
|
|
+ SYSERROR("Failed to set capabilitys");
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+#endif
|
|
|
|
|
+ return 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
struct oci_hook_conf {
|
|
|
|
|
defs_hook *ocihook;
|
|
|
|
|
|
|
|
|
|
diff --git a/src/lxc/conf.h b/src/lxc/conf.h
|
2019-12-25 15:57:42 +08:00
|
|
|
index 44feb986..b92c48e1 100644
|
2019-09-30 11:03:07 -04:00
|
|
|
--- a/src/lxc/conf.h
|
|
|
|
|
+++ b/src/lxc/conf.h
|
|
|
|
|
@@ -498,6 +498,7 @@ int lxc_clear_init_args(struct lxc_conf *lxc_conf);
|
|
|
|
|
int lxc_clear_populate_devices(struct lxc_conf *c);
|
|
|
|
|
int lxc_clear_rootfs_masked_paths(struct lxc_conf *c);
|
|
|
|
|
int lxc_clear_rootfs_ro_paths(struct lxc_conf *c);
|
|
|
|
|
+int lxc_drop_caps(struct lxc_conf *conf);
|
|
|
|
|
|
|
|
|
|
/* isulad add end */
|
|
|
|
|
|
|
|
|
|
diff --git a/src/lxc/start.c b/src/lxc/start.c
|
2019-12-25 15:57:42 +08:00
|
|
|
index 040909c3..357e81d2 100644
|
2019-09-30 11:03:07 -04:00
|
|
|
--- a/src/lxc/start.c
|
|
|
|
|
+++ b/src/lxc/start.c
|
|
|
|
|
@@ -1411,6 +1411,11 @@ static int do_start(void *data)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
+ if (prctl(PR_SET_KEEPCAPS, 1) < 0) {
|
|
|
|
|
+ SYSERROR("Failed to keep permitted capabilities");
|
|
|
|
|
+ goto out_warn_father;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
/* The container has been setup. We can now switch to an unprivileged
|
|
|
|
|
* uid/gid.
|
|
|
|
|
*/
|
|
|
|
|
@@ -1448,6 +1453,17 @@ static int do_start(void *data)
|
|
|
|
|
goto out_warn_father;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /* isulad: drop the cap of current process */
|
|
|
|
|
+ if (prctl(PR_SET_KEEPCAPS, 0) < 0) {
|
|
|
|
|
+ SYSERROR("Failed to clear permitted capabilities");
|
|
|
|
|
+ goto out_warn_father;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (lxc_drop_caps(handler->conf)) {
|
|
|
|
|
+ SYSERROR("Failed to drop caps");
|
|
|
|
|
+ goto out_warn_father;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
/* After this call, we are in error because this ops should not return
|
|
|
|
|
* as it execs.
|
|
|
|
|
*/
|
|
|
|
|
--
|
2019-12-25 15:57:42 +08:00
|
|
|
2.23.0
|
2019-09-30 11:03:07 -04:00
|
|
|
|