From bfd292ec35c7b768f9fb5cff4d921f3133e62b19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 9 Oct 2016 11:44:03 -0400 Subject: [PATCH] nspawn: fix parsing of numeric arguments for --private-users The documentation says lists "yes", "no", "pick", and numeric arguments. But parse_boolean was attempted first, so various numeric arguments were misinterpreted. In particular, this fixes --private-users=0 to mean the same thing as --private-users=0:65536. While at it, use strndupa to avoid some error handling. Also give a better error for an empty UID range. I think it's likely that people will use --private-users=0:0 thinking that the argument means UID:GID. --- src/nspawn/nspawn.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index c3698b1a40..d29866c3fe 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -900,13 +900,12 @@ static int parse_argv(int argc, char *argv[]) { case ARG_PRIVATE_USERS: - r = optarg ? parse_boolean(optarg) : 1; - if (r == 0) { + if (streq_ptr(optarg, "no")) { /* no: User namespacing off */ arg_userns_mode = USER_NAMESPACE_NO; arg_uid_shift = UID_INVALID; arg_uid_range = UINT32_C(0x10000); - } else if (r > 0) { + } else if (!optarg || streq(optarg, "yes")) { /* yes: User namespacing on, UID range is read from root dir */ arg_userns_mode = USER_NAMESPACE_FIXED; arg_uid_shift = UID_INVALID; @@ -917,23 +916,20 @@ static int parse_argv(int argc, char *argv[]) { arg_uid_shift = UID_INVALID; arg_uid_range = UINT32_C(0x10000); } else { - _cleanup_free_ char *buffer = NULL; const char *range, *shift; /* anything else: User namespacing on, UID range is explicitly configured */ range = strchr(optarg, ':'); if (range) { - buffer = strndup(optarg, range - optarg); - if (!buffer) - return log_oom(); - shift = buffer; + shift = strndupa(optarg, range - optarg); range++; - if (safe_atou32(range, &arg_uid_range) < 0 || arg_uid_range <= 0) { - log_error("Failed to parse UID range: %s", range); - return -EINVAL; - } + r = safe_atou32(range, &arg_uid_range); + if (r < 0) + return log_error_errno(r, "Failed to parse UID range '%s': %m", range); + if (arg_uid_range == 0) + return log_error_errno(EINVAL, "UID range cannot be 0."); } else shift = optarg;