[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 20:16:09 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).
> 
> Signed-off-by: Christian Seiler <christian at iwakd.de>

Thanks Christian!

Acked-by: Serge E. Hallyn <serge.hallyn at 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
> 




More information about the lxc-devel mailing list