Hi On Fri, Jan 9, 2015 at 12:07 AM, Stéphane Graber <stgra...@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 | 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. 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 > systemd-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/systemd-devel _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel