SELinuxProject / refpolicy

SELinux Reference Policy v2
https://github.com/SELinuxProject/refpolicy/wiki
GNU General Public License v2.0
297 stars 128 forks source link

Allow system_dbusd_t read/write privilege to tun_tap_device_t #190

Closed dsommers closed 4 years ago

dsommers commented 4 years ago

I'm working on the OpenVPN 3 Linux project which is a brand new OpenVPN client which makes heavy use of D-Bus to solve a lot of challenges the current OpenVPN 2.x generation has on modern Linux systems.

OpenVPN 3 Linux depends heavily on D-Bus, where multiple daemons serve very specific task and the IPC happens over D-Bus. One challenge we have on SELinux enabled systems (in particular Fedora and RHEL) is that SELinux does not allow the dbus-daemon to pass a FD from one D-Bus service to another one when the FD is tied to /dev/net/tun.

Currently we ship our own SELinux policy to resolve this issue, which can be seen here in openvpn3.te.

The policy we wrote attempted to be a generic as possible (with the filename being the exception), as this doesn't look like an OpenVPN only related issue, but something which could hit anyone wanting to pass a FD to a tun device over D-Bus.

If this looks like a reasonable solution which could be applied to the the SELinux reference policy, I'm happy to submit a pull-request for it.

dsommers commented 4 years ago

For reference, the AVC denial without this policy looks like this:

type=AVC msg=audit(1582227542.557:3045): avc:  denied  { read write } for  pid=1741 comm="dbus-daemon" path="/dev/net/tun" dev="devtmpfs" ino=486 scontext=system_u:system_r:system_dbusd_t:s0-s0:c0.c1023 tcontext=system_u:object_r:tun_tap_device_t:s0 tclass=chr_file permissive=0

This is from a RHEL-7.7 system.

pebenito commented 4 years ago

Is this denial breaking the fd passing or is it simply generating a denial message? Since dbus is only passing the fd for the device, I wouldn't be surprised if this may be something that could be dontaudited.

dsommers commented 4 years ago

The denial causes the D-Bus connection from the calling process to be disconnected (typical behavior when permission errors occurs). Resulting in the calling process not to being able to continue working properly. Allowing this event to happen, everything works as expected.

In this case, it is a D-Bus privileged service returning a fd based a call from an unprivileged D-Bus client. There is also a related scenario, where the client is sending an FD to the same service over D-Bus where there are no denials happening (the reverse situation). Here SELinux is blocking the FD passing silently - but the same bad behaviour occurs; D-Bus client loses the connection to the D-Bus daemon. Setting SELinux into permissive mode "fixes" this issue.

dsommers commented 4 years ago

This is pretty easy to test on Fedora/RHEL/CentOS.

With the dbus_access_tuntap_device boolean disabled, the client will not be able to connect and the session start attempt will fail. With the boolean enabled, it will connect as you would normally expect.

To test the second scenario, edit the Exec= line in /usr/share/dbus-1/system-services/net.openvpn.v3.backends.service to not include the --client-disable-protect-socket argument.

More details:

pebenito commented 4 years ago

I'd accept a patch, though you should use the corenet_rw_tun_tap_dev() interface instead of a raw allow rule.

dsommers commented 4 years ago

Please let me know if this pull-request is acceptable.