Skip to content

UID/GID permission switching restrictions under Fakeroot return EPERM #190

Description

@doanbaotrung

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

  1. Start the guest environment under fakeroot or as guest root (UID 0).
  2. 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;
 }

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions