When attaching to a container with a user namespace, try to detect the user and group ids of init via /proc and attach as that same user. Only if that is unsuccessful, fall back to (0, 0).
Signed-off-by: Christian Seiler <christ...@iwakd.de> --- src/lxc/attach.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ src/lxc/attach.h | 2 ++ src/lxc/lxc_attach.c | 15 +++++++++++---- 3 files changed, 60 insertions(+), 4 deletions(-) diff --git a/src/lxc/attach.c b/src/lxc/attach.c index d1b3b0a..c74faf1 100644 --- a/src/lxc/attach.c +++ b/src/lxc/attach.c @@ -429,3 +429,50 @@ char *lxc_attach_getpwshell(uid_t uid) exit(-1); } } + +void lxc_attach_get_init_uidgid(uid_t* init_uid, gid_t* init_gid) +{ + FILE *proc_file; + char proc_fn[MAXPATHLEN]; + char *line = NULL; + size_t line_bufsz = 0; + int ret; + long value = -1; + uid_t uid = (uid_t)-1; + gid_t gid = (gid_t)-1; + + /* read capabilities */ + snprintf(proc_fn, MAXPATHLEN, "/proc/%d/status", 1); + + proc_file = fopen(proc_fn, "r"); + if (!proc_file) + return; + + while (getline(&line, &line_bufsz, proc_file) != -1) { + /* format is: real, effective, saved set user, fs + * we only care about real uid + */ + ret = sscanf(line, "Uid: %ld", &value); + if (ret != EOF && ret > 0) { + uid = (uid_t) value; + } else { + ret = sscanf(line, "Gid: %ld", &value); + if (ret != EOF && ret > 0) + gid = (gid_t) value; + } + if (uid != (uid_t)-1 && gid != (gid_t)-1) + break; + } + + fclose(proc_file); + free(line); + + /* only override arguments if we found something */ + if (uid != (uid_t)-1) + *init_uid = uid; + if (gid != (gid_t)-1) + *init_gid = gid; + + /* TODO: we should also parse supplementary groups and use + * setgroups() to set them */ +} diff --git a/src/lxc/attach.h b/src/lxc/attach.h index f448b1e..ef5d87b 100644 --- a/src/lxc/attach.h +++ b/src/lxc/attach.h @@ -40,4 +40,6 @@ extern int lxc_attach_drop_privs(struct lxc_proc_context_info *ctx); extern char *lxc_attach_getpwshell(uid_t uid); +extern void lxc_attach_get_init_uidgid(uid_t* init_uid, gid_t* init_gid); + #endif diff --git a/src/lxc/lxc_attach.c b/src/lxc/lxc_attach.c index 711e1de..25cc2d5 100644 --- a/src/lxc/lxc_attach.c +++ b/src/lxc/lxc_attach.c @@ -418,13 +418,20 @@ int main(int argc, char *argv[]) lxc_sync_fini(handler); if (namespace_flags & CLONE_NEWUSER) { - /* XXX FIXME this should get the uid of the container init and setuid to that */ - /* XXX FIXME or perhaps try to map in the lxc-attach caller's uid? */ - if (setgid(0)) { + uid_t init_uid = 0; + gid_t init_gid = 0; + + /* ignore errors, we will fall back to root in that case + * (/proc was not mounted etc.) + */ + lxc_attach_get_init_uidgid(&init_uid, &init_gid); + + /* try to set the uid/gid combination */ + if (setgid(init_gid)) { SYSERROR("switching to container gid"); return -1; } - if (setuid(0)) { + if (setuid(init_uid)) { SYSERROR("switching to container uid"); return -1; } -- 1.7.10.4 ------------------------------------------------------------------------------ Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the endpoint security space. For insight on selecting the right partner to tackle endpoint security challenges, access the full report. http://p.sf.net/sfu/symantec-dev2dev _______________________________________________ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel