[lxc-devel] [PATCH 3/8] container creation: support unpriv container creation in user namespaces

Serge Hallyn serge.hallyn at ubuntu.com
Mon Jul 22 15:02:46 UTC 2013


Quoting Stéphane Graber (stgraber at ubuntu.com):
> On Fri, Jul 19, 2013 at 02:26:50PM +0000, Serge Hallyn wrote:
> > From: Serge Hallyn <serge.hallyn at ubuntu.com>
> > 
> > 1. lxcapi_create: don't try to unshare and mount for dir backed containers
> > 
> > It's unnecessary, and breaks unprivileged lxc-create (since unpriv users
> > cannot yet unshare(CLONE_NEWNS)).
> > 
> > 2. api_create: chown rootfs
> > 
> > chown rootfs to the host uid to which container root will be mapped
> > 
> > 3. create: run template in a mapped user ns
> > 
> > 4. use (setuid-root) newxidmap to set id_map if we are not root
> > 
> > This is needed to be able to set userns mappings as an unprivileged
> > user, for unprivileged lxc-start.
> > 
> > Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>
> > ---
> >  src/lxc/conf.c         | 107 +++++++++++++++++++++++++++-----
> >  src/lxc/conf.h         |   4 ++
> >  src/lxc/lxccontainer.c | 162 +++++++++++++++++++++++++++++++++++++++++++++----
> >  3 files changed, 244 insertions(+), 29 deletions(-)
> > 
> > diff --git a/src/lxc/conf.c b/src/lxc/conf.c
> > index 46320dd..2e202ec 100644
> > --- a/src/lxc/conf.c
> > +++ b/src/lxc/conf.c
> > @@ -2547,6 +2547,11 @@ static int write_id_mapping(enum idtype idtype, pid_t pid, const char *buf,
> >  	return ret < 0 ? ret : closeret;
> >  }
> >  
> > +int do_call_newxid(char *str)
> > +{
> > +	return system(str);
> > +}
> > +
> 
> Hmm, what? :)
> 
> Is that meant to evolve into something more than an alias of system()?

Heh, it started out as more.  I did at one point almost pull it out, but
then I wasn't quite sure yet what was going to happen with it in the
end.

I guess I can squash it.

> >  int lxc_map_ids(struct lxc_list *idmap, pid_t pid)
> >  {
> >  	struct lxc_list *iterator;
> > @@ -2554,31 +2559,49 @@ int lxc_map_ids(struct lxc_list *idmap, pid_t pid)
> >  	int ret = 0;
> >  	enum idtype type;
> >  	char *buf = NULL, *pos;
> > +	int am_root = (getuid() == 0);
> >  
> >  	for(type = ID_TYPE_UID; type <= ID_TYPE_GID; type++) {
> >  		int left, fill;
> > -
> > -		pos = buf;
> > -		lxc_list_for_each(iterator, idmap) {
> > -			/* The kernel only takes <= 4k for writes to /proc/<nr>/[ug]id_map */
> > -			if (!buf)
> > -				buf = pos = malloc(4096);
> > +		int had_entry = 0;
> > +		if (!buf) {
> > +			buf = pos = malloc(4096);
> >  			if (!buf)
> >  				return -ENOMEM;
> > +		}
> > +		pos = buf;
> > +		if (!am_root)
> > +			pos += sprintf(buf, "/usr/bin/new%cidmap %d ",
> 
> May be worth having autoconf figure out the paths for those as they very
> well may be moved to /bin.

Yeah, these should be done through autoconf.

Well, or we could use execvp as below.

As for usernsexec, we first need to figure out what program we actually
want to use.

Do we want to ship usernsexec.c with lxc, or do we want to push
something into coreutils that serves our purpose?

Normally I'd prefer the latter, but coreutils in ubuntu seems to be
lagging - and upstream hasn't done a release lately - so I didn't
want to deal with it right now.

-serge




More information about the lxc-devel mailing list