From 3a49291f4b82e746294df1772e9ab7eb957a9771 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Thu, 26 Jan 2023 22:18:47 +0100 Subject: [PATCH] nspawn: Drop CAP_NET_BIND_SERVICE when in userns but not in netns If we're in a user namespace but not unsharing the network namespace, we won't be able to bind any privileged ports even with CAP_NET_BIND_SERVICE, so let's drop it from the retained capabilities so services can condition themselves on that. (cherry picked from commit 2642d22adc66771bd8bbb4187dc3de5472d04ad6) --- src/nspawn/nspawn.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 63fca75ad3..6c978b6c8b 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -1716,7 +1716,16 @@ static int parse_argv(int argc, char *argv[]) { * --directory=". */ arg_directory = TAKE_PTR(arg_template); - arg_caps_retain = (arg_caps_retain | plus | (arg_private_network ? UINT64_C(1) << CAP_NET_ADMIN : 0)) & ~minus; + arg_caps_retain |= plus; + arg_caps_retain |= arg_private_network ? UINT64_C(1) << CAP_NET_ADMIN : 0; + + /* If we're not unsharing the network namespace and are unsharing the user namespace, we won't have + * permissions to bind ports in the container, so let's drop the CAP_NET_BIND_SERVICE capability to + * indicate that. */ + if (!arg_private_network && arg_userns_mode != USER_NAMESPACE_NO && arg_uid_shift > 0) + arg_caps_retain &= ~(UINT64_C(1) << CAP_NET_BIND_SERVICE); + + arg_caps_retain &= ~minus; /* Make sure to parse environment before we reset the settings mask below */ r = parse_environment();