Skip to content

Missing SYS_setgroups (Syscall 159) on AArch64 breaks privilege-dropping guest processes #189

Description

@doanbaotrung

Description

In emulation environments, guest processes that attempt to drop privileges (for example, standard package managers like apt-get spawning a helper process as user _apt or GID 65534) crash or fail to execute with the following error:
E: setgroups 65534 failed - setgroups (38: Function not implemented)
E: Method gave invalid 400 URI Failure message: Failed to setgroups - setgroups (38: Function not implemented)

This is because system call 159 (setgroups on Linux AArch64) is unimplemented in elfuse, returning ENOSYS.

Steps to Reproduce

  1. Run a guest process under elfuse that drops group privileges (e.g. running apt-get install when the _apt sandbox user exists).
  2. The guest process invokes the standard glibc setgroups function.
  • Expected behavior: The group list is successfully cleared or set, allowing the process to continue.
  • Actual behavior: The call fails with ENOSYS ("Function not implemented").

Root Cause

  1. System call 159 is not defined in src/syscall/abi.h.
  2. The syscall is not registered in the generated dispatch header src/syscall/dispatch.tbl.
  3. There is no implementation wrapper in src/syscall/sys.c or src/syscall/syscall.c.

Proposed Solution

Under root or fakeroot emulation (standard for local dev container runtimes), setgroups cannot actually be executed on the host. It should be emulated as a no-op that returns success (0) to guest processes.

Suggested Patch:

  1. Define SYS_setgroups in src/syscall/abi.h:

    #define SYS_setgroups 159
  2. Register the syscall in src/syscall/dispatch.tbl:

    SYS_setgroups sc_setgroups 0
    
  3. Declare the syscall handler in src/syscall/sys.h:

    int64_t sys_setgroups(guest_t *g, int size, uint64_t list_gva);
  4. Define the no-op implementation in src/syscall/sys.c:

    int64_t sys_setgroups(guest_t *g, int size, uint64_t list_gva)
    {
        /* Under fakeroot/root emulation, allow setgroups to succeed as a no-op.
         * Non-root guests get EPERM.
         */
        if (proc_get_euid() == 0 || proc_fakeroot_enabled()) {
            return 0;
        }
        return -LINUX_EPERM;
    }
  5. Register the wrapper in src/syscall/syscall.c:

    SC_FORWARD(sc_setgroups, sys_setgroups(g, (int) x0, x1))

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