Meumeu / WiVRn

An OpenXR streaming application to a standalone headset
GNU General Public License v3.0
134 stars 22 forks source link

Add systemd hardening options #80

Closed Pandapip1 closed 2 days ago

Pandapip1 commented 4 days ago

Documentation

Untested. Please ensure that WiVRn still runs with these options set.

xytovl commented 4 days ago

I have tried the patch, the server works fine but this breaks the feature to automatically start a configured application on connect. When the application is a steam steam:// command, Steam complains about missing user namespaces. RestrictNamespaces=user doesn't fix the issue.

damaestro commented 4 days ago

We should maybe also add RemoveIPC.

Pandapip1 commented 4 days ago

RemoveIPC added, RestrictNamespaces removed entirely. Mind trying this configuration?

PassiveLemon commented 4 days ago

I had problems when NoNewPrivileges was set true.

xytovl commented 4 days ago

I think we can only harden a part of the code, the process is the following:

main process starts, optns a TCP socket, publishes on avahi and waits for connections. When a connection is received, it forks into a new process to handle it. If application is set in configuration file, it also forks and execs the user-defined command.

We don't have restrictions on what the application can do, and any hardening options can break it.

Pandapip1 commented 3 days ago

main process starts, optns a TCP socket, publishes on avahi and waits for connections. When a connection is received, it forks into a new process to handle it. If application is set in configuration file, it also forks and execs the user-defined command.

We don't have restrictions on what the application can do, and any hardening options can break it.

Would it be possible to have a second systemd service (wivrn-application.service) that runs when wivrn.service becomes ready, instead of the process forking?

xytovl commented 3 days ago

Would it be possible to have a second systemd service (wivrn-application.service) that runs when wivrn.service becomes ready, instead of the process forking?

I would like to avoid a dependency on systemd.

Current loop:

  1. (process a) publish mDNS service
  2. (process a) wait for TCP connection
  3. fork application -> process b
  4. fork server process -> process c
  5. (process a) wait for c to complete
  6. (process a) terminate b
  7. (process a) go back to 1

We want process a and c to be sandboxed, if b is a separate unit file, a must be able to start it, more than once, and terminate it.

Pandapip1 commented 3 days ago

Okay. I've updated the loop without putting a hard dependency on systemd.

Pandapip1 commented 3 days ago

This looks very good, have you tested that we can still ask systemd to start new units when we have all the restrictions?

No, this is completely untested. I don't even know if it builds. I'm writing a nix derivation (well, modifying one) so that I can test locally.

xytovl commented 3 days ago

I pushed some fixes, and tested in systemd mode.

I would like to select the logic for systemd/fork mode at run-time before merging to master so that running the binary outside of an unit file would fork, and form unit file call into systemd.

PassiveLemon commented 2 days ago

Tested and it works. I was able to successfully run wlx-overlay-s as a WiVRn application and it opens in wivrn-application.service without crashing, while it otherwise would in the hardened service.

Pandapip1 commented 2 days ago

Would you like me to fixup the commit history?

xytovl commented 2 days ago

Would you like me to fixup the commit history?

I already squashed the fixes into the first commit, and made a separate one where I introduce the cli11 dependency. I think it's fine like this.

PassiveLemon commented 2 days ago

I noticed WARN [u_linux_try_to_set_realtime_priority_on_thread] Could not raise priority for thread 'Multi Client Module' when using the exact same systemd hardening options. Does anyone else get this? Trying to determine if its a Nix issue