tests: also fuzz packets sent in the DHCP6_STATE_SOLICITATION state
With aborts enabled the fuzzer can catch issues like
https://github.com/systemd/systemd/commit/26a63b81322a3bd8b9fbd43f75897c391708de2c
Let's extend it a bit to let it cover issues like
https://github.com/systemd/systemd/pull/22406#discussion_r798932098
Thomas Haller [Thu, 3 Feb 2022 17:55:18 +0000 (18:55 +0100)]
sd-dhcp6-client: fix sending prefix delegation request during rebind
Fixes an assertion failure "pd->type == SD_DHCP6_OPTION_IA_PD" in dhcp6_option_append_pd().
Something similar was done in commit 26a63b81322a ('sd-dhcp6-client: Fix
sending prefix delegation request (#17136)'). The justification is
probably the same.
In D-Bus, clients connect to a bus (the usual case), or use direct
questions to each other (the unusual case). A bus is a program one can
connect to and implemented by dbus-daemon or dbus-broker. HOwever,
busses never connect between each other, that doesn't exist. Hence don't
claim so.
This is probably confusion about the fact that sd-bus calls D-Bus
connection objects just "sd_bus" for simplicity, given they are used in
99% of the cases to connect to a bus — only in exceptional cases they
are used for direct connections between peers without involving a bus.
Michael Olbrich [Wed, 2 Feb 2022 14:33:07 +0000 (15:33 +0100)]
shutdown: don't stop the watchdog
This basically reverts #22079.
Stopping the watchdog is wrong. The reboot watchdog is supposed to cover
the whole time from the point when systemd start systemd-reboot until the
hardware resets.
Otherwise the system may hang in the final shutdown phase.
Add a comment, why keeping the watchdog running is correct here.
Michael Olbrich [Wed, 2 Feb 2022 14:26:53 +0000 (15:26 +0100)]
watchdog: fix watchdog_set_device() when the default watchdog device is used
If watchdog_set_device() is not called before open_watchdog() then
'watchdog_device' remains 'NULL' while the device is open.
As a result, the "same device" check in watchdog_set_device() does not work
correctly: If no device is specified (e.g. from watchdog_free_device())
then the current fd is not closed.
Fix this by setting 'watchdog_device' to the correct device during
open_watchdog()
hostnamed: drop "iteractive" parameter from GetHardwareSerial()
Since a long time the D-Bus spec knows a special bit in its message
header for indicating that "interactive" authentication is OK. The
original hostnamed API is before that was added hence most functions
expose that boolean as explicit argument.
For new added functions let's get rid of it, the message flag is good
enough and replaces it with complete functionality.
No new APIs should carry the "interactive" boolean flag explicitly as
argument anymore.
test-network: disable 'no-member' warning for the Utilities class
The warning is correct, since we don't inherit the necessary
unittest.TestCase class, but that's on purpose, since the Utilities
class is not supposed to be instantiated on its own, but should
complement other classes' definitions which do inherit from the
unittest.TestCase class.
test-network: use raw strings for regexes with backslashes
It currently works because `\(` and `\)` are not valid escape sequences,
so they're not treated differently. Using raw strings (or double
backslashes) is a more correct solution.
test-network: convert certain multiline strings to comments
Multiline comments are converted to docstrings only when they're the
first statement in a function/method. Even though they're still a no-op
otherwise, let's use "true" comments to make pylint happy.
journal: when copying journal file to undo NOCOW flag, go via fd
We have the journal file open already, hence reference it via the fd
insted of the file name. After all, some other tool might have
renamed/deleted it already.
Let's not actually reuse the fd though, since we want a separate file
offset for the copying, hence just make it simply and reopen via
/proc/self/fd/.
tests: pass FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION to fuzzers
to let them use reproducible identifiers, which should make it possible
to really use files copied from OSS-Fuzz to reproduce issues on
GHActions and locally. Prompted by https://github.com/systemd/systemd/pull/22365
Rationale: the focus here should be on the fact that these are "unified"
images, whether our stub is used or not, or something else doesn't
really matter. Moreover, these are still Linux entries. Hence, emphasize
that these are *unified* images, and *Linux* images, and deemphesize
that our sd-stub is likely used.
to make sure outgoing packets based on incoming packets are fine.
It's just another follow-up to
https://github.com/systemd/systemd/pull/10200.
Better late than never :-)
dhcp-identifier: always use a fixed machine-id while fuzzing
It's a follow-up to https://github.com/systemd/systemd/pull/10200 where
that fuzzer was introduced. At the time it was run regularly on machines
where machine-id wasn't present so it was kind of reproducible. Now
it's run on CIFuzz and CFLite using GHActions with the public OSS-Fuzz
corpora (based on that particular machine-id) so to fully utilize
those corpora it's necessary to use it always. Other than that
it makes it possible for fuzzers targeting outgoing packets
based on incoming packets like https://bugs.launchpad.net/ubuntu/+source/systemd/+bug/1795921
to get past client_parse_message on my machine :-)
Before the commit, when `mkdir_parents_internal()` is called from `mkdir_p()`,
it uses `_mkdir()` as `flag` is zero. But after the commit, `mkdir_safe_internal()`
is always used. Hence, if the path contains a symlink, it fails with -ENOTDIR.
To fix the issue, this makes `mkdir_p()` calls `mkdir_parents_internal()` with
MKDIR_FOLLOW_SYMLINK flag.
Originally, we always used the mmap logic to determine the current end
of the file. ab6e257b3e4e5b95f3750ed019bed6e89989e41b changed this so
that we always used pread().
With this change we'll use pread() from the synchronization thread and
mmap otherwise.
tests: rework test macros to not take code as parameters
C macros are nasty. We use them, but we try to be conservative with
them. In particular passing literal, complex code blocks as argument is
icky, because of "," handling of C, and also because it's quite a
challange for most code highlighters and similar. Hence, let's avoid
that. Using macros for genreating functions is OK but if so, the
parameters should be simple words, not full code blocks.
hence, rework DEFINE_CUSTOM_TEST_MAIN() to take a function name instead
of code block as argument.
As side-effect this also fixes a bunch of cases where we might end up
returning a negative value from main().
Some uses of DEFINE_CUSTOM_TEST_MAIN() inserted local variables into the
main() functions, these are replaced by static variables, and their
destructors by the static destructor logic.
This doesn't fix any bugs or so, it's just supposed to make the code
easier to work with and improve it easthetically.
Or in other words: let's use macros where it really makes sense, but
let's not go overboard with it.
(And yes, FOREACH_DIRENT() is another one of those macros that take
code, and I dislike that too and regret I ever added that.)
units: we need systemd-journald.service from systemd-journal-flush.service
This is a follow-up for d5ee050ffc9d413253932d9340ade8c8fb111092, and
reintroduces a requirement dep from systemd-journal-flush.service onto
systemd-journald.service, but a weaker one than originally: a Wants= one
instead of a Requires= one.
Why? Simply because the service issues an IPC call to the journald,
hence it should pull it in. (Note that socket activation doesn't happen
for the Varlink socket it uses, hence we should pull in the service
itself.)
Joan Bruguera [Sun, 30 Jan 2022 16:56:32 +0000 (17:56 +0100)]
resolved: Allow test-resolved-stream to run concurrently
Since test-resolved-stream brings up a simple DNS server on 127.0.0.1:12345,
only one instance could run at a time, so it would fail when run like
`meson test -C build test-resolved-stream --repeat=1000`.
Similarly, if by chance something is up on port 12345, the test would fail.
To make the test more reliable, run it in an isolated user + network namespace.
If this fails (some distributions disable user namespaces), just run as before.
Joan Bruguera [Sun, 30 Jan 2022 11:51:10 +0000 (12:51 +0100)]
resolved: Read as much as possible per stream EPOLLIN event
In commit 2aaf6bb6e99b0f2bd73e0c49bef9e11a2844bf1a, an issue was fixed where
systemd-resolved could get stuck for multiple seconds waiting for incoming data,
since GnuTLS/OpenSSL can buffer a TLS record, so data could be available, but
no EPOLLIN event would be generated.
To fix this, a somewhat elaborate logic consisting on asking the TLS library
whether it had buffered data, then "faking" an EPOLLIN event was implemented.
However, there is a much simpler solution: Always read as much data as available
(i.e. until we get an event like EAGAIN when trying to read) from the stream
when we get an EPOLLIN event, instead of at most a single packet per event.
This approach does not require asking the TLS library whether it has buffered
data, and the logic is exactly the same for both the TCP and TLS case.
test-resolved-stream is fixed to avoid a latent double free bug.
Joan Bruguera [Mon, 31 Jan 2022 20:28:32 +0000 (21:28 +0100)]
resolved: Avoid multiple SSL writes per DoT packet
In the DoT case, dns_stream_writev decomposed an iovec into multiple
dnstls_stream_write calls, which resulted in multiple SSL writes and multiple
TLS records. This can be checked from a network capture, e.g. using socat:
socat -v -x openssl-listen:853,reuseaddr,fork,cert=my.cert,key=my.key,verify=0 openssl:8.8.8.8:853
Instead, propagate the iovec as-is into the DoT handling code. For GnuTLS, the
library provides support for buffering ('corking') a record. OpenSSL has no
such facility, so we join the iovec into a single buffer then call SSL_write.
socat capture of `resolvectl -4 query --cache=no example.com` before the commit: