lxc-attach: User namespaces: Use init's user & group id when attaching

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 <christian@iwakd.de>
This commit is contained in:
Christian Seiler 2013-03-06 20:43:52 +01:00 committed by Serge Hallyn
parent 21da9912d4
commit cb3e61fa37
3 changed files with 60 additions and 4 deletions

View File

@ -428,3 +428,50 @@ char *lxc_attach_getpwshell(uid_t uid)
exit(-1); 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 */
}

View File

@ -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 char *lxc_attach_getpwshell(uid_t uid);
extern void lxc_attach_get_init_uidgid(uid_t* init_uid, gid_t* init_gid);
#endif #endif

View File

@ -418,13 +418,20 @@ int main(int argc, char *argv[])
lxc_sync_fini(handler); lxc_sync_fini(handler);
if (namespace_flags & CLONE_NEWUSER) { if (namespace_flags & CLONE_NEWUSER) {
/* XXX FIXME this should get the uid of the container init and setuid to that */ uid_t init_uid = 0;
/* XXX FIXME or perhaps try to map in the lxc-attach caller's uid? */ gid_t init_gid = 0;
if (setgid(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"); SYSERROR("switching to container gid");
return -1; return -1;
} }
if (setuid(0)) { if (setuid(init_uid)) {
SYSERROR("switching to container uid"); SYSERROR("switching to container uid");
return -1; return -1;
} }