Skip to content

No way for a guest-initiated exec to enter fakeroot #265

Description

@doanbaotrung

No way for a guest-initiated exec to enter fakeroot

Summary

ELFUSE_FAKEROOT / --fakeroot can only be decided before the guest starts.
There is no way for a program running inside the guest to elevate, which makes a
sudo-style workflow impossible without running the entire session as root.

Why the existing knobs don't cover it

  • ELFUSE_FAKEROOT is read in main() (src/main.c), i.e. once per host process
    at startup.
  • A guest execve replaces the guest image inside the same host process, so
    main() never runs again and the setting cannot change.
  • A guest fork does spawn a new host process, but src/runtime/forkipc.c passes
    the parent's host environ plus an explicit --fakeroot copied from the
    parent's current state. The guest's own environment is never consulted, so
    export ELFUSE_FAKEROOT=1 inside the guest has no effect.

Net effect: fakeroot is all-or-nothing for the lifetime of a guest tree.

Use case

An embedder wants the guest to run unprivileged (uid 1000) by default, but needs a
sudo-equivalent so package managers work on demand. Today the only options are
running the whole session as root, or intercepting sudo on the host command line —
which only sees the top-level program, not a sudo typed into a shell inside the
guest.

A setuid helper is not a workaround either: it cannot reach euid=0, because the
host owner is not root and the chown overlay that could record root ownership is
in-memory only, so it does not survive into a later process. See the related report
on setuid-on-exec granting the unmapped host uid.

Possible approaches

  1. An opt-in env var naming an executable that enters fakeroot, e.g.
    ELFUSE_FAKEROOT_EXEC=/path/to/helper — when execve resolves to exactly that
    path, enable fakeroot for the new image. Off unless set, so no default-on
    privilege hole, and it reuses proc_set_fakeroot_enabled().
  2. Fix the setuid-on-exec uid mapping and persist the chown overlay, so a helper
    recorded as root-owned and setuid grants euid=0 through ordinary setuid
    semantics. More faithful, but a larger change.

Approach 1 is far smaller; approach 2 needs no new configuration surface.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions