[CRIU] [PATCH 4/5] userns: parse /proc/PID/{u,g}id_map

Andrew Vagin avagin at parallels.com
Mon Feb 10 21:17:38 PST 2014


On Tue, Feb 11, 2014 at 08:47:48AM +0400, Pavel Emelyanov wrote:
> On 02/11/2014 12:58 AM, Andrey Vagin wrote:
> > Signed-off-by: Andrey Vagin <avagin at openvz.org>
> > ---
> >  namespaces.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
> >  1 file changed, 105 insertions(+), 2 deletions(-)
> > 
> > diff --git a/namespaces.c b/namespaces.c
> > index 8119d99..524b47b 100644
> > --- a/namespaces.c
> > +++ b/namespaces.c
> > @@ -15,6 +15,7 @@
> >  
> >  #include "protobuf.h"
> >  #include "protobuf/ns.pb-c.h"
> > +#include "protobuf/userns.pb-c.h"
> >  
> >  static struct ns_desc *ns_desc_array[] = {
> >  	&net_ns_desc,
> > @@ -388,12 +389,114 @@ int gen_predump_ns_mask(void)
> >  	return 0;
> >  }
> >  
> > -static int dump_user_ns(pid_t pid, int ns_id)
> > +static int parse_id_map(pid_t pid, char *name, UidGidExtent ***pb_exts)
> >  {
> > -	pr_err("User namesapces are not supported yet\n");
> > +	UidGidExtent *extents = NULL;
> > +	int len = 0, size = 0, fd, ret, i;
> > +	FILE *f;
> > +
> > +	fd = open_proc(pid, "%s", name);
> 
> fd is left opened.

No, it isn't

The file  descriptor is not dup'ed, and will be closed when the
stream created by fdopen() is closed

> 
> > +	if (fd < 0) {
> > +		pr_perror("Unable to open %s", name);
> > +		return -1;
> 
> Will it always fail on Fedora with USER_NS turned off?

It is executed only if a processes executed in another userns

> 
> > +	}
> > +
> > +	f = fdopen(fd, "r");
> 
> Why not fopen_proc() instead?

I didn't know that we have it. Thanks

> 
> > +	if (f == NULL) {
> > +		close(fd);
> > +		return -1;
> > +	}
> > +
> > +	ret = -1;
> > +	while (1) {
> > +		UidGidExtent *ext;
> > +
> > +		if (len == size) {
> > +			UidGidExtent *t;
> > +
> > +			size = size * 2 + 1;
> > +			t = xrealloc(extents, size * sizeof(UidGidExtent));
> > +			if (t == NULL)
> > +				break;
> > +			extents = t;
> > +		}
> > +
> > +		ext = &extents[len];
> > +
> > +		uid_gid_extent__init(ext);
> > +		ret = fscanf(f, "%d %d %d", &ext->first,
> > +				&ext->lower_first, &ext->count);
> > +		if (ret != 3) {
> > +			if (errno != 0) {
> > +				pr_perror("Unable to parse extents");
> > +				ret = -1;
> > +			} else
> > +				ret = 0;
> > +			break;
> > +		}
> > +		pr_err("%d %d %d\n", ext->first, ext->lower_first, ext->count);
> > +		len++;
> > +	}
> > +
> > +	fclose(f);
> > +
> > +	if (ret)
> > +		goto err;
> > +
> > +	if (len) {
> > +		*pb_exts = xmalloc(sizeof(UidGidExtent *) * len);
> > +		if (*pb_exts == NULL)
> > +			goto err;
> > +
> > +		for (i = 0; i < len; i++)
> > +			*pb_exts[i] = &extents[i];
> > +	} else {
> > +		xfree(extents);
> > +		*pb_exts = NULL;
> > +	}
> > +
> > +	return len;
> > +err:
> > +	xfree(extents);
> >  	return -1;
> >  }
> >  
> > +static int dump_user_ns(pid_t pid, int ns_id)
> > +{
> > +	UsernsEntry e = USERNS_ENTRY__INIT;
> > +	int fd, ret, exit_code = -1;
> > +
> > +	ret = parse_id_map(pid, "uid_map", &e.uid_map);
> > +	if (ret < 0)
> > +		goto err;
> > +	e.n_uid_map = ret;
> > +
> > +	ret = parse_id_map(pid, "gid_map", &e.gid_map);
> > +	if (ret < 0)
> > +		goto err;
> > +	e.n_gid_map = ret;
> > +
> > +	fd = open_image(CR_FD_USERNS, O_DUMP, ns_id);
> > +	if (fd < 0)
> > +		goto err;
> > +	ret = pb_write_one(fd, &e, PB_USERNS);
> > +	close(fd);
> > +	if (ret < 0)
> > +		goto err;
> > +
> > +	exit_code = 0;
> > +err:
> > +	if (e.uid_map) {
> > +		xfree(e.uid_map[0]);
> > +		xfree(e.uid_map);
> > +	}
> > +	if (e.gid_map) {
> > +		xfree(e.gid_map[0]);
> > +		xfree(e.gid_map);
> > +	}
> > +	return exit_code;
> > +}
> > +
> >  static int do_dump_namespaces(struct ns_id *ns)
> >  {
> >  	int ret = -1;
> > 
> 
> 


More information about the CRIU mailing list