These new calls will do three things:
1. in case of FILE* stuff: flush any pending bytes onto the fd, just in
case
2. seal the backing memfd
3. seek back to the beginning.
Note that this adds sealing to serialization: once we serialized fully,
we'll seal the thing off for further modifications, before we pass the
fd over to the target process. This should add a bit of robustness, and
maybe finds a bug or two one day, if we accidentally write to a
serialization that is complete.
Let's bump the kernel baseline a bit to 4.3 and thus require ambient
caps.
This allows us to remove support for a variety of special casing, most
importantly the ExecStart=!! hack.
If there is an error with the execv call in fork_agent the
program exits without any meaningful log message. Log the
command and errno so the user gets more information about
the failure.
Fixes: #33418
Signed-off-by: Mauri de Souza Meneguzzo <mauri870@gmail.com>
This is useful for situations where an array of FDs is to be passed into
a child process (i.e. by passing it through safe_fork). This function
can be called in the child (before calling exec) to pack the FDs to all
be next to each-other starting from SD_LISTEN_FDS_START (i.e. 3)
Sometimes it makes sense to hard kill a client if we die. Let's hence
add a third FORK_DEATHSIG flag for this purpose: FORK_DEATHSIG_SIGKILL.
To make things less confusing this also renames FORK_DEATHSIG to
FORK_DEATHSIG_SIGTERM to make clear it sends SIGTERM. We already had
FORK_DEATHSIG_SIGINT, hence this makes things nicely symmetric.
A bunch of users are switched over for FORK_DEATHSIG_SIGKILL where we
know it's safe to abort things abruptly. This should make some kernel
cases more robust, since we cannot get confused by signal masks or such.
While we are at it, also fix a bunch of bugs where we didn't take
FORK_DEATHSIG_SIGINT into account in safe_fork()
kernel-install uses do_execute(). We would log whenever a spawned child
finished, but we would not log anything when the child is launched. When the
children log output without a prefix (as the kernel-install plugins do), it
is hard to see where that output is coming from.
We shouldn't report that the file is empty if the stating fails. Let's do the
same as in other places, and just ignore the error and let the subsequent
operation fail.
-1 was used everywhere, but -EBADF or -EBADFD started being used in various
places. Let's make things consistent in the new style.
Note that there are two candidates:
EBADF 9 Bad file descriptor
EBADFD 77 File descriptor in bad state
Since we're initializating the fd, we're just assigning a value that means
"no fd yet", so it's just a bad file descriptor, and the first errno fits
better. If instead we had a valid file descriptor that became invalid because
of some operation or state change, the other errno would fit better.
In some places, initialization is dropped if unnecessary.
rearrange_stdio() invalidates specified fds even on failure, which means
we should always invalidate the fds we pass in no matter what. Let's
make this explicit by using TAKE_FD() for that everywhere.
Note that in many places we such invalidation doesnt get us much
behaviour-wise, since we don't use the variables anymore later. But
TAKE_FD() in a way is also documentation, it encodes explicitly that the
fds are invalidated here, so I think it's a good thing to always make
this explicit here.
Even though it's just a fallback path, let's not be sloppy and allocate in
the crash handler.
> The deadlock happens because systemd crash in malloc() then in signal
> handler, it calls malloc() (close_all_fds()-> opendir()-> __alloc_dir())
> again. malloc() is not a signal-safe function, maybe we should re-think
> the logic here.
Fixes#20266.
Library code should not call freeze(), this is something that should
only be done by "application code", so moving it into shared/ is appropriate.
The fallback to call _exit() is dropped: let's trust that the infinite loop
is infinite.
Currently it's only used in two places in src/shared/, so the function was
already included just once in compiled code. But it seems appropriate to
move it there anyway, because library code should have no need to fork
agents, so it doesn't belong in basic/.