On Fri, Jan 09, 2015 at 11:08:26AM +0100, David Herrmann wrote: > Hi > > On Fri, Jan 9, 2015 at 12:07 AM, Stéphane Graber <[email protected]> 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 | 43 +++++++++++++++++++++++++++++++++++++++++++ > > src/shared/virt.h | 1 + > > 2 files changed, 44 insertions(+) > > > > diff --git a/src/shared/virt.c b/src/shared/virt.c > > index f10baab..7fa8d0b 100644 > > --- a/src/shared/virt.c > > +++ b/src/shared/virt.c > > @@ -22,6 +22,7 @@ > > #include <string.h> > > #include <errno.h> > > #include <unistd.h> > > +#include <limits.h> > > > > #include "util.h" > > #include "virt.h" > > @@ -363,3 +364,45 @@ 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; > > + > > + _cleanup_free_ char* uid_map = NULL; > > + _cleanup_free_ char* gid_map = NULL; > > + > > + uid_t id_host = 0; > > + uid_t id_container = 0; > > + uid_t id_count = 0; > > + > > + /* Check if we are uid-shifted */ > > + r = read_one_line_file("/proc/self/uid_map", &uid_map); > > + if (r == 0 && > > + sscanf(uid_map, "%u %u %u", &id_host, &id_container, > > &id_count) && > > + (id_host != 0 || id_container != 0 || id_count != UINT_MAX)) > > + return 1; > > + > > + /* Check if we are gid-shifted */ > > + r = read_one_line_file("/proc/self/gid_map", &gid_map); > > + if (r == 0 && > > + sscanf(gid_map, "%u %u %u", &id_host, &id_container, > > &id_count) && > > + (id_host != 0 || id_container != 0 || id_count != UINT_MAX)) > > + return 1; > > + > > Do these files describe the mapping into the init_user_ns or into the > parent namespace? Because in the second case, if you create a > user-namespace with a non-identity mapping and inside of it a user-ns > with an identity-mapping, your detect_userns() will return 0, even > though you run in a user-namespace.
Into the parent namespace.
An example is:
- host (0 0 4294967295) (init_user_ns all uids mapped)
- container (0 1000000 1000000) (a million uids mapped from 0 to 1000000 in
the namespace, corresponding to 1000000 to 1999999 on the host)
- sub-container (0 100000 65536) (65536 uids mapped from 0 to 65536 in the
namespace, corresponding to 100000 to 165534 in container and 1100000 to
1165534 on the host)
You can't create a new userns mapping uids which aren't in your own
userns so the child userns map will at most be the same as its parent.
So it's therefore impossible to have a sub-userns with a map of "0 0
4294967295" if its parent userns has something more restrictive. If it
doesn't, then we're back in that last corner case where you can indeed
create userns with a map identical to the init_user_ns map in which case
uid 0 in container == uid 0 on the host.
>
> Thanks
> David
>
> > + /* In the following cases, let's assume we are in the host
> > namespace:
> > + - Neither uid_map nor gid_map exist in /proc/self.
> > + (this indicates lack of userns support in the kernel)
> > +
> > + - Both the uid and gid map equals to the complete set of
> > available
> > + uids or gids. This can only be true on the host namespace or
> > if a
> > + container was setup to have the same map as the host.
> > +
> > + That last possibility isn't detectable short of guessing
> > + based on syscall results but there's also no real use case
> > + for such a setup (why create a new uid/gid mapping namespace
> > + if you then re-use the host map as-is?).
> > + */
> > +
> > + return 0;
> > +}
> > diff --git a/src/shared/virt.h b/src/shared/virt.h
> > index 7194ab2..e19c7e8 100644
> > --- a/src/shared/virt.h
> > +++ b/src/shared/virt.h
> > @@ -33,3 +33,4 @@ enum {
> > };
> >
> > int detect_virtualization(const char **id);
> > +int detect_userns(void);
> > --
> > 1.9.1
> >
> > _______________________________________________
> > systemd-devel mailing list
> > [email protected]
> > http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
Stéphane Graber
Ubuntu developer
http://www.ubuntu.com
signature.asc
Description: Digital signature
_______________________________________________ systemd-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/systemd-devel
