Skip to content

Fix #103: Resolve local privilege escalation in API IPC path#109

Open
NodeAndNails wants to merge 1 commit into
AceSLS:mainfrom
NodeAndNails:fix-103-priv-esc
Open

Fix #103: Resolve local privilege escalation in API IPC path#109
NodeAndNails wants to merge 1 commit into
AceSLS:mainfrom
NodeAndNails:fix-103-priv-esc

Conversation

@NodeAndNails
Copy link
Copy Markdown

Dropping the API IPC file in /tmp (world-writable) let any local user write install|appId|library to it, forcing Steam to install arbitrary apps.

  • Moved the IPC file to $XDG_RUNTIME_DIR with 0600 permissions.
  • Falls back to ~/.config/SLSsteam if XDG isn't set.
  • Added lstat() checks on the fallback dir to block symlink traversal and verified ownership to stop cross-UID attacks.
  • Checked mkdir() return value so we don't silently run in a broken state if it fails.
  • Added a stat()/geteuid() check in onFileChange() to reject commands if the file owner doesn't match (TOCTOU mitigation).
  • Added SLSAPI::deinit() to clean up the IPC file.
  • Wired deinit() into unload() in main.cpp. (Note: Steam's normal exit skips unload(), so XDG tmpfs cleanup on logout is the actual safety net).
  • Changed path to std::string in api.hpp so we can handle dynamic paths without buffer issues.

Replaces #104. Sorry, I forgot to use a separate branch when I wrote this and pushed straight to my main. Moving it here to keep things clean.

Dropping the API IPC file in /tmp (world-writable) let any local user write "install|appId|library" to it, forcing Steam to install arbitrary apps.

- Moved the IPC file to $XDG_RUNTIME_DIR with 0600 permissions.
- Falls back to ~/.config/SLSsteam if XDG isn't set.
- Added lstat() checks on the fallback dir to block symlink traversal and verified ownership to stop cross-UID attacks.
- Checked mkdir() return value so we don't silently run in a broken state if it fails.
- Added a stat()/geteuid() check in onFileChange() to reject commands if the file owner doesn't match (TOCTOU mitigation).
- Added SLSAPI::deinit() to clean up the IPC file.
- Wired deinit() into unload() in main.cpp. (Note: Steam's normal exit skips unload(), so XDG tmpfs cleanup on logout is the actual safety net).
- Changed path to std::string in api.hpp so we can handle dynamic paths without buffer issues.
@AceSLS
Copy link
Copy Markdown
Owner

AceSLS commented May 22, 2026

Replaces #104. Sorry, I forgot to use a separate branch when I wrote this and pushed straight to my main. Moving it here to keep things clean.

It's fine thank you very much for the PR. I am sorry for stalling so long but life is keeping me pretty busy lately and I just lack the time and energy to review & test this right now.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants