]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
execute: don't honour PrivateNetwork() if we lack CAP_NET_ADMIN
authorLennart Poettering <lennart@poettering.net>
Fri, 23 Jun 2023 14:06:29 +0000 (16:06 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 23 Jun 2023 20:52:13 +0000 (22:52 +0200)
Somehow the Linux kernel allows us to allocate a network namespace if we
possess CAP_SYS_ADMIN but doesn't allow us to configure it, unless we
also have CAP_NET_ADMIN.

Taking that into consideration let's avoid allocating a network
namespace we cannot even configure "lo" in.

This is common case if nspawn is invoked without userns and without
netns, because in that case it will have CAP_SYS_ADMIN but no
CAP_NET_ADMIN.

This also takes down a notch the messages about the automatic
downgrading. These have been LOG_WARNING so far, and I downgraded them
to LOG_NOTICE, since in an environment where CAP_NET_ADMIN is not
available this is really not something to be concerned about, but still
noticable. With that it's still more priorized than regular LOG_INFO.

Fixes: #27292
src/core/execute.c

index 90af8fa619d9b0ed64c9290b308ec0aeb0640e3d..9c0a2f4e8f72f8aa620c03fe8e359ea1fab9e16f 100644 (file)
@@ -5412,12 +5412,16 @@ static int exec_child(
 
         if (exec_needs_network_namespace(context) && runtime && runtime->shared && runtime->shared->netns_storage_socket[0] >= 0) {
 
-                if (ns_type_supported(NAMESPACE_NET)) {
+                /* Try to enable network namespacing if network namespacing is available and we have
+                 * CAP_NET_ADMIN. We need CAP_NET_ADMIN to be able to configure the loopback device in the
+                 * new network namespace. And if we don't have that, then we could only create a network
+                 * namespace without the ability to set up "lo". Hence gracefully skip things then. */
+                if (ns_type_supported(NAMESPACE_NET) && have_effective_cap(CAP_NET_ADMIN) > 0) {
                         r = setup_shareable_ns(runtime->shared->netns_storage_socket, CLONE_NEWNET);
                         if (r < 0) {
                                 if (ERRNO_IS_PRIVILEGE(r))
-                                        log_unit_warning_errno(unit, r,
-                                                               "PrivateNetwork=yes is configured, but network namespace setup failed, ignoring: %m");
+                                        log_unit_notice_errno(unit, r,
+                                                               "PrivateNetwork=yes is configured, but network namespace setup not permitted, proceeding without: %m");
                                 else {
                                         *exit_status = EXIT_NETWORK;
                                         return log_unit_error_errno(unit, r, "Failed to set up network namespacing: %m");
@@ -5428,7 +5432,7 @@ static int exec_child(
                         return log_unit_error_errno(unit, SYNTHETIC_ERRNO(EOPNOTSUPP),
                                                     "NetworkNamespacePath= is not supported, refusing.");
                 } else
-                        log_unit_warning(unit, "PrivateNetwork=yes is configured, but the kernel does not support network namespaces, ignoring.");
+                        log_unit_notice(unit, "PrivateNetwork=yes is configured, but the kernel does not support or we lack privileges for network namespace, proceeding without.");
         }
 
         if (exec_needs_ipc_namespace(context) && runtime && runtime->shared && runtime->shared->ipcns_storage_socket[0] >= 0) {