Skip to content

Let a marked exec enter fakeroot mode - #268

Draft
doanbaotrung wants to merge 1 commit into
sysprog21:mainfrom
open-sources-port:fakeroot-exec
Draft

Let a marked exec enter fakeroot mode#268
doanbaotrung wants to merge 1 commit into
sysprog21:mainfrom
open-sources-port:fakeroot-exec

Conversation

@doanbaotrung

@doanbaotrung doanbaotrung commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

Fakeroot could only be armed before the first guest image ran, via --fakeroot or ELFUSE_FAKEROOT, so nothing a guest did afterwards could raise privilege. A guest shell had no equivalent of sudo: the one command that needs root forced the whole session to run as root.

Add ELFUSE_FAKEROOT_EXEC, naming a single executable whose exec crosses into fakeroot. sys_execve compares the requested path against it before shebang resolution repoints the path at an interpreter, so a wrapper script elevates on its own path rather than on /bin/sh, and it matches either the guest path or the host path so the embedder can name the binary in whichever namespace it knows.

The transition is committed alongside the setuid credential commit, past every failure path, so an exec that never happens leaves the caller unprivileged. It sets root ids and the process-wide gate, mirroring what proc_identity_init does for --fakeroot at startup, and reaches fork children through the --fakeroot argv forkipc already derives from that gate. With the variable unset, which is the default, no exec ever elevates.

tests/test-fakeroot-exec.c re-execs itself as the marked path and covers the unprivileged start, the elevated exec, root surviving a fork into a fresh host process, the exec'ing parent keeping its own ids, and a copy of the same program at another path not elevating. The escape hatch is elfuse-only, so the qemu lane skips it.

Fix #265


Summary by cubic

Let a marked exec opt into fakeroot so guests can start unprivileged and elevate a single command, like sudo. Fixes #265.

  • New Features
    • Added ELFUSE_FAKEROOT_EXEC to name one executable whose exec enters fakeroot. Requires an absolute path (guest or host); exact string match only. Unset or invalid means no elevation.
    • Decision happens before shebang resolution, so wrapper scripts elevate on their own path, not /bin/sh.
    • Transition occurs only on successful exec; sets uid/gid 0 and the process-wide fakeroot gate. Forked children inherit; the exec'ing parent keeps its ids.
    • Added tests/test-fakeroot-exec.c to cover unprivileged start, marked exec reaching root, root surviving a fork, and non-matching spellings/copies not elevating. The QEMU lane skips this elfuse-only behavior.

Written for commit 038b0f7. Summary will update on new commits.

Review in cubic

@doanbaotrung
doanbaotrung marked this pull request as draft August 3, 2026 16:45

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

All reported issues were addressed across 6 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread src/syscall/exec.c Outdated
Comment thread src/syscall/exec.c Outdated
Comment thread tests/test-fakeroot-exec.c Outdated
Comment thread src/syscall/exec.c Outdated
Comment thread tests/test-fakeroot-exec.c Outdated
Fakeroot could only be armed before the first guest image ran, via
--fakeroot or ELFUSE_FAKEROOT, so nothing a guest did afterwards
could raise privilege. A guest shell had no equivalent of sudo: the
one command that needs root forced the whole session to run as root.

Add ELFUSE_FAKEROOT_EXEC, naming a single executable whose exec
crosses into fakeroot. sys_execve compares the requested path
against it before shebang resolution repoints the path at an
interpreter, so a wrapper script elevates on its own path rather
than on /bin/sh, and it matches either the guest path or the host
path so the embedder can name the binary in whichever namespace it
knows.

The transition is committed alongside the setuid credential commit,
past every failure path, so an exec that never happens leaves the
caller unprivileged. It sets root ids and the process-wide gate,
mirroring what proc_identity_init does for --fakeroot at startup,
and reaches fork children through the --fakeroot argv forkipc
already derives from that gate. With the variable unset, which is
the default, no exec ever elevates.

tests/test-fakeroot-exec.c re-execs itself as the marked path and
covers the unprivileged start, the elevated exec, root surviving a
fork into a fresh host process, the exec'ing parent keeping its own
ids, and a copy of the same program at another path not elevating.
The escape hatch is elfuse-only, so the qemu lane skips it.

Fix sysprog21#265
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.

No way for a guest-initiated exec to enter fakeroot

1 participant