From c99cfb2c1602203101eb324de4d23a7b57406318 Mon Sep 17 00:00:00 2001 From: Nicolas Iooss Date: Sun, 19 Apr 2020 11:43:45 +0200 Subject: [PATCH] sysnetwork: allow using "ip netns" When using network namespaces with `ip netns`, command `ip` creates files in `/run/netns` that are mountpoints for `nsfs`. For example: $ ip netns add VPN $ ls -Z /run/netns/VPN system_u:object_r:nsfs_t /run/netns/VPN $ findmnt /run/netns/VPN TARGET SOURCE FSTYPE OPTIONS /run/netns/VPN nsfs[net:[4026532371]] nsfs rw /run/netns/VPN nsfs[net:[4026532371]] nsfs rw From a shell CLI, it is possible to retrieve the name of the current network namespace: $ ip netns exec VPN bash $ ip netns identify $$ VPN This requires reading `/proc/$PID/ns/net`, which is labelled as a user domain. Allow this access using `userdom_read_all_users_state()`. Signed-off-by: Nicolas Iooss --- policy/modules/kernel/filesystem.if | 18 ++++++++++++++++++ policy/modules/system/sysnetwork.fc | 2 ++ policy/modules/system/sysnetwork.te | 14 ++++++++++++++ policy/modules/system/userdomain.if | 1 + 4 files changed, 35 insertions(+) diff --git a/policy/modules/kernel/filesystem.if b/policy/modules/kernel/filesystem.if index 7fefd48dd..41baab615 100644 --- a/policy/modules/kernel/filesystem.if +++ b/policy/modules/kernel/filesystem.if @@ -3620,6 +3620,24 @@ interface(`fs_read_nsfs_files',` allow $1 nsfs_t:file read_file_perms; ') +######################################## +## +## Unmount an nsfs filesystem. +## +## +## +## Domain allowed access. +## +## +# +interface(`fs_unmount_nsfs',` + gen_require(` + type nsfs_t; + ') + + allow $1 nsfs_t:filesystem unmount; +') + ######################################## ## ## Get the attributes of a pstore filesystem. diff --git a/policy/modules/system/sysnetwork.fc b/policy/modules/system/sysnetwork.fc index efbfbde1e..fddf9f693 100644 --- a/policy/modules/system/sysnetwork.fc +++ b/policy/modules/system/sysnetwork.fc @@ -81,6 +81,8 @@ ifdef(`distro_redhat',` /run/dhclient.* -- gen_context(system_u:object_r:dhcpc_runtime_t,s0) /run/dhcpcd(/.*)? gen_context(system_u:object_r:dhcpc_runtime_t,s0) +/run/netns -d gen_context(system_u:object_r:ifconfig_runtime_t,s0) +/run/netns/[^/]+ -- <> ifdef(`distro_gentoo',` /var/lib/dhcpc(/.*)? gen_context(system_u:object_r:dhcpc_state_t,s0) diff --git a/policy/modules/system/sysnetwork.te b/policy/modules/system/sysnetwork.te index f95e1387f..8b5e0c2f1 100644 --- a/policy/modules/system/sysnetwork.te +++ b/policy/modules/system/sysnetwork.te @@ -35,6 +35,9 @@ type ifconfig_exec_t; init_system_domain(ifconfig_t, ifconfig_exec_t) role system_r types ifconfig_t; +type ifconfig_runtime_t; +files_pid_file(ifconfig_runtime_t) + type net_conf_t; files_type(net_conf_t) @@ -303,6 +306,13 @@ allow ifconfig_t self:netlink_route_socket create_netlink_socket_perms; allow ifconfig_t self:netlink_xfrm_socket create_netlink_socket_perms; allow ifconfig_t self:tcp_socket { create ioctl }; +# Allow "ip netns" to remount /var/run/netns and to mount network namespace files on /var/run/netns/$NSNAME +allow ifconfig_t ifconfig_runtime_t:dir mounton; +allow ifconfig_t ifconfig_runtime_t:file mounton; +manage_files_pattern(ifconfig_t, ifconfig_runtime_t, ifconfig_runtime_t) +create_dirs_pattern(ifconfig_t, ifconfig_runtime_t, ifconfig_runtime_t) +files_pid_filetrans(ifconfig_t, ifconfig_runtime_t, dir) + kernel_use_fds(ifconfig_t) kernel_read_system_state(ifconfig_t) kernel_read_network_state(ifconfig_t) @@ -322,7 +332,9 @@ files_read_etc_files(ifconfig_t) files_read_etc_runtime_files(ifconfig_t) fs_getattr_xattr_fs(ifconfig_t) +fs_read_nsfs_files(ifconfig_t) fs_search_auto_mountpoints(ifconfig_t) +fs_unmount_nsfs(ifconfig_t) selinux_dontaudit_getattr_fs(ifconfig_t) @@ -345,6 +357,8 @@ seutil_use_runinit_fds(ifconfig_t) sysnet_dontaudit_rw_dhcpc_udp_sockets(ifconfig_t) +# For "ip netns identify $$" +userdom_read_all_users_state(ifconfig_t) userdom_use_user_terminals(ifconfig_t) userdom_use_all_users_fds(ifconfig_t) diff --git a/policy/modules/system/userdomain.if b/policy/modules/system/userdomain.if index c15a90a8b..d24297e32 100644 --- a/policy/modules/system/userdomain.if +++ b/policy/modules/system/userdomain.if @@ -4388,6 +4388,7 @@ interface(`userdom_read_all_users_state',` ') read_files_pattern($1, userdomain, userdomain) + read_lnk_files_pattern($1, userdomain, userdomain) kernel_search_proc($1) ')