Skip to content

process spawning in libnative does not account for unrecoverable execve failures #13874

Closed
@mstewartgallus

Description

@mstewartgallus

Sometimes when execve fails it doesn't return with an error. Quoting from the blog EWONTFIX here:

For common reasons it might fail, the execve syscall returns failure in the original process image, allowing the program to handle the error. However, failure of execve is not entirely atomic:

The kernel may fail setting up the VM for the new process image after the original VM has already been destroyed; the main situation under which this would happen is resource exhaustion.

Even after the kernel successfully sets up the new VM and transfers execution to the new process image, it's possible to have failures prior to the transfer of control to the actual application program. This could happen in the dynamic linker (resource exhaustion or other transient failures mapping required libraries or loading configuration files) or libc startup code. Using musl libc with static linking or even dynamic linking with no additional libraries eliminates these failure cases, but systemd is intended to be used with glibc.

This means that using a pipe to report errors is incorrect or at least does not cover all cases.

My personal hack to get around the issue is here.

In order to check for execve aborts I wait for exits or stops and arrange for a stop signal to be delivered atomically after execve and then continue. Currently, in my own code I do not actually check for the specific exit status that is generated when execve aborts but that will be easy to add in later.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions