FeralInteractive / gamemode

Optimise Linux system performance on demand
BSD 3-Clause "New" or "Revised" License
4.75k stars 185 forks source link

What's the idea behind running GameMode as a user daemon? #82

Open kakra opened 6 years ago

kakra commented 6 years ago

Is your feature request related to a problem? Please describe. I wonder what's the idea behind running gamemode as a per-user daemon? Sure, it allows easy choice for users to opt-in or opt-out. But GameMode already has to climb a few obstacles like creating a suid cpugovctl or requiring the user to adjust different limits.

Describe the solution you'd like I'd prefer if GameMode would run as a system wide service. Users could opt-in or opt-out by being a member of a configurable unix group (and the group acts as a opt-in or opt-out operator). The cpugovctl could be integrated right into the daemon. Also, the daemon could drop all capabilities except the ones required to adjust selected system settings (i.e. CAP_SYS_NICE). I think it could even be possible to let it switch to and run as a non-root user then for increased security. Files that need root access could hold an open file descriptor before switching to non-root.

Describe alternatives you've considered An alternative would be to create little suid helpers for every privileged feature but users are free to run those from /usr/libexec which is not very secure nor safe. It would at least require a unix group allowed to run those, and you need to be member of it which kind of resembles the idea of this issue itself.

gicmo commented 6 years ago

I had the same question in #61

kakra commented 6 years ago

Yes, although you just asked and then it was closed. I think that the reasoning should be quite different:

@aejsmith wrote:

There's a couple of reasons for using a session daemon:

  • Means that the whole daemon doesn't run with elevated privileges, just the parts that need it (cpugovctl).
  • Allows configuration on a per-user basis - one of the locations it attempts to read the configuration from is the the user's home directory (see README.md for the list of locations)

I think that the first point is not very convincing because you now hand control off the daemon, and those helpers are setuid, and can be run at any time without control of the daemon. The sysadmin needs to protect these binaries then to be executed only by selected people. Now, the daemon would also not be able to execute those helpers.

About the second point: The daemon could still be able to read per user config files or even per game. It's even not configured via cmdline options in the first place.

@gicmo As for concurrency, I don't think this is an issue. The daemon runs a listener in the user dbus session. If another user runs a seconds instance, there's no conflict. And I doubt that two users would run a game at the same time, but anyways: I that case the daemons don't know from each other and powersave mode may be turned on or off at the wrong time without the other daemon knowing. Explicitly that could be solved, too, with a single system daemon.

aejsmith commented 6 years ago

Yes, although you just asked and then it was closed. I think that the reasoning should be quite different:

@aejsmith wrote:

There's a couple of reasons for using a session daemon:

  • Means that the whole daemon doesn't run with elevated privileges, just the parts that need it (cpugovctl).
  • Allows configuration on a per-user basis - one of the locations it attempts to read the configuration from is the the user's home directory (see README.md for the list of locations)

I think that the first point is not very convincing because you now hand control off the daemon, and those helpers are setuid, and can be run at any time without control of the daemon. The sysadmin needs to protect these binaries then to be executed only by selected people. Now, the daemon would also not be able to execute those helpers.

About the second point: The daemon could still be able to read per user config files or even per game. It's even not configured via cmdline options in the first place.

The cpugovctl helper is not setuid. Polkit is used (the daemon runs it through pkexec), so access control can be handled through that. The default policy only allows the active session to change the governor. Other functionality (e.g. your scheduling policy changes) relies on existing security mechanisms to determine whether or not users are allowed to make those changes.

An aspect to the per-user configuration that I didn't mention on that previous issue is custom scripts. If the daemon were a system service, in addition to having to look up per-user configs based on the user of the process that made the request, we'd also have to handle executing the scripts as that user, as well as making sure the environment is set up such that the scripts can access the desktop session, etc. That makes things quite a bit more tricky from a security perspective.

kakra commented 6 years ago

@aejsmith Okay, that clears up a fair bit of why this decision was made. Also, I didn't realize it used pkexec. However, it looks like it doesn't work here without suid. I'll try to reproduce the behavior by running through pkexec on cmdline.

kakra commented 6 years ago

Works when started from cmdline... It looks like I see it fail sometimes when started through the systemd service. I'll look into that later, I already suspect where the problem may be.