This replaces the local implementation of a timeout file lock with our
new generic one.
Note that a comment in the old code claimed we couldn't use alarm()-like timeouts,
but htat's not entirely true: we can if we use SIGKILL, and thus know
for sure that the process will be dead in case the timer is hit before
we actually enter the file lock syscall. But we also know it will be
delivered if we hit after.
This is just like lock_generic(), but applies the lock with a timeout.
This requires jumping through some hoops by executing things in a child
process, so that we can abort if necessary via a timer. Linux after all
has no native way to take file locks with a timeout.
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()
This is just like FORMAT_PROC_FD_PATH() but goes via the PID number
rather than the "self" symlink.
This is useful whenever we want to generate a path that is useful
outside of our local scope.
varlink_dispatch() is a simple wrapper around json_dispatch() that
returns clean, standards-compliant InvalidParameter error back to
clients, if the specified JSON cannot be parsed properly.
For this json_dispatch() is extended to return the offending field's
name. Because it already has quite a few parameters, I then renamed
json_dispatch() to json_dispatch_full() and made json_dispatch() a
wrapper around it that passes the new argument as NULL. While doing so I
figured we should also get rid of the bad= argument in the short
wrapper, since it's only used in the OCI code.
To simplify the OCI code this adds a second wrapper oci_dispatch()
around json_dispatch_full(), that fills in bad= the way we want.
Net result: instead of one json_dispatch() call there are now:
1. json_dispatch_full() for the fully feature mother of all dispathers.
2. json_dispatch() for the simpler version that you want to use most of
the time.
3. varlink_dispatch() that generates nice Varlink errors
4. oci_dispatch() that does the OCI specific error handling
And that's all there is.
To avoid timeouts in oss-fuzz. The timeout reported in #29736 happened
with a ~500K test case, so with a conservative 128K limit we should
still be well within a range for any reasonable-ish generated input to
get through, while avoiding timeouts.
Resolves: #29736
Prior to this commit, if the target had been a symlink, we did nothing
with it. Let's try with fchmodat2() and skip gracefully if not supported.
Co-authored-by: Mike Yuan <me@yhndnzj.com>
Follow-up for 8b45281daa
and preparation for later commits.
Since libcs are more interested in the POSIX `fchmodat(3)`, they are
unlikely to provide a direct wrapper for this syscall. Thus, the headers
we examine to set `HAVE_*` are picked somewhat arbitrarily.
Also, hook up `try_fchmodat2()` in `test-seccomp.c`. (Also, correct that
function's prototype, despite the fact that mistake would not matter in
practice)
Co-authored-by: Mike Yuan <me@yhndnzj.com>
Currently the ID_NET_DRIVER is set in net_setup_link builtin.
But this is called pretty late in the udev processing chain.
Right now in some custom rules it was workarounded by calling ethtool
binary directly, which is ugly.
So let's split this code to a separate builtin.
If we use CHASE_PARENT on a path ending in ".." then things are a bit
weird, because we the last path we look at is actually the *parent* and not
the *child* of the preceeding path. Hence we cannot just return the 2nd
to last fd we look at. We have to correct it, by going *two* levels up,
to get to the actual parent, and make sure CHASE_PARENT does what it
should.
Example: for the path /a/b/c chase() with CHASE_PARENT will return
/a/b/c as path, and the fd returned points to /a/b. All good. But now,
for the path /a/b/c/.. chase() with CHASE_PARENT would previously return
/a/b as path (which is OK) but the fd would point to /a/b/c, which is
*not* the parent of /a/b, after all! To get to the actual parent of
/a/b we have to go *two* levels up to get to /a.
Very confusing. But that's what we here for, no?
@mrc0mmand ran into this in https://github.com/systemd/systemd/pull/28891#issuecomment-1782833722
Several udev rules depends on the previous behavior, i.e. that udev
replaces the devlink with the newer device node when the priority is
equivalent. Let's relax the optimization done by
331aa7aa15.
Follow-up for 331aa7aa15.
Note, the offending commit drops O(N) of file reads per uevent, and this
commit does not change the computational order. So, hopefully the
performance impact of this change is small enough.
Fixes#28141.
Let's unconditionally drop privileges before submitting the coredump log
message.
Let's make the codepaths where we acquired a coredump and where we
didn't more alike: let's drop privs in both cases.
This is not only safer, but means that the coredump messages are always
accessible by the owner of the aborted process.
Let's not claim a process dumped core if that was disabled via resource
limits.
While we are at it, switch from stack to heap allocation for the log
message, as it includes a stack trace which can be arbitrarily large.
Fixes: #28559
If we have a DDI that contains only a /usr/ tree (and which is thus
combined with a tmpfs for root on boot) we previously would try to apply
idmapping to the tmpfs, but not the /usr/ mount. That's broken of
course.
Fix this by applying it to both trees.
Let's wait until the child is fully done with mounting it's own
instances of procfs/sysfs before we destroy our fully visible copies of
it.
This borrows heavily from Christian Brauners fix#29521, but splits the
place + sync into two steps so that the child payload is not started
before the parent has destroyed the procfs instance.
Alternative to: #29521Fixes: #28157
The device node may be different from we want to activate, and we may
try to activate different device in the subsequent loop. In such case,
we should enable the automatic removal for the unexpected device.
Otherwise, it will not be removed even when not necessary anymore.
This module reads password from kernel keyring and sets it as PAM authtok.
It's inspired by gdm's pam_gdm, which reads the LUKS password stored by
systemd-cryptsetup, so Gnome Keyring can be automatically unlocked if set
to the same password (when autologin is enabled so the user doesn't enter
a password in gdm).