Skip to content

Fix #4233: mkosi runs into permission errors even when running as root#4268

Open
JiwaniZakir wants to merge 1 commit intosystemd:mainfrom
JiwaniZakir:fix/4233-mkosi-runs-into-permission-errors-even
Open

Fix #4233: mkosi runs into permission errors even when running as root#4268
JiwaniZakir wants to merge 1 commit intosystemd:mainfrom
JiwaniZakir:fix/4233-mkosi-runs-into-permission-errors-even

Conversation

@JiwaniZakir
Copy link
Copy Markdown

Closes #4233

Skip user namespace entry in acquire_privileges when running as real root with a non-zero delegate value.

Changes

mkosi/sandbox.pyacquire_privileges()
The condition on line 802 that gates early-exit (returning False, meaning "don't enter a user namespace") previously blocked that exit whenever delegate was truthy. It now allows the early exit when both os.getuid() == 0 and os.getgid() == 0, so a real-root process is not forced into a user namespace solely because of a non-zero delegate argument.

# before
and not delegate
# after
and (not delegate or (os.getuid() == 0 and os.getgid() == 0))

tests/test_sandbox.py (new file)
Adds test_acquire_privileges_root_with_delegate_skips_userns, which mocks have_effective_cap to return True, patches os.getuid/os.getgid to return 0, and asserts that acquire_privileges(foreign=True, delegate=3) returns False.

Motivation

When mkosi is invoked as root, the sandbox set up before ensure_directories_exist() was entering a user namespace because delegate was non-zero. Inside that namespace the process no longer held host-root privileges, making directories under paths like /home/user/... (mode 0700) inaccessible. The result was a PermissionError: [Errno 13] Permission denied on a mkdir call for the build directory, even though the caller was UID 0 on the host. The regression was introduced in #4160, which added the delegate parameter path through acquire_privileges.

Real root does not benefit from a user namespace for privilege escalation purposes — it already has the capabilities it needs — so skipping namespace entry when uid == gid == 0 is both correct and safe.

Testing

Unit test added in tests/test_sandbox.py validates the fixed code path directly:

$ python -m pytest tests/test_sandbox.py -v
tests/test_sandbox.py::test_acquire_privileges_root_with_delegate_skips_userns PASSED

Manual verification: running mkosi as root with a build directory inside a 0700 home directory no longer raises PermissionError and proceeds through ensure_directories_exist() successfully.


This PR was created with AI assistance (Claude). The changes were reviewed by quality gates and a critic model before submission.

When mkosi runs as root with acquire_privileges(foreign=True, delegate=3),
the `and not delegate` guard forced entering a user namespace even though
root already has all necessary host privileges. Inside that namespace root
lost host-filesystem access, causing PermissionError in
ensure_directories_exist() for paths under another user's home directory.

Fix by returning early (no user namespace) when the calling process is
already true root (UID=0, GID=0), regardless of the delegate count.

Fixes: systemd#4233

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Comment thread tests/test_sandbox.py
Comment on lines +21 to +22
result = acquire_privileges(foreign=True, delegate=3)
assert result is False
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
result = acquire_privileges(foreign=True, delegate=3)
assert result is False
assert not acquire_privileges(foreign=True, delegate=3)

Comment thread tests/test_sandbox.py
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The regression test is a nice thought, but I don't see it surviving the next refactor. The internal API of sandbox.py changes as requirements for it change. The relevant thing is the behaviour as seen from the outside.

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

Labels

None yet

Development

Successfully merging this pull request may close these issues.

mkosi runs into permission errors even when running as root

2 participants