Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XDG_CONFIG_HOME below /etc doesn't work #726

Open
greaka opened this issue Dec 17, 2024 · 7 comments
Open

XDG_CONFIG_HOME below /etc doesn't work #726

greaka opened this issue Dec 17, 2024 · 7 comments

Comments

@greaka
Copy link

greaka commented Dec 17, 2024

Your system information

  • Steam Runtime Version: scout but soldier probably?
  • Distribution (e.g. Ubuntu 18.04): Arch
  • Link to your full system information (Help -> Steam Runtime Diagnostics) in a Gist: greaka/0c348dd0308d2b51b151d186c19088f8
  • Have you checked for system updates?: [Yes/No] Yes
  • What compatibility tool are you using?: [None / Steam Linux Runtime / Proton 5.13+ / older Proton] Steam Linux Runtime
  • What versions are listed in steamapps/common/SteamLinuxRuntime/VERSIONS.txt? enoent
  • What versions are listed in steamapps/common/SteamLinuxRuntime_soldier/VERSIONS.txt?
  • ~/.steam/root/ubuntu12_32/steam-runtime/version.txt? steam-runtime_0.20241024.105847
#Name   Version     Runtime Runtime_Version Comment
depot   0.20241118.108551           # Overall version number
pressure-vessel 0.20241118.0    scout       # pressure-vessel-bin.tar.gz
scripts 0.20241118.0            # from steam-runtime-tools
soldier 0.20241118.108551   soldier 0.20241118.108551   # soldier_platform_0.20241118.108551/
  • What versions are listed in steamapps/common/SteamLinuxRuntime_sniper/VERSIONS.txt?
#Name   Version     Runtime Runtime_Version Comment
depot   0.20241118.108552           # Overall version number
pressure-vessel 0.20241118.0    scout       # pressure-vessel-bin.tar.gz
scripts 0.20241118.0            # from steam-runtime-tools
sniper  0.20241118.108552   sniper  0.20241118.108552   # sniper_platform_0.20241118.108552/

Please describe your issue in as much detail as possible:

The runtime ignores xdg_config_home when under /etc, which causes games to lose the ability to persist configs/savegames/etc.

I don't know what to do short of moving xdg out of etc, which is not an easy task on a years old system. If the runtime instead would mount it read-only, then I could at least setup a symlink to get those games redirected to home or something.

Another option would be to implement Unsharing the home directory, which would circumvent this issue by fully sandboxing this directory per app.

gist of game output: greaka/0c348dd0308d2b51b151d186c19088f8/#file-slr-app294100-t20241217t005138-log

Steps for reproducing this issue:

  1. set XDG_CONFIG_HOME=/etc/xdg
  2. run any linux native steam game (I used rimworld as example)
  3. observe progress being lost
@smcv
Copy link
Contributor

smcv commented Dec 18, 2024

This is an instance of the same sort of limitation that means we can't support home directories below /usr/local: the /usr and /etc directories are under the control of the runtime environment, which is part of the isolation between the host system (unpredictable, sometimes frequently upgraded, sometimes very old) and the game's container (as predictable as possible, so that the game can continue to run several years from now).

set XDG_CONFIG_HOME=/etc/xdg

Does this mean you are running Steam as root? (I'm pretty sure that's not intended to be supported.) Normally ordinary users should not be able to write to anywhere below /etc.

If files and directories below /etc/xdg are owned by a non-root user, then that's quite likely to be a privilege escalation vulnerability from that user to any other user on the system, because programs and libraries usually trust /etc to be under sysadmin control.

@smcv
Copy link
Contributor

smcv commented Dec 18, 2024

/etc/xdg is meant to be controlled by the system administrator and/or the OS distribution packages, while XDG_CONFIG_HOME (normally ~/.config) is meant to be controlled by an individual user. Having games write their saved games, etc. into /etc/xdg seems very strange: if another user of the same system runs a copy of the same game, it doesn't seem like an intended situation to expect the game to load (and presumably attempt to overwrite) your personal saved games.

Even if you are the system administrator, it's a good principle to use as few privileges as possible at any given time ("least privilege"); and even if you are the only human user of a system, Linux is a multi-user system which uses system user accounts for privilege separation, for example to run system services.

Well-behaved implementations of the XDG basedir spec are meant to obey $XDG_CONFIG_HOME, but unfortunately many implementations are not well-behaved, and it's common for .config to be hard-coded. As a result, I would recommend using the default ~/.config unless there is a very compelling reason not to.

Sometimes there will even be one code path that obeys $XDG_CONFIG_HOME and another that hard-codes .config: for example, Rimworld uses the Unity engine, which I believe uses $XDG_CONFIG_HOME correctly, but the Steam Cloud sync configuration for Rimworld hard-codes .config, so Rimworld saved games will only sync correctly to the Steam Cloud if you have XDG_CONFIG_HOME either unset or set to "$HOME/.config".

I don't know what to do short of moving xdg out of etc, which is not an easy task on a years old system.

You could do the opposite of the symlinks you suggested: move your personal files out of /etc/xdg into some suitable directory controlled by your own user ID (normally that's ~/.config), set XDG_CONFIG_HOME to that directory, and create symlinks or bind-mounts in /etc/xdg pointing to those files' new locations?

If your personal files are owned by your own uid and the OS distribution's files are owned by root, then that's one easy way to tell which is which: find -uid/find -user might be helpful.

The good news is that if configuration is not found in $XDG_CONFIG_HOME, well-behaved implementations of the XDG basedir spec should fall back to loading it from $XDG_CONFIG_DIRS, a list of read-only directories which has /etc/xdg as its default. So this migration might well be less painful than you expect. (However, as noted above, not all implementations of the XDG basedir spec are well-behaved, so I expect that you'll find that some applications do need their configuration moved.)

Because the XDG directories are controlled by environment variables, it would also be possible to move just the saved game data for a particular game (e.g. for Rimworld, move /etc/xdg/unity3d/Ludeon Studios/RimWorld by Ludeon Studios to ~/.config/unity3d/Ludeon Studios/RimWorld by Ludeon Studios), and then set the game's Launch Options to:

XDG_CONFIG_HOME="$HOME/.config" %command%

But I would recommend migrating all of your personal configuration into ~/.config: the longer you let it accumulate in /etc/xdg, the more difficult it will be to disentangle.

If the runtime instead would mount it read-only, then I could at least setup a symlink to get those games redirected to home or something.

The runtime cannot safely bind-mount /etc/xdg from the host system, because /etc/xdg frequently contains system-integration stuff from your OS distribution, which contains paths and syntax that are correct for the host system's installed libraries but would not be correct inside the Steam Runtime environment. For example, /etc/xdg/autostart contains references to programs in /usr which are not present in a Steam Runtime container.

Another option would be to implement Unsharing the home directory

This is implemented, in fact. It's experimental and not routinely tested, but you can activate it (at your own risk) by setting the Launch Options to PRESSURE_VESSEL_SHARE_HOME=0 %command%. Good luck!

One known limitation is that it's known to break Steam Cloud sync, but as noted above, Steam Cloud sync will often not work on your system anyway (in particular, not for Rimworld).

When unsharing the home directory, pressure-vessel always uses XDG_CONFIG_HOME="$HOME/.config" inside the app-specific $HOME.

@smcv
Copy link
Contributor

smcv commented Dec 18, 2024

@kisak-valve: I suggest retitling this issue to something like XDG_CONFIG_HOME below /etc doesn't work to describe its scope more precisely.

@smcv
Copy link
Contributor

smcv commented Dec 18, 2024

The runtime ignores xdg_config_home when under /etc, which causes games to lose the ability to persist configs/savegames/etc.

The relevant diagnostic message is:

pressure-vessel-wrap[3192798]: W: Not sharing path XDG_CONFIG_HOME="/etc/xdg" with container because "/etc" is reserved by the container framework

@kisak-valve kisak-valve changed the title xdg not set up correctly XDG_CONFIG_HOME below /etc doesn't work Dec 18, 2024
@greaka
Copy link
Author

greaka commented Dec 19, 2024

Thank you for the detailed response. I agree that /etc/xdg is a bad place to have xdg_config_home in. It bit me multiple times already and only one of my systems have it set up that way for that reason.

I will probably take your suggestion to heart and move out of there. However, let me make the case for doing something on the runtime side about it anyway.

You mention that both steam cloud sync and many games hardcode to ~/.config, while you as runtime assume that programs are well behaved and use xdg_config_home. You kind of also assume that xdg_config_home is always set to ~/.config. If this is the case anyway, I think the runtime should set xdg_config_home to ~/.config regardless for every game, because any other configuration would break anyway. You make an assumption on how the system behaves and are in the position to control and make games uphold that assumption.

@smcv
Copy link
Contributor

smcv commented Dec 19, 2024

You mention that both steam cloud sync and many games hardcode to ~/.config, while you as runtime assume that programs are well behaved and use xdg_config_home. You kind of also assume that xdg_config_home is always set to ~/.config.

Not quite: we assume that XDG_CONFIG_HOME is somewhere that we can safely share with the container. It could equally well be ~/etc or /srv/personal/config or even /ConfigHome. Games or components that implement the basedir spec incorrectly would still have trouble with this, and it doesn't really have any compelling advantages over ~/.config, so I wouldn't recommend it; but the container runtime framework would work fine.

The problem with /etc/xdg is that it's specifically in /etc, which is one of a few paths that we need to reserve for use by the runtime (alongside the more obvious /usr).

@greaka
Copy link
Author

greaka commented Dec 19, 2024

The runtime could overwrite the value only for reserved paths then. It's not perfect, but would at least be a safe-guard.

I understand that this is kind of niche regardless.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants