[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