From a719de928649384d63b903fb0036aafd5fa78822 Mon Sep 17 00:00:00 2001
From: zhangxiaoyu <zhangxiaoyu58@huawei.com>
Date: Thu, 7 Dec 2023 11:11:31 +0800
Subject: [PATCH] bugfix about cgroup, mount propagation and capabilities

Signed-off-by: zhangxiaoyu <zhangxiaoyu58@huawei.com>
---
 src/lxc/attach_options.h       |  2 --
 src/lxc/cgroups/cgfsng.c       | 15 +++++++----
 src/lxc/cgroups/cgroup_utils.c | 10 ++++++++
 src/lxc/conf.c                 | 47 +++++++++-------------------------
 src/lxc/confile.c              | 12 +++++++++
 src/lxc/start.c                |  8 +++++-
 src/lxc/tools/lxc_attach.c     |  5 ++--
 7 files changed, 54 insertions(+), 45 deletions(-)

diff --git a/src/lxc/attach_options.h b/src/lxc/attach_options.h
index fe8bf6d..c1627d7 100644
--- a/src/lxc/attach_options.h
+++ b/src/lxc/attach_options.h
@@ -169,8 +169,6 @@ typedef struct lxc_attach_options_t {
 	const char *suffix;
 	bool disable_pty;
 	bool open_stdin;
-	gid_t *add_gids; /* attach user additional gids */
-	size_t add_gids_len; // iSulad TODO: shoud replace by lxc_groups_t groups;
 #endif
 } lxc_attach_options_t;
 
diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c
index a9a8f2c..5fd12ff 100644
--- a/src/lxc/cgroups/cgfsng.c
+++ b/src/lxc/cgroups/cgfsng.c
@@ -486,8 +486,15 @@ static int cgroup_tree_remove(struct hierarchy **hierarchies, const char *path_p
 		int ret;
 
 		ret = cgroup_tree_prune(h->dfd_base, path_prune);
+#ifdef HAVE_ISULAD
+		if (ret < 0) {
+			SYSWARN("Failed to destroy %d(%s)", h->dfd_base, path_prune);
+			return -1;
+		}
+#else
 		if (ret < 0)
 			SYSWARN("Failed to destroy %d(%s)", h->dfd_base, path_prune);
+#endif
 		else
 			TRACE("Removed cgroup tree %d(%s)", h->dfd_base, path_prune);
 
@@ -1459,10 +1466,7 @@ __cgfsng_ops static bool cgfsng_payload_create(struct cgroup_ops *ops, struct lx
 		DEBUG("no controller found, isgnore isulad_cgfsng_payload_create");
 		return true;
 	}
-	if (ops->container_cgroup) {
-		free(ops->container_cgroup);
-		ops->container_cgroup = NULL;
-	}
+	free_equal(ops->container_cgroup, ops->container_limit_cgroup);
 #endif
 
 	if (ops->container_cgroup || ops->container_limit_cgroup)
@@ -4408,6 +4412,7 @@ __cgfsng_ops static int cgfsng_data_init(struct cgroup_ops *ops)
 		return ret_set_errno(-1, ENOMEM);
 
 	ops->container_cgroup = move_ptr(container_cgroup);
+	ops->container_limit_cgroup = ops->container_cgroup;
 #endif
 
 	return 0;
@@ -4425,7 +4430,7 @@ __cgfsng_ops static const char *isulad_cgfsng_get_cgroup_full_path(struct cgroup
 				      controller ? controller : "(null)");
 
 	if (!h->path_con)
-		h->path_con = must_make_path(h->at_mnt, h->at_base, ops->container_cgroup, NULL);
+		h->path_con = make_cgroup_path(h, h->at_base, ops->container_cgroup, NULL);
 
 	return h->path_con;
 }
diff --git a/src/lxc/cgroups/cgroup_utils.c b/src/lxc/cgroups/cgroup_utils.c
index dc2fbec..252799e 100644
--- a/src/lxc/cgroups/cgroup_utils.c
+++ b/src/lxc/cgroups/cgroup_utils.c
@@ -52,8 +52,18 @@ int cgroup_tree_prune(int dfd, const char *path)
 	 */
 	dfd_disown = open_at(dfd, path, PROTECT_OPEN,
 			     PROTECT_LOOKUP_BENEATH_WITH_SYMLINKS, 0);
+#ifdef HAVE_ISULAD
+	if (dfd_disown < 0) {
+		if (errno == ENOENT) {
+			WARN("Destroy %d(%s) do not exist", dfd, path);
+			return 0;
+		}
+		return -errno;
+	}
+#else
 	if (dfd_disown < 0)
 		return -errno;
+#endif
 
 	dfd_dup = dup_cloexec(dfd_disown);
 	if (dfd_dup < 0)
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 7a70bca..84b8baf 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -590,6 +590,13 @@ int lxc_rootfs_init(struct lxc_conf *conf, bool userns)
 			return log_trace_errno(0, EINVAL, "Not pinning on ZFS filesystem");
 	}
 
+#ifdef HAVE_ISULAD
+	// isulad rootfs type is null
+	if (!rootfs->bdev_type) {
+		return log_trace_errno(0, EINVAL, "Not pinning on rootfs");
+	}
+#endif
+
 	dfd_path = open_at(-EBADF, rootfs->path, PROTECT_OPATH_FILE, 0, 0);
 	if (dfd_path < 0)
 		return syserror("Failed to open \"%s\"", rootfs->path);
@@ -1767,9 +1774,12 @@ static int lxc_pivot_root(const struct lxc_rootfs *rootfs)
 	 * nearly all relevant use-cases. Instead, establish the container's
 	 * rootfs as a separate peer group mirroring the behavior on the host.
 	 */
+#ifndef HAVE_ISULAD
+	// shared mount propagation will cause maskedpath mount twice
 	ret = mount("", ".", "", MS_SHARED | MS_REC, NULL);
 	if (ret < 0)
 		return log_error_errno(-errno, errno, "Failed to turn new root mount tree into shared mount tree");
+#endif
 
 	TRACE("Changed into new rootfs \"%s\"", rootfs->mount);
 	return 0;
@@ -3530,17 +3540,6 @@ static int capabilities_allow(struct lxc_conf *conf)
 		if (cap->cap > last_cap)
 			continue;
 
-#ifdef HAVE_ISULAD
-		/* Do not keep any cap*/
-		if (strcmp(cap->cap_name, "ISULAD_KEEP_NONE") == 0) {
-			DEBUG("Do not keep any capability");
-			__u32 i;
-			for(i = 0; i < nr_u32; i++) {
-				keep_bits[i] = 0;
-			}
-			break;
-		}
-#endif
 		set_bit(cap->cap, keep_bits);
 		DEBUG("Keeping %s (%d) capability", cap->cap_name, cap->cap);
 	}
@@ -6267,9 +6266,7 @@ int lxc_drop_caps(struct lxc_conf *conf)
 #define __DEF_CAP_TO_MASK(x) (1U << ((x) & 31))
 #if HAVE_LIBCAP
 	int ret = 0;
-	int nret = 0;
 	size_t i = 0;
-	__u32 capid;
 	__u32 last_cap;
 	size_t numcaps;
 	struct cap_entry *cap_entry;
@@ -6295,28 +6292,8 @@ int lxc_drop_caps(struct lxc_conf *conf)
 	(void)memset(caplist, 0, numcaps * sizeof(int));
 
 	list_for_each_entry(cap_entry, &conf->caps.list, head) {
-		/* isulad: Do not keep any cap*/
-		if (strcmp(cap_entry->cap_name, "ISULAD_KEEP_NONE") == 0) {
-			DEBUG("Do not keep any capability");
-			for(i = 0; i < numcaps; i++) {
-				caplist[i] = 0;
-			}
-			break;
-		}
-
-		nret = parse_cap(cap_entry->cap_name, &capid);
-		if (nret == -2)
-			continue;
-
-		if (nret < 0) {
-			ERROR("unknown capability %s", cap_entry->cap_name);
-			ret = -1;
-			goto out;
-		}
-
-		DEBUG("keep capability '%s' (%d)", cap_entry->cap_name, capid);
-
-		caplist[capid] = 1;
+		DEBUG("keep capability '%s' (%d)", cap_entry->cap_name, cap_entry->cap);
+		caplist[cap_entry->cap] = 1;
 	}
 
 	struct __user_cap_header_struct cap_header_data;
diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index aa5c790..d0984b0 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -2509,6 +2509,18 @@ static int add_cap_entry(struct lxc_conf *conf, char *caps, bool keep)
 			continue;
 		}
 
+#ifdef HAVE_ISULAD
+		/* isulad: Do not keep any cap*/
+		if (strequal(token, "ISULAD_KEEP_NONE")) {
+			if (!keep)
+				return syserror_set(-EINVAL, "The \"ISULAD_KEEP_NONE\" keyword is only valid when keeping caps");
+
+			lxc_clear_config_caps(conf);
+			conf->caps.keep = true;
+			return 0;
+		}
+#endif
+
 		ret = parse_cap(token, &cap);
 		if (ret < 0) {
 			if (ret != -2)
diff --git a/src/lxc/start.c b/src/lxc/start.c
index b1ccdcb..1c8e258 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -1067,9 +1067,15 @@ int get_all_pids(struct cgroup_ops *cg_ops, pid_t **pids, size_t *len)
 static int set_cgroup_freezer(struct cgroup_ops *cg_ops, const char *value)
 {
 	char *fullpath;
+	const char *cgroup_path;
 	int ret;
 
-	fullpath = must_make_path(cg_ops->get_cgroup_full_path(cg_ops, "freezer"), "freezer.state", NULL);
+	cgroup_path = cg_ops->get_cgroup_full_path(cg_ops, "freezer");
+	if (cgroup_path == NULL) {
+		return -1;
+	}
+
+	fullpath = must_make_path(cgroup_path, "freezer.state", NULL);
 	ret = lxc_write_to_file(fullpath, value, strlen(value), false, 0666);
 	free(fullpath);
 	return ret;
diff --git a/src/lxc/tools/lxc_attach.c b/src/lxc/tools/lxc_attach.c
index 1283bcf..edceb8c 100644
--- a/src/lxc/tools/lxc_attach.c
+++ b/src/lxc/tools/lxc_attach.c
@@ -723,8 +723,9 @@ int main(int argc, char *argv[])
 	}
 
 	if (my_args.add_gids) {
-		attach_options.add_gids = my_args.add_gids;
-		attach_options.add_gids_len = my_args.add_gids_len;
+		attach_options.groups.list = my_args.add_gids;
+		attach_options.groups.size = my_args.add_gids_len;
+		attach_options.attach_flags |= LXC_ATTACH_SETGROUPS;
 	}
 
 	/* isulad: add do attach background */
-- 
2.25.1

