Games Team policy on games being setgid
Simon McVittie <[email protected]> Sun, 28 Dec 2025 15:46:52 +0000
| Newsgroups | gmane.linux.debian.devel.games |
|---|---|
| Message-ID | <[email protected]> |
Policy ยง11.11 says that games may be setgid games (2755 root:games) in order to access high score tables, saved games and so on. I think we should discourage this practice. In particular, in cases where this has been added as a Debian-specific patch rather than being supported by the game's upstream developer, I think we should revert those patches and return the game to being completely unprivileged, even if this is a loss of functionality (no shared high-score tables on multi-user systems). More details ------------ Typical uses of setgid games are: * a high-score table /var/games/foogame is 0664 root:games, allowing foogame to maintain its high-score table system-wide * or more general saved game state from one player might be used by another player, for example "bones files" in Nethack that result in the remains of a dead player character from a previous run appearing in a subsequent run * or perhaps just tamper-proofing per-user saved games so that the player cannot easily cheat using an editor ... but to me, at least, using system-wide security mechanisms for these purposes seems rather like using a grenade to crack a nut. Making a game setgid results in it running with more privileges than its caller. If the caller can trick the game into accessing files in ways that it was not intended to, using its setgid privilege, in ways that the caller would not be able to do, then that is arguably a security vulnerability (potentially resulting in the full CVE circus). However, typical games have not been written to be hardened against a malicious caller supplying them with a crafted execution environment that will induce them to do things of the attacker's choice: the most obvious example is that they'll often completely trust attacker-supplied environment variables, in ways that provide the attacker with easy arbitrary code execution. Indeed, a lot of basic, expected functionality like X11 $DISPLAY and D-Bus $DBUS_SESSION_BUS_ADDRESS relies on the ability to inherit environment variables! Even if the games themselves were hardened against a crafted execution environment, typical libraries used by games are not: for example SDL trusts and obeys many environment variables, without considering whether they might be attacker-supplied. Such libraries cannot be safely used by a setuid/setgid/setcap executable unless it sanitizes its execution environment before the first call into the library, for example checking environment variables against an allowlist. I'm 99% sure that we don't have any games that actually do this, and certainly we do have games that *don't* do this. This might seem like a silly thing to be concerned about: in the typical historical use of the games group, for high score tables, one might reasonably assume that the worst-case scenario is that the attacker can cheat by recording an unattainably high score for themselves. However, being setgid also opens up attack surface that game authors have not necessarily considered. A worst-case scenario here is: suppose users watson and moriarty share a multi-user system. watson is an avid player of some roguelike game that saves files in /var/games owned by group games (let's say foogame), and moriarty wishes to gain control over watson's account. If moriarty can find an exploitable vulnerability in foogame's saved game parsing code, then he can construct a crafted savegame to exploit that vulnerability, and use any game that can be tricked into overwriting arbitrary files with games group privileges (not just foogame! any game that shares the group!) to put it into place. The most extreme impact possible here is arbitrary code execution as user watson (account takeover), the next time watson plays foogame. To me, this seems too high a price to pay for shared high-score tables. Other practical problems ------------------------ If a setgid game has a dependency tree that includes a library that does not support running setgid, and contains a safety-catch against accidentally doing so (GTK is a prominent example), then the game will simply not work. For example this is one of the few regressions I've found so far while trying to replace "classic" SDL2 with sdl2-compat: https://github.com/libsdl-org/sdl2-compat/issues/564, https://bugs.debian.org/1123953 Or, if a library tries its best to mitigate the security issues inherent in setgid (for example glibc, Mesa and Vulkan-Loader use secure_getenv() when they read environment variables), then functionality will be lost for setgid games (for example LD_LIBRARY_PATH, LIBGL_DRIVERS_PATH, GALLIUM_DRIVER and VK_LOADER_DEVICE_SELECT won't work as expected). Suggested policy ---------------- Perhaps something like this: Games should not be setuid or setcap. New games should not be setgid. Existing games should only be setgid games if not doing so would result in data loss or a serious loss of functionality. Ideally, they should migrate data into $HOME so that they do not need to continue to be setgid in every future Debian release. Games that are setgid games should read the data that they need to read, and then irreversibly drop privileges (for example setresgid() setting the effective and saved gids equal to the real gid), before calling into non-trivial dependency libraries. Games should not be setgid if their upstream developer does not intentionally support this. Examples -------- src:angband has explicit upstream support for being setgid games, in order to tamper-proof its saved games. My opinion is that this is security theatre that is unlikely to be worth the risk, and we should not have done this - although a transition from where we are now to the desired state without data loss might not be possible. src:hannah has upstream code that writes to ~/.hannah [1] but has been patched (debian/patches/fix_score_dir.diff) to write scores to /var/games/hannah. I'm sure this seemed like a good idea in 2008, but I think we should not have done this, and I think we should remedy this by treating /var/games/hannah as read-only, and writing new high-scores into ~/.hannah, or even $XDG_DATA_DIR/Hannah. See also -------- * https://github.com/libsdl-org/SDL/issues/14717 * https://github.com/libsdl-org/sdl2-compat/issues/564, https://bugs.debian.org/1123953 * https://dwheeler.com/secure-programs/Secure-Programs-HOWTO/ (in practice nobody writes games this way!) ---------------------------------------------------------------------- [1] actually /home/$USER/.hannah, but I think that's a bug, and it should be ~/.hannah rather than assuming that $HOME will always be /home/$USER