Description
In emulation environments running in fakeroot mode or as the virtual guest root user, guest processes that attempt to change their UID or GID (such as invoking seteuid or setegid to drop privileges to a non-root system user) fail and abort with the following error:
E: seteuid 42 failed - seteuid (1: Operation not permitted)
This occurs because elfuse's internal permission checks restrict UID/GID changes strictly to the currently configured guest UID/GID values, ignoring the fact that a root or fakeroot guest process is allowed to switch to any arbitrary user ID.
Steps to Reproduce
- Start the guest environment under
fakeroot or as guest root (UID 0).
- Execute a guest program that drops privileges to another user ID (e.g. user
_apt with UID 42):
python3 -c "import os; os.seteuid(42)"
- Expected behavior: The UID change succeeds (since the process is running as root/fakeroot).
- Actual behavior: The call fails with
OSError: [Errno 1] Operation not permitted.
Root Cause
In proc-identity.c, uid_is_permitted and gid_is_permitted only allow switching to IDs that match the process's active credentials:
static bool uid_is_permitted(uint32_t val)
{
return val == emu_uid || val == emu_euid || val == emu_suid;
}
static bool gid_is_permitted(uint32_t val)
{
return val == emu_gid || val == emu_egid || val == emu_sgid;
}
Under Linux, a process with effective UID 0 (or running in a fakeroot sandbox) is allowed to change its credentials to any arbitrary UID/GID. Since elfuse blocks these switches, guest processes cannot drop privileges.
Proposed Solution
Modify uid_is_permitted and gid_is_permitted in src/syscall/proc-identity.c to allow any UID/GID switches when running under fakeroot or if the guest process has root privileges (emu_euid == 0).
Suggested Patch:
diff --git a/src/syscall/proc-identity.c b/src/syscall/proc-identity.c
index 859a07c..27c71a3 100644
--- a/src/syscall/proc-identity.c
+++ b/src/syscall/proc-identity.c
@@ -107,11 +107,15 @@
static bool uid_is_permitted(uint32_t val)
{
+ if (emu_euid == 0 || fakeroot_enabled)
+ return true;
return val == emu_uid || val == emu_euid || val == emu_suid;
}
static bool gid_is_permitted(uint32_t val)
{
+ if (emu_euid == 0 || fakeroot_enabled)
+ return true;
return val == emu_gid || val == emu_egid || val == emu_sgid;
}
Description
In emulation environments running in
fakerootmode or as the virtual guestrootuser, guest processes that attempt to change their UID or GID (such as invokingseteuidorsetegidto drop privileges to a non-root system user) fail and abort with the following error:E: seteuid 42 failed - seteuid (1: Operation not permitted)This occurs because
elfuse's internal permission checks restrict UID/GID changes strictly to the currently configured guest UID/GID values, ignoring the fact that a root or fakeroot guest process is allowed to switch to any arbitrary user ID.Steps to Reproduce
fakerootor as guestroot(UID 0)._aptwith UID42):python3 -c "import os; os.seteuid(42)"OSError: [Errno 1] Operation not permitted.Root Cause
In proc-identity.c,
uid_is_permittedandgid_is_permittedonly allow switching to IDs that match the process's active credentials:Under Linux, a process with effective UID
0(or running in a fakeroot sandbox) is allowed to change its credentials to any arbitrary UID/GID. Sinceelfuseblocks these switches, guest processes cannot drop privileges.Proposed Solution
Modify
uid_is_permittedandgid_is_permittedinsrc/syscall/proc-identity.cto allow any UID/GID switches when running underfakerootor if the guest process has root privileges (emu_euid == 0).Suggested Patch: