diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2016-10-20 23:41:21 -0400 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2016-10-26 20:12:51 -0400 |
commit | 299a34c11a4241f8c5832ccd5a7bc13263f8488b (patch) | |
tree | f67f997d142debec99297a095f4687f65bf7c00e /src/detect-virt/detect-virt.c | |
parent | 24597ee0e626b61f134e09b4e871449ef86b1343 (diff) |
detect-virt: add --private-users switch to check if a userns is active
Various things don't work when we're running in a user namespace, but it's
pretty hard to reliably detect if that is true.
A function is added which looks at /proc/self/uid_map and returns false
if the default "0 0 UINT32_MAX" is found, and true if it finds anything else.
This misses the case where an 1:1 mapping with the full range was used, but
I don't know how to distinguish this case.
'systemd-detect-virt --private-users' is very similar to
'systemd-detect-virt --chroot', but we check for a user namespace instead.
Diffstat (limited to 'src/detect-virt/detect-virt.c')
-rw-r--r-- | src/detect-virt/detect-virt.c | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/src/detect-virt/detect-virt.c b/src/detect-virt/detect-virt.c index 5d51589a31..4b8956f0ad 100644 --- a/src/detect-virt/detect-virt.c +++ b/src/detect-virt/detect-virt.c @@ -31,6 +31,7 @@ static enum { ONLY_VM, ONLY_CONTAINER, ONLY_CHROOT, + ONLY_PRIVATE_USERS, } arg_mode = ANY_VIRTUALIZATION; static void help(void) { @@ -41,6 +42,7 @@ static void help(void) { " -c --container Only detect whether we are run in a container\n" " -v --vm Only detect whether we are run in a VM\n" " -r --chroot Detect whether we are run in a chroot() environment\n" + " --private-users Only detect whether we are running in a user namespace\n" " -q --quiet Don't output anything, just set return value\n" , program_invocation_short_name); } @@ -48,16 +50,18 @@ static void help(void) { static int parse_argv(int argc, char *argv[]) { enum { - ARG_VERSION = 0x100 + ARG_VERSION = 0x100, + ARG_PRIVATE_USERS, }; static const struct option options[] = { - { "help", no_argument, NULL, 'h' }, - { "version", no_argument, NULL, ARG_VERSION }, - { "container", no_argument, NULL, 'c' }, - { "vm", no_argument, NULL, 'v' }, - { "chroot", no_argument, NULL, 'r' }, - { "quiet", no_argument, NULL, 'q' }, + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + { "container", no_argument, NULL, 'c' }, + { "vm", no_argument, NULL, 'v' }, + { "chroot", no_argument, NULL, 'r' }, + { "private-users", no_argument, NULL, ARG_PRIVATE_USERS }, + { "quiet", no_argument, NULL, 'q' }, {} }; @@ -85,6 +89,10 @@ static int parse_argv(int argc, char *argv[]) { arg_mode = ONLY_CONTAINER; break; + case ARG_PRIVATE_USERS: + arg_mode = ONLY_PRIVATE_USERS; + break; + case 'v': arg_mode = ONLY_VM; break; @@ -151,6 +159,15 @@ int main(int argc, char *argv[]) { return r ? EXIT_SUCCESS : EXIT_FAILURE; + case ONLY_PRIVATE_USERS: + r = running_in_userns(); + if (r < 0) { + log_error_errno(r, "Failed to check for user namespace: %m"); + return EXIT_FAILURE; + } + + return r ? EXIT_SUCCESS : EXIT_FAILURE; + case ANY_VIRTUALIZATION: default: r = detect_virtualization(); |