Skip to content

🐛 fix(unix): decide root redirect by effective uid - #666

Merged
gaborbernat merged 6 commits into
mainfrom
fix/use-site-effective-uid
Oct 28, 2026
Merged

gaborbernat merged 6 commits into
mainfrom
fix/use-site-effective-uid

Conversation

@gaborbernat

@gaborbernat gaborbernat commented Oct 28, 2026 •

Copy link
Copy Markdown
Member

Fixes #673. _use_site checked getuid() == 0, the real uid, while docs/howto.rst tells callers to pass use_site_for_root=True when os.geteuid() == 0. A program started through a setuid-root launcher, with the caller's real uid and effective uid 0, followed the docs and still got the caller's ~/.config and other user_* directories, created root-owned directories there, and searched them before /etc/xdg. With this PR the redirect, the runtime directory names and the runtime owner check use the effective uid.

The root redirect read the real uid

A setuid executable keeps the caller's real uid and runs with the file owner's effective uid (credentials(7)), and getuid() returns the real one (getuid(2)). _use_site therefore returned False for such a process, and every user_* property, place_*_file and find_*_file resolved under the caller's home. Directories it created there were owned by uid 0, since ownership follows the effective uid. _use_site now checks geteuid(), the same test the how-to gives.

The runtime directory used the real uid

/run/user/<uid>, runtime-<uid> and the owner check in _runtime_dir_problem used the real uid, so a setuid-root process accepted the caller's /run/user/1000 as its private runtime directory. _runtime_dir_problem follows Qt's checkXdgRuntimeDir, which uses geteuid() for both the owner check and the fallback name. The names and the owner check now use the uid that owns what the process creates.

Behavior changes

Processes whose real and effective uid agree, including anything started by sudo, su, pkexec, doas or a service manager, see no change. A setuid-root process with use_site_for_root=True now gets the site directories, and its runtime directory falls back to /run/user/0 or runtime-0 instead of the caller's. A process that started as root and lowered only its effective uid now gets the user directories instead of the site ones. The home directory lookup when HOME is unset still uses the real uid, matching os.path.expanduser; with the redirect fixed it only applies to directories that are not redirected, such as the media directories.

Reported by Anthropic's OSS Scanner: ANT-2026-OARVZZ26.

use_site_for_root checked the real uid, while docs/howto.rst tells callers
to enable it when os.geteuid() == 0. A setuid-root process (real uid of
the caller, effective uid 0) got the caller's home directories and created
root-owned directories there. The runtime directory name and owner check
used the real uid too, so such a process accepted the caller's
/run/user/<uid> as its own. All three now use the effective uid, which
owns what the process creates and matches Qt's checkXdgRuntimeDir.

Discovered by Anthropic's OSS Scanner, as vulnerability ANT-2026-OARVZZ26.
@gaborbernat gaborbernat added bug Something isn't working security Fixes a security vulnerability labels Oct 28, 2026
@gaborbernat
gaborbernat requested a review from ofek as a code owner October 28, 2026 07:07
@gaborbernat gaborbernat removed the security Fixes a security vulnerability label Oct 28, 2026
@gaborbernat
gaborbernat merged commit 790ff18 into main Oct 28, 2026
41 checks passed
@gaborbernat
gaborbernat deleted the fix/use-site-effective-uid branch October 28, 2026 18:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

use_site_for_root decides on the real uid

1 participant