Skip to content

Hardcoded /etc/passwd and /etc/group intercepts break guest name resolution #188

Description

@doanbaotrung

Description

In emulation environments using a custom guest filesystem (sysroot), standard name-resolution lookups (e.g. calling getgrnam("messagebus") or querying grp.getgrnam in Python) fail to resolve newly added users or groups.

This occurs because elfuse intercepts all open operations on /etc/passwd and /etc/group and returns a hardcoded mock database. This shadows the guest's real user and group databases inside the sysroot, making any users or groups added during package provisioning completely invisible.

Steps to Reproduce

  1. Provision a full guest rootfs prefix (e.g., Ubuntu).
  2. Create or add a new system group (e.g., messagebus with GID 997) using groupadd or systemd-sysusers.
  3. Try to resolve the group inside the guest environment using python or getent:
    python3 -c "import grp; print(grp.getgrnam('messagebus'))"
  • Expected behavior: The group resolves successfully, returning the GID.
  • Actual behavior: Lookup fails with KeyError: "getgrnam(): name not found: 'messagebus'".

Root Cause

  1. In path.c, path_might_use_open_intercept intercepts /etc/passwd and /etc/group:
    if (!strcmp(path, "/etc/mtab") || !strcmp(path, "/etc/passwd") ||
        !strcmp(path, "/etc/group"))
        return true;
  2. In procemu.c, elfuse intercepts the open call and serves a hardcoded synthetic literal:
    if (!strcmp(path, "/etc/group")) {
        return proc_emit_literal(
            "root:x:0:\n"
            "staff:x:20:\n"
            "user:x:1000:\n");
    }

This synthetic literal completely overrides the actual /etc/group file located in the guest's sysroot prefix.


Proposed Solution

If a custom guest sysroot is configured, elfuse should bypass these synthetic intercepts and allow the guest to read the real /etc/passwd and /etc/group files inside the rootfs.

Suggested Patch:

Modify path_might_use_open_intercept in src/syscall/path.c to check if a sysroot is snapshot-active and bypass the intercept:

    if (!strcmp(path, "/etc/mtab"))
        return true;
    if (!strcmp(path, "/etc/passwd") || !strcmp(path, "/etc/group")) {
        char sr[LINUX_PATH_MAX];
        if (proc_sysroot_snapshot(sr, sizeof(sr)))
            return false; // Bypass synthetic intercept and read from guest sysroot
        return true;
    }

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