mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-08-14 12:56:46 +00:00
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:
parent
21da9912d4
commit
cb3e61fa37
@ -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 */
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user