[lxc-devel] [lxc/master] conf: kill old chown_mapped_root()

brauner on Github lxc-bot at linuxcontainers.org
Wed Jun 10 21:35:23 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 522 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200610/24356407/attachment.bin>
-------------- next part --------------
From ecdeed4666f32f73693419f8f63c50ad18dafef6 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Wed, 10 Jun 2020 23:33:59 +0200
Subject: [PATCH] conf: kill old chown_mapped_root()

It's now a wrapper around userns_exec_mapped_root() which allows us to avoid
fork() + exec() lxc-usernsexec makes things way nicer to test with ASAN etc.

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/conf.c | 121 -------------------------------------------------
 src/lxc/conf.h |   5 +-
 2 files changed, 4 insertions(+), 122 deletions(-)

diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 5cbca60006..77d02d088d 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -2896,127 +2896,6 @@ int find_unmapped_nsid(const struct lxc_conf *conf, enum idtype idtype)
 	return freeid;
 }
 
-int chown_mapped_root_exec_wrapper(void *args)
-{
-	execvp("lxc-usernsexec", args);
-	return -1;
-}
-
-/* chown_mapped_root: for an unprivileged user with uid/gid X to
- * chown a dir to subuid/subgid Y, he needs to run chown as root
- * in a userns where nsid 0 is mapped to hostuid/hostgid Y, and
- * nsid Y is mapped to hostuid/hostgid X.  That way, the container
- * root is privileged with respect to hostuid/hostgid X, allowing
- * him to do the chown.
- */
-int chown_mapped_root(const char *path, const struct lxc_conf *conf)
-{
-	uid_t rootuid, rootgid;
-	int hostuid, hostgid, ret;
-	struct stat sb;
-	char map1[100], map2[100], map3[100], map4[100], map5[100];
-	char ugid[100];
-	const char *args1[] = {"lxc-usernsexec",
-			 "-m", map1,
-			 "-m", map2,
-			 "-m", map3,
-			 "-m", map5,
-			 "--", "chown", ugid, path,
-			 NULL};
-	const char *args2[] = {"lxc-usernsexec",
-			 "-m", map1,
-			 "-m", map2,
-			 "-m", map3,
-			 "-m", map4,
-			 "-m", map5,
-			 "--", "chown", ugid, path,
-			 NULL};
-	char cmd_output[PATH_MAX];
-
-	rootuid = get_mapped_rootid(conf, ID_TYPE_UID);
-	if (!uid_valid(rootuid))
-		return log_error(-1, "No uid mapping for container root");
-
-	rootgid = get_mapped_rootid(conf, ID_TYPE_GID);
-	if (!gid_valid(rootgid))
-		return log_error(-1, "No gid mapping for container root");
-
-	hostuid = geteuid();
-	if (hostuid == 0) {
-		if (chown(path, rootuid, rootgid) < 0)
-			return log_error(-1, "Error chowning %s", path);
-
-		return 0;
-	}
-
-	/* nothing to do */
-	if (rootuid == hostuid)
-		return log_info(0, "Container root is our uid; no need to chown");
-
-	/* save the current gid of "path" */
-	if (stat(path, &sb) < 0)
-		return log_error(-1, "Error stat %s", path);
-
-	/* Update the path argument in case this was overlayfs. */
-	args1[sizeof(args1) / sizeof(args1[0]) - 2] = path;
-	args2[sizeof(args2) / sizeof(args2[0]) - 2] = path;
-
-	/*
-	 * A file has to be group-owned by a gid mapped into the
-	 * container, or the container won't be privileged over it.
-	 */
-	hostgid = getegid();
-	DEBUG("trying to chown \"%s\" to %d", path, hostgid);
-	if (sb.st_uid == hostuid &&
-	    mapped_hostid(sb.st_gid, conf, ID_TYPE_GID) < 0 &&
-	    chown(path, -1, hostgid) < 0)
-		return log_error(-1, "Failed chgrping %s", path);
-
-	/* "u:0:rootuid:1" */
-	ret = snprintf(map1, 100, "u:0:%d:1", rootuid);
-	if (ret < 0 || ret >= 100)
-		return log_error(-1, "Error uid printing map string");
-
-	/* "u:hostuid:hostuid:1" */
-	ret = snprintf(map2, 100, "u:%d:%d:1", hostuid, hostuid);
-	if (ret < 0 || ret >= 100)
-		return log_error(-1, "Error uid printing map string");
-
-	/* "g:0:rootgid:1" */
-	ret = snprintf(map3, 100, "g:0:%d:1", rootgid);
-	if (ret < 0 || ret >= 100)
-		return log_error(-1, "Error gid printing map string");
-
-	/* "g:pathgid:rootgid+pathgid:1" */
-	ret = snprintf(map4, 100, "g:%d:%d:1", (gid_t)sb.st_gid,
-		       rootgid + (gid_t)sb.st_gid);
-	if (ret < 0 || ret >= 100)
-		return log_error(-1, "Error gid printing map string");
-
-	/* "g:hostgid:hostgid:1" */
-	ret = snprintf(map5, 100, "g:%d:%d:1", hostgid, hostgid);
-	if (ret < 0 || ret >= 100)
-		return log_error(-1, "Error gid printing map string");
-
-	/* "0:pathgid" (chown) */
-	ret = snprintf(ugid, 100, "0:%d", (gid_t)sb.st_gid);
-	if (ret < 0 || ret >= 100)
-		return log_error(-1, "Error owner printing format string for chown");
-
-	if (hostgid == sb.st_gid)
-		ret = run_command(cmd_output, sizeof(cmd_output),
-				  chown_mapped_root_exec_wrapper,
-				  (void *)args1);
-	else
-		ret = run_command(cmd_output, sizeof(cmd_output),
-				  chown_mapped_root_exec_wrapper,
-				  (void *)args2);
-	if (ret < 0)
-		ERROR("lxc-usernsexec failed: %s", cmd_output);
-
-	return ret;
-}
-
 /* NOTE: Must not be called from inside the container namespace! */
 int lxc_create_tmp_proc_mount(struct lxc_conf *conf)
 {
diff --git a/src/lxc/conf.h b/src/lxc/conf.h
index 63d6e8cfb7..17cec5d596 100644
--- a/src/lxc/conf.h
+++ b/src/lxc/conf.h
@@ -443,7 +443,6 @@ extern int setup_resource_limits(struct lxc_list *limits, pid_t pid);
 extern int find_unmapped_nsid(const struct lxc_conf *conf, enum idtype idtype);
 extern int mapped_hostid(unsigned id, const struct lxc_conf *conf,
 			 enum idtype idtype);
-extern int chown_mapped_root(const char *path, const struct lxc_conf *conf);
 extern int userns_exec_1(const struct lxc_conf *conf, int (*fn)(void *),
 			 void *data, const char *fn_name);
 extern int userns_exec_full(struct lxc_conf *conf, int (*fn)(void *),
@@ -476,5 +475,9 @@ extern int userns_exec_minimal(const struct lxc_conf *conf,
 			       int (*fn_child)(void *), void *fn_child_data);
 extern int userns_exec_mapped_root(const char *path, int path_fd,
 				   const struct lxc_conf *conf);
+static inline int chown_mapped_root(const char *path, const struct lxc_conf *conf)
+{
+	return userns_exec_mapped_root(path, -EBADF, conf);
+}
 
 #endif /* __LXC_CONF_H */


More information about the lxc-devel mailing list