Background
#57 (fixing #54) maps host EPERM from chown(2) / fchown(2) / lchown(2) /
fchownat(2) to a no-op success so emulated-root guests stop aborting on the
unprivileged macOS host's EPERM. That patch unblocks the >90% of programs
that only check the return value (dpkg, tar -p, install, k0s startup,
package extractors, etc.).
It deliberately leaves a known gap: the host file's owner is not actually
changed, so any subsequent stat()/fstat()/lstat()/fstatat()/statx()
from the guest sees the host's real owner, not the value the program just
"chowned" to.
Problem
Programs that verify ownership after chown will mis-behave. Real cases:
tar --same-owner / cpio -p doing a verification pass after extraction.
cp -p / rsync -a flows that diff metadata to decide whether a re-copy is
needed.
install -o user -g group chains that compare against the installed file.
- OCI layer-commit logic (this repo's own Phase 3/4 layer-snapshot path)
needs the intended ownership in the layer's tar metadata, not the host's
uid (likely 501:20 on macOS).
find -uid / find -gid, ls -l showing wrong owners — annoyance, not
correctness, but visible.
- Python
shutil.chown followed by os.stat().st_uid assertions in install
scripts.
The current behavior is "silent half-correct": guest sees chown() == 0 but
stat() returns the host owner.
Why real host chown is not the answer
macOS only lets uid 0 chown to arbitrary ids. Making elfuse work as real
root would require running the whole emulator under sudo, which is a poor
default (every guest syscall now runs as host root) and inappropriate for a
dev tool. An opt-in ELFUSE_REAL_ROOT=1 escape hatch is plausible but does
not solve the rootless case that #57 actually targets.
Out of scope
- Real host
chown via sudo / setuid binary.
- Mapping the guest credential to a different host credential (uid-mapped
user namespaces).
- ACLs / extended POSIX attributes beyond owner/group.
Acceptance criteria
References
Background
#57 (fixing #54) maps host
EPERMfromchown(2)/fchown(2)/lchown(2)/fchownat(2)to a no-op success so emulated-root guests stop aborting on theunprivileged macOS host's
EPERM. That patch unblocks the >90% of programsthat only check the return value (
dpkg,tar -p,install, k0s startup,package extractors, etc.).
It deliberately leaves a known gap: the host file's owner is not actually
changed, so any subsequent
stat()/fstat()/lstat()/fstatat()/statx()from the guest sees the host's real owner, not the value the program just
"chowned" to.
Problem
Programs that verify ownership after
chownwill mis-behave. Real cases:tar --same-owner/cpio -pdoing a verification pass after extraction.cp -p/rsync -aflows that diff metadata to decide whether a re-copy isneeded.
install -o user -g groupchains that compare against the installed file.needs the intended ownership in the layer's tar metadata, not the host's
uid (likely
501:20on macOS).find -uid/find -gid,ls -lshowing wrong owners — annoyance, notcorrectness, but visible.
shutil.chownfollowed byos.stat().st_uidassertions in installscripts.
The current behavior is "silent half-correct": guest sees
chown() == 0butstat()returns the host owner.Why real host
chownis not the answermacOS only lets
uid 0chown to arbitrary ids. Making elfuse work as realroot would require running the whole emulator under
sudo, which is a poordefault (every guest syscall now runs as host root) and inappropriate for a
dev tool. An opt-in
ELFUSE_REAL_ROOT=1escape hatch is plausible but doesnot solve the rootless case that #57 actually targets.
Out of scope
chownviasudo/ setuid binary.user namespaces).
Acceptance criteria
chown(p, u, g); stat(p, &st); assert(st.st_uid == u && st.st_gid == g);succeeds for the chown family on any path the guest can write to.
chownfailures with non-EPERMerrors (e.g.ENOENT,EBADF) stillpropagate (regression guard for Treat chown EPERM as no-op success for emulated-root guests #57).
fork/execveof guest processes within oneelfuse session.
tests/covers the round-trip (the repro from chown(2)/fchown(2) fail with EPERM under emulation when the host process is non-root #54extended with a post-chown
stat()check).the resulting tar/blob metadata.
References