]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core/namespace: mount new sysfs when new network namespace is requested
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 17 Feb 2023 04:50:17 +0000 (13:50 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 23 Feb 2023 06:09:13 +0000 (15:09 +0900)
Even when a mount namespace is created, previously host's sysfs is used,
especially with RootDirectory= or RootImage=, thus service processes can
still access the properties of the network interfaces in the main network
namespace through sysfs.

This makes, sysfs is remounted with the new network namespace tag, except
when PrivateMounts= is explicitly disabled. Hence, the properties of the
network interfaces in the main network namespace cannot be accessed by
service processes through sysfs.

Fixes #26422.

man/systemd.exec.xml
src/core/execute.c
src/core/namespace.c
src/core/namespace.h

index bad21ceb0c2bc7792e542a3f100a80a9fc47b526..daa2a595f05d12b6fcb94d6c6653bbf8ae8adfd2 100644 (file)
@@ -1663,6 +1663,10 @@ BindReadOnlyPaths=/var/lib/systemd</programlisting>
         not available), and the unit should be written in a way that does not solely rely on this setting for
         security.</para>
 
+        <para>When this option is enabled, <varname>PrivateMounts=</varname> is implied unless it is
+        explicitly disabled, and <filename>/sys</filename> will be remounted to associate it with the new
+        network namespace.</para>
+
         <para>When this option is used on a socket unit any sockets bound on behalf of this unit will be
         bound within a private network namespace. This may be combined with
         <varname>JoinsNamespaceOf=</varname> to listen on sockets inside of network namespaces of other
@@ -1684,6 +1688,10 @@ BindReadOnlyPaths=/var/lib/systemd</programlisting>
         <varname>NetworkNamespacePath=</varname> configured, as otherwise the network namespace of those
         units is reused.</para>
 
+        <para>When this option is enabled, <varname>PrivateMounts=</varname> is implied unless it is
+        explicitly disabled, and <filename>/sys</filename> will be remounted to associate it with the new
+        network namespace.</para>
+
         <para>When this option is used on a socket unit any sockets bound on behalf of this unit will be
         bound within the specified network namespace.</para>
 
index 39ece6e7358af2d4ac41bb6b7dab97042dc5b107..3971695fb668dd2da883402e8e06dfcdc8c170fb 100644 (file)
@@ -2075,6 +2075,7 @@ bool exec_needs_mount_namespace(
 
         if (context->private_devices ||
             context->private_mounts > 0 ||
+            (context->private_mounts < 0 && exec_needs_network_namespace(context)) ||
             context->protect_system != PROTECT_SYSTEM_NO ||
             context->protect_home != PROTECT_HOME_NO ||
             context->protect_kernel_tunables ||
@@ -3606,6 +3607,7 @@ static int apply_mount_namespace(
                         .protect_system = context->protect_system,
                         .protect_proc = context->protect_proc,
                         .proc_subset = context->proc_subset,
+                        .private_network = exec_needs_network_namespace(context),
                         .private_ipc = exec_needs_ipc_namespace(context),
                         /* If NNP is on, we can turn on MS_NOSUID, since it won't have any effect anymore. */
                         .mount_nosuid = context->no_new_privileges && !mac_selinux_use(),
index 8e3c272f40f6676882d004007afb03adf2b7f1e9..3b0896039bc13a37895c179ab471b0b72b65f59a 100644 (file)
@@ -1748,6 +1748,7 @@ static size_t namespace_calculate_mounts(
                 !!log_namespace +
                 setup_propagate + /* /run/systemd/incoming */
                 !!notify_socket +
+                ns_info->private_network + /* /sys */
                 ns_info->private_ipc; /* /dev/mqueue */
 }
 
@@ -2354,6 +2355,12 @@ int setup_namespace(
                         };
                 }
 
+                if (ns_info->private_network)
+                        *(m++) = (MountEntry) {
+                                .path_const = "/sys",
+                                .mode = PRIVATE_SYSFS,
+                        };
+
                 if (ns_info->private_ipc)
                         *(m++) = (MountEntry) {
                                 .path_const = "/dev/mqueue",
index 70e27994cc4bb8894a88482d9d896c87699fe9b7..74f78784b6805636b4ae36f9ed73ba210a699235 100644 (file)
@@ -61,6 +61,7 @@ struct NamespaceInfo {
         bool protect_kernel_logs;
         bool mount_apivfs;
         bool protect_hostname;
+        bool private_network;
         bool private_ipc;
         bool mount_nosuid;
         ProtectHome protect_home;