Like it's customary in our codebase bus_error_message() internally takes
abs() of the passed error anyway, hence no need to explicitly negate it.
We mostly got this right, but in too many cases we didn't. Fix that.
We generally don't support prefix being != /usr, and this is hardcoded
all over the place. In the systemd.pc file it wasn't so far. Let's
adjust this to match the rest of the codebase.
This really doesn't matter given that AF_xyz and PF_xyz are equivalent
in all ways, but we almost always use AF_xyz, hence stick to it
universally and convert the remaining PF_ to AF_
sd_seat_get_sessions() would return 0 in the 'n_uids' (now 'ret_n_uids') output
parameter when 'uid' (now 'ret_uids') was passed as NULL.
While at it, drop FOREACH_WORD() use.
Also use any whitespace as separator. In practice this shouldn't matter, since
logind always uses spaces, but it seems nicer to not specify this explicitly,
and the default is more flexible.
This tries to address the "bind"/"unbind" uevent kernel API breakage, by
changing the semantics of device tags.
Previously, tags would be applied on uevents (and the database entries
they result in) only depending on the immediate context. This means that
if one uevent causes the tag to be set and the next to be unset, this
would immediately effect what apps would see and the database entries
would contain each time. This is problematic however, as tags are a
filtering concept, and if tags vanish then clients won't hence notice
when a device stops being relevant to them since not only the tags
disappear but immediately also the uevents for it are filtered including
the one necessary for the app to notice that the device lost its tag and
hence relevance.
With this change tags become "sticky". If a tag is applied is once
applied to a device it will stay in place forever, until the device is
removed. Tags can never be removed again. This means that an app
watching a specific set of devices by filtering for a tag is guaranteed
to not only see the events where the tag is set but also all follow-up
events where the tags might be removed again.
This change of behaviour is unfortunate, but is required due to the
kernel introducing new "bind" and "unbind" uevents that generally have
the effect that tags and properties disappear and apps hence don't
notice when a device looses relevance to it. "bind"/"unbind" events were
introduced in kernel 4.12, and are now used in more and more subsystems.
The introduction broke userspace widely, and this commit is an attempt
to provide a way for apps to deal with it.
While tags are now "sticky" a new automatic device property
CURRENT_TAGS is introduced (matching the existing TAGS property) that
always reflects the precise set of tags applied on the most recent
events. Thus, when subscribing to devices through tags, all devices that
ever had the tag put on them will be be seen, and by CURRENT_TAGS it may
be checked whether the device right at the moment matches the tag
requirements.
See: #7587#7018#8221
For discussion around this see: https://pagure.io/fedora-workstation/issue/82
Recovery keys for homed are very similar to regular passwords, except
that they are exclusively generated by the computer, and not chosen by
the user. The idea is that they are printed or otherwise stored
externally and not what users type in every day.
Taking inspiration from Windows and MacOS this uses 256bit keys. We
format them in 64 yubikey modhex characters, in groups of 8 chars
separated by dashes.
Why yubikey modhex? modhex only uses characters that are are located at
the same place in western keyboard designs. This should reduce the
chance for incorrect inputs for a major chunk of our users, though
certainly not all. This is particular relevant during early boot and
recovery situations, where there's a good chance the keyboard mapping is
not correctly set up.
let's make sure we collect the right error code from errno, otherwise
we'll see EPERM (i.e. error 1) for all errors readv() returns (since it
returns -1 on error), including EAGAIN.
This is definitely backport material.
A fix-up for 3691bcf3c5.
Fixes: #16699
We frequently want to set a timer relative to the current time. Let's
add an explicit API for this. This not only saves us a few lines of code
everywhere and simplifies things, but also allows us to do correct
overflow checking.
SD_JOURNAL_FOREACH_DATA() and SD_JOURNAL_FOREACH_UNIQUE() would immediately
terminate when a field couldn't be accessed. This can happen for example when a
field is compressed with an unavailable compression format. But it's likely
that this is the wrong thing to do: the caller for example might want to
iterate over the fields but isn't interested in all of them. coredumpctl is
like this: it uses SD_JOURNAL_FOREACH_DATA() but only uses a subset of the
fields.
Add two new functions sd_journal_enumerate_good_data() and
sd_journal_enumerate_good_unique() that retry sd_journal_enumerate_data() and
sd_journal_enumerate_unique() if the return value is something that applies to
a single field: ENOBUS, E2BIG, EOPNOTSUPP.
Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1856037.
An alternative would be to make the macros themselves smarter instead of adding
new symbols, and do the looping internally in the macro. I don't like that
approach for two reasons. First, it would embed the logic in the macro, so
recompilation would be required if we decide to update the logic. With the
current version of the patch, recompilation is required to use the new symbols,
but after that, library upgrades are enough. So the current approach is safer
in case further updates are needed. Second, our headers use primitive C, and it
is hard to do the macros without using newer features.
When sd_netlink_call_async() timed out, then we reply the synthetic
error message, but it was not sealed. So, reading the message causes
the following assertion:
```
Assertion 'm->sealed' failed at src/libsystemd/sd-netlink/netlink-message.c:652, function netlink_message_read_internal(). Ignoring.
```
When renaming a network interface, the new name may be used as an
alternative name. In that case, let's swap the current name and the
alternative name. That is, first drop the new name from the list of
alternative names, then rename the interface, finally set the old name
as an alternative name.
We use LOG_PRI() in all log_*() functions, so let's do that here too for
consistency. Effectively this doesn't change anything since we only use
LOG_{INFO,DEBUG,...} as the argument.
We never return anything higher than 63, so using "long unsigned"
as the type only confused the reader. (We can still use "long unsigned"
and safe_atolu() to parse the kernel file.)
Add support for creating a MACVLAN interface in "source" mode by
specifying Mode=source in the [MACVLAN] section of a .netdev file.
A list of allowed MAC addresses for the corresponding MACVLAN can also
be specified with the SourceMACAddress= option of the [MACVLAN] section.
An example .netdev file:
[NetDev]
Name=macvlan0
Kind=macvlan
MACAddress=02:DE:AD:BE:EF:00
[MACVLAN]
Mode=source
SourceMACAddress=02:AB:AB:AB:AB:01 02:CD:CD:CD:CD:01
SourceMACAddress=02:EF:EF:EF:EF:01
The same keys can also be specified in [MACVTAP] for MACVTAP kinds of
interfaces, with the same semantics.
We'd try to map a zero-byte buffer from a NULL pointer, which is undefined behaviour.
src/systemd/src/libsystemd/sd-bus/bus-message.c:3161:60: runtime error: applying zero offset to null pointer
#0 0x7f6ff064e691 in find_part /work/build/../../src/systemd/src/libsystemd/sd-bus/bus-message.c:3161:60
#1 0x7f6ff0640788 in message_peek_body /work/build/../../src/systemd/src/libsystemd/sd-bus/bus-message.c:3283:16
#2 0x7f6ff064e8db in enter_struct_or_dict_entry /work/build/../../src/systemd/src/libsystemd/sd-bus/bus-message.c:3967:21
#3 0x7f6ff06444ac in bus_message_enter_struct /work/build/../../src/systemd/src/libsystemd/sd-bus/bus-message.c:4009:13
#4 0x7f6ff0641dde in sd_bus_message_enter_container /work/build/../../src/systemd/src/libsystemd/sd-bus/bus-message.c:4136:21
#5 0x7f6ff0619874 in sd_bus_message_dump /work/build/../../src/systemd/src/libsystemd/sd-bus/bus-dump.c:178:29
#6 0x4293d9 in LLVMFuzzerTestOneInput /work/build/../../src/systemd/src/fuzz/fuzz-bus-message.c:39:9
#7 0x441986 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/libfuzzer/FuzzerLoop.cpp:558:15
#8 0x44121e in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) /src/libfuzzer/FuzzerLoop.cpp:470:3
#9 0x443164 in fuzzer::Fuzzer::ReadAndExecuteSeedCorpora(std::__1::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /src/libfuzzer/FuzzerLoop.cpp:770:7
#10 0x4434bc in fuzzer::Fuzzer::Loop(std::__1::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /src/libfuzzer/FuzzerLoop.cpp:799:3
#11 0x42d2bc in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/libfuzzer/FuzzerDriver.cpp:846:6
#12 0x42978a in main /src/libfuzzer/FuzzerMain.cpp:19:10
#13 0x7f6fef13c82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
#14 0x407808 in _start (out/fuzz-bus-message+0x407808)
Patch contains a coccinelle script, but it only works in some cases. Many
parts were converted by hand.
Note: I did not fix errors in return value handing. This will be done separate
to keep the patch comprehensible. No functional change is intended in this
patch.
This is an attempt to clean up the POP3/SMTP/LPR/… DHCP lease server
data logic in networkd. This reduces code duplication and fixes a number
of bugs.
This removes any support for collecting POP3/SMPT/LPR servers acquired
via local DHCP client releases since noone uses that, and given how old
these protocols are I doubt this will change. It keeps support for
configuring them for the dhcp server however.
The differences between the DNS/NTP/SIP/POP3/SMTP/LPR configuration
logics are minimized.
This removes the relevant symbols from sd-network.h (which is an
internal API only at this point after all).
This is unfortunately not well test, given the old code for this had
barely any tests. But the new code should not perform worse at least,
and allow us to release, since it corrects some interfaces visible in
the .network configuration format.
Fixes: #15943
Prompted by the discussion on #16110, let's migrate more code to
fd_wait_for_event().
This only leaves 7 places where we call into poll()/poll() directly in
our entire codebase. (one of which is fd_wait_for_event() itself)
poll() sets POLLNVAL inside of the poll structures if an invalid fd is
passed. So far we generally didn't check for that, thus not taking
notice of the error. Given that this specific kind of error is generally
indication of a programming error, and given that our code is embedded
into our projects via NSS or because people link against our library,
let's explicitly check for this and convert it to EBADF.
(I ran into a busy loop because of this missing check when some of my
test code accidentally closed an fd it shouldn't close, so this is a
real thing)
Tracking down #15931 confused the hell out of me, since running homed in
gdb from the command line worked fine, but doing so as a service failed.
Let's make this more debuggable and check if we live in the host netns
when allocating a new udev monitor.
This is just debug stuff, so that if things don't work, a quick debug
run will reveal what is going on.
That said, while we are at it, also fix unexpected closing of passed in
fd when failing.
Clean up the naming of the sd-path enums. Previously, the more recently
added fields where named in the form SD_PATH_xyz_DIR and
SD_PATH_xyz_PATH, while the older fields where called just SD_PATH_xyz
and SD_PATH_SEARCH_xyz. Let's clean this up, to come to a more unified
way how we name this stuff.
I opted to stick to the old naming, i.e. dropthe suffixes. It's a bit of
a bike-shedding question of course, but I think there's a good reason to
avoid the additional DIR and PATH suffixes: the enum prefix contains
"PATH" anyway (i.e. "SD_PATH_"), so including PATH twice in each name is
redundant. Moreover, the key difference between the enums with the "dir"
and the "path" in the name is that the latter are *seach* paths, and I
think this is better emphasized by sticking to the "SEARCH" in the name.
Moreover dropping the suffixes makes the identifiers a lot shorter, in
particular in the "systemd-path" list output. And that's always good.
This means the naming pkgconfig file and in sd-path slightly deviate
(though the mapping is very simple), but I think that's OK, given that
this is developer facing and not user facing.
ROOTPREFIX doesn't include the trailing /, hence add it in where needed.
Also, given that sysctl.d/, binfmt.d/, sysusers.d/ are generally
accessed before /var/ is up they should use ROOTPREFIX rather than
PREFIX. Fix that.
Each of bus_set_address_{user,system} had two users, and each of the two users
would set the internal flag manually. We should do that internally in the
functions instead.
While at it, only set the flag when setting the address is actually successful.
This doesn't change anything for current users, but it seems more correct.
Those are fairly trivial to reimplement, but any non-trivial user of sd-bus
is likely to need them. So let's expose them to save everyone the trouble.
I'm keeping the internal functions and making the public ones thin wrappers,
because for the internal uses we don't need the additional asserts, and also we
can't expose _pure_ annotation easily, and dropping it would likely make the
compiled code a bit less efficient.
In the linked reproducer, m->fields_size == 0, and we calculate ri == -1, which
of course doesn't end well. Skip the whole calculation if m->fields_size == 0,
and also check that we don't go negative even if it is non-zero.
Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=19446 and #15583.
While investigating why some of my netlink calls would timeout I
stumbled upon the definition of the max write queue length. Finding this
constant made me believe we still had a write queue in the code - which
isn't true. The netlink write queue code was removed in #189.
When set, the offset specified for the vtable entry is passed to the
handler as-is, and is not added to the userdata pointer. This is useful
in case methods/properties are mixed on the same vtable, that expect to
operate relative to some object in memory and that expect pointers to
absolute memory, or that just want a number passed.
This also makes sure the control buffer is properly aligned. This
matters, as otherwise the control buffer might not be aligned and the
cmsg buffer counting might be off. The incorrect alignment is becoming
visible by using recvmsg_safe() as we suddenly notice the MSG_CTRUNC bit
set because of this.
That said, apparently this isn't enough to make this work on all
kernels. Since I couldn't figure this out, we now add 1K to the buffer
to be sure. We do this once already, also for a pktinfo structure
(though an IPv4/IPv6) one. I am puzzled by this, but this shouldn't
matter much. it works locally just fine, except for those ubuntu CI
kernels...
While we are at it, make some other changes too, to simplify and
modernize the function.
We always need to make them unions with a "struct cmsghdr" in them, so
that things properly aligned. Otherwise we might end up at an unaligned
address and the counting goes all wrong, possibly making the kernel
refuse our buffers.
Also, let's make sure we initialize the control buffers to zero when
sending, but leave them uninitialized when reading.
Both the alignment and the initialization thing is mentioned in the
cmsg(3) man page.
We need to use the CMSG_SPACE() macro to size the control buffers, not
CMSG_LEN(). The former is rounded up to next alignment boundary, the
latter is not. The former should be used for allocations, the latter for
encoding how much of it is actually initialized. See cmsg(3) man page
for details about this.
Given how confusing this is, I guess we don't have to be too ashamed
here, in most cases we actually did get this right.
Our hashmap and set helpers return a different code whenever an entry
already exists, so let's use this to avoid unsetting scan_uptodate when
not necessary.
Thus, the return convention for
sd_device_enumerator_add_match_subsystem,
sd_device_enumerator_add_match_sysattr,
sd_device_enumerator_add_match_property,
sd_device_enumerator_add_match_sysname,
sd_device_enumerator_add_match_tag,
device_enumerator_add_match_parent_incremental,
sd_device_enumerator_add_match_parent,
sd_device_enumerator_allow_uninitialized,
device_enumerator_add_match_is_initialized
is that "1" is returned if action was taken, and "0" on noop.
If we're using a set with _put_strdup(), most of the time we want to use
string hash ops on the set, and free the strings when done. This defines
the appropriate a new string_hash_ops_free structure to automatically free
the keys when removing the set, and makes set_put_strdup() and set_put_strdupv()
instantiate the set with those hash ops.
hashmap_put_strdup() was already doing something similar.
(It is OK to instantiate the set earlier, possibly with a different hash ops
structure. set_put_strdup() will then use the existing set. It is also OK
to call set_free_free() instead of set_free() on a set with
string_hash_ops_free, the effect is the same, we're just overriding the
override of the cleanup function.)
No functional change intended.
This adds the sd_notify_barrier function, to allow users to synchronize against
the reception of sd_notify(3) status messages. It acts as a synchronization
point, and a successful return gurantees that all previous messages have been
consumed by the manager. This can be used to eliminate race conditions where
the sending process exits too early for systemd to associate its PID to a
cgroup and attribute the status message to a unit correctly.
systemd-notify now uses this function for proper notification delivery and be
useful for NotifyAccess=all units again in user mode, or in cases where it
doesn't have a control process as parent.
Fixes: #2739
With cgroup v2 the cgroup freezer is implemented as a cgroup
attribute called cgroup.freeze. cgroup can be frozen by writing "1"
to the file and kernel will send us a notification through
"cgroup.events" after the operation is finished and processes in the
cgroup entered quiescent state, i.e. they are not scheduled to
run. Writing "0" to the attribute file does the inverse and process
execution is resumed.
This commit exposes above low-level functionality through systemd's DBus
API. Each unit type must provide specialized implementation for these
methods, otherwise, we return an error. So far only service, scope, and
slice unit types provide the support. It is possible to check if a
given unit has the support using CanFreeze() DBus property.
Note that DBus API has a synchronous behavior and we dispatch the reply
to freeze/thaw requests only after the kernel has notified us that
requested operation was completed.
Let's be extra careful whenever we return from recvmsg() and see
MSG_CTRUNC set. This generally means we ran into a programming error, as
we didn't size the control buffer large enough. It's an error condition
we should at least log about, or propagate up. Hence do that.
This is particularly important when receiving fds, since for those the
control data can be of any size. In particular on stream sockets that's
nasty, because if we miss an fd because of control data truncation we
cannot recover, we might not even realize that we are one off.
(Also, when failing early, if there's any chance the socket might be
AF_UNIX let's close all received fds, all the time. We got this right
most of the time, but there were a few cases missing. God, UNIX is hard
to use)
ubsan complains that we add an offset to a NULL ptr here in some cases.
Which isn't really a bug though, since we only use it as the end
condition for a for loop, but we can still fix it...
Fixes: #15522
A warning is emitted from sd_bus_message_{get,set}_priority. Those functions
are exposed by pystemd, so we have no easy way of checking if anything is
calling them.
Just making the functions always return without doing anything would be an
option, but then we could leave the caller with an undefined variable. So I
think it's better to make the functions emit a warnings and return priority=0
in the get operation.
Consumers of the sd-bus convenience API can't make convenience
helpers of their own without va_list variants.
This commit is a mechanical change splitting out the existing function
bodies into bare va_list variants having a 'v' suffixed to the names.
The original functions now simply create the va_list before forwarding
the call on to the va_list variant, and the va_list variants dispense
with those steps.
sd_bus_reply_method_errno already does the same two checks
(sd_bus_error_is_set(error), r < 0) internally. But it did them in opposite
order. The effect is the same, because sd_bus_reply_method_errno falls back to
sd_bus_reply_method_error, but it seems inelegant. So let's simplify
bus_maybe_reply_error() to offload the job fully to sd_bus_reply_method_errno().
No functional change.
So far we had various ad hoc APIs to query search paths:
systemd-analyze unit-paths, lookup_paths_log(), the pkgconfig file,
debug logs emitted by systemd-analyze cat-config.
But answering a simple question "what is the search path for tmpfiles,
sysusers, .network files, ..." is surprisingly hard.
I think we should have an api that makes it easy to query this. Pkgconfig is
not bad, but it is primarily a development tool, so it's not available in many
context. Also it can't provide support for paths which are influenced by
environment variables, and I'd like to be able to answer the question "what is
the search path for ..., assuming that VAR_FOO=... is set?".
Extending sd-path to support more of our internal paths seems to be most
flexible solution. We already have systemd-path which provides a nice
way to query, and we can add stuff like optional descriptions later on.
We we essentially get a nice programmatic and commmandline apis for the price
of one.
The two functions were duplicating a lot of functionality and more
importantly, they both had explicit lists of types which are search
paths. I want to add more types, and I don't want to have to remember
to add them to both lists.
I think the two names were both pretty bad. They did not give a proper hint
what the difference between the two functions is, and sd_path_home sounds like
it is somehow related to /home or home directories or whatever, when in fact
both functions return the same set of paths as either a colon-delimited string
or a strv. "_strv" suffix is used by various functions in sd-bus, so let's
reuse that.
Those functions are not public yet, so let's rename.
In those functions where bus defaults to the m->bus, we should also
resolve the magic parameters. And if neither called with bus=NULL
and an unattached message, return properly instead of crashing in assert
later.
It fully initializes the address structure, so no need for pre-initialization,
and also returns the length of the address, so no need to recalculate using
SOCKADDR_UN_LEN().
socklen_t is unsigned, so let's not use an int for it. (It doesn't matter, but
seems cleaner and more portable to not assume anything about the type.)