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

Djalal Harouni tixxdz at opendz.org
Thu Jan 8 12:11:24 PST 2015


On Thu, Jan 08, 2015 at 02:59:46PM -0500, Stéphane Graber wrote:
> 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.
Yes, then that code comment is confusing.

Thanks!

> > 
> > Cheers,
> > 
> > Tom
> 
> -- 
> Stéphane Graber
> Ubuntu developer
> http://www.ubuntu.com



> _______________________________________________
> systemd-devel mailing list
> systemd-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/systemd-devel


-- 
Djalal Harouni
http://opendz.org


More information about the systemd-devel mailing list