[lxc-devel] [lxc/master] lxc_unshare: Add uid_mapping when creating userns

marcosps on Github lxc-bot at linuxcontainers.org
Wed Nov 29 15:11:23 UTC 2017


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 956 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20171129/ee749002/attachment.bin>
-------------- next part --------------
From 2a6e985bfbe8699a59e6c266ebdfbb462b6ad995 Mon Sep 17 00:00:00 2001
From: Marcos Paulo de Souza <marcos.souza.org at gmail.com>
Date: Tue, 28 Nov 2017 23:49:28 -0200
Subject: [PATCH] lxc_unshare: Add uid_mapping when creating userns

Change conf.c to export function write_id_mapping, which will now be
called inside main function of lxc_unshare.c.

This is required because setuid syscalls only permits a new userns to
set a new uid if the uid of parameter is mapped inside the ns using
uid_map file[1]. So, just after the clone invocation, map the uid passed as
parameter into the newly created user namespace, and put the current uid
as the ID-outside-ns. After the mapping is done, setuid call succeeds.

Closes: #494

[1] https://elixir.free-electrons.com/linux/latest/source/kernel/user_namespace.c#L286

Signed-off-by: Marcos Paulo de Souza <marcos.souza.org at gmail.com>
---
 src/lxc/conf.c              |  2 +-
 src/lxc/conf.h              |  3 +++
 src/lxc/tools/lxc_unshare.c | 29 +++++++++++++++++++++++++++++
 3 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index ae30b5b87..611b23a50 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -2431,7 +2431,7 @@ struct lxc_conf *lxc_conf_init(void)
 	return new;
 }
 
-static int write_id_mapping(enum idtype idtype, pid_t pid, const char *buf,
+int write_id_mapping(enum idtype idtype, pid_t pid, const char *buf,
 			    size_t buf_size)
 {
 	char path[MAXPATHLEN];
diff --git a/src/lxc/conf.h b/src/lxc/conf.h
index 58302cf30..f6c453a45 100644
--- a/src/lxc/conf.h
+++ b/src/lxc/conf.h
@@ -361,6 +361,9 @@ struct lxc_conf {
 	char *inherit_ns[LXC_NS_MAX];
 };
 
+int write_id_mapping(enum idtype idtype, pid_t pid, const char *buf,
+			    size_t buf_size);
+
 #ifdef HAVE_TLS
 extern __thread struct lxc_conf *current_config;
 #else
diff --git a/src/lxc/tools/lxc_unshare.c b/src/lxc/tools/lxc_unshare.c
index 1b56d31b3..bfdb206dd 100644
--- a/src/lxc/tools/lxc_unshare.c
+++ b/src/lxc/tools/lxc_unshare.c
@@ -31,6 +31,7 @@
 #include <signal.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/eventfd.h>
 #include <sys/socket.h>
 #include <sys/types.h>
 #include <sys/wait.h>
@@ -44,6 +45,10 @@
 #include "network.h"
 #include "utils.h"
 
+
+static int wait_fd = -1;
+static int val = 0;
+
 struct my_iflist
 {
 	char *mi_ifname;
@@ -112,6 +117,9 @@ static int do_start(void *arg)
 	int want_default_mounts = start_arg->want_default_mounts;
 	const char *want_hostname = start_arg->want_hostname;
 
+	/* waiting until uid maps is set */
+	read(wait_fd, &val, sizeof(char));
+
 	if ((flags & CLONE_NEWNS) && want_default_mounts)
 		lxc_setup_fs();
 
@@ -241,12 +249,33 @@ int main(int argc, char *argv[])
 		exit(EXIT_FAILURE);
 	}
 
+	if (start_arg.setuid) {
+		wait_fd = eventfd(0, EFD_CLOEXEC);
+		if (wait_fd == -1) {
+			perror("eventfd");
+			exit(EXIT_FAILURE);
+		}
+	}
+
 	pid = lxc_clone(do_start, &start_arg, flags);
 	if (pid < 0) {
 		fprintf(stderr, "failed to clone\n");
 		exit(EXIT_FAILURE);
 	}
 
+	if (start_arg.setuid) {
+		char *umap = (char *)alloca(100);
+		/* create new uid mapping using current UID and the one
+		 * specified as parameter
+		 */
+		snprintf(umap, 100, "%d %d 1", *(start_arg.uid), getuid());
+		if (write_id_mapping(ID_TYPE_UID, pid, umap, strlen(umap))) {
+			fprintf(stderr, "uid mapping failed\n");
+			exit(EXIT_FAILURE);
+		}
+		write(wait_fd, &val, 8);
+	}
+
 	if (my_iflist) {
 		for (tmpif = my_iflist; tmpif; tmpif = tmpif->mi_next) {
 			if (lxc_netdev_move_by_name(tmpif->mi_ifname, pid, NULL) < 0)


More information about the lxc-devel mailing list