Quoting Christian Seiler (christ...@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).
> 
> Signed-off-by: Christian Seiler <christ...@iwakd.de>

Thanks Christian!

Acked-by: Serge E. Hallyn <serge.hal...@ubuntu.com>

> ---
>  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 */

Note I'm still not sure what the comment above here means :)

> +     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

Reply via email to