Let's always write "1 << 0", "1 << 1" and so on, except where we need
more than 31 flag bits, where we write "UINT64(1) << 0", and so on to force
64bit values.
cgroup: relax checks for block device cgroup settings
This drops needless safety checks that ensure we only reference block
devices for blockio/io settings. The backing code was already able to
accept regular file system paths too, in which case the backing device
node of that file system would be used. Hence, let's drop the artificial
restrictions and open up this underlying functionality.
blockdev-util: let's initialize return parameter on success
We document the rule that return values >= 0 of functions are supposed
to indicate success, and that in case of success all return parameters
should be initialized. Let's actually do so.
meson: also reject shifts that change the sign bit
../src/test/test-sizeof.c: In function ‘main’:
../src/test/test-sizeof.c:70:24: error: result of ‘1 << 31’ requires 33 bits to represent, but ‘int’ only has 32 bits [-Werror=shift-overflow=]
X = (1 << 31),
^~
cc1: some warnings being treated as errors
Jun 11 14:29:12 krowka systemd[1]: /etc/systemd/system/workingdir.service:6: = path is not normalizedWorkingDirectory: /../../etc
↓
Jun 11 14:32:12 krowka systemd[1]: /etc/systemd/system/workingdir.service:6: WorkingDirectory= path is not normalized: /../../etc
Since bb28e68477a3a39796e4999a6cbc6ac6345a9159 parsing failures of
certain unit file settings will result in load failures of units. This
introduces a new load state "bad-setting" that is entered in precisely
this case.
With this addition error messages on bad settings should be a lot more
explicit, as we don't have to show some generic "errno" error in that
case, but can explicitly say that a bad setting is at fault.
Internally this unit load state is entered as soon as any configuration
loader call returns ENOEXEC. Hence: config parser calls should return
ENOEXEC now for such essential unit file settings. Turns out, they
generally already do.
man: don't mention "stub" and "merged" unit load states
These states should never be visible to the outside, as they are used
only internally while loading unit. Hence let's drop them from the
documentation.
core: use bus_unit_validate_load_state() for generating LoadError unit bus property
The load_error is only valid in some load_state cases, lets generate
prettier messages for other cases too, by reusing the
bus_unit_validate_load_state() call which does jus that.
Clients (such as systemctl) ignored LoadError unles LoadState was
"error" before. With this change they could even show LoadError in other
cases and it would show a useful name.
Let's use a switch() statement, cover more cases with pretty messages.
Also let's rename it to "validate", as that's more specific that
"check", as it implies checking for a "valid"/"good" state, which is
what this function does.
This makes two changes: first of all we will now explicitly check
whether a domain to test against an NSEC record is actually below the
signer's name. This is relevant for NSEC records that chain up the end
and the beginning of a zone: we shouldn't alow that NSEC record to match
against domains outside of the zone.
This also fixes how we handle NSEC checks for domains that are prefixes
of the NSEC RR domain itself, fixing #8164 which triggers this specific
case. The non-wildcard NSEC check is simplified for that, we can
directly make our between check, there's no need to find the "Next
Closer" first, as the between check should not be affected by additional
prefixes. For the wild card NSEC check we'll prepend the asterisk in
this case to the NSEC RR itself to make a correct check.
0. 0x7fce77519ca5 in ascii_is_valid systemd/src/basic/utf8.c:252:9
1. 0x7fce774d203c in ellipsize_mem systemd/src/basic/string-util.c:544:13
2. 0x7fce7730a299 in print_multiline systemd/src/shared/logs-show.c:244:37
3. 0x7fce772ffdf3 in output_short systemd/src/shared/logs-show.c:495:25
4. 0x7fce772f5a27 in show_journal_entry systemd/src/shared/logs-show.c:1077:15
5. 0x7fce772f66ad in show_journal systemd/src/shared/logs-show.c:1164:29
6. 0x4a2fa0 in LLVMFuzzerTestOneInput systemd/src/fuzz/fuzz-journal-remote.c:64:21
...
I didn't reproduce the issue, but this looks like an obvious error: the length
is specified, so we shouldn't use the string with any functions for normal
C-strings.
The primary motivation is to catch enum values created through a shift that is
too big:
../src/test/test-sizeof.c:26:29: error: left shift count >= width of type [-Werror=shift-count-overflow]
enum_with_shift = 1 << 32,
^~
cc1: some warnings being treated as errors
This introduces a has_data boolean field in struct unit_files which can
be used to detect the end of the array.
Use a _cleanup_ for struct unit_files in acquire_time_data and its
callers. Code for acquire_time_data is also simplified by replacing
goto's with straight returns.
Tested: By running the commands below, also checking them under valgrind.
- build/systemd-analyze blame
- build/systemd-analyze critical-chain
- build/systemd-analyze plot
scsi_id: use _cleanup_free_ on buffer allocated by get_file_options
This simplifies the code a bit and hopefully fixes Coverity finding
CID 1382966. There was not actually a resource leak here (Coverity
seemed to be confused by thinking log_oom() could actually return 0),
but the fix doesn't hurt and should make this code more resilient to
future refactorings.
Tested: builds fine, manually called scsi_id, seems to work ok.
lldp: check that lldp neighbor raw data size is in expected range
This fixes an insecure use of tainted data as argument to functions that
allocate memory and read from files, which could be tricked into getting
networkctl to allocate a large amount of memory and fill it with file
data.
This was uncovered by Coverity. Fixes CID 1393254.
udev-builtin-usb_id: Check full range of size returned by read()
This shouldn't be necessary, since read() should never return a size
larger than the size of the buffer passed in, but Coverity doesn't seem
to understand that.
We could possibly fix this with a model file for Coverity, but given
changing the code is not that much of a biggie, let's just do that
instead.
Fixes CID 996458: Overflowed or truncated value (or a value computed
from an overflowed or truncated value) `pos` used as array index.
Tested: `ninja -C build/ test`, builds without warnings, test cases pass.
CODING_STYLE: allow c99-style mixed code and declarations
We already allowed variables to be declared in the middle of a function
(whenever a new scope was opened), so this isn't such a big change. Sometimes
we would open a scope just to work around this prohibition.
But sometimes the code can be much clearer if the variable is declared
somewhere in the middle of a scope, in particular if the declaration is
combined with initialization or acquisition of some resources. So let's allow
this, but keep things in the old style, unless there's a good reason to move
the variable declaration to a different place.
core: enumerate perpetual units in a separate per-unit-type method
Previously the enumerate() callback defined for each unit type would do
two things:
1. It would create perpetual units (i.e. -.slice, system.slice, -.mount and
init.scope)
2. It would enumerate units from /proc/self/mountinfo, /proc/swaps and
the udev database
With this change these two parts are split into two seperate methods:
enumerate() now only does #2, while enumerate_perpetual() is responsible
for #1. Why make this change? Well, perpetual units should have a
slightly different effect that those found through enumeration: as
perpetual units should be up unconditionally, perpetually and thus never
change state, they should also not pull in deps by their state changing,
not even when the state is first set to active. Thus, their state is
generally initialized through the per-device coldplug() method in
similar fashion to the deserialized state from a previous run would be
put into place. OTOH units found through regular enumeration should
result in state changes (and thus pull in deps due to state changes),
hence their state should be put in effect in the catchup() method
instead. Hence, given this difference, let's also separate the
functions, so that the rule is:
1. What is created in enumerate_perpetual() should be started in
coldplug()
2. What is created in enumerate() should be started in catchup().
This makes sure that any device changes that might have happened while
we were restarting/reloading will be noticed properly. For that we'll
now properly serialize/deserialize both the device unit state and the
device "found" flags, and restore these initially in the "coldplug"
phase of the manager deserialization. While enumerating the udev devices
during startup we'll put together a new "found" flags mask, which we'll
the switch to in the "catchup" phase of the manager deserialization,
which follows the "coldplug" phase.
Note that during the "coldplug" phase no unit state change events are
generated, which is different for the "catchall" phase which will do
that. Thus we correctly make sure that the deserialized state won't pull
in new deps, but any device's change while we were reloading would.
This is very similar to the existing unit method coldplug() but is
called a bit later. The idea is that that coldplug() restores the unit
state from before any prior reload/restart, i.e. puts the deserialized
state in effect. The catchup() call is then called a bit later, to
catch up with the system state for which we missed notifications while
we were reloading. This is only really useful for mount, swap and device
mount points were we should be careful to generate all missing unit
state change events (i.e. call unit_notify() appropriately) for
everything that happened while we were reloading.
let's drop the "now" argument, it's exactly what MANAGER_IS_RUNNING()
returns, hence let's use that instead to simplify things.
Moreover, let's change the add/found argument pair to become found/mask,
which allows us to change multiple flags at the same time into opposing
directions, which will be useful later on.
Also, let's change the return type to void. It's a notifier call where
callers will ignore the return value anyway as it is nothing actionable.