I have an interesting use case. I'm running systemd in a container to simulate a VM for testing purposes. I'm able to run systemd just fine, but I need my default user to not be root so that anything execing into the container will get the right user and only then become root via sudo.
My ENTRYPOINT
is sudo /usr/lib/systemd/systemd --system --unit=multi-user.target
, and it works just fine for most things. However, due to the sudo
invocation, systemd does not get PID 1, which some downstream systemd units depend on.
According to the docs:
Process model
When sudo runs a command, it calls fork(2), sets up the execution environment as described above, and calls the execve system call in the child process. The main sudo process waits until the command has completed, then passes the command's exit status to the security policy's close function and exits. If an I/O logging plugin is configured or if the security policy explicitly requests it, a new pseudo-terminal (“pty”) is created and a second sudo process is used to relay job control signals between the user's existing pty and the new pty the command is being run in. This extra process makes it possible to, for example, suspend and resume the command. Without it, the command would be in what POSIX terms an “orphaned process group” and it would not receive any job control signals. As a special case, if the policy plugin does not define a close function and no pty is required, sudo will execute the command directly instead of calling fork(2) first. The sudoers policy plugin will only define a close function when I/O logging is enabled, a pty is required, or the pam_session or pam_setcred options are enabled. Note that pam_session and pam_setcred are enabled by default on systems using PAM.
Is there a way to tell sudo to replace itself with the child process that it runs, similar to exec
in Bash? Is there another better way to do this? It seems that I'd need to change "the policy plugin" potentially for just this one command, but I'm not sure how to do this.
docker exec
gets an unprivileged user instead. It seems that I need to write some C or rust tosetuid
/setgid
to root and thenexecve
, replacing the current program with systemd as true PID 1.