[lxc-devel] [PATCH 3/3] lxc-attach: User namespaces: Use init's user & group id when attaching
Serge Hallyn
serge.hallyn at ubuntu.com
Wed Mar 6 15:46:50 UTC 2013
Quoting Christian Seiler (christian at iwakd.de):
> 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).
> ---
> src/lxc/attach.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++
> src/lxc/attach.h | 2 ++
> src/lxc/lxc_attach.c | 15 ++++++++++----
> 3 files changed, 66 insertions(+), 4 deletions(-)
>
> diff --git a/src/lxc/attach.c b/src/lxc/attach.c
> index 88356e1..399ec36 100644
> --- a/src/lxc/attach.c
> +++ b/src/lxc/attach.c
> @@ -479,3 +479,56 @@ struct passwd *lxc_attach_getpwuid(uid_t uid)
> exit(-1);
> }
> }
> +
> +int 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 */
What does this comment mean?
> + snprintf(proc_fn, MAXPATHLEN, "/proc/%d/status", 1);
> +
> + proc_file = fopen(proc_fn, "r");
> + if (!proc_file)
> + return -1;
> +
> + 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 */
> +
> + /* at least some entries were not found, we return error */
> + if (uid == (uid_t)-1 || gid == (gid_t)-1)
> + return -1;
> +
> + return 0;
> +}
> diff --git a/src/lxc/attach.h b/src/lxc/attach.h
> index 90e693a..1e9b87e 100644
> --- a/src/lxc/attach.h
> +++ b/src/lxc/attach.h
> @@ -41,4 +41,6 @@ extern int lxc_attach_drop_privs(struct lxc_proc_context_info *ctx);
> struct passwd;
> extern struct passwd *lxc_attach_getpwuid(uid_t uid);
>
> +extern int 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 9c86ffe..cdc1601 100644
> --- a/src/lxc/lxc_attach.c
> +++ b/src/lxc/lxc_attach.c
> @@ -417,13 +417,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.)
> + */
It's fine if you want to do that, but then please have
lxc_attach_get_init_uidgid() return void, drop this comment
and drop the cast below :)
But also... you don't actually re-try with init_gid/init_uid of 0.
If lxc_attach_get_init_uidgid() set one of those to -1, then you'll
just fail here.
> + (void) 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
>
More information about the lxc-devel
mailing list