summaryrefslogtreecommitdiff
path: root/src/detect-virt
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2016-10-20 23:41:21 -0400
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2016-10-26 20:12:51 -0400
commit299a34c11a4241f8c5832ccd5a7bc13263f8488b (patch)
treef67f997d142debec99297a095f4687f65bf7c00e /src/detect-virt
parent24597ee0e626b61f134e09b4e871449ef86b1343 (diff)
downloadsystemd-299a34c11a4241f8c5832ccd5a7bc13263f8488b.tar.gz
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')
-rw-r--r--src/detect-virt/detect-virt.c31
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();