[systemd-devel] [PATCH 1/2] Add detect_userns to detect uid/gid shifts

Stéphane Graber stgraber at ubuntu.com
Thu Jan 8 11:59:46 PST 2015


On Thu, Jan 08, 2015 at 08:43:12PM +0100, Tom Gundersen wrote:
> On Thu, Jan 8, 2015 at 8:27 PM, Stéphane Graber <stgraber at ubuntu.com> wrote:
> > This adds a new detect_userns function in virt.c which will check
> > whether systemd is running in the host user namespace (single map of all
> > available uids and gids) or is using a uid/gid map.
> >
> > The check makes sure that uid_map and gid_map are both exactly equal to
> > the default host map (assuming 32bit uid_t) for a process running in the
> > host namespace.
> > ---
> >  src/shared/virt.c | 22 ++++++++++++++++++++++
> >  src/shared/virt.h |  1 +
> >  2 files changed, 23 insertions(+)
> >
> > diff --git a/src/shared/virt.c b/src/shared/virt.c
> > index f10baab..3d94e1f 100644
> > --- a/src/shared/virt.c
> > +++ b/src/shared/virt.c
> > @@ -363,3 +363,25 @@ int detect_virtualization(const char **id) {
> >
> >          return VIRTUALIZATION_NONE;
> >  }
> > +
> > +/* Detect whether we run in a uid/gid shifted namespace */
> > +int detect_userns(void) {
> > +        int r;
> > +        static const char host_id_map[] = "         0          0 4294967295";
> > +        char *uid_map = NULL;
> > +        char *gid_map = NULL;
> > +
> > +        /* Check if we are uid-shifted */
> > +        r = read_one_line_file("/proc/self/uid_map", &uid_map);
> > +        if (r == 0 && !streq(uid_map, host_id_map))
> > +                return 1;
> > +
> > +        /* Check if we are gid-shifted */
> > +        r = read_one_line_file("/proc/self/gid_map", &gid_map);
> > +        if (r == 0 && !streq(gid_map, host_id_map))
> 
> Minor nit: would be nicer to parse these strings into numbers rather
> than rely on the whitespace never changing, no? Also, would be a bit
> nicer not to use the magic number 4294967295 but some #defined
> constant instead.

Sure, I'll do that.

> > +                return 1;
> > +
> > +        /* If both uid_map and gid_map don't exist or if they both match
> > +         * the full uid/gid range, then we're not inside a user namespace */
> 
> Hm, this is not necessarily true is it? In my naive test, it works
> just fine to set up a usernamespace with the identity mapping.
> Moreover, this appears to be functionally different from the initial
> user namespaces (somewhat counter-intuitively I might add), so
> treating the identity mapping as 'no user namespace' is probably not
> the right thing to do.
> 
> Is there no better way to test for this?

I'm not sure I understand what you mean there.

When you unshare CLONE_NEWUSER, your uid_map and gid_map are empty. You
can then write a map using your own uid and gid or use a privileged
helper to write a larger map.

The only case where you could be in a separate user namespace and still
have the same map as the host is if you had a privileged helper write
the whole host uid and gid map to your process' uid_map and gid_map, in
which case, your process' uid 0 is mapped to the host uid 0 and while
you are technically in a different namespace than the host, your
accesses are identical and so it's not unreasonable to have
detect_userns report this as the host namespace.

> 
> Cheers,
> 
> Tom

-- 
Stéphane Graber
Ubuntu developer
http://www.ubuntu.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.freedesktop.org/archives/systemd-devel/attachments/20150108/ccdbe3ca/attachment.sig>


More information about the systemd-devel mailing list