]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #10152 from yuwata/udev-use-extract
authorLennart Poettering <lennart@poettering.net>
Fri, 5 Oct 2018 15:11:43 +0000 (17:11 +0200)
committerGitHub <noreply@github.com>
Fri, 5 Oct 2018 15:11:43 +0000 (17:11 +0200)
udev: small cleanups

288 files changed:
TODO
docs/CODE_OF_CONDUCT.md [new file with mode: 0644]
docs/TRANSIENT-SETTINGS.md
docs/_config.yml
docs/index.md [new file with mode: 0644]
man/journalctl.xml
man/os-release.xml
man/rules/meson.build
man/sd-id128.xml
man/sd_id128_get_machine.xml
man/sd_id128_randomize.xml
man/systemctl.xml
man/systemd-id128.xml [new file with mode: 0644]
man/systemd.journal-fields.xml
man/systemd.kill.xml
man/systemd.link.xml
man/systemd.service.xml
meson.build
meson_options.txt
po/tr.po
src/basic/env-util.c
src/basic/fileio.c
src/basic/fs-util.c
src/basic/hashmap.h
src/basic/hexdecoct.c
src/basic/parse-util.c
src/basic/path-util.c
src/basic/process-util.c
src/basic/string-util.c
src/basic/string-util.h
src/basic/time-util.c
src/basic/unit-def.c
src/basic/unit-def.h
src/basic/utf8.c
src/basic/utf8.h
src/boot/efi/meson.build
src/boot/efi/splash.c
src/core/dbus-kill.c
src/core/execute.c
src/core/kill.c
src/core/kill.h
src/core/load-fragment-gperf.gperf.m4
src/core/manager.c
src/core/service.c
src/core/unit.c
src/core/unit.h
src/fuzz/fuzz-bus-message.c [new file with mode: 0644]
src/fuzz/fuzz-dhcp6-client.c [new file with mode: 0644]
src/fuzz/fuzz-ndisc-rs.c [new file with mode: 0644]
src/fuzz/meson.build
src/id128/id128.c [new file with mode: 0644]
src/import/import-raw.c
src/import/pull-job.c
src/journal-remote/journal-upload-journal.c
src/journal-remote/journal-upload.c
src/journal/journal-verify.c
src/journal/journalctl.c
src/journal/test-journal-syslog.c
src/libsystemd-network/dhcp-identifier.c
src/libsystemd-network/dhcp6-internal.h
src/libsystemd-network/dhcp6-option.c
src/libsystemd-network/icmp6-util.c
src/libsystemd-network/ndisc-router.c
src/libsystemd-network/radv-internal.h
src/libsystemd-network/sd-dhcp-client.c
src/libsystemd-network/sd-dhcp-lease.c
src/libsystemd-network/sd-dhcp6-client.c
src/libsystemd-network/sd-lldp.c
src/libsystemd-network/sd-ndisc.c
src/libsystemd-network/sd-radv.c
src/libsystemd/libsystemd.sym
src/libsystemd/sd-bus/bus-dump.c
src/libsystemd/sd-bus/bus-message.c
src/libsystemd/sd-bus/bus-signature.c
src/libsystemd/sd-bus/test-bus-cleanup.c
src/libsystemd/sd-bus/test-bus-gvariant.c
src/libsystemd/sd-bus/test-bus-marshal.c
src/libsystemd/sd-bus/test-bus-match.c
src/libsystemd/sd-bus/test-bus-signature.c
src/libsystemd/sd-bus/test-bus-track.c
src/libsystemd/sd-device/test-sd-device.c [new file with mode: 0644]
src/libsystemd/sd-event/sd-event.c
src/libsystemd/sd-id128/sd-id128.c
src/network/networkd-dhcp6.c
src/network/networkd-link.c
src/network/networkd-link.h
src/network/networkd-manager.c
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/networkd-routing-policy-rule.c
src/network/networkd-routing-policy-rule.h
src/nspawn/nspawn-cgroup.c
src/nspawn/nspawn-seccomp.c
src/nspawn/nspawn.c
src/shared/bus-unit-util.c
src/shared/dns-domain.c
src/shared/id128-print.c [new file with mode: 0644]
src/shared/id128-print.h [new file with mode: 0644]
src/shared/install.c
src/shared/meson.build
src/shared/seccomp-util.c
src/shared/seccomp-util.h
src/shared/tests.h
src/systemd/meson.build
src/systemd/sd-dhcp6-client.h
src/systemd/sd-id128.h
src/systemd/sd-messages.h
src/test/meson.build
src/test/test-execute.c
src/test/test-fs-util.c
src/test/test-install-root.c
src/test/test-process-util.c
src/test/test-sd-hwdb.c [new file with mode: 0644]
src/test/test-seccomp.c
src/test/test-string-util.c
src/test/test-utf8.c
src/udev/net/ethtool-util.c
src/udev/net/ethtool-util.h
src/udev/net/link-config-gperf.gperf
src/udev/net/link-config.c
src/udev/net/link-config.h
src/udev/udev-builtin-net_id.c
test/fuzz-regressions/.gitattributes [deleted file]
test/fuzz-regressions/meson.build [deleted file]
test/fuzz/.gitattributes [moved from test/fuzz-corpus/.gitattributes with 100% similarity]
test/fuzz/fuzz-bus-message/crash-26bba7182dedc8848939931d9fcefcb7922f2e56 [new file with mode: 0644]
test/fuzz/fuzz-bus-message/crash-29ed3c202e0ffade3cad42c8bbeb6cc68a21eb8e [new file with mode: 0644]
test/fuzz/fuzz-bus-message/crash-32bf69483cbd4f2e6d46c25a2f92a472109aee45 [new file with mode: 0644]
test/fuzz/fuzz-bus-message/crash-37449529b1ad867f0c2671fa80aca5d7812a2b70 [new file with mode: 0644]
test/fuzz/fuzz-bus-message/crash-4162a61a79e4c5a832ca5232212f75fa560a1f75 [new file with mode: 0644]
test/fuzz/fuzz-bus-message/crash-4f0211eb269e28db941961061494bfdbf3345e54 [new file with mode: 0644]
test/fuzz/fuzz-bus-message/crash-603dfd98252375ac7dbced53c2ec312671939a36 [new file with mode: 0644]
test/fuzz/fuzz-bus-message/crash-b88ad9ecf4aacf4a0caca5b5543953265367f084 [new file with mode: 0644]
test/fuzz/fuzz-bus-message/crash-c1b37b4729b42c0c05b23cba4eed5d8102498a1e [new file with mode: 0644]
test/fuzz/fuzz-bus-message/crash-d8f3941c74219b4c03532c9b244d5ea539c61af5 [new file with mode: 0644]
test/fuzz/fuzz-bus-message/crash-e1b811da5ca494e494b77c6bd8e1c2f2989425c5 [new file with mode: 0644]
test/fuzz/fuzz-bus-message/leak-c09c0e2256d43bc5e2d02748c8d8760e7bc25d20 [new file with mode: 0644]
test/fuzz/fuzz-bus-message/message1 [new file with mode: 0644]
test/fuzz/fuzz-bus-message/timeout-08ee8f6446a4064db064e8e0b3d220147f7d0b5b [new file with mode: 0644]
test/fuzz/fuzz-dhcp-server/discover-existing [moved from test/fuzz-corpus/dhcp-server/discover-existing with 100% similarity]
test/fuzz/fuzz-dhcp-server/discover-new [moved from test/fuzz-corpus/dhcp-server/discover-new with 100% similarity]
test/fuzz/fuzz-dhcp-server/release [moved from test/fuzz-corpus/dhcp-server/release with 100% similarity]
test/fuzz/fuzz-dhcp-server/request-existing [moved from test/fuzz-corpus/dhcp-server/request-existing with 100% similarity]
test/fuzz/fuzz-dhcp-server/request-new [moved from test/fuzz-corpus/dhcp-server/request-new with 100% similarity]
test/fuzz/fuzz-dhcp-server/request-reboot [moved from test/fuzz-corpus/dhcp-server/request-reboot with 100% similarity]
test/fuzz/fuzz-dhcp-server/request-renew [moved from test/fuzz-corpus/dhcp-server/request-renew with 100% similarity]
test/fuzz/fuzz-dhcp6-client/crash-4003c06fce43a11fbd22f02584df2807ac333eae [new file with mode: 0644]
test/fuzz/fuzz-dhcp6-client/crash-6e88fcb6b85c9436bcbe05219aa8e550194645ef [new file with mode: 0644]
test/fuzz/fuzz-dhcp6-client/oss-fuzz-10746 [new file with mode: 0644]
test/fuzz/fuzz-dns-packet/issue-7888 [moved from test/fuzz-regressions/fuzz-dns-packet/issue-7888 with 100% similarity]
test/fuzz/fuzz-dns-packet/oss-fuzz-5465 [moved from test/fuzz-regressions/fuzz-dns-packet/oss-fuzz-5465 with 100% similarity]
test/fuzz/fuzz-journal-remote/crash-5a8f03d4c3a46fcded39527084f437e8e4b54b76 [moved from test/fuzz-regressions/fuzz-journal-remote/crash-5a8f03d4c3a46fcded39527084f437e8e4b54b76 with 100% similarity]
test/fuzz/fuzz-journal-remote/crash-96dee870ea66d03e89ac321eee28ea63a9b9aa45 [moved from test/fuzz-regressions/fuzz-journal-remote/crash-96dee870ea66d03e89ac321eee28ea63a9b9aa45 with 100% similarity]
test/fuzz/fuzz-journal-remote/invalid-ts.txt [moved from test/fuzz-corpus/journal-remote/invalid-ts.txt with 100% similarity]
test/fuzz/fuzz-journal-remote/oss-fuzz-8659 [moved from test/fuzz-regressions/fuzz-journal-remote/oss-fuzz-8659 with 100% similarity]
test/fuzz/fuzz-journal-remote/oss-fuzz-8686 [moved from test/fuzz-regressions/fuzz-journal-remote/oss-fuzz-8686 with 100% similarity]
test/fuzz/fuzz-journal-remote/sample.txt [moved from test/fuzz-corpus/journal-remote/sample.txt with 100% similarity]
test/fuzz/fuzz-journald-syslog/github-9795 [moved from test/fuzz-regressions/fuzz-journald-syslog/github-9795 with 100% similarity]
test/fuzz/fuzz-journald-syslog/github-9820 [moved from test/fuzz-regressions/fuzz-journald-syslog/github-9820 with 100% similarity]
test/fuzz/fuzz-journald-syslog/github-9827 [moved from test/fuzz-regressions/fuzz-journald-syslog/github-9827 with 100% similarity]
test/fuzz/fuzz-journald-syslog/github-9829 [moved from test/fuzz-regressions/fuzz-journald-syslog/github-9829 with 100% similarity]
test/fuzz/fuzz-ndisc-rs/timeout-2815b773c712fa33bea62f541dfa3017c64ea2f1 [new file with mode: 0644]
test/fuzz/fuzz-ndisc-rs/timeout-61fff7fd1e5dcc07e1b656baab29065ce634ad5b [new file with mode: 0644]
test/fuzz/fuzz-unit-file/dev-mapper-fedora_krowka\x2dswap.swap [moved from test/fuzz-corpus/unit-file/dev-mapper-fedora_krowka\x2dswap.swap with 100% similarity]
test/fuzz/fuzz-unit-file/directives.service [moved from test/fuzz-corpus/unit-file/directives.service with 99% similarity]
test/fuzz/fuzz-unit-file/empty.scope [moved from test/fuzz-corpus/unit-file/empty.scope with 100% similarity]
test/fuzz/fuzz-unit-file/machine.slice [moved from test/fuzz-corpus/unit-file/machine.slice with 100% similarity]
test/fuzz/fuzz-unit-file/oss-fuzz-10007 [moved from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-10007 with 100% similarity]
test/fuzz/fuzz-unit-file/oss-fuzz-6884 [moved from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6884 with 100% similarity]
test/fuzz/fuzz-unit-file/oss-fuzz-6885 [moved from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6885 with 100% similarity]
test/fuzz/fuzz-unit-file/oss-fuzz-6886 [moved from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6886 with 100% similarity]
test/fuzz/fuzz-unit-file/oss-fuzz-6892 [moved from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6892 with 100% similarity]
test/fuzz/fuzz-unit-file/oss-fuzz-6897 [moved from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6897 with 100% similarity]
test/fuzz/fuzz-unit-file/oss-fuzz-6897-evverx [moved from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6897-evverx with 100% similarity]
test/fuzz/fuzz-unit-file/oss-fuzz-6908 [moved from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6908 with 100% similarity]
test/fuzz/fuzz-unit-file/oss-fuzz-6917 [moved from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6917 with 100% similarity]
test/fuzz/fuzz-unit-file/oss-fuzz-6977 [moved from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6977 with 100% similarity]
test/fuzz/fuzz-unit-file/oss-fuzz-6977-unminimized [moved from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6977-unminimized with 100% similarity]
test/fuzz/fuzz-unit-file/oss-fuzz-7004 [moved from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-7004 with 100% similarity]
test/fuzz/fuzz-unit-file/oss-fuzz-8064 [moved from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-8064 with 100% similarity]
test/fuzz/fuzz-unit-file/oss-fuzz-8827 [moved from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-8827 with 100% similarity]
test/fuzz/fuzz-unit-file/proc-sys-fs-binfmt_misc.automount [moved from test/fuzz-corpus/unit-file/proc-sys-fs-binfmt_misc.automount with 100% similarity]
test/fuzz/fuzz-unit-file/syslog.socket [moved from test/fuzz-corpus/unit-file/syslog.socket with 100% similarity]
test/fuzz/fuzz-unit-file/systemd-ask-password-console.path [moved from test/fuzz-corpus/unit-file/systemd-ask-password-console.path with 100% similarity]
test/fuzz/fuzz-unit-file/systemd-machined.service [moved from test/fuzz-corpus/unit-file/systemd-machined.service with 100% similarity]
test/fuzz/fuzz-unit-file/systemd-resolved.service [moved from test/fuzz-corpus/unit-file/systemd-resolved.service with 100% similarity]
test/fuzz/fuzz-unit-file/systemd-tmpfiles-clean.timer [moved from test/fuzz-corpus/unit-file/systemd-tmpfiles-clean.timer with 100% similarity]
test/fuzz/fuzz-unit-file/timers.target [moved from test/fuzz-corpus/unit-file/timers.target with 100% similarity]
test/fuzz/fuzz-unit-file/var-lib-machines.mount [moved from test/fuzz-corpus/unit-file/var-lib-machines.mount with 100% similarity]
test/fuzz/meson.build [new file with mode: 0644]
test/meson.build
test/test-execute/exec-dynamicuser-fixeduser-one-supplementarygroup.service
test/test-execute/exec-dynamicuser-fixeduser.service
test/test-execute/exec-dynamicuser-supplementarygroups.service
test/test-execute/exec-supplementarygroups-multiple-groups-default-group-user.service
test/test-execute/exec-supplementarygroups-multiple-groups-withgid.service
test/test-execute/exec-supplementarygroups-multiple-groups-withuid.service
test/test-execute/exec-supplementarygroups-single-group-user.service
test/test-execute/exec-supplementarygroups-single-group.service
test/test-execute/exec-supplementarygroups.service
test/test-execute/exec-systemcallfilter-with-errno-multi.service [new file with mode: 0644]
test/test-execute/exec-umask-0177.service
test/test-execute/exec-umask-default.service
test/test-network/conf/11-dummy.netdev [new file with mode: 0644]
test/test-network/conf/12-dummy.netdev [new file with mode: 0644]
test/test-network/conf/21-macvlan.netdev [new file with mode: 0644]
test/test-network/conf/21-macvtap.netdev [new file with mode: 0644]
test/test-network/conf/21-vlan.netdev [new file with mode: 0644]
test/test-network/conf/21-vlan.network [new file with mode: 0644]
test/test-network/conf/23-active-slave.network [new file with mode: 0644]
test/test-network/conf/23-bond199.network [new file with mode: 0644]
test/test-network/conf/23-emit-lldp.network [new file with mode: 0644]
test/test-network/conf/23-primary-slave.network [new file with mode: 0644]
test/test-network/conf/23-test1-bond199.network [new file with mode: 0644]
test/test-network/conf/24-lldp.network [new file with mode: 0644]
test/test-network/conf/24-search-domain.network [new file with mode: 0644]
test/test-network/conf/25-address-link-section.network [new file with mode: 0644]
test/test-network/conf/25-address-section-miscellaneous.network [new file with mode: 0644]
test/test-network/conf/25-address-section.network [new file with mode: 0644]
test/test-network/conf/25-bond-active-backup-slave.netdev [new file with mode: 0644]
test/test-network/conf/25-bond.netdev [new file with mode: 0644]
test/test-network/conf/25-bridge.netdev [new file with mode: 0644]
test/test-network/conf/25-geneve.netdev [new file with mode: 0644]
test/test-network/conf/25-gre-tunnel.netdev [new file with mode: 0644]
test/test-network/conf/25-gretap-tunnel.netdev [new file with mode: 0644]
test/test-network/conf/25-ip6gre-tunnel.netdev [new file with mode: 0644]
test/test-network/conf/25-ip6tnl-tunnel.netdev [new file with mode: 0644]
test/test-network/conf/25-ipip-tunnel-independent.netdev [new file with mode: 0644]
test/test-network/conf/25-ipip-tunnel.netdev [new file with mode: 0644]
test/test-network/conf/25-ipv6-address-label-section.network [new file with mode: 0644]
test/test-network/conf/25-ipvlan.netdev [new file with mode: 0644]
test/test-network/conf/25-link-section-unmanaged.network [new file with mode: 0644]
test/test-network/conf/25-route-section.network [new file with mode: 0644]
test/test-network/conf/25-route-tcp-window-settings.network [new file with mode: 0644]
test/test-network/conf/25-route-type.network [new file with mode: 0644]
test/test-network/conf/25-sit-tunnel.netdev [new file with mode: 0644]
test/test-network/conf/25-sysctl.network [new file with mode: 0644]
test/test-network/conf/25-tap.netdev [new file with mode: 0644]
test/test-network/conf/25-tun.netdev [new file with mode: 0644]
test/test-network/conf/25-vcan.netdev [new file with mode: 0644]
test/test-network/conf/25-veth.netdev [new file with mode: 0644]
test/test-network/conf/25-vrf.netdev [new file with mode: 0644]
test/test-network/conf/25-vti-tunnel.netdev [new file with mode: 0644]
test/test-network/conf/25-vti6-tunnel.netdev [new file with mode: 0644]
test/test-network/conf/25-vxlan.netdev [new file with mode: 0644]
test/test-network/conf/26-bridge-slave-interface-1.network [new file with mode: 0644]
test/test-network/conf/26-bridge-slave-interface-2.network [new file with mode: 0644]
test/test-network/conf/26-bridge.netdev [new file with mode: 0644]
test/test-network/conf/bridge99.network [new file with mode: 0644]
test/test-network/conf/configure-without-carrier.network [new file with mode: 0644]
test/test-network/conf/dhcp-client-anonymize.network [new file with mode: 0644]
test/test-network/conf/dhcp-client-critical-connection.network [new file with mode: 0644]
test/test-network/conf/dhcp-client-ipv4-dhcp-settings.network [new file with mode: 0644]
test/test-network/conf/dhcp-client-ipv4-only-ipv6-disabled.network [new file with mode: 0644]
test/test-network/conf/dhcp-client-ipv4-only.network [new file with mode: 0644]
test/test-network/conf/dhcp-client-ipv6-only.network [new file with mode: 0644]
test/test-network/conf/dhcp-client-ipv6-rapid-commit.network [new file with mode: 0644]
test/test-network/conf/dhcp-client-listen-port.network [new file with mode: 0644]
test/test-network/conf/dhcp-client-route-metric.network [new file with mode: 0644]
test/test-network/conf/dhcp-client-route-table.network [new file with mode: 0644]
test/test-network/conf/dhcp-client-timezone-router.network [new file with mode: 0644]
test/test-network/conf/dhcp-client.network [new file with mode: 0644]
test/test-network/conf/dhcp-server-timezone-router.network [new file with mode: 0644]
test/test-network/conf/dhcp-server-veth-peer.network [new file with mode: 0644]
test/test-network/conf/dhcp-server.network [new file with mode: 0644]
test/test-network/conf/dhcp-v4-server-veth-peer.network [new file with mode: 0644]
test/test-network/conf/gretap.network [new file with mode: 0644]
test/test-network/conf/gretun.network [new file with mode: 0644]
test/test-network/conf/ip6gretap.network [new file with mode: 0644]
test/test-network/conf/ip6tnl.network [new file with mode: 0644]
test/test-network/conf/ipip.network [new file with mode: 0644]
test/test-network/conf/ipv6-prefix-veth.network [new file with mode: 0644]
test/test-network/conf/ipv6-prefix.network [new file with mode: 0644]
test/test-network/conf/ipvlan.network [new file with mode: 0644]
test/test-network/conf/macvlan.network [new file with mode: 0644]
test/test-network/conf/macvtap.network [new file with mode: 0644]
test/test-network/conf/routing-policy-rule.network [new file with mode: 0644]
test/test-network/conf/sit.network [new file with mode: 0644]
test/test-network/conf/test-static.network [new file with mode: 0644]
test/test-network/conf/vti.network [new file with mode: 0644]
test/test-network/conf/vti6.network [new file with mode: 0644]
test/test-network/conf/vxlan.network [new file with mode: 0644]
test/test-network/systemd-networkd-tests.py [new file with mode: 0755]
tools/make-index-md.sh [new file with mode: 0755]
tools/oss-fuzz.sh
units/systemd-ask-password-console.path
units/systemd-ask-password-console.service.in
units/systemd-ask-password-wall.path

diff --git a/TODO b/TODO
index f3d6f56a4f1818618b4038697c47babe0ce26fc0..13af83dfe62b930c4e87271138b4d0c7f74d45d7 100644 (file)
--- a/TODO
+++ b/TODO
@@ -15,8 +15,27 @@ Janitorial Clean-ups:
 * rework mount.c and swap.c to follow proper state enumeration/deserialization
   semantics, like we do for device.c now
 
+Before v240:
+
+* move portablectl into /usr/bin
+
+* portables: introduce a new unit file directory /etc/systemd/system.attached/
+  or so, where we attach portable services to
+
 Features:
 
+* consider splitting out all temporary file creation APIs (we have so many in
+  fileio.h and elsewhere!) into a new util file of its own.
+
+* set memory.oom.group in cgroupsv2 for all leaf cgroups
+
+* whenever oom_kill memory.event event is triggered print a nice log message
+
+* Move RestrictAddressFamily= to the new cgroup create socket
+
+* support the bind/connect/sendmsg cgroup stuff for sandboxing, and possibly
+  patching around
+
 * chown() tty a service is attached to after the service goes down
 
 * optionally, if a per-partition GPT flag is set for the root/home/… partitions
@@ -83,9 +102,6 @@ Features:
   5. add autodetection of hibernation images, and add "noresume" to disable
      this
 
-* portables: introduce a new unit file directory /etc/systemd/system.attached/
-  or so, where we attach portable services to
-
 * cgroups: use inotify to get notified when somebody else modifies cgroups
   owned by us, then log a friendly warning.
 
@@ -172,10 +188,6 @@ Features:
 * add bpf-based implementation of devices cgroup controller logic for compat
   with cgroupsv2 as supported by newest kernel
 
-* introduce sd_id128_get_boot_app_specific() which is like
-  sd_id128_get_machine_app_specific(). After all on long-running systems both
-  IDs have similar properties.
-
 * sd-bus: add vtable flag, that may be used to request client creds implicitly
   and asynchronously before dispatching the operation
 
diff --git a/docs/CODE_OF_CONDUCT.md b/docs/CODE_OF_CONDUCT.md
new file mode 100644 (file)
index 0000000..b3b46cd
--- /dev/null
@@ -0,0 +1,14 @@
+# The systemd Community Conduct Guidelines
+
+This document provides community guidelines for a safe, respectful, productive, and collaborative place for any person who is willing to contribute to systemd. It applies to all “collaborative spaces”, which is defined as community communications channels (such as mailing lists, submitted patches, commit comments, etc.).
+
+- Participants will be tolerant of opposing views.
+- Participants must ensure that their language and actions are free of personal attacks and disparaging personal remarks.
+- When interpreting the words and actions of others, participants should always assume good intentions.
+- Behaviour which can be reasonably considered harassment will not be tolerated.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at systemd-conduct@googlegroups.com. This team currently consists of David Strauss <<systemd-conduct@davidstrauss.net>>, Ekaterina Gerasimova (Kat) <<Kittykat3756@gmail.com>>, and Zbigniew Jędrzejewski-Szmek <<zbyszek@in.waw.pl>>. In the unfortunate event that you wish to make a complaint against one of the members, you may instead contact any of the other members individually.
+
+All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident.
index bb13cfdbfe7885ca61e0f8f28c49bf8831774f17..1b9a240e5c3ec8aa133c77f2e2c84d824d0cd4a0 100644 (file)
@@ -257,6 +257,7 @@ All process killing settings are available for transient units:
 ✓ KillMode=
 ✓ KillSignal=
 ✓ FinalKillSignal=
+✓ WatchdogSignal=
 ```
 
 ## Service Unit Settings
index c7418817439b2f071c93a4a6cee831e996123c0b..cc35c1df2caa93681dc09d66b3c37ed898755f19 100644 (file)
@@ -1 +1 @@
-theme: jekyll-theme-slate
\ No newline at end of file
+theme: jekyll-theme-modernist
\ No newline at end of file
diff --git a/docs/index.md b/docs/index.md
new file mode 100644 (file)
index 0000000..32366cc
--- /dev/null
@@ -0,0 +1,25 @@
+# systemd Documentation
+
+* [The Boot Loader Specification](BOOT_LOADER_SPECIFICATION.md)
+
+* [Control Group APIs and Delegation](CGROUP_DELEGATION.md)
+
+* [The systemd Community Conduct Guidelines](CODE_OF_CONDUCT.md)
+
+* [Code Quality Tools](CODE_QUALITY.md)
+
+* [Contributing](CONTRIBUTING.md)
+
+* [Porting systemd To New Distributions](DISTRO_PORTING.md)
+
+* [Known Environment Variables](ENVIRONMENT.md)
+
+* [Portable Services Introduction](PORTABLE_SERVICES.md)
+
+* [Steps to a successful release](RELEASE.md)
+
+* [What settings are currently available for transient units?](TRANSIENT-SETTINGS.md)
+
+* [Notes for Translators](TRANSLATORS.md)
+
+* [Users, Groups, UIDs and GIDs on `systemd` systems](UIDS-GIDS.md)
index a4f9e2d7ee288633ed648de28074a697ce1d7603..91461a77323a42c204ef58a01c8be41502bc9efc 100644 (file)
         </para></listitem>
       </varlistentry>
 
-      <varlistentry>
-        <term><option>--new-id128</option></term>
-
-        <listitem><para>Instead of showing journal contents, generate
-        a new 128-bit ID suitable for identifying messages. This is
-        intended for usage by developers who need a new identifier for
-        a new message they introduce and want to make
-        recognizable. This will print the new ID in four different
-        formats which can be copied into source code or similar.
-        </para></listitem>
-      </varlistentry>
-
       <varlistentry>
         <term><option>--header</option></term>
 
index 58b86390da6e6368bff1869a1bb1de1ae27695e7..0efd2638410e4c10145fab6feebf2869a27cc651 100644 (file)
 
       <varlistentry>
         <term><varname>HOME_URL=</varname></term>
+        <term><varname>DOCUMENTATION_URL=</varname></term>
         <term><varname>SUPPORT_URL=</varname></term>
         <term><varname>BUG_REPORT_URL=</varname></term>
         <term><varname>PRIVACY_POLICY_URL=</varname></term>
 
         <listitem><para>Links to resources on the Internet related to 
-        the operating system. <varname>HOME_URL=</varname> should refer
-        to the homepage of the operating system, or alternatively some
-        homepage of the specific version of the operating system.
+        the operating system.
+        <varname>HOME_URL=</varname> should refer to the homepage of
+        the operating system, or alternatively some homepage of the
+        specific version of the operating system.
+        <varname>DOCUMENTATION_URL=</varname> should refer to the main
+        documentation page for this operating system.
         <varname>SUPPORT_URL=</varname> should refer to the main
         support page for the operating system, if there is any. This
         is primarily intended for operating systems which vendors
index 99915c5e9f73c4e0382abd3ab2f9076aa4ec90be..303b584654977d01609b089b2106081cfb0996cd 100644 (file)
@@ -438,6 +438,7 @@ manpages = [
  ['sd_id128_get_machine',
   '3',
   ['sd_id128_get_boot',
+   'sd_id128_get_boot_app_specific',
    'sd_id128_get_invocation',
    'sd_id128_get_machine_app_specific'],
   ''],
@@ -658,6 +659,7 @@ manpages = [
   'ENABLE_HIBERNATE'],
  ['systemd-hostnamed.service', '8', ['systemd-hostnamed'], 'ENABLE_HOSTNAMED'],
  ['systemd-hwdb', '8', [], 'ENABLE_HWDB'],
+ ['systemd-id128', '1', [], ''],
  ['systemd-importd.service', '8', ['systemd-importd'], 'ENABLE_IMPORTD'],
  ['systemd-inhibit', '1', [], ''],
  ['systemd-initctl.service',
index fbcf4bf3677ad0d971e92564f0a325046b892397..4425c45d1e08a5a206b33d632c65c6f767982022 100644 (file)
@@ -141,8 +141,8 @@ int main(int argc, char **argv) {
 }</programlisting>
 
     <para>Note that new, randomized IDs may be generated with
-    <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
-    <option>--new-id128</option> option.</para>
+    <citerefentry><refentrytitle>systemd-id128</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
+    <command>new</command> command.</para>
   </refsect1>
 
   <xi:include href="libsystemd-pkgconfig.xml" />
index 9587aa7d66a30edb225ee197f7457a22b70b50be..088483832471b244b2e55b462e634c072c73478c 100644 (file)
@@ -22,6 +22,7 @@
     <refname>sd_id128_get_machine</refname>
     <refname>sd_id128_get_machine_app_specific</refname>
     <refname>sd_id128_get_boot</refname>
+    <refname>sd_id128_get_boot_app_specific</refname>
     <refname>sd_id128_get_invocation</refname>
     <refpurpose>Retrieve 128-bit IDs</refpurpose>
   </refnamediv>
         <paramdef>sd_id128_t *<parameter>ret</parameter></paramdef>
       </funcprototype>
 
+      <funcprototype>
+        <funcdef>int <function>sd_id128_get_boot_app_specific</function></funcdef>
+        <paramdef>sd_id128_t <parameter>app_id</parameter></paramdef>
+        <paramdef>sd_id128_t *<parameter>ret</parameter></paramdef>
+      </funcprototype>
+
       <funcprototype>
         <funcdef>int <function>sd_id128_get_invocation</function></funcdef>
         <paramdef>sd_id128_t *<parameter>ret</parameter></paramdef>
     <function>sd_id128_get_machine()</function>, but retrieves a machine ID that is specific to the application that is
     identified by the indicated application ID. It is recommended to use this function instead of
     <function>sd_id128_get_machine()</function> when passing an ID to untrusted environments, in order to make sure
-    that the original machine ID may not be determined externally. The application-specific ID should be generated via
-    a tool like <command>journalctl --new-id128</command>, and may be compiled into the application. This function will
-    return the same application-specific ID for each combination of machine ID and application ID. Internally, this
-    function calculates HMAC-SHA256 of the application ID, keyed by the machine ID.</para>
-
-    <para><function>sd_id128_get_boot()</function> returns the boot ID
-    of the executing kernel. This reads and parses the
-    <filename>/proc/sys/kernel/random/boot_id</filename> file exposed
-    by the kernel. It is randomly generated early at boot and is
-    unique for every running kernel instance. See
-    <citerefentry project='man-pages'><refentrytitle>random</refentrytitle><manvolnum>4</manvolnum></citerefentry>
-    for more information. This function also internally caches the
-    returned ID to make this call a cheap operation.</para>
+    that the original machine ID may not be determined externally. This way, the ID used by the application remains
+    stable on a given machine, but cannot be easily correlated with IDs used in other applications on the same
+    machine. The application-specific ID should be generated via a tool like <command>systemd-id128 new</command>,
+    and may be compiled into the application. This function will return the same application-specific ID for each
+    combination of machine ID and application ID. Internally, this function calculates HMAC-SHA256 of the application
+    ID, keyed by the machine ID.</para>
+
+    <para><function>sd_id128_get_boot()</function> returns the boot ID of the executing kernel. This reads and parses
+    the <filename>/proc/sys/kernel/random/boot_id</filename> file exposed by the kernel. It is randomly generated early
+    at boot and is unique for every running kernel instance. See <citerefentry
+    project='man-pages'><refentrytitle>random</refentrytitle><manvolnum>4</manvolnum></citerefentry> for more
+    information. This function also internally caches the returned ID to make this call a cheap operation. It is
+    recommended to use this ID as-is only in trusted environments. In untrusted environments it is recommended to
+    derive an application specific ID using <function>sd_id128_get_machine_app_specific()</function>, see below.</para>
+
+    <para><function>sd_id128_get_boot_app_specific()</function> is analogous to
+    <function>sd_id128_get_machine_app_specific()</function> but returns an ID that changes between boots. Some
+    machines may be used for a long time without rebooting, hence the boot ID may remain constant for a long time, and
+    has properties similar to the machine ID during that time.</para>
 
     <para><function>sd_id128_get_invocation()</function> returns the invocation ID of the currently executed
     service. In its current implementation, this reads and parses the <varname>$INVOCATION_ID</varname> environment
     <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry> for details. The
     ID is cached internally. In future a different mechanism to determine the invocation ID may be added.</para>
 
-    <para>Note that <function>sd_id128_get_machine_app_specific()</function>, <function>sd_id128_get_boot()</function>
-    and <function>sd_id128_get_invocation()</function> always return UUID v4 compatible IDs.
-    <function>sd_id128_get_machine()</function> will also return a UUID v4-compatible ID on new installations but might
-    not on older.  It is possible to convert the machine ID into a UUID v4-compatible one. For more information, see
+    <para>Note that <function>sd_id128_get_machine_app_specific()</function>, <function>sd_id128_get_boot()</function>,
+    <function>sd_id128_get_boot_app_specific()</function>, and <function>sd_id128_get_invocation()</function> always
+    return UUID v4 compatible IDs.  <function>sd_id128_get_machine()</function> will also return a UUID v4-compatible
+    ID on new installations but might not on older. It is possible to convert the machine ID into a UUID v4-compatible
+    one. For more information, see
     <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
 
     <para>For more information about the <literal>sd_id128_t</literal>
     <title>Return Value</title>
 
     <para>Those calls return 0 on success (in which case <parameter>ret</parameter> is filled in),
-    or a negative errno-style error code. In particular, <function>sd_id128_get_machine()</function>
-    and <function>sd_id128_get_machine_app_specific()</function> return <constant>-ENOENT</constant>
-    if <filename>/etc/machine-id</filename> is missing, and <constant>-ENOMEDIUM</constant> if is
-    empty or all zeros.</para>
+    or a negative errno-style error code. In particular,
+    <function>sd_id128_get_machine()</function>,
+    <function>sd_id128_get_machine_app_specific()</function>, and
+    <function>sd_id128_get_boot_app_specific()</function> return <constant>-ENOENT</constant> if
+    <filename>/etc/machine-id</filename> is missing, and <constant>-ENOMEDIUM</constant> if is empty
+    or all zeros.</para>
   </refsect1>
 
   <xi:include href="libsystemd-pkgconfig.xml" />
     <example>
       <title>Application-specific machine ID</title>
 
-      <para>Here's a simple example for an application specific machine ID:</para>
+      <para>First, generate the application ID:</para>
+      <programlisting>$ systemd-id128 -p new
+As string:
+c273277323db454ea63bb96e79b53e97
+
+As UUID:
+c2732773-23db-454e-a63b-b96e79b53e97
+
+As man:sd-id128(3) macro:
+#define MESSAGE_XYZ SD_ID128_MAKE(c2,73,27,73,23,db,45,4e,a6,3b,b9,6e,79,b5,3e,97)
+...
+</programlisting>
+
+      <para>Then use the new identifier in an example application:</para>
 
       <programlisting><xi:include href="id128-app-specific.c" parse="text" /></programlisting>
     </example>
 
     <para>
       <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>systemd-id128</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>sd-id128</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
index 4f7cd71398d2890ceebaea3e4726c0060855fa16..4f5b160bd9921026464e5c0954f2f4b861928ea6 100644 (file)
@@ -52,9 +52,9 @@
     type, see
     <citerefentry><refentrytitle>sd-id128</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
 
-    <para><citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
-    <option>--new-id128</option> option may be used as a command line
-    front-end for <function>sd_id128_randomize()</function>.</para>
+    <para><citerefentry><refentrytitle>systemd-id128</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
+    <command>new</command> command may be used as a command line front-end for
+    <function>sd_id128_randomize()</function>.</para>
   </refsect1>
 
   <refsect1>
index 2bf20142c09c84e679dcaca470698e5097a5140c..b16efb8701a879527d311b96580f24dd9aaaf6e4 100644 (file)
         <listitem>
           <para>Just print what would be done. Currently supported by verbs
           <command>halt</command>, <command>poweroff</command>, <command>reboot</command>,
-          <command>kexec</command>, <command>suspend</command>,
-          <command>hibernate</command>, <command>hybrid-sleep</command>,
+          <command>kexec</command>, <command>suspend</command>, <command>hibernate</command>,
+          <command>hybrid-sleep</command>, <command>suspend-then-hibernate</command>,
           <command>default</command>, <command>rescue</command>,
           <command>emergency</command>, and <command>exit</command>.</para>
         </listitem>
@@ -1884,6 +1884,17 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
             sleep operation is successfully enqueued. It will not wait for the sleep/wake-up cycle to complete.</para>
           </listitem>
         </varlistentry>
+
+        <varlistentry>
+          <term><command>suspend-then-hibernate</command></term>
+
+          <listitem>
+            <para>Suspend the system and hibernate it after the delay specified in <filename>systemd-sleep.conf</filename>.
+            This will trigger activation of the special target unit <filename>suspend-then-hibernate.target</filename>.
+            This command is asynchronous, and will return after the hybrid sleep operation is successfully enqueued.
+            It will not wait for the sleep/wake-up or hibernate/thaw cycle to complete.</para>
+          </listitem>
+        </varlistentry>
       </variablelist>
     </refsect2>
 
diff --git a/man/systemd-id128.xml b/man/systemd-id128.xml
new file mode 100644 (file)
index 0000000..8a76ccc
--- /dev/null
@@ -0,0 +1,122 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+  "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!-- SPDX-License-Identifier: LGPL-2.1+ -->
+
+<refentry id="systemd-id128" xmlns:xi="http://www.w3.org/2001/XInclude">
+
+  <refentryinfo>
+    <title>systemd-id128</title>
+    <productname>systemd</productname>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>systemd-id128</refentrytitle>
+    <manvolnum>1</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>systemd-id128</refname>
+    <refpurpose>Generate and print sd-128 identifiers</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <cmdsynopsis>
+      <command>systemd-id128</command>
+      <arg choice="opt" rep="repeat">OPTIONS</arg>
+      <arg choice="plain">new</arg>
+    </cmdsynopsis>
+
+    <cmdsynopsis>
+      <command>systemd-id128</command>
+      <arg choice="opt" rep="repeat">OPTIONS</arg>
+      <arg choice="plain">machine-id</arg>
+    </cmdsynopsis>
+
+    <cmdsynopsis>
+      <command>systemd-id128</command>
+      <arg choice="opt" rep="repeat">OPTIONS</arg>
+      <arg choice="plain">boot-id</arg>
+    </cmdsynopsis>
+
+    <cmdsynopsis>
+      <command>systemd-id128</command>
+      <arg choice="opt" rep="repeat">OPTIONS</arg>
+      <arg choice="plain">invocation-id</arg>
+    </cmdsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para><command>id128</command> may be used to conveniently print
+    <citerefentry><refentrytitle>sd-id128</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+    UUIDs. What identifier is printed depends on the specific verb.</para>
+
+    <para>With <command>new</command>, a new random identifier will be generated.</para>
+
+    <para>With <command>machine-id</command>, the identifier of the current machine will be
+    printed. See
+    <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+    </para>
+
+    <para>With <command>boot-id</command>, the identifier of the current boot will be
+    printed.</para>
+
+    <para>Both <command>machine-id</command> and <command>boot-id</command> may be combined
+    with the <option>--app-specific=<replaceable>app-id</replaceable></option> switch to
+    generate application-specific IDs. See
+    <citerefentry><refentrytitle>sd_id128_get_machine</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+    for the discussion when this is useful.</para>
+
+    <para>With <command>invocation-id</command>, the identifier of the current service invocation
+    will be printed. This is available in systemd services. See
+    <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Options</title>
+
+    <para>The following options are understood:</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><option>-p</option></term>
+        <term><option>--pretty</option></term>
+
+        <listitem><para>Generate output as programming language snippets.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-a <replaceable>app-id</replaceable></option></term>
+        <term><option>--app-specific=<replaceable>app-id</replaceable></option></term>
+
+        <listitem><para>With this option, an identifier that is the result of hashing the
+        application identifier <replaceable>app-id</replaceable> and the machine identifier will be
+        printed. The <replaceable>app-id</replaceable> argument must be a valid sd-id128 string
+        identifying the application.</para>
+        </listitem>
+      </varlistentry>
+
+      <xi:include href="standard-options.xml" xpointer="help" />
+      <xi:include href="standard-options.xml" xpointer="version" />
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Exit status</title>
+
+    <para>On success, 0 is returned, a non-zero failure code otherwise.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+    <para>
+      <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd-id128</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_id128_get_machine</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+    </para>
+  </refsect1>
+
+</refentry>
index 942c6ba91a3582ae62d07415138d6d32425ddd69..76e1de72ca498f1d621ad661633f223442cf7702 100644 (file)
       <varlistentry>
         <term><varname>MESSAGE_ID=</varname></term>
         <listitem>
-          <para>A 128-bit message identifier ID for recognizing
-          certain message types, if this is desirable. This should
-          contain a 128-bit ID formatted as a lower-case hexadecimal
-          string, without any separating dashes or suchlike. This is
-          recommended to be a UUID-compatible ID, but this is not
-          enforced, and formatted differently. Developers can generate
-          a new ID for this purpose with <command>journalctl
-          <option>--new-id128</option></command>.
+          <para>A 128-bit message identifier ID for recognizing certain message types, if this is desirable. This
+          should contain a 128-bit ID formatted as a lower-case hexadecimal string, without any separating dashes or
+          suchlike. This is recommended to be a UUID-compatible ID, but this is not enforced, and formatted
+          differently. Developers can generate a new ID for this purpose with <command>systemd-id128 new</command>.
           </para>
         </listitem>
       </varlistentry>
index 1a429062406a84185f95a99c624025e428672e0f..9b264ecbf5869a62531a3ae8ec09c0c102d187df 100644 (file)
         </para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><varname>WatchdogSignal=</varname></term>
+        <listitem><para>Specifies which signal to use to terminate the
+        service when the watchdog timeout expires (enabled through
+        <varname>WatchdogSec=</varname>). Defaults to <constant>SIGABRT</constant>.
+        </para></listitem>
+      </varlistentry>
+
     </variablelist>
   </refsect1>
 
index 16c4aeba65635163d29da9dbe15d7535df416098..66c788afcb473ffbd1e332f2175c2458d0b39457 100644 (file)
           Takes a boolean value. Unset by default, which means that the kernel default
           will be used.</para>
 
-          <para>Note that if autonegotiation is enabled, speed and duplex settings are
-          read-only. If autonegotation is disabled, speed and duplex settings are writable
+          <para>Note that if autonegotiation is enabled, speed, duplex and advertise settings are
+          read-only. If autonegotation is disabled, speed, duplex and advertise settings are writable
           if the driver supports multiple link modes.</para>
         </listitem>
       </varlistentry>
           </variablelist>
         </listitem>
       </varlistentry>
+      <varlistentry>
+        <term><varname>Advertise=</varname></term>
+        <listitem>
+          <para>This sets what speeds and duplex modes of operation are advertised for auto-negotiation.
+          The supported values are:
+
+          <table>
+            <title>Supported advertise values</title>
+            <tgroup cols='3'>
+              <colspec colname='Advertise' />
+              <colspec colname='Speed' />
+              <colspec colname='Duplex Mode' />
+
+              <thead><row>
+                <entry>Advertise</entry>
+                <entry>Speed (Mbps)</entry>
+                <entry>Duplex Mode</entry>
+              </row></thead>
+              <tbody>
+
+                <row><entry><literal>10baset-half</literal></entry>
+                <entry>10</entry><entry>half</entry></row>
+
+                <row><entry><literal>10baset-full</literal></entry>
+                <entry>10</entry><entry>full</entry></row>
+
+                <row><entry><literal>100baset-half</literal></entry>
+                <entry>100</entry><entry>half</entry></row>
+
+                <row><entry><literal>100baset-full</literal></entry>
+                <entry>100</entry><entry>full</entry></row>
+
+                <row><entry><literal>1000baset-half</literal></entry>
+                <entry>1000</entry><entry>half</entry></row>
+
+                <row><entry><literal>1000baset-full</literal></entry>
+                <entry>1000</entry><entry>full</entry></row>
+
+                <row><entry><literal>10000baset-full</literal></entry>
+                <entry>10000</entry><entry>full</entry></row>
+
+                <row><entry><literal>2500basex-full</literal></entry>
+                <entry>2500</entry><entry>full</entry></row>
+
+                <row><entry><literal>1000basekx-full</literal></entry>
+                <entry>1000</entry><entry>full</entry></row>
+
+                <row><entry><literal>10000basekx4-full</literal></entry>
+                <entry>10000</entry><entry>full</entry></row>
+
+                <row><entry><literal>10000basekr-full</literal></entry>
+                <entry>10000</entry><entry>full</entry></row>
+
+                <row><entry><literal>10000baser-fec</literal></entry>
+                <entry>10000</entry><entry>full</entry></row>
+
+                <row><entry><literal>20000basemld2-full</literal></entry>
+                <entry>20000</entry><entry>full</entry></row>
+
+                <row><entry><literal>20000basekr2-full</literal></entry>
+                <entry>20000</entry><entry>full</entry></row>
+              </tbody>
+            </tgroup>
+          </table>
+
+          By default this is unset, i.e. all possible modes will be advertised.
+          This option may be specified more than once, in which case all specified speeds and modes are advertised.
+          If the empty string is assigned to this option, the list is reset, and all prior assignments have no effect.
+          </para>
+        </listitem>
+      </varlistentry>
       <varlistentry>
         <term><varname>TCPSegmentationOffload=</varname></term>
         <listitem>
index 0cd5385f9bdb9ba56d488604290705d5fdf9bea2..beb4420cf0f91f0d37385aeb48eaaeed987e883e 100644 (file)
         "keep-alive ping"). If the time between two such calls is
         larger than the configured time, then the service is placed in
         a failed state and it will be terminated with
-        <constant>SIGABRT</constant>. By setting
+        <constant>SIGABRT</constant> (or the signal specified by
+        <varname>WatchdogSignal=</varname>). By setting
         <varname>Restart=</varname> to <option>on-failure</option>,
         <option>on-watchdog</option>, <option>on-abnormal</option> or
         <option>always</option>, the service will be automatically
index c29f622143b67123bdb6e824905e584964e8f239..554e67e5dd0c1f571eedec9d9ad0c5019f8f0d63 100644 (file)
@@ -781,6 +781,7 @@ conf.set10('ENABLE_DEBUG_HASHMAP', enable_debug_hashmap)
 conf.set10('ENABLE_DEBUG_MMAP_CACHE', enable_debug_mmap_cache)
 
 conf.set10('VALGRIND', get_option('valgrind'))
+conf.set10('LOG_TRACE', get_option('log-trace'))
 
 #####################################################################
 
@@ -1476,7 +1477,7 @@ foreach tuple : [['myhostname', 'ENABLE_NSS_MYHOSTNAME'],
                 module = tuple[0]
 
                 sym = 'src/nss-@0@/nss-@0@.sym'.format(module)
-                version_script_arg = join_paths(meson.current_source_dir(), sym)
+                version_script_arg = join_paths(meson.source_root(), sym)
 
                 nss = shared_library(
                         'nss_' + module,
@@ -1731,7 +1732,7 @@ if conf.get('ENABLE_LOGIND') == 1
         public_programs += exe
 
         if conf.get('HAVE_PAM') == 1
-                version_script_arg = join_paths(meson.current_source_dir(), pam_systemd_sym)
+                version_script_arg = join_paths(meson.source_root(), pam_systemd_sym)
                 pam_systemd = shared_library(
                         'pam_systemd',
                         pam_systemd_c,
@@ -2323,6 +2324,14 @@ executable('systemd-cgroups-agent',
            install : true,
            install_dir : rootlibexecdir)
 
+exe = executable('systemd-id128',
+                 'src/id128/id128.c',
+                 include_directories : includes,
+                 link_with : [libshared],
+                 install_rpath : rootlibexecdir,
+                 install : true)
+public_programs += exe
+
 exe = executable('systemd-path',
                  'src/path/path.c',
                  include_directories : includes,
@@ -2847,9 +2856,7 @@ foreach tuple : sanitizers
                                 test('@0@:@1@:@2@'.format(b, c, sanitizer),
                                      env,
                                      args : [exe.full_path(),
-                                             join_paths(meson.source_root(),
-                                                        'test/fuzz-regressions',
-                                                        p)])
+                                             join_paths(meson.source_root(), p)])
                         endif
                 endforeach
         endif
@@ -2861,7 +2868,7 @@ endforeach
 if git.found()
         all_files = run_command(
                 git,
-                ['--git-dir=@0@/.git'.format(meson.current_source_dir()),
+                ['--git-dir=@0@/.git'.format(meson.source_root()),
                  'ls-files',
                  ':/*.[ch]'])
         all_files = files(all_files.stdout().split())
@@ -2869,10 +2876,10 @@ if git.found()
         custom_target(
                 'tags',
                 output : 'tags',
-                command : [env, 'etags', '-o', '@0@/TAGS'.format(meson.current_source_dir())] + all_files)
+                command : [env, 'etags', '-o', '@0@/TAGS'.format(meson.source_root())] + all_files)
         run_target(
                 'ctags',
-                command : [env, 'ctags', '-o', '@0@/tags'.format(meson.current_source_dir())] + all_files)
+                command : [env, 'ctags', '-o', '@0@/tags'.format(meson.source_root())] + all_files)
 endif
 
 if git.found()
@@ -2885,17 +2892,17 @@ endif
 if git.found()
         git_head = run_command(
                 git,
-                ['--git-dir=@0@/.git'.format(meson.current_source_dir()),
+                ['--git-dir=@0@/.git'.format(meson.source_root()),
                  'rev-parse', 'HEAD']).stdout().strip()
         git_head_short = run_command(
                 git,
-                ['--git-dir=@0@/.git'.format(meson.current_source_dir()),
+                ['--git-dir=@0@/.git'.format(meson.source_root()),
                  'rev-parse', '--short=7', 'HEAD']).stdout().strip()
 
         run_target(
                 'git-snapshot',
                 command : ['git', 'archive',
-                           '-o', '@0@/systemd-@1@.tar.gz'.format(meson.current_source_dir(),
+                           '-o', '@0@/systemd-@1@.tar.gz'.format(meson.source_root(),
                                                                  git_head_short),
                            '--prefix', 'systemd-@0@/'.format(git_head),
                            'HEAD'])
@@ -2909,6 +2916,10 @@ run_target(
         depends : [man, libsystemd, libudev],
         command : [meson_check_api_docs_sh, libsystemd.full_path(), libudev.full_path()])
 
+run_target(
+        'make-index-md',
+        command : ['sh', '@0@/tools/make-index-md.sh'.format(meson.source_root()), meson.source_root()])
+
 ############################################################
 
 status = [
@@ -3049,10 +3060,10 @@ foreach tuple : [
         ['blkid'],
         ['dbus'],
         ['glib'],
-        ['nss-myhostname',   conf.get('ENABLE_NSS_MYHOSTNAME') == 1],
-        ['nss-mymachines',   conf.get('ENABLE_NSS_MYMACHINES') == 1],
-        ['nss-resolve',      conf.get('ENABLE_NSS_RESOLVE') == 1],
-        ['nss-systemd',      conf.get('ENABLE_NSS_SYSTEMD') == 1],
+        ['nss-myhostname'],
+        ['nss-mymachines'],
+        ['nss-resolve'],
+        ['nss-systemd'],
         ['hwdb'],
         ['tpm'],
         ['man pages',        want_man],
@@ -3068,6 +3079,7 @@ foreach tuple : [
         ['debug hashmap'],
         ['debug mmap cache'],
         ['valgrind',         conf.get('VALGRIND') == 1],
+        ['trace logging',    conf.get('LOG_TRACE') == 1],
 ]
 
         if tuple.length() >= 2
index 7b1f61bf464ba30ecb727f0f2928079c81640bd2..83ade5bea41fc7484c1e79fda891f6b3335f460a 100644 (file)
@@ -51,6 +51,8 @@ option('memory-accounting-default', type : 'boolean',
        description : 'enable MemoryAccounting= by default')
 option('valgrind', type : 'boolean', value : false,
        description : 'do extra operations to avoid valgrind warnings')
+option('log-trace', type : 'boolean', value : false,
+       description : 'enable low level debug logging')
 
 option('utmp', type : 'boolean',
        description : 'support for utmp/wtmp log handling')
@@ -278,9 +280,9 @@ option('dbus', type : 'combo', choices : ['auto', 'true', 'false'],
 
 option('gnu-efi', type : 'combo', choices : ['auto', 'true', 'false'],
        description : 'gnu-efi support for sd-boot')
-option('efi-cc', type : 'string', value : 'gcc',
+option('efi-cc', type : 'array',
        description : 'the compiler to use for EFI modules')
-option('efi-ld', type : 'string', value : 'ld',
+option('efi-ld', type : 'string',
        description : 'the linker to use for EFI modules')
 option('efi-libdir', type : 'string',
        description : 'path to the EFI lib directory')
index 3c0a19af7b3ea3ad31bd89020db50d1d778e5262..3f4f49feae150c9c70998f6310abd22d5279977d 100644 (file)
--- a/po/tr.po
+++ b/po/tr.po
@@ -10,8 +10,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: systemd master\n"
 "Report-Msgid-Bugs-To: https://github.com/systemd/systemd/issues\n"
-"POT-Creation-Date: 2018-03-27 03:26+0000\n"
-"PO-Revision-Date: 2018-04-22 21:20+0300\n"
+"POT-Creation-Date: 2018-08-23 15:26+0000\n"
+"PO-Revision-Date: 2018-10-01 20:20+0300\n"
 "Last-Translator: Muhammet Kara <muhammetk@gnome.org>\n"
 "Language-Team: Turkish <gnome-turk@gnome.org>\n"
 "Language: tr_TR\n"
@@ -50,11 +50,11 @@ msgstr ""
 "Sistem servislerini veya birim dosyalarını yönetmek kimlik doğrulaması "
 "gerektiriyor."
 
-#: src/core/org.freedesktop.systemd1.policy.in:53
+#: src/core/org.freedesktop.systemd1.policy.in:54
 msgid "Set or unset system and service manager environment variables"
 msgstr "Sistem ve servis yöneticisi ortam değişkenlerini ayarla ya da kaldır"
 
-#: src/core/org.freedesktop.systemd1.policy.in:54
+#: src/core/org.freedesktop.systemd1.policy.in:55
 msgid ""
 "Authentication is required to set or unset system and service manager "
 "environment variables."
@@ -62,27 +62,27 @@ msgstr ""
 "Sistem ve servis yöneticisi ortam değişkenlerini ayarlamak ya da kaldırmak "
 "kimlik doğrulaması gerektiriyor."
 
-#: src/core/org.freedesktop.systemd1.policy.in:63
+#: src/core/org.freedesktop.systemd1.policy.in:64
 msgid "Reload the systemd state"
 msgstr "systemd durumunu yeniden yükle"
 
-#: src/core/org.freedesktop.systemd1.policy.in:64
+#: src/core/org.freedesktop.systemd1.policy.in:65
 msgid "Authentication is required to reload the systemd state."
 msgstr "systemd durumunu yeniden yüklemek kimlik doğrulaması gerektiriyor."
 
-#: src/hostname/org.freedesktop.hostname1.policy:22
+#: src/hostname/org.freedesktop.hostname1.policy:20
 msgid "Set host name"
 msgstr "Makine adını ayarla"
 
-#: src/hostname/org.freedesktop.hostname1.policy:23
+#: src/hostname/org.freedesktop.hostname1.policy:21
 msgid "Authentication is required to set the local host name."
 msgstr "Yerel makine adını ayarlamak kimlik doğrulaması gerektiriyor."
 
-#: src/hostname/org.freedesktop.hostname1.policy:32
+#: src/hostname/org.freedesktop.hostname1.policy:30
 msgid "Set static host name"
 msgstr "Statik makine adı ayarla"
 
-#: src/hostname/org.freedesktop.hostname1.policy:33
+#: src/hostname/org.freedesktop.hostname1.policy:31
 msgid ""
 "Authentication is required to set the statically configured local host name, "
 "as well as the pretty host name."
@@ -90,14 +90,23 @@ msgstr ""
 "Statik olarak yapılandırılmış konak makine adını ve yerel makine adını "
 "ayarlamak kimlik doğrulaması gerektiriyor."
 
-#: src/hostname/org.freedesktop.hostname1.policy:43
+#: src/hostname/org.freedesktop.hostname1.policy:41
 msgid "Set machine information"
 msgstr "Makine bilgisini ayarla"
 
-#: src/hostname/org.freedesktop.hostname1.policy:44
+#: src/hostname/org.freedesktop.hostname1.policy:42
 msgid "Authentication is required to set local machine information."
 msgstr "Yerel makine bilgisini ayarlamak kimlik doğrulaması gerektiriyor."
 
+#: src/hostname/org.freedesktop.hostname1.policy:51
+msgid "Get product UUID"
+msgstr "Ürün UUID'ini al"
+
+#: src/hostname/org.freedesktop.hostname1.policy:52
+#| msgid "Authentication is required to reload '$(unit)'."
+msgid "Authentication is required to get product UUID."
+msgstr "Ürün UUID'ini almak için kimlik doğrulaması gereklidir."
+
 #: src/import/org.freedesktop.import1.policy:22
 msgid "Import a VM or container image"
 msgstr "Bir SM ya da kapsayıcı kalıbını içe aktar"
@@ -569,12 +578,45 @@ msgstr ""
 "Yerel sanal makineler ve kapsayıcı kalıplarını yönetmek için kimlik "
 "doğrulaması gereklidir."
 
+#: src/portable/org.freedesktop.portable1.policy:13
+msgid "Inspect a portable service image"
+msgstr "Bir taşınabilir hizmet kalıbını incele"
+
+#: src/portable/org.freedesktop.portable1.policy:14
+#| msgid "Authentication is required to import a VM or container image"
+msgid "Authentication is required to inspect a portable service image."
+msgstr ""
+"Bir taşınabilir hizmet kalıbını incelemek için kimlik doğrulaması gereklidir."
+
+#: src/portable/org.freedesktop.portable1.policy:23
+msgid "Attach or detach a portable service image"
+msgstr "Bir taşınabilir hizmet kalıbını tuttur ya da ayır"
+
+#: src/portable/org.freedesktop.portable1.policy:24
+#| msgid "Authentication is required for attaching a device to a seat."
+msgid ""
+"Authentication is required to attach or detach a portable service image."
+msgstr ""
+"Bir taşınabilir hizmet kalıbını tutturmak ya da ayırmak için kimlik "
+"doğrulaması gereklidir."
+
+#: src/portable/org.freedesktop.portable1.policy:34
+msgid "Delete or modify portable service image"
+msgstr "Taşınabilir hizmet kalıbını sil ya da değiştir"
+
+#: src/portable/org.freedesktop.portable1.policy:35
+#| msgid "Authentication is required to download a VM or container image"
+msgid ""
+"Authentication is required to delete or modify a portable service image."
+msgstr ""
+"Taşınabilir hizmet kalıbını silmek ya da değiştirmek için kimlik doğrulaması "
+"gereklidir."
+
 #: src/resolve/org.freedesktop.resolve1.policy:22
 msgid "Register a DNS-SD service"
 msgstr "Bir DNS-SD hizmeti kaydet"
 
 #: src/resolve/org.freedesktop.resolve1.policy:23
-#| msgid "Authentication is required to set a wall message"
 msgid "Authentication is required to register a DNS-SD service"
 msgstr "Bir DNS-SD hizmeti kaydetmek için kimlik doğrulaması gereklidir"
 
@@ -583,7 +625,6 @@ msgid "Unregister a DNS-SD service"
 msgstr "Bir DNS-SD hizmetinin kaydını sil"
 
 #: src/resolve/org.freedesktop.resolve1.policy:34
-#| msgid "Authentication is required to set a wall message"
 msgid "Authentication is required to unregister a DNS-SD service"
 msgstr ""
 "Bir DNS-SD hizmetinin kaydını silmek için kimlik doğrulaması gereklidir"
@@ -616,44 +657,44 @@ msgstr ""
 "Gerçek zamanlı saat olarak yerel zaman dilimini veya UTC'yi ayarlamak kimlik "
 "doğrulaması gerektiriyor."
 
-#: src/timedate/org.freedesktop.timedate1.policy:54
+#: src/timedate/org.freedesktop.timedate1.policy:53
 msgid "Turn network time synchronization on or off"
 msgstr "Ağ zaman eş zamanlamasını aç veya kapat"
 
-#: src/timedate/org.freedesktop.timedate1.policy:55
+#: src/timedate/org.freedesktop.timedate1.policy:54
 msgid ""
 "Authentication is required to control whether network time synchronization "
 "shall be enabled."
 msgstr ""
 "Ağ zaman eş zamanlamasını kontrol etmek kimlik doğrulaması gerektiriyor."
 
-#: src/core/dbus-unit.c:496
+#: src/core/dbus-unit.c:326
 msgid "Authentication is required to start '$(unit)'."
 msgstr "'$(unit)' başlatmak için kimlik doğrulaması gereklidir."
 
-#: src/core/dbus-unit.c:497
+#: src/core/dbus-unit.c:327
 msgid "Authentication is required to stop '$(unit)'."
 msgstr "'$(unit)' durdurmak için kimlik doğrulaması gereklidir."
 
-#: src/core/dbus-unit.c:498
+#: src/core/dbus-unit.c:328
 msgid "Authentication is required to reload '$(unit)'."
 msgstr "'$(unit)' yeniden yüklemek için kimlik doğrulaması gereklidir."
 
-#: src/core/dbus-unit.c:499 src/core/dbus-unit.c:500
+#: src/core/dbus-unit.c:329 src/core/dbus-unit.c:330
 msgid "Authentication is required to restart '$(unit)'."
 msgstr "'$(unit)' yeniden başlatmak için kimlik doğrulaması gereklidir."
 
-#: src/core/dbus-unit.c:607
+#: src/core/dbus-unit.c:437
 msgid "Authentication is required to kill '$(unit)'."
 msgstr "'$(unit)' sonlandırmak için kimlik doğrulaması gereklidir."
 
-#: src/core/dbus-unit.c:638
+#: src/core/dbus-unit.c:468
 msgid "Authentication is required to reset the \"failed\" state of '$(unit)'."
 msgstr ""
 "'$(unit)'in \"failed\" (başarısız) durumunu sıfırlamak için kimlik "
 "doğrulaması gereklidir."
 
-#: src/core/dbus-unit.c:671
+#: src/core/dbus-unit.c:501
 msgid "Authentication is required to set properties on '$(unit)'."
 msgstr ""
 "'$(unit)' üzerindeki özellikleri ayarlamak için kimlik doğrulaması "
index a784a30e1d08d2621fb9e686c2ca281ba75f5698..3b8130b03e468d64149c9455cf5040f17c702f86 100644 (file)
@@ -114,7 +114,7 @@ bool strv_env_is_valid(char **e) {
                 if (!env_assignment_is_valid(*p))
                         return false;
 
-                /* Check if there are duplicate assginments */
+                /* Check if there are duplicate assignments */
                 k = strcspn(*p, "=");
                 STRV_FOREACH(q, p + 1)
                         if (strneq(*p, *q, k) && (*q)[k] == '=')
@@ -388,7 +388,7 @@ int strv_env_replace(char ***l, char *p) {
         assert(p);
 
         /* Replace first occurrence of the env var or add a new one in the
-         * string list. Drop other occurences. Edits in-place. Does not copy p.
+         * string list. Drop other occurrences. Edits in-place. Does not copy p.
          * p must be a valid key=value assignment.
          */
 
index ea607f8cfb94d12ae5907c306333368463bf4e4d..d2fd4c47b3f2acb8d2b0e01ecb2ecbc25902840d 100644 (file)
@@ -1492,6 +1492,7 @@ int open_serialization_fd(const char *ident) {
 }
 
 int link_tmpfile(int fd, const char *path, const char *target) {
+        int r;
 
         assert(fd >= 0);
         assert(target);
@@ -1504,8 +1505,9 @@ int link_tmpfile(int fd, const char *path, const char *target) {
          * operation currently (renameat2() does), and there is no nice way to emulate this. */
 
         if (path) {
-                if (rename_noreplace(AT_FDCWD, path, AT_FDCWD, target) < 0)
-                        return -errno;
+                r = rename_noreplace(AT_FDCWD, path, AT_FDCWD, target);
+                if (r < 0)
+                        return r;
         } else {
                 char proc_fd_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(fd) + 1];
 
index 1fa76bda3de92d6ce4d4d3030229a5937b8f0015..3d83fc9b1006a84c2e51053ca4486454caf3199d 100644 (file)
@@ -89,41 +89,44 @@ int rmdir_parents(const char *path, const char *stop) {
 }
 
 int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) {
-        struct stat buf;
-        int ret;
+        int r;
 
-        ret = renameat2(olddirfd, oldpath, newdirfd, newpath, RENAME_NOREPLACE);
-        if (ret >= 0)
+        /* Try the ideal approach first */
+        if (renameat2(olddirfd, oldpath, newdirfd, newpath, RENAME_NOREPLACE) >= 0)
                 return 0;
 
-        /* renameat2() exists since Linux 3.15, btrfs added support for it later.
-         * If it is not implemented, fallback to another method. */
-        if (!IN_SET(errno, EINVAL, ENOSYS))
+        /* renameat2() exists since Linux 3.15, btrfs and FAT added support for it later. If it is not implemented,
+         * fall back to a different method. */
+        if (!IN_SET(errno, EINVAL, ENOSYS, ENOTTY))
                 return -errno;
 
-        /* The link()/unlink() fallback does not work on directories. But
-         * renameat() without RENAME_NOREPLACE gives the same semantics on
-         * directories, except when newpath is an *empty* directory. This is
-         * good enough. */
-        ret = fstatat(olddirfd, oldpath, &buf, AT_SYMLINK_NOFOLLOW);
-        if (ret >= 0 && S_ISDIR(buf.st_mode)) {
-                ret = renameat(olddirfd, oldpath, newdirfd, newpath);
-                return ret >= 0 ? 0 : -errno;
+        /* Let's try to use linkat()+unlinkat() as fallback. This doesn't work on directories and on some file systems
+         * that do not support hard links (such as FAT, most prominently), but for files it's pretty close to what we
+         * want — though not atomic (i.e. for a short period both the new and the old filename will exist). */
+        if (linkat(olddirfd, oldpath, newdirfd, newpath, 0) >= 0) {
+
+                if (unlinkat(olddirfd, oldpath, 0) < 0) {
+                        r = -errno; /* Backup errno before the following unlinkat() alters it */
+                        (void) unlinkat(newdirfd, newpath, 0);
+                        return r;
+                }
+
+                return 0;
         }
 
-        /* If it is not a directory, use the link()/unlink() fallback. */
-        ret = linkat(olddirfd, oldpath, newdirfd, newpath, 0);
-        if (ret < 0)
+        if (!IN_SET(errno, EINVAL, ENOSYS, ENOTTY, EPERM)) /* FAT returns EPERM on link()… */
                 return -errno;
 
-        ret = unlinkat(olddirfd, oldpath, 0);
-        if (ret < 0) {
-                /* backup errno before the following unlinkat() alters it */
-                ret = errno;
-                (void) unlinkat(newdirfd, newpath, 0);
-                errno = ret;
+        /* OK, neither RENAME_NOREPLACE nor linkat()+unlinkat() worked. Let's then fallback to the racy TOCTOU
+         * vulnerable accessat(F_OK) check followed by classic, replacing renameat(), we have nothing better. */
+
+        if (faccessat(newdirfd, newpath, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
+                return -EEXIST;
+        if (errno != ENOENT)
+                return -errno;
+
+        if (renameat(olddirfd, oldpath, newdirfd, newpath) < 0)
                 return -errno;
-        }
 
         return 0;
 }
index 274afb395c2375a7ba8262a5e08d69d94435811e..b771ceccdc6cec9f70c7889bdf3fefb8d96c1d20 100644 (file)
@@ -15,7 +15,7 @@
  * necessary to instantiate an object for each Hashmap use.
  *
  * If ENABLE_DEBUG_HASHMAP is defined (by configuring with --enable-debug=hashmap),
- * the implemention will:
+ * the implementation will:
  * - store extra data for debugging and statistics (see tools/gdb-sd_dump_hashmaps.py)
  * - perform extra checks for invalid use of iterators
  */
index 7748e8352cde715d695718d41f210812b53845dc..c0f96409fdf6db4c699740d5d4e2fbfe5fa806e6 100644 (file)
@@ -79,7 +79,7 @@ static int unhex_next(const char **p, size_t *l) {
         assert(l);
 
         /* Find the next non-whitespace character, and decode it. We
-         * greedily skip all preceeding and all following whitespace. */
+         * greedily skip all preceding and all following whitespace. */
 
         for (;;) {
                 if (*l == 0)
@@ -592,8 +592,7 @@ static int base64_append_width(
 
         _cleanup_free_ char *x = NULL;
         char *t, *s;
-        ssize_t slen, len, avail;
-        int line, lines;
+        ssize_t len, slen, avail, line, lines;
 
         len = base64mem(p, l, &x);
         if (len <= 0)
@@ -602,6 +601,9 @@ static int base64_append_width(
         lines = DIV_ROUND_UP(len, width);
 
         slen = strlen_ptr(sep);
+        if (lines > (SSIZE_MAX - plen - 1 - slen) / (indent + width + 1))
+                return -ENOMEM;
+
         t = realloc(*prefix, plen + 1 + slen + (indent + width + 1) * lines);
         if (!t)
                 return -ENOMEM;
@@ -647,7 +649,7 @@ static int unbase64_next(const char **p, size_t *l) {
         assert(l);
 
         /* Find the next non-whitespace character, and decode it. If we find padding, we return it as INT_MAX. We
-         * greedily skip all preceeding and all following whitespace. */
+         * greedily skip all preceding and all following whitespace. */
 
         for (;;) {
                 if (*l == 0)
index db38f91c832ad31dc68322eb42e367983d8e77aa..a9085348b555b64c733e42b10c858d9073660649 100644 (file)
@@ -570,7 +570,7 @@ int parse_fractional_part_u(const char **p, size_t digits, unsigned *res) {
 
         s = *p;
 
-        /* accept any number of digits, strtoull is limted to 19 */
+        /* accept any number of digits, strtoull is limited to 19 */
         for (i=0; i < digits; i++,s++) {
                 if (*s < '0' || *s > '9') {
                         if (i == 0)
index b62786f27e6eb2515aa0a9bd609403d1e2bacf86..f3c6c16aae5fb5e5b70908eea5f3eb9e1f39ea4a 100644 (file)
@@ -425,7 +425,7 @@ int path_compare(const char *a, const char *b) {
         assert(a);
         assert(b);
 
-        /* A relative path and an abolute path must not compare as equal.
+        /* A relative path and an absolute path must not compare as equal.
          * Which one is sorted before the other does not really matter.
          * Here a relative path is ordered before an absolute path. */
         d = (a[0] == '/') - (b[0] == '/');
index c887f9708b3661794dd05ab14d8a92407d52f5cc..1098cf453f68baff538d3e22ad2aa68d3408cd05 100644 (file)
@@ -425,7 +425,7 @@ int is_kernel_thread(pid_t pid) {
                 q += l;
         }
 
-        /* Skip preceeding whitespace */
+        /* Skip preceding whitespace */
         l = strspn(q, WHITESPACE);
         if (l < 1)
                 return -EINVAL;
index 07b11d4fc8b3de4348c30f7c2797216fef49a557..c6dad5275fe16b08e4fac292bb12315845479a52 100644 (file)
@@ -1008,7 +1008,7 @@ int free_and_strdup(char **p, const char *s) {
 
         assert(p);
 
-        /* Replaces a string pointer with an strdup()ed new string,
+        /* Replaces a string pointer with a strdup()ed new string,
          * possibly freeing the old one. */
 
         if (streq_ptr(*p, s))
@@ -1027,6 +1027,32 @@ int free_and_strdup(char **p, const char *s) {
         return 1;
 }
 
+int free_and_strndup(char **p, const char *s, size_t l) {
+        char *t;
+
+        assert(p);
+        assert(s || l == 0);
+
+        /* Replaces a string pointer with a strndup()ed new string,
+         * freeing the old one. */
+
+        if (!*p && !s)
+                return 0;
+
+        if (*p && s && strneq(*p, s, l) && (l > strlen(*p) || (*p)[l] == '\0'))
+                return 0;
+
+        if (s) {
+                t = strndup(s, l);
+                if (!t)
+                        return -ENOMEM;
+        } else
+                t = NULL;
+
+        free_and_replace(*p, t);
+        return 1;
+}
+
 #if !HAVE_EXPLICIT_BZERO
 /*
  * Pointer to memset is volatile so that compiler must de-reference
index a337dbc35f769d3b8761aa93199453d6661b6905..2d9788ac13f80f272cf7a02a5754f1db50e11bdf 100644 (file)
@@ -181,6 +181,7 @@ char *strrep(const char *s, unsigned n);
 int split_pair(const char *s, const char *sep, char **l, char **r);
 
 int free_and_strdup(char **p, const char *s);
+int free_and_strndup(char **p, const char *s, size_t l);
 
 /* Normal memmem() requires haystack to be nonnull, which is annoying for zero-length buffers */
 static inline void *memmem_safe(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) {
index 81d3f3f38f77a7c8dc384d52f113d229b2ab1a26..9ac739b42adbcef607eab9304c592de7982aba51 100644 (file)
@@ -905,7 +905,7 @@ int parse_timestamp(const char *t, usec_t *usec) {
                  * Otherwise just cut it off. */
                 with_tz = !STR_IN_SET(tz, tzname[0], tzname[1]);
 
-                /* Cut off the timezone if we dont need it. */
+                /* Cut off the timezone if we don't need it. */
                 if (with_tz)
                         t = strndupa(t, last_space - t);
 
index ac6a9b37e8f1f6bd372df8c0bbb41e7ae2972459..245daabcf82f280ed97263abcd31e99d42859e88 100644 (file)
@@ -169,7 +169,7 @@ static const char* const service_state_table[_SERVICE_STATE_MAX] = {
         [SERVICE_EXITED] = "exited",
         [SERVICE_RELOAD] = "reload",
         [SERVICE_STOP] = "stop",
-        [SERVICE_STOP_SIGABRT] = "stop-sigabrt",
+        [SERVICE_STOP_WATCHDOG] = "stop-watchdog",
         [SERVICE_STOP_SIGTERM] = "stop-sigterm",
         [SERVICE_STOP_SIGKILL] = "stop-sigkill",
         [SERVICE_STOP_POST] = "stop-post",
index d7e2d746696bf21eb01343a3bbcc11d0b37597ba..85f3e42d30b9c652aa14c877c63ccec4a2d7a870 100644 (file)
@@ -108,7 +108,7 @@ typedef enum ServiceState {
         SERVICE_EXITED,            /* Nothing is running anymore, but RemainAfterExit is true hence this is OK */
         SERVICE_RELOAD,
         SERVICE_STOP,              /* No STOP_PRE state, instead just register multiple STOP executables */
-        SERVICE_STOP_SIGABRT,      /* Watchdog timeout */
+        SERVICE_STOP_WATCHDOG,
         SERVICE_STOP_SIGTERM,
         SERVICE_STOP_SIGKILL,
         SERVICE_STOP_POST,
index a5ce1a2944ae61ed342ef6ad99f6a4d4a6f01db7..e0d1949dc7f7527533eee527d113b22d2b70886f 100644 (file)
@@ -61,12 +61,12 @@ static bool unichar_is_control(char32_t ch) {
 }
 
 /* count of characters used to encode one unicode char */
-static int utf8_encoded_expected_len(const char *str) {
-        unsigned char c;
+static size_t utf8_encoded_expected_len(const char *str) {
+        uint8_t c;
 
         assert(str);
 
-        c = (unsigned char) str[0];
+        c = (uint8_t) str[0];
         if (c < 0x80)
                 return 1;
         if ((c & 0xe0) == 0xc0)
@@ -86,7 +86,7 @@ static int utf8_encoded_expected_len(const char *str) {
 /* decode one unicode char */
 int utf8_encoded_to_unichar(const char *str, char32_t *ret_unichar) {
         char32_t unichar;
-        int len, i;
+        size_t len, i;
 
         assert(str);
 
@@ -118,6 +118,7 @@ int utf8_encoded_to_unichar(const char *str, char32_t *ret_unichar) {
         for (i = 1; i < len; i++) {
                 if (((char32_t)str[i] & 0xc0) != 0x80)
                         return -EINVAL;
+
                 unichar <<= 6;
                 unichar |= (char32_t)str[i] & 0x3f;
         }
@@ -154,22 +155,23 @@ bool utf8_is_printable_newline(const char* str, size_t length, bool newline) {
         return true;
 }
 
-const char *utf8_is_valid(const char *str) {
-        const uint8_t *p;
+char *utf8_is_valid(const char *str) {
+        const char *p;
 
         assert(str);
 
-        for (p = (const uint8_t*) str; *p; ) {
+        p = str;
+        while (*p) {
                 int len;
 
-                len = utf8_encoded_valid_unichar((const char *)p);
+                len = utf8_encoded_valid_unichar(p);
                 if (len < 0)
                         return NULL;
 
                 p += len;
         }
 
-        return str;
+        return (char*) str;
 }
 
 char *utf8_escape_invalid(const char *str) {
@@ -312,18 +314,25 @@ size_t utf8_encode_unichar(char *out_utf8, char32_t g) {
         return 0;
 }
 
-char *utf16_to_utf8(const void *s, size_t length) {
+char *utf16_to_utf8(const char16_t *s, size_t length /* bytes! */) {
         const uint8_t *f;
         char *r, *t;
 
-        r = new(char, (length * 4 + 1) / 2 + 1);
+        assert(s);
+
+        /* Input length is in bytes, i.e. the shortest possible character takes 2 bytes. Each unicode character may
+         * take up to 4 bytes in UTF-8. Let's also account for a trailing NUL byte. */
+        if (length * 2 < length)
+                return NULL; /* overflow */
+
+        r = new(char, length * 2 + 1);
         if (!r)
                 return NULL;
 
-        f = s;
+        f = (const uint8_t*) s;
         t = r;
 
-        while (f < (const uint8_t*) s + length) {
+        while (f + 1 < (const uint8_t*) s + length) {
                 char16_t w1, w2;
 
                 /* see RFC 2781 section 2.2 */
@@ -333,13 +342,13 @@ char *utf16_to_utf8(const void *s, size_t length) {
 
                 if (!utf16_is_surrogate(w1)) {
                         t += utf8_encode_unichar(t, w1);
-
                         continue;
                 }
 
                 if (utf16_is_trailing_surrogate(w1))
-                        continue;
-                else if (f >= (const uint8_t*) s + length)
+                        continue; /* spurious trailing surrogate, ignore */
+
+                if (f + 1 >= (const uint8_t*) s + length)
                         break;
 
                 w2 = f[1] << 8 | f[0];
@@ -347,7 +356,7 @@ char *utf16_to_utf8(const void *s, size_t length) {
 
                 if (!utf16_is_trailing_surrogate(w2)) {
                         f -= 2;
-                        continue;
+                        continue; /* surrogate missing its trailing surrogate, ignore */
                 }
 
                 t += utf8_encode_unichar(t, utf16_surrogate_pair_to_unichar(w1, w2));
@@ -357,6 +366,79 @@ char *utf16_to_utf8(const void *s, size_t length) {
         return r;
 }
 
+size_t utf16_encode_unichar(char16_t *out, char32_t c) {
+
+        /* Note that this encodes as little-endian. */
+
+        switch (c) {
+
+        case 0 ... 0xd7ffU:
+        case 0xe000U ... 0xffffU:
+                out[0] = htole16(c);
+                return 1;
+
+        case 0x10000U ... 0x10ffffU:
+                c -= 0x10000U;
+                out[0] = htole16((c >> 10) + 0xd800U);
+                out[1] = htole16((c & 0x3ffU) + 0xdc00U);
+                return 2;
+
+        default: /* A surrogate (invalid) */
+                return 0;
+        }
+}
+
+char16_t *utf8_to_utf16(const char *s, size_t length) {
+        char16_t *n, *p;
+        size_t i;
+        int r;
+
+        assert(s);
+
+        n = new(char16_t, length + 1);
+        if (!n)
+                return NULL;
+
+        p = n;
+
+        for (i = 0; i < length;) {
+                char32_t unichar;
+                size_t e;
+
+                e = utf8_encoded_expected_len(s + i);
+                if (e <= 1) /* Invalid and single byte characters are copied as they are */
+                        goto copy;
+
+                if (i + e > length) /* sequence longer than input buffer, then copy as-is */
+                        goto copy;
+
+                r = utf8_encoded_to_unichar(s + i, &unichar);
+                if (r < 0) /* sequence invalid, then copy as-is */
+                        goto copy;
+
+                p += utf16_encode_unichar(p, unichar);
+                i += e;
+                continue;
+
+        copy:
+                *(p++) = htole16(s[i++]);
+        }
+
+        *p = 0;
+        return n;
+}
+
+size_t char16_strlen(const char16_t *s) {
+        size_t n = 0;
+
+        assert(s);
+
+        while (*s != 0)
+                n++, s++;
+
+        return n;
+}
+
 /* expected size used to encode one unicode char */
 static int utf8_unichar_to_encoded_len(char32_t unichar) {
 
@@ -376,8 +458,9 @@ static int utf8_unichar_to_encoded_len(char32_t unichar) {
 
 /* validate one encoded unicode char and return its length */
 int utf8_encoded_valid_unichar(const char *str) {
-        int len, i, r;
         char32_t unichar;
+        size_t len, i;
+        int r;
 
         assert(str);
 
@@ -399,14 +482,14 @@ int utf8_encoded_valid_unichar(const char *str) {
                 return r;
 
         /* check if encoded length matches encoded value */
-        if (utf8_unichar_to_encoded_len(unichar) != len)
+        if (utf8_unichar_to_encoded_len(unichar) != (int) len)
                 return -EINVAL;
 
         /* check if value has valid range */
         if (!unichar_is_valid(unichar))
                 return -EINVAL;
 
-        return len;
+        return (int) len;
 }
 
 size_t utf8_n_codepoints(const char *str) {
index e8af7a576b80b740b9bd2744d07d97389c7f119a..3de798050d6f89d0b9bb01246326518b7efcf981 100644 (file)
@@ -14,7 +14,7 @@
 
 bool unichar_is_valid(char32_t c);
 
-const char *utf8_is_valid(const char *s) _pure_;
+char *utf8_is_valid(const char *s) _pure_;
 char *ascii_is_valid(const char *s) _pure_;
 char *ascii_is_valid_n(const char *str, size_t len);
 
@@ -25,21 +25,26 @@ char *utf8_escape_invalid(const char *s);
 char *utf8_escape_non_printable(const char *str);
 
 size_t utf8_encode_unichar(char *out_utf8, char32_t g);
-char *utf16_to_utf8(const void *s, size_t length);
+size_t utf16_encode_unichar(char16_t *out, char32_t c);
+
+char *utf16_to_utf8(const char16_t *s, size_t length /* bytes! */);
+char16_t *utf8_to_utf16(const char *s, size_t length);
+
+size_t char16_strlen(const char16_t *s); /* returns the number of 16bit words in the string (not bytes!) */
 
 int utf8_encoded_valid_unichar(const char *str);
 int utf8_encoded_to_unichar(const char *str, char32_t *ret_unichar);
 
 static inline bool utf16_is_surrogate(char16_t c) {
-        return (0xd800 <= c && c <= 0xdfff);
+        return c >= 0xd800U && c <= 0xdfffU;
 }
 
 static inline bool utf16_is_trailing_surrogate(char16_t c) {
-        return (0xdc00 <= c && c <= 0xdfff);
+        return c >= 0xdc00U && c <= 0xdfffU;
 }
 
 static inline char32_t utf16_surrogate_pair_to_unichar(char16_t lead, char16_t trail) {
-                return ((lead - 0xd800) << 10) + (trail - 0xdc00) + 0x10000;
+        return ((((char32_t) lead - 0xd800U) << 10) + ((char32_t) trail - 0xdc00U) + 0x10000U);
 }
 
 size_t utf8_n_codepoints(const char *str);
index c5509e73d19b7a64f2b434f68c063bfd4714313d..aa897c62a13fa044879dd004671a409c8530a4c7 100644 (file)
@@ -34,7 +34,13 @@ stub_sources = '''
 
 if conf.get('ENABLE_EFI') == 1 and get_option('gnu-efi') != 'false'
         efi_cc = get_option('efi-cc')
+        if efi_cc.length() == 0
+                efi_cc = cc.cmd_array()
+        endif
         efi_ld = get_option('efi-ld')
+        if efi_ld == ''
+                efi_ld = find_program('ld', required: true)
+        endif
         efi_incdir = get_option('efi-includedir')
 
         gnu_efi_path_arch = ''
@@ -51,10 +57,13 @@ if conf.get('ENABLE_EFI') == 1 and get_option('gnu-efi') != 'false'
 
         efi_libdir = get_option('efi-libdir')
         if efi_libdir == ''
-                cmd = 'cd /usr/lib/$(@0@ -print-multi-os-directory) && pwd'.format(efi_cc)
-                ret = run_command('sh', '-c', cmd)
+                ret = run_command(efi_cc + ['-print-multi-os-directory'])
                 if ret.returncode() == 0
-                        efi_libdir = ret.stdout().strip()
+                        path = join_paths('/usr/lib', ret.stdout().strip())
+                        ret = run_command('realpath', '-e', path)
+                        if ret.returncode() == 0
+                                efi_libdir = ret.stdout().strip()
+                        endif
                 endif
         endif
 
@@ -143,7 +152,7 @@ if have_gnu_efi
                 o_file = custom_target(file + '.o',
                                        input : file,
                                        output : file + '.o',
-                                       command : [efi_cc, '-c', '@INPUT@', '-o', '@OUTPUT@']
+                                       command : efi_cc + ['-c', '@INPUT@', '-o', '@OUTPUT@']
                                                  + compile_args,
                                        depend_files : efi_headers)
                 if (common_sources + systemd_boot_sources).contains(file)
@@ -154,7 +163,7 @@ if have_gnu_efi
                 endif
         endforeach
 
-        libgcc_file_name = run_command(efi_cc, '-print-libgcc-file-name').stdout().strip()
+        libgcc_file_name = run_command(efi_cc + ['-print-libgcc-file-name']).stdout().strip()
         systemd_boot_efi_name = 'systemd-boot@0@.efi'.format(EFI_MACHINE_TYPE_NAME)
         stub_efi_name = 'linux@0@.efi.stub'.format(EFI_MACHINE_TYPE_NAME)
         no_undefined_symbols = find_program('no-undefined-symbols.sh')
index a78f8fd6739256bb0fa7b36efa1cffbba4d57ea9..ba4a2c5da0a808f504040184368d674752851021 100644 (file)
@@ -280,7 +280,7 @@ EFI_STATUS graphics_splash(UINT8 *content, UINTN len, const EFI_GRAPHICS_OUTPUT_
                           GraphicsOutput->Mode->Info->VerticalResolution, 0);
 
         /* EFI buffer */
-        blt_size = dib->x * dib->y * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
+        blt_size = sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * dib->x * dib->y;
         blt = AllocatePool(blt_size);
         if (!blt)
                 return EFI_OUT_OF_RESOURCES;
index 3e2a7694a7b053f969ddf4c177b43c89c9b11089..e2b3a0d51750a5e233f3e2472e47f54013a1f445 100644 (file)
@@ -15,12 +15,14 @@ const sd_bus_vtable bus_kill_vtable[] = {
         SD_BUS_PROPERTY("FinalKillSignal", "i", bus_property_get_int, offsetof(KillContext, final_kill_signal), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("SendSIGKILL", "b", bus_property_get_bool, offsetof(KillContext, send_sigkill), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("SendSIGHUP", "b", bus_property_get_bool,  offsetof(KillContext, send_sighup), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("WatchdogSignal", "i", bus_property_get_int, offsetof(KillContext, watchdog_signal), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_VTABLE_END
 };
 
 static BUS_DEFINE_SET_TRANSIENT_PARSE(kill_mode, KillMode, kill_mode_from_string);
 static BUS_DEFINE_SET_TRANSIENT_TO_STRING(kill_signal, "i", int32_t, int, "%" PRIi32, signal_to_string_with_check);
 static BUS_DEFINE_SET_TRANSIENT_TO_STRING(final_kill_signal, "i", int32_t, int, "%" PRIi32, signal_to_string_with_check);
+static BUS_DEFINE_SET_TRANSIENT_TO_STRING(watchdog_signal, "i", int32_t, int, "%" PRIi32, signal_to_string_with_check);
 
 int bus_kill_context_set_transient_property(
                 Unit *u,
@@ -52,5 +54,8 @@ int bus_kill_context_set_transient_property(
         if (streq(name, "FinalKillSignal"))
                 return bus_set_transient_final_kill_signal(u, name, &c->final_kill_signal, message, flags, error);
 
+        if (streq(name, "WatchdogSignal"))
+                return bus_set_transient_watchdog_signal(u, name, &c->watchdog_signal, message, flags, error);
+
         return 0;
 }
index 9be95c96ae3011f1cfbe0c46bbc3eccb51068532..0ef5d2d212f50aa776b0374bba7647f6017a47c8 100644 (file)
@@ -1432,7 +1432,7 @@ static int apply_syscall_filter(const Unit* u, const ExecContext *c, bool needs_
                         return r;
         }
 
-        return seccomp_load_syscall_filter_set_raw(default_action, c->syscall_filter, action);
+        return seccomp_load_syscall_filter_set_raw(default_action, c->syscall_filter, action, false);
 }
 
 static int apply_syscall_archs(const Unit *u, const ExecContext *c) {
@@ -1515,7 +1515,7 @@ static int apply_protect_kernel_modules(const Unit *u, const ExecContext *c) {
         if (skip_seccomp_unavailable(u, "ProtectKernelModules="))
                 return 0;
 
-        return seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + SYSCALL_FILTER_SET_MODULE, SCMP_ACT_ERRNO(EPERM));
+        return seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + SYSCALL_FILTER_SET_MODULE, SCMP_ACT_ERRNO(EPERM), false);
 }
 
 static int apply_private_devices(const Unit *u, const ExecContext *c) {
@@ -1530,7 +1530,7 @@ static int apply_private_devices(const Unit *u, const ExecContext *c) {
         if (skip_seccomp_unavailable(u, "PrivateDevices="))
                 return 0;
 
-        return seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + SYSCALL_FILTER_SET_RAW_IO, SCMP_ACT_ERRNO(EPERM));
+        return seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + SYSCALL_FILTER_SET_RAW_IO, SCMP_ACT_ERRNO(EPERM), false);
 }
 
 static int apply_restrict_namespaces(const Unit *u, const ExecContext *c) {
index 73fa556d135f1841a05554009e1f78fe61e44115..6fe96cfc07c0f2018989b07e742eb02d0d6cf954 100644 (file)
@@ -12,6 +12,7 @@ void kill_context_init(KillContext *c) {
         c->final_kill_signal = SIGKILL;
         c->send_sigkill = true;
         c->send_sighup = false;
+        c->watchdog_signal = SIGABRT;
 }
 
 void kill_context_dump(KillContext *c, FILE *f, const char *prefix) {
index f4e312d75a591f78aeac248b6e849f32bbb3e1ee..f3915be1dcfcd62ef569ab7b0c1de2eea40ef108 100644 (file)
@@ -24,6 +24,7 @@ struct KillContext {
         int final_kill_signal;
         bool send_sigkill;
         bool send_sighup;
+        int watchdog_signal;
 };
 
 typedef enum KillWho {
index ad9c458aa788246e98e95ef20330ca38b0ffa5e4..7410d4709cae512cefeae0c0d0fe7021388a7f24 100644 (file)
@@ -152,7 +152,8 @@ m4_define(`KILL_CONTEXT_CONFIG_ITEMS',
 $1.SendSIGHUP,                   config_parse_bool,                  0,                             offsetof($1, kill_context.send_sighup)
 $1.KillMode,                     config_parse_kill_mode,             0,                             offsetof($1, kill_context.kill_mode)
 $1.KillSignal,                   config_parse_signal,                0,                             offsetof($1, kill_context.kill_signal)
-$1.FinalKillSignal,              config_parse_signal,                0,                             offsetof($1, kill_context.final_kill_signal)'
+$1.FinalKillSignal,              config_parse_signal,                0,                             offsetof($1, kill_context.final_kill_signal)
+$1.WatchdogSignal,               config_parse_signal,                0,                             offsetof($1, kill_context.watchdog_signal)'
 )m4_dnl
 m4_define(`CGROUP_CONTEXT_CONFIG_ITEMS',
 `$1.Slice,                       config_parse_unit_slice,            0,                             0
index 5baa30d3dde69eac16c0c78918a887eaabc49933..c361a1ec076cf7d9c7a33d0ea8f628ab29d11c21 100644 (file)
@@ -3459,9 +3459,7 @@ int manager_reload(Manager *m) {
         m->uid_refs = hashmap_free(m->uid_refs);
         m->gid_refs = hashmap_free(m->gid_refs);
 
-        q = lookup_paths_init(&m->lookup_paths, m->unit_file_scope, 0, NULL);
-        if (q < 0 && r >= 0)
-                r = q;
+        r = lookup_paths_init(&m->lookup_paths, m->unit_file_scope, 0, NULL);
 
         q = manager_run_environment_generators(m);
         if (q < 0 && r >= 0)
index 722a9e9ae7792e103fe1af6bfd4501573f2aaf7a..778bce832e6622208f53368b8395cea8af76ee48 100644 (file)
@@ -48,7 +48,7 @@ static const UnitActiveState state_translation_table[_SERVICE_STATE_MAX] = {
         [SERVICE_EXITED] = UNIT_ACTIVE,
         [SERVICE_RELOAD] = UNIT_RELOADING,
         [SERVICE_STOP] = UNIT_DEACTIVATING,
-        [SERVICE_STOP_SIGABRT] = UNIT_DEACTIVATING,
+        [SERVICE_STOP_WATCHDOG] = UNIT_DEACTIVATING,
         [SERVICE_STOP_SIGTERM] = UNIT_DEACTIVATING,
         [SERVICE_STOP_SIGKILL] = UNIT_DEACTIVATING,
         [SERVICE_STOP_POST] = UNIT_DEACTIVATING,
@@ -69,7 +69,7 @@ static const UnitActiveState state_translation_table_idle[_SERVICE_STATE_MAX] =
         [SERVICE_EXITED] = UNIT_ACTIVE,
         [SERVICE_RELOAD] = UNIT_RELOADING,
         [SERVICE_STOP] = UNIT_DEACTIVATING,
-        [SERVICE_STOP_SIGABRT] = UNIT_DEACTIVATING,
+        [SERVICE_STOP_WATCHDOG] = UNIT_DEACTIVATING,
         [SERVICE_STOP_SIGTERM] = UNIT_DEACTIVATING,
         [SERVICE_STOP_SIGKILL] = UNIT_DEACTIVATING,
         [SERVICE_STOP_POST] = UNIT_DEACTIVATING,
@@ -1031,7 +1031,7 @@ static void service_set_state(Service *s, ServiceState state) {
                     SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST,
                     SERVICE_RUNNING,
                     SERVICE_RELOAD,
-                    SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
+                    SERVICE_STOP, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
                     SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL,
                     SERVICE_AUTO_RESTART))
                 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
@@ -1039,7 +1039,7 @@ static void service_set_state(Service *s, ServiceState state) {
         if (!IN_SET(state,
                     SERVICE_START, SERVICE_START_POST,
                     SERVICE_RUNNING, SERVICE_RELOAD,
-                    SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
+                    SERVICE_STOP, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
                     SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL)) {
                 service_unwatch_main_pid(s);
                 s->main_command = NULL;
@@ -1048,7 +1048,7 @@ static void service_set_state(Service *s, ServiceState state) {
         if (!IN_SET(state,
                     SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST,
                     SERVICE_RELOAD,
-                    SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
+                    SERVICE_STOP, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
                     SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL)) {
                 service_unwatch_control_pid(s);
                 s->control_command = NULL;
@@ -1063,7 +1063,7 @@ static void service_set_state(Service *s, ServiceState state) {
         if (!IN_SET(state,
                     SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST,
                     SERVICE_RUNNING, SERVICE_RELOAD,
-                    SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
+                    SERVICE_STOP, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
                     SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL) &&
             !(state == SERVICE_DEAD && UNIT(s)->job))
                 service_close_socket_fd(s);
@@ -1102,7 +1102,7 @@ static usec_t service_coldplug_timeout(Service *s) {
                 return usec_add(UNIT(s)->active_enter_timestamp.monotonic, s->runtime_max_usec);
 
         case SERVICE_STOP:
-        case SERVICE_STOP_SIGABRT:
+        case SERVICE_STOP_WATCHDOG:
         case SERVICE_STOP_SIGTERM:
         case SERVICE_STOP_SIGKILL:
         case SERVICE_STOP_POST:
@@ -1137,7 +1137,7 @@ static int service_coldplug(Unit *u) {
             (IN_SET(s->deserialized_state,
                     SERVICE_START, SERVICE_START_POST,
                     SERVICE_RUNNING, SERVICE_RELOAD,
-                    SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
+                    SERVICE_STOP, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
                     SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL))) {
                 r = unit_watch_pid(UNIT(s), s->main_pid);
                 if (r < 0)
@@ -1149,7 +1149,7 @@ static int service_coldplug(Unit *u) {
             IN_SET(s->deserialized_state,
                    SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST,
                    SERVICE_RELOAD,
-                   SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
+                   SERVICE_STOP, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
                    SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL)) {
                 r = unit_watch_pid(UNIT(s), s->control_pid);
                 if (r < 0)
@@ -1780,8 +1780,8 @@ fail:
 static int state_to_kill_operation(ServiceState state) {
         switch (state) {
 
-        case SERVICE_STOP_SIGABRT:
-                return KILL_ABORT;
+        case SERVICE_STOP_WATCHDOG:
+                return KILL_WATCHDOG;
 
         case SERVICE_STOP_SIGTERM:
         case SERVICE_FINAL_SIGTERM:
@@ -1827,9 +1827,9 @@ static void service_enter_signal(Service *s, ServiceState state, ServiceResult f
                         goto fail;
 
                 service_set_state(s, state);
-        } else if (IN_SET(state, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM) && s->kill_context.send_sigkill)
+        } else if (IN_SET(state, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM) && s->kill_context.send_sigkill)
                 service_enter_signal(s, SERVICE_STOP_SIGKILL, SERVICE_SUCCESS);
-        else if (IN_SET(state, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL))
+        else if (IN_SET(state, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL))
                 service_enter_stop_post(s, SERVICE_SUCCESS);
         else if (state == SERVICE_FINAL_SIGTERM && s->kill_context.send_sigkill)
                 service_enter_signal(s, SERVICE_FINAL_SIGKILL, SERVICE_SUCCESS);
@@ -1841,7 +1841,7 @@ static void service_enter_signal(Service *s, ServiceState state, ServiceResult f
 fail:
         log_unit_warning_errno(UNIT(s), r, "Failed to kill processes: %m");
 
-        if (IN_SET(state, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL))
+        if (IN_SET(state, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL))
                 service_enter_stop_post(s, SERVICE_FAILURE_RESOURCES);
         else
                 service_enter_dead(s, SERVICE_FAILURE_RESOURCES, true);
@@ -2291,7 +2291,7 @@ static int service_start(Unit *u) {
         /* We cannot fulfill this request right now, try again later
          * please! */
         if (IN_SET(s->state,
-                   SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
+                   SERVICE_STOP, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
                    SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL))
                 return -EAGAIN;
 
@@ -2361,7 +2361,7 @@ static int service_stop(Unit *u) {
 
         /* Already on it */
         if (IN_SET(s->state,
-                   SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
+                   SERVICE_STOP, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
                    SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL))
                 return 0;
 
@@ -3130,7 +3130,7 @@ static void service_notify_cgroup_empty_event(Unit *u) {
                 service_enter_running(s, SERVICE_SUCCESS);
                 break;
 
-        case SERVICE_STOP_SIGABRT:
+        case SERVICE_STOP_WATCHDOG:
         case SERVICE_STOP_SIGTERM:
         case SERVICE_STOP_SIGKILL:
 
@@ -3274,7 +3274,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
                                 service_enter_running(s, f);
                                 break;
 
-                        case SERVICE_STOP_SIGABRT:
+                        case SERVICE_STOP_WATCHDOG:
                         case SERVICE_STOP_SIGTERM:
                         case SERVICE_STOP_SIGKILL:
 
@@ -3409,7 +3409,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
                                 service_enter_signal(s, SERVICE_STOP_SIGTERM, f);
                                 break;
 
-                        case SERVICE_STOP_SIGABRT:
+                        case SERVICE_STOP_WATCHDOG:
                         case SERVICE_STOP_SIGTERM:
                         case SERVICE_STOP_SIGKILL:
                                 if (main_pid_good(s) <= 0)
@@ -3480,8 +3480,8 @@ static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *us
                 service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_TIMEOUT);
                 break;
 
-        case SERVICE_STOP_SIGABRT:
-                log_unit_warning(UNIT(s), "State 'stop-sigabrt' timed out. Terminating.");
+        case SERVICE_STOP_WATCHDOG:
+                log_unit_warning(UNIT(s), "State 'stop-watchdog' timed out. Terminating.");
                 service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_TIMEOUT);
                 break;
 
@@ -3560,7 +3560,7 @@ static int service_dispatch_watchdog(sd_event_source *source, usec_t usec, void
                 log_unit_error(UNIT(s), "Watchdog timeout (limit %s)!",
                                format_timespan(t, sizeof(t), watchdog_usec, 1));
 
-                service_enter_signal(s, SERVICE_STOP_SIGABRT, SERVICE_FAILURE_WATCHDOG);
+                service_enter_signal(s, SERVICE_STOP_WATCHDOG, SERVICE_FAILURE_WATCHDOG);
         } else
                 log_unit_warning(UNIT(s), "Watchdog disabled! Ignoring watchdog timeout (limit %s)!",
                                  format_timespan(t, sizeof(t), watchdog_usec, 1));
@@ -3967,7 +3967,7 @@ static bool service_needs_console(Unit *u) {
                       SERVICE_RUNNING,
                       SERVICE_RELOAD,
                       SERVICE_STOP,
-                      SERVICE_STOP_SIGABRT,
+                      SERVICE_STOP_WATCHDOG,
                       SERVICE_STOP_SIGTERM,
                       SERVICE_STOP_SIGKILL,
                       SERVICE_STOP_POST,
index 6ca8f6a97f947003f5e46f5825bdfc383601ce70..5817fc1637431a79d74e097f51eaa51a9235048f 100644 (file)
@@ -4509,8 +4509,8 @@ static int operation_to_signal(KillContext *c, KillOperation k) {
         case KILL_KILL:
                 return c->final_kill_signal;
 
-        case KILL_ABORT:
-                return SIGABRT;
+        case KILL_WATCHDOG:
+                return c->watchdog_signal;
 
         default:
                 assert_not_reached("KillOperation unknown");
index 3770c01acdedd51b3049239a38ce718eb1b30b8f..861a2c1746c19f03d35fe6c682c204b260729d47 100644 (file)
@@ -19,7 +19,7 @@ typedef enum KillOperation {
         KILL_TERMINATE,
         KILL_TERMINATE_AND_LOG,
         KILL_KILL,
-        KILL_ABORT,
+        KILL_WATCHDOG,
         _KILL_OPERATION_MAX,
         _KILL_OPERATION_INVALID = -1
 } KillOperation;
diff --git a/src/fuzz/fuzz-bus-message.c b/src/fuzz/fuzz-bus-message.c
new file mode 100644 (file)
index 0000000..9842c62
--- /dev/null
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include <errno.h>
+#include <stdio.h>
+
+#include "alloc-util.h"
+#include "bus-dump.h"
+#include "bus-message.h"
+#include "env-util.h"
+#include "fd-util.h"
+#include "fuzz.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+        _cleanup_free_ char *out = NULL; /* out should be freed after g */
+        size_t out_size;
+        _cleanup_fclose_ FILE *g = NULL;
+        _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
+        _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
+        _cleanup_free_ void *buffer = NULL;
+        int r;
+
+        /* We don't want to fill the logs with messages about parse errors.
+         * Disable most logging if not running standalone */
+        if (!getenv("SYSTEMD_LOG_LEVEL"))
+                log_set_max_level(LOG_CRIT);
+
+        r = sd_bus_new(&bus);
+        assert_se(r >= 0);
+
+        assert_se(buffer = memdup(data, size));
+
+        r = bus_message_from_malloc(bus, buffer, size, NULL, 0, NULL, &m);
+        if (r == -EBADMSG)
+                return 0;
+        assert_se(r >= 0);
+        TAKE_PTR(buffer);
+
+        if (getenv_bool("SYSTEMD_FUZZ_OUTPUT") <= 0)
+                assert_se(g = open_memstream(&out, &out_size));
+
+        bus_message_dump(m, g ?: stdout, BUS_MESSAGE_DUMP_WITH_HEADER);
+
+        r = sd_bus_message_rewind(m, true);
+        assert_se(r >= 0);
+
+        return 0;
+}
diff --git a/src/fuzz/fuzz-dhcp6-client.c b/src/fuzz/fuzz-dhcp6-client.c
new file mode 100644 (file)
index 0000000..32a3c30
--- /dev/null
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include <unistd.h>
+
+#include "sd-dhcp6-client.h"
+#include "sd-event.h"
+
+#include "dhcp6-internal.h"
+#include "dhcp6-protocol.h"
+#include "fd-util.h"
+#include "fuzz.h"
+
+static int test_dhcp_fd[2];
+
+int dhcp6_network_send_udp_socket(int s, struct in6_addr *server_address,
+                                  const void *packet, size_t len) {
+        return len;
+}
+
+int dhcp6_network_bind_udp_socket(int index, struct in6_addr *local_address) {
+        assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, test_dhcp_fd) >= 0);
+        return test_dhcp_fd[0];
+}
+
+static void fuzz_client(const uint8_t *data, size_t size, bool is_information_request_enabled) {
+        _cleanup_(sd_event_unrefp) sd_event *e;
+        _cleanup_(sd_dhcp6_client_unrefp) sd_dhcp6_client *client = NULL;
+        struct in6_addr address = { { { 0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01 } } };
+
+        assert_se(sd_event_new(&e) >= 0);
+        assert_se(sd_dhcp6_client_new(&client) >= 0);
+        assert_se(sd_dhcp6_client_attach_event(client, e, 0) >= 0);
+        assert_se(sd_dhcp6_client_set_ifindex(client, 42) == 0);
+        assert_se(sd_dhcp6_client_set_local_address(client, &address) >= 0);
+        assert_se(sd_dhcp6_client_set_information_request(client, is_information_request_enabled) == 0);
+
+        assert_se(sd_dhcp6_client_start(client) >= 0);
+
+        if (size >= sizeof(DHCP6Message))
+                assert_se(sd_dhcp6_client_set_transaction_id(client, htobe32(0x00ffffff) & ((const DHCP6Message *) data)->transaction_id) == 0);
+
+        assert_se(write(test_dhcp_fd[1], data, size) == (ssize_t) size);
+
+        sd_event_run(e, (uint64_t) -1);
+
+        assert_se(sd_dhcp6_client_stop(client) >= 0);
+
+        test_dhcp_fd[1] = safe_close(test_dhcp_fd[1]);
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+        /* This triggers client_receive_advertise */
+        fuzz_client(data, size, false);
+
+        /* This triggers client_receive_reply */
+        fuzz_client(data, size, true);
+
+        return 0;
+}
diff --git a/src/fuzz/fuzz-ndisc-rs.c b/src/fuzz/fuzz-ndisc-rs.c
new file mode 100644 (file)
index 0000000..7f2d8f8
--- /dev/null
@@ -0,0 +1,57 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include <netinet/icmp6.h>
+#include <arpa/inet.h>
+
+#include "alloc-util.h"
+#include "icmp6-util.h"
+#include "fuzz.h"
+#include "sd-ndisc.h"
+#include "socket-util.h"
+#include "ndisc-internal.h"
+
+static int test_fd[2];
+
+int icmp6_bind_router_solicitation(int index) {
+        assert_se(socketpair(AF_UNIX, SOCK_DGRAM, 0, test_fd) >= 0);
+        return test_fd[0];
+}
+
+int icmp6_bind_router_advertisement(int index) {
+        return -ENOSYS;
+}
+
+int icmp6_receive(int fd, void *iov_base, size_t iov_len,
+                  struct in6_addr *dst, triple_timestamp *timestamp) {
+        assert_se(read(fd, iov_base, iov_len) == (ssize_t) iov_len);
+
+        if (timestamp)
+                triple_timestamp_get(timestamp);
+
+        return 0;
+}
+
+int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) {
+        return 0;
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+        struct ether_addr mac_addr = {
+                .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}
+        };
+        _cleanup_(sd_event_unrefp) sd_event *e = NULL;
+        _cleanup_(sd_ndisc_unrefp) sd_ndisc *nd = NULL;
+
+        assert_se(sd_event_new(&e) >= 0);
+        assert_se(sd_ndisc_new(&nd) >= 0);
+        assert_se(sd_ndisc_attach_event(nd, e, 0) >= 0);
+        assert_se(sd_ndisc_set_ifindex(nd, 42) >= 0);
+        assert_se(sd_ndisc_set_mac(nd, &mac_addr) >= 0);
+        assert_se(sd_ndisc_start(nd) >= 0);
+        assert_se(write(test_fd[1], data, size) == (ssize_t) size);
+        (void) sd_event_run(e, (uint64_t) -1);
+        assert_se(sd_ndisc_stop(nd) >= 0);
+        close(test_fd[1]);
+
+        return 0;
+}
index 40c623345d05be9502331e39af73161ace723707..31ee41cbe02008be3401bffd750e1dcf225b7eee 100644 (file)
@@ -1,6 +1,10 @@
 # SPDX-License-Identifier: LGPL-2.1+
 
 fuzzers += [
+        [['src/fuzz/fuzz-bus-message.c'],
+         [libshared],
+         []],
+
         [['src/fuzz/fuzz-dns-packet.c',
           dns_type_headers],
          [libsystemd_resolve_core,
@@ -9,11 +13,30 @@ fuzzers += [
           libgpg_error,
           libm]],
 
+        [['src/fuzz/fuzz-dhcp6-client.c',
+          'src/libsystemd-network/dhcp-identifier.h',
+          'src/libsystemd-network/dhcp-identifier.c',
+          'src/libsystemd-network/dhcp6-internal.h',
+          'src/systemd/sd-dhcp6-client.h'],
+         [libshared,
+          libsystemd_network],
+         []],
+
         [['src/fuzz/fuzz-dhcp-server.c'],
          [libsystemd_network,
           libshared],
          []],
 
+        [['src/fuzz/fuzz-ndisc-rs.c',
+          'src/libsystemd-network/dhcp-identifier.h',
+          'src/libsystemd-network/dhcp-identifier.c',
+          'src/libsystemd-network/icmp6-util.h',
+          'src/systemd/sd-dhcp6-client.h',
+          'src/systemd/sd-ndisc.h'],
+         [libshared,
+          libsystemd_network],
+         []],
+
         [['src/fuzz/fuzz-unit-file.c'],
          [libcore,
           libshared],
diff --git a/src/id128/id128.c b/src/id128/id128.c
new file mode 100644 (file)
index 0000000..a639131
--- /dev/null
@@ -0,0 +1,167 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include <getopt.h>
+#include <stdio.h>
+
+#include "alloc-util.h"
+#include "id128-print.h"
+#include "terminal-util.h"
+#include "util.h"
+#include "verbs.h"
+
+static bool arg_pretty = false;
+static sd_id128_t arg_app = {};
+
+static int verb_new(int argc, char **argv, void *userdata) {
+        return id128_print_new(arg_pretty);
+}
+
+static int verb_machine_id(int argc, char **argv, void *userdata) {
+        sd_id128_t id;
+        int r;
+
+        if (sd_id128_is_null(arg_app))
+                r = sd_id128_get_machine(&id);
+        else
+                r = sd_id128_get_machine_app_specific(arg_app, &id);
+        if (r < 0)
+                return log_error_errno(r, "Failed to get %smachine-ID: %m",
+                                       sd_id128_is_null(arg_app) ? "" : "app-specific ");
+
+        return id128_pretty_print(id, arg_pretty);
+}
+
+static int verb_boot_id(int argc, char **argv, void *userdata) {
+        sd_id128_t id;
+        int r;
+
+        if (sd_id128_is_null(arg_app))
+                r = sd_id128_get_boot(&id);
+        else
+                r = sd_id128_get_boot_app_specific(arg_app, &id);
+        if (r < 0)
+                return log_error_errno(r, "Failed to get %sboot-ID: %m",
+                                       sd_id128_is_null(arg_app) ? "" : "app-specific ");
+
+        return id128_pretty_print(id, arg_pretty);
+}
+
+static int verb_invocation_id(int argc, char **argv, void *userdata) {
+        sd_id128_t id;
+        int r;
+
+        if (!sd_id128_is_null(arg_app))
+                return log_error_errno(EINVAL, "Verb \"invocation-id\" cannot be combined with --app-specific=.");
+
+        r = sd_id128_get_invocation(&id);
+        if (r < 0)
+                return log_error_errno(r, "Failed to get invocation-ID: %m");
+
+        return id128_pretty_print(id, arg_pretty);
+}
+
+static int help(void) {
+        _cleanup_free_ char *link = NULL;
+        int r;
+
+        r = terminal_urlify_man("systemd-id128", "1", &link);
+        if (r < 0)
+                return log_oom();
+
+        printf("%s [OPTIONS...] {COMMAND} ...\n\n"
+               "Generate and print id128 strings.\n\n"
+               "  -h --help               Show this help\n\n"
+               "  -p --pretty             Generate samples of program code\n\n"
+               "  -a --app-specific=ID    Generate app-specific IDs\n\n"
+               "Commands:\n"
+               "  new                     Generate a new id128 string\n"
+               "  machine-id              Print the ID of current machine\n"
+               "  boot-id                 Print the ID of current boot\n"
+               "  invocation-id           Print the ID of current invocation\n"
+               "  help                    Show this help\n"
+               "\nSee the %s for details.\n"
+               , program_invocation_short_name
+               , link
+        );
+
+        return 0;
+}
+
+static int verb_help(int argc, char **argv, void *userdata) {
+        return help();
+}
+
+static int parse_argv(int argc, char *argv[]) {
+        enum {
+                ARG_VERSION = 0x100,
+        };
+
+        static const struct option options[] = {
+                { "help",         no_argument,       NULL, 'h'              },
+                { "version",      no_argument,       NULL, ARG_VERSION      },
+                { "app-specific", required_argument, NULL, 'a'              },
+                {},
+        };
+
+        int c, r;
+
+        assert(argc >= 0);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "hpa:", options, NULL)) >= 0)
+                switch (c) {
+
+                case 'h':
+                        return help();
+
+                case ARG_VERSION:
+                        return version();
+
+                case 'p':
+                        arg_pretty = true;
+                        break;
+
+                case 'a':
+                        r = sd_id128_from_string(optarg, &arg_app);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to parse \"%s\" as application-ID: %m", optarg);
+                        break;
+
+                case '?':
+                        return -EINVAL;
+
+                default:
+                        assert_not_reached("Unhandled option");
+                }
+
+        return 1;
+}
+
+static int id128_main(int argc, char *argv[]) {
+        static const Verb verbs[] = {
+                { "new",            VERB_ANY, 1,        0,  verb_new           },
+                { "machine-id",     VERB_ANY, 1,        0,  verb_machine_id    },
+                { "boot-id",        VERB_ANY, 1,        0,  verb_boot_id       },
+                { "invocation-id",  VERB_ANY, 1,        0,  verb_invocation_id },
+                { "help",           VERB_ANY, VERB_ANY, 0,  verb_help          },
+                {}
+        };
+
+        return dispatch_verb(argc, argv, verbs, NULL);
+}
+
+int main(int argc, char *argv[]) {
+        int r;
+
+        log_parse_environment();
+        log_open();
+
+        r = parse_argv(argc, argv);
+        if (r <= 0)
+                goto finish;
+
+        r = id128_main(argc, argv);
+
+ finish:
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
index f31432cd046b3c1d915de01b5d3611970957359c..4537c4210cadd2e425309e0bb3ae235817203786 100644 (file)
@@ -307,7 +307,7 @@ static int raw_import_write(const void *p, size_t sz, void *userdata) {
 
         n = sparse_write(i->output_fd, p, sz, 64);
         if (n < 0)
-                return -errno;
+                return (int) n;
         if ((size_t) n < sz)
                 return -EIO;
 
index 1f78f0971859be4af7ff920fec51616c8a5e6c80..c494bbec3cbc1a4427ada27618234ad4fc2fcbcc 100644 (file)
@@ -233,10 +233,13 @@ static int pull_job_write_uncompressed(const void *p, size_t sz, void *userdata)
 
                 if (j->allow_sparse)
                         n = sparse_write(j->disk_fd, p, sz, 64);
-                else
+                else {
                         n = write(j->disk_fd, p, sz);
+                        if (n < 0)
+                                n = -errno;
+                }
                 if (n < 0)
-                        return log_error_errno(errno, "Failed to write file: %m");
+                        return log_error_errno((int) n, "Failed to write file: %m");
                 if ((size_t) n < sz) {
                         log_error("Short write");
                         return -EIO;
index 3991dcb7d269593910288fd5b5fdd8372f94f4b7..205ce182a2cf50450b208fd71a1cd5c008249e42 100644 (file)
@@ -34,7 +34,8 @@ static ssize_t write_entry(char *buf, size_t size, Uploader *u) {
 
                         r = snprintf(buf + pos, size - pos,
                                      "__CURSOR=%s\n", u->current_cursor);
-                        if (pos + r > size)
+                        assert(r >= 0);
+                        if ((size_t) r > size - pos)
                                 /* not enough space */
                                 return pos;
 
@@ -58,7 +59,8 @@ static ssize_t write_entry(char *buf, size_t size, Uploader *u) {
 
                         r = snprintf(buf + pos, size - pos,
                                      "__REALTIME_TIMESTAMP="USEC_FMT"\n", realtime);
-                        if (r + pos > size)
+                        assert(r >= 0);
+                        if ((size_t) r > size - pos)
                                 /* not enough space */
                                 return pos;
 
@@ -83,7 +85,8 @@ static ssize_t write_entry(char *buf, size_t size, Uploader *u) {
 
                         r = snprintf(buf + pos, size - pos,
                                      "__MONOTONIC_TIMESTAMP="USEC_FMT"\n", monotonic);
-                        if (r + pos > size)
+                        assert(r >= 0);
+                        if ((size_t) r > size - pos)
                                 /* not enough space */
                                 return pos;
 
@@ -108,7 +111,8 @@ static ssize_t write_entry(char *buf, size_t size, Uploader *u) {
 
                         r = snprintf(buf + pos, size - pos,
                                      "_BOOT_ID=%s\n", sd_id128_to_string(boot_id, sid));
-                        if (r + pos > size)
+                        assert(r >= 0);
+                        if ((size_t) r > size - pos)
                                 /* not enough space */
                                 return pos;
 
index 5e17d363937005d8bf618003785dfc14210f397b..157ed413b1952722b30b0fd153a3aa9361006ca1 100644 (file)
@@ -284,7 +284,7 @@ static size_t fd_input_callback(void *buf, size_t size, size_t nmemb, void *user
         ssize_t r;
 
         assert(u);
-        assert(nmemb <= SSIZE_MAX / size);
+        assert(nmemb < SSIZE_MAX / size);
 
         if (u->input < 0)
                 return 0;
index c2f0467c6e3ae9a2b2f6c3e840ca9cfbc91df74d..5569ddc31368650f008eee4df508bb9d3b80232b 100644 (file)
@@ -60,10 +60,11 @@ static void draw_progress(uint64_t p, usec_t *last_usec) {
 }
 
 static uint64_t scale_progress(uint64_t scale, uint64_t p, uint64_t m) {
+        /* Calculates scale * p / m, but handles m == 0 safely, and saturates.
+         * Currently all callers use m >= 1, but we keep the check to be defensive.
+         */
 
-        /* Calculates scale * p / m, but handles m == 0 safely, and saturates */
-
-        if (p >= m || m == 0)
+        if (p >= m || m == 0) /* lgtm [cpp/constant-comparison] */
                 return scale;
 
         return scale * p / m;
index a9e4af1dd8838ad1a65aab8959dc5fb1f645593c..2f8d2e9596f201c2433dee918db11864939ffd3b 100644 (file)
@@ -38,6 +38,7 @@
 #include "fsprg.h"
 #include "glob-util.h"
 #include "hostname-util.h"
+#include "id128-print.h"
 #include "io-util.h"
 #include "journal-def.h"
 #include "journal-internal.h"
@@ -362,7 +363,6 @@ static int help(void) {
                "     --list-catalog          Show all message IDs in the catalog\n"
                "     --dump-catalog          Show entries in the message catalog\n"
                "     --update-catalog        Update the message catalog database\n"
-               "     --new-id128             Generate a new 128-bit ID\n"
                "     --setup-keys            Generate a new FSS key pair\n"
                "\nSee the %s for details.\n"
                , program_invocation_short_name
@@ -424,7 +424,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "no-full",        no_argument,       NULL, ARG_NO_FULL        },
                 { "lines",          optional_argument, NULL, 'n'                },
                 { "no-tail",        no_argument,       NULL, ARG_NO_TAIL        },
-                { "new-id128",      no_argument,       NULL, ARG_NEW_ID128      },
+                { "new-id128",      no_argument,       NULL, ARG_NEW_ID128      }, /* deprecated */
                 { "quiet",          no_argument,       NULL, 'q'                },
                 { "merge",          no_argument,       NULL, 'm'                },
                 { "this-boot",      no_argument,       NULL, ARG_THIS_BOOT      }, /* deprecated */
@@ -1007,35 +1007,6 @@ static int parse_argv(int argc, char *argv[]) {
         return 1;
 }
 
-static int generate_new_id128(void) {
-        sd_id128_t id;
-        int r;
-        unsigned i;
-
-        r = sd_id128_randomize(&id);
-        if (r < 0)
-                return log_error_errno(r, "Failed to generate ID: %m");
-
-        printf("As string:\n"
-               SD_ID128_FORMAT_STR "\n\n"
-               "As UUID:\n"
-               "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n\n"
-               "As man:sd-id128(3) macro:\n"
-               "#define MESSAGE_XYZ SD_ID128_MAKE(",
-               SD_ID128_FORMAT_VAL(id),
-               SD_ID128_FORMAT_VAL(id));
-        for (i = 0; i < 16; i++)
-                printf("%02x%s", id.bytes[i], i != 15 ? "," : "");
-        fputs(")\n\n", stdout);
-
-        printf("As Python constant:\n"
-               ">>> import uuid\n"
-               ">>> MESSAGE_XYZ = uuid.UUID('" SD_ID128_FORMAT_STR "')\n",
-               SD_ID128_FORMAT_VAL(id));
-
-        return 0;
-}
-
 static int add_matches(sd_journal *j, char **args) {
         char **i;
         bool have_term = false;
@@ -2092,7 +2063,7 @@ int main(int argc, char *argv[]) {
         switch (arg_action) {
 
         case ACTION_NEW_ID128:
-                r = generate_new_id128();
+                r = id128_print_new(true);
                 goto finish;
 
         case ACTION_SETUP_KEYS:
index 415b9d23ca897ebe1f2d45e72e8fb3bc01028527..45be7e5bc4457c17f498502e5e820897c980d9b9 100644 (file)
@@ -22,7 +22,7 @@ static void test_syslog_parse_identifier(const char *str,
 
 static void test_syslog_parse_priority(const char *str, int priority, int ret) {
         const char *buf = str;
-        int priority2, ret2;
+        int priority2 = 0, ret2;
 
         ret2 = syslog_parse_priority(&buf, &priority2, false);
 
index 531cf6783bfdb96aa296004306aa9ea25ed2477d..77c584ee60a9484a5daf6a509bab397da72a0bb8 100644 (file)
@@ -108,8 +108,13 @@ int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len) {
         assert(len);
 
         r = sd_id128_get_machine(&machine_id);
-        if (r < 0)
+        if (r < 0) {
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+                machine_id = SD_ID128_MAKE(01, 02, 03, 04, 05, 06, 07, 08, 09, 0a, 0b, 0c, 0d, 0e, 0f, 10);
+#else
                 return r;
+#endif
+        }
 
         unaligned_write_be16(&duid->type, DUID_TYPE_EN);
         unaligned_write_be32(&duid->en.pen, SYSTEMD_PEN);
index c45b068fd7cccfa48b0b32b193729ab791c9f9fe..63d8fe35f8078a1bc7c09f492d5ac1369c521694 100644 (file)
@@ -89,7 +89,7 @@ int dhcp6_option_append_pd(uint8_t *buf, size_t len, DHCP6IA *pd);
 int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn);
 int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode,
                        size_t *optlen, uint8_t **optvalue);
-int dhcp6_option_parse_status(DHCP6Option *option);
+int dhcp6_option_parse_status(DHCP6Option *option, size_t len);
 int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia);
 int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen,
                                 struct in6_addr **addrs, size_t count,
index 18196b12573cd44d86de0cef3030864b0c2a189c..cf19d366d3b0c512b0a67cc6f4da5523f66fb87c 100644 (file)
@@ -247,10 +247,11 @@ int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode,
         return 0;
 }
 
-int dhcp6_option_parse_status(DHCP6Option *option) {
+int dhcp6_option_parse_status(DHCP6Option *option, size_t len) {
         DHCP6StatusOption *statusopt = (DHCP6StatusOption *)option;
 
-        if (be16toh(option->len) + sizeof(DHCP6Option) < sizeof(*statusopt))
+        if (len < sizeof(DHCP6StatusOption) ||
+            be16toh(option->len) + sizeof(DHCP6Option) < sizeof(DHCP6StatusOption))
                 return -ENOBUFS;
 
         return be16toh(statusopt->status);
@@ -277,7 +278,7 @@ static int dhcp6_option_parse_address(DHCP6Option *option, DHCP6IA *ia,
         }
 
         if (be16toh(option->len) + sizeof(DHCP6Option) > sizeof(*addr_option)) {
-                r = dhcp6_option_parse_status((DHCP6Option *)addr_option->options);
+                r = dhcp6_option_parse_status((DHCP6Option *)addr_option->options, be16toh(option->len) + sizeof(DHCP6Option) - sizeof(*addr_option));
                 if (r != 0)
                         return r < 0 ? r: 0;
         }
@@ -317,7 +318,7 @@ static int dhcp6_option_parse_pdprefix(DHCP6Option *option, DHCP6IA *ia,
         }
 
         if (be16toh(option->len) + sizeof(DHCP6Option) > sizeof(*pdprefix_option)) {
-                r = dhcp6_option_parse_status((DHCP6Option *)pdprefix_option->options);
+                r = dhcp6_option_parse_status((DHCP6Option *)pdprefix_option->options, be16toh(option->len) + sizeof(DHCP6Option) - sizeof(*pdprefix_option));
                 if (r != 0)
                         return r < 0 ? r: 0;
         }
@@ -462,7 +463,7 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia) {
 
                 case SD_DHCP6_OPTION_STATUS_CODE:
 
-                        status = dhcp6_option_parse_status(option);
+                        status = dhcp6_option_parse_status(option, optlen);
                         if (status) {
                                 log_dhcp6_client(client, "IA status %d",
                                                  status);
@@ -563,7 +564,7 @@ int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, char *
                                 /* Literal label */
                                 label = (const char *)&optval[pos];
                                 pos += c;
-                                if (pos > optlen)
+                                if (pos >= optlen)
                                         return -EMSGSIZE;
 
                                 if (!GREEDY_REALLOC(ret, allocated, n + !first + DNS_LABEL_ESCAPED_MAX)) {
index 736df222f03367195149fa8353e3cb9e2c67b38a..8bee24e5689a685ac84cb2698bc54579495f50f8 100644 (file)
@@ -174,12 +174,8 @@ int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *dst,
         iov.iov_len = size;
 
         len = recvmsg(fd, &msg, MSG_DONTWAIT);
-        if (len < 0) {
-                if (IN_SET(errno, EAGAIN, EINTR))
-                        return 0;
-
+        if (len < 0)
                 return -errno;
-        }
 
         if ((size_t) len != size)
                 return -EINVAL;
index c6e75ab312acde8f8197e4116779204df2597f19..b982dcc07df82604f3716a2322db57016b037568 100644 (file)
@@ -168,7 +168,7 @@ int ndisc_router_parse(sd_ndisc_router *rt) {
 
                         if (has_mtu) {
                                 log_ndisc("MTU option specified twice, ignoring.");
-                                continue;
+                                break;
                         }
 
                         if (length != 8) {
@@ -209,7 +209,7 @@ int ndisc_router_parse(sd_ndisc_router *rt) {
 
                         if (has_flag_extension) {
                                 log_ndisc("Flags extension option specified twice, ignoring.");
-                                continue;
+                                break;
                         }
 
                         if (length < 1*8) {
index b221c6f6c50d3a6d854d20a6d127569f30efc01d..cd4435230723d5d46a9f877445f60e4fd6a52de6 100644 (file)
@@ -85,5 +85,4 @@ struct sd_radv_prefix {
 
 #define log_radv_full(level, error, fmt, ...) log_internal(level, error, __FILE__, __LINE__, __func__, "RADV: " fmt, ##__VA_ARGS__)
 #define log_radv_errno(error, fmt, ...) log_radv_full(LOG_DEBUG, error, fmt, ##__VA_ARGS__)
-#define log_radv_warning_errno(error, fmt, ...) log_radv_full(LOG_WARNING, error, fmt, ##__VA_ARGS__)
 #define log_radv(fmt, ...) log_radv_errno(0, fmt, ##__VA_ARGS__)
index 0995f091f5d020437a38c96b2e0139df35d7e1b1..3e8d985aa73136ffe9dc27502c35e6247dc40abe 100644 (file)
@@ -698,7 +698,7 @@ static int client_message_init(
            let the server know how large the server may make its DHCP messages.
 
            Note (from ConnMan): Some DHCP servers will send bigger DHCP packets
-           than the defined default size unless the Maximum Messge Size option
+           than the defined default size unless the Maximum Message Size option
            is explicitly set
 
            RFC3442 "Requirements to Avoid Sizing Constraints":
index a65e6166fbe808caa299ba9b23365a777feb6aae..863818d6da2820326bf9cde477bcf7c1d4fbe458 100644 (file)
@@ -258,6 +258,8 @@ static sd_dhcp_lease *dhcp_lease_free(sd_dhcp_lease *lease) {
                 free(option);
         }
 
+        free(lease->root_path);
+        free(lease->timezone);
         free(lease->hostname);
         free(lease->domainname);
         free(lease->dns);
@@ -330,8 +332,7 @@ static int lease_parse_string(const uint8_t *option, size_t len, char **ret) {
                 if (!string)
                         return -ENOMEM;
 
-                free(*ret);
-                *ret = string;
+                free_and_replace(*ret, string);
         }
 
         return 0;
index b306f07eb98f4ee3c3b501576d595a90bdcbae3f..c07d831f7d29551bf27264906a25be4ac3a28585 100644 (file)
@@ -49,7 +49,7 @@ struct sd_dhcp6_client {
         DHCP6IA ia_pd;
         sd_event_source *timeout_t1;
         sd_event_source *timeout_t2;
-        int request;
+        unsigned request;
         be32_t transaction_id;
         usec_t transaction_start;
         struct sd_dhcp6_lease *lease;
@@ -368,6 +368,14 @@ int sd_dhcp6_client_set_address_request(sd_dhcp6_client *client, int request) {
         return 0;
 }
 
+int sd_dhcp6_client_set_transaction_id(sd_dhcp6_client *client, uint32_t transaction_id) {
+        assert_return(client, -EINVAL);
+
+        client->transaction_id = transaction_id;
+
+        return 0;
+}
+
 int sd_dhcp6_client_get_lease(sd_dhcp6_client *client, sd_dhcp6_lease **ret) {
         assert_return(client, -EINVAL);
 
@@ -387,17 +395,10 @@ static void client_notify(sd_dhcp6_client *client, int event) {
                 client->callback(client, event, client->userdata);
 }
 
-static void client_set_lease(sd_dhcp6_client *client, sd_dhcp6_lease *lease) {
-        assert(client);
-
-        (void) sd_dhcp6_lease_unref(client->lease);
-        client->lease = sd_dhcp6_lease_ref(lease);
-}
-
 static int client_reset(sd_dhcp6_client *client) {
         assert(client);
 
-        client_set_lease(client, NULL);
+        client->lease = sd_dhcp6_lease_unref(client->lease);
 
         client->receive_message =
                 sd_event_source_unref(client->receive_message);
@@ -411,6 +412,9 @@ static int client_reset(sd_dhcp6_client *client) {
         client->timeout_resend_expire =
                 sd_event_source_unref(client->timeout_resend_expire);
 
+        client->timeout_t1 = sd_event_source_unref(client->timeout_t1);
+        client->timeout_t2 = sd_event_source_unref(client->timeout_t2);
+
         client->state = DHCP6_STATE_STOPPED;
 
         return 0;
@@ -844,8 +848,8 @@ static int client_parse_message(
                 uint8_t *optval;
                 be32_t iaid_lease;
 
-                if (len < offsetof(DHCP6Option, data) ||
-                    len < offsetof(DHCP6Option, data) + be16toh(option->len))
+                if (len < pos + offsetof(DHCP6Option, data) ||
+                    len < pos + offsetof(DHCP6Option, data) + be16toh(option->len))
                         return -ENOBUFS;
 
                 optcode = be16toh(option->code);
@@ -896,7 +900,7 @@ static int client_parse_message(
                         break;
 
                 case SD_DHCP6_OPTION_STATUS_CODE:
-                        status = dhcp6_option_parse_status(option);
+                        status = dhcp6_option_parse_status(option, optlen);
                         if (status) {
                                 log_dhcp6_client(client, "%s Status %s",
                                                  dhcp6_message_type_to_string(message->type),
@@ -1001,7 +1005,7 @@ static int client_parse_message(
                         break;
                 }
 
-                pos += sizeof(*option) + optlen;
+                pos += offsetof(DHCP6Option, data) + optlen;
         }
 
         if (!clientid) {
@@ -1061,8 +1065,8 @@ static int client_receive_reply(sd_dhcp6_client *client, DHCP6Message *reply, si
                         return 0;
         }
 
-        client_set_lease(client, lease);
-        lease = NULL;
+        sd_dhcp6_lease_unref(client->lease);
+        client->lease = TAKE_PTR(lease);
 
         return DHCP6_STATE_BOUND;
 }
@@ -1090,8 +1094,8 @@ static int client_receive_advertise(sd_dhcp6_client *client, DHCP6Message *adver
         r = dhcp6_lease_get_preference(client->lease, &pref_lease);
 
         if (r < 0 || pref_advertise > pref_lease) {
-                client_set_lease(client, lease);
-                lease = NULL;
+                sd_dhcp6_lease_unref(client->lease);
+                client->lease = TAKE_PTR(lease);
                 r = 0;
         }
 
index e60aebc627763720c71ba256cad5cd0d2140cead..f72ef204b91aa22198e58fdbda318fe3f2488d07 100644 (file)
@@ -119,7 +119,7 @@ static int lldp_add_neighbor(sd_lldp *lldp, sd_lldp_neighbor *n) {
                 }
 
                 if (lldp_neighbor_equal(n, old)) {
-                        /* Is this equal, then restart the TTL counter, but don't do anyting else. */
+                        /* Is this equal, then restart the TTL counter, but don't do anything else. */
                         old->timestamp = n->timestamp;
                         lldp_start_timer(lldp, old);
                         lldp_callback(lldp, SD_LLDP_EVENT_REFRESHED, old);
index acab75ee183a54b99571293bef2cfe18e3c9c7cb..126a2929a96ad640846d31102b78e47535677a4f 100644 (file)
@@ -221,7 +221,14 @@ static int ndisc_recv(sd_event_source *s, int fd, uint32_t revents, void *userda
                         break;
 
                 case -EPFNOSUPPORT:
-                        log_ndisc("Received invalid source address from ICMPv6 socket.");
+                        log_ndisc("Received invalid source address from ICMPv6 socket. Ignoring.");
+                        break;
+
+                case -EAGAIN: /* ignore spurious wakeups */
+                        break;
+
+                default:
+                        log_ndisc_errno(r, "Unexpected error while reading from ICMPv6, ignoring: %m");
                         break;
                 }
 
index b4de6bda909b57750891ea64e01aef1dd7c91ae6..89c5a334972efb478f05d8940cb439d5e3db03e9 100644 (file)
@@ -249,8 +249,11 @@ static int radv_recv(sd_event_source *s, int fd, uint32_t revents, void *userdat
                         log_radv("Received invalid source address from ICMPv6 socket. Ignoring.");
                         break;
 
+                case -EAGAIN: /* ignore spurious wakeups */
+                        break;
+
                 default:
-                        log_radv_warning_errno(r, "Error receiving from ICMPv6 socket: %m");
+                        log_radv_errno(r, "Unexpected error receiving from ICMPv6 socket: %m");
                         break;
                 }
 
@@ -261,7 +264,7 @@ static int radv_recv(sd_event_source *s, int fd, uint32_t revents, void *userdat
 
         r = radv_send(ra, &src, ra->lifetime);
         if (r < 0)
-                log_radv_warning_errno(r, "Unable to send solicited Router Advertisement to %s: %m", addr);
+                log_radv_errno(r, "Unable to send solicited Router Advertisement to %s: %m", addr);
         else
                 log_radv("Sent solicited Router Advertisement to %s", addr);
 
@@ -294,7 +297,7 @@ static int radv_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
 
         r = radv_send(ra, NULL, ra->lifetime);
         if (r < 0)
-                log_radv_warning_errno(r, "Unable to send Router Advertisement: %m");
+                log_radv_errno(r, "Unable to send Router Advertisement: %m");
 
         /* RFC 4861, Section 6.2.4, sending initial Router Advertisements */
         if (ra->ra_sent < SD_RADV_MAX_INITIAL_RTR_ADVERTISEMENTS) {
@@ -348,7 +351,7 @@ _public_ int sd_radv_stop(sd_radv *ra) {
            with zero lifetime  */
         r = radv_send(ra, NULL, 0);
         if (r < 0)
-                log_radv_warning_errno(r, "Unable to send last Router Advertisement with router lifetime set to zero: %m");
+                log_radv_errno(r, "Unable to send last Router Advertisement with router lifetime set to zero: %m");
 
         radv_reset(ra);
         ra->fd = safe_close(ra->fd);
index b5760989c4df0153d334a78b353c5aef04114f91..480ef39c7adbe8b6b3edbb134082e8ab4bab485d 100644 (file)
@@ -576,4 +576,78 @@ global:
         sd_bus_message_readv;
         sd_bus_set_method_call_timeout;
         sd_bus_get_method_call_timeout;
+
+        sd_device_ref;
+        sd_device_unref;
+
+        sd_device_new_from_syspath;
+        sd_device_new_from_devnum;
+        sd_device_new_from_subsystem_sysname;
+        sd_device_new_from_device_id;
+
+        sd_device_get_parent;
+        sd_device_get_parent_with_subsystem_devtype;
+
+        sd_device_get_syspath;
+        sd_device_get_subsystem;
+        sd_device_get_devtype;
+        sd_device_get_devnum;
+        sd_device_get_ifindex;
+        sd_device_get_driver;
+        sd_device_get_devpath;
+        sd_device_get_devname;
+        sd_device_get_sysname;
+        sd_device_get_sysnum;
+
+        sd_device_get_is_initialized;
+        sd_device_get_usec_since_initialized;
+
+        sd_device_get_tag_first;
+        sd_device_get_tag_next;
+        sd_device_get_devlink_first;
+        sd_device_get_devlink_next;
+        sd_device_get_property_first;
+        sd_device_get_property_next;
+        sd_device_get_sysattr_first;
+        sd_device_get_sysattr_next;
+
+        sd_device_has_tag;
+        sd_device_get_property_value;
+        sd_device_get_sysattr_value;
+
+        sd_device_set_sysattr_value;
+
+        sd_device_enumerator_new;
+        sd_device_enumerator_ref;
+        sd_device_enumerator_unref;
+
+        sd_device_enumerator_get_device_first;
+        sd_device_enumerator_get_device_next;
+        sd_device_enumerator_get_subsystem_first;
+        sd_device_enumerator_get_subsystem_next;
+
+        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;
+        sd_device_enumerator_add_match_parent;
+        sd_device_enumerator_allow_uninitialized;
+
+        sd_device_unrefp;
+        sd_device_enumerator_unrefp;
+
+        sd_hwdb_ref;
+        sd_hwdb_unref;
+
+        sd_hwdb_new;
+
+        sd_hwdb_get;
+
+        sd_hwdb_seek;
+        sd_hwdb_enumerate;
+
+        sd_hwdb_unrefp;
+
+        sd_id128_get_boot_app_specific;
 } LIBSYSTEMD_239;
index 888f161768caf16d069bbe07f792b50df9cb5bac..506ed0d73c3303444258796b490217f7e7c032d6 100644 (file)
@@ -57,8 +57,14 @@ int bus_message_dump(sd_bus_message *m, FILE *f, unsigned flags) {
                         "%s%s%s Type=%s%s%s  Endian=%c  Flags=%u  Version=%u  Priority=%"PRIi64,
                         m->header->type == SD_BUS_MESSAGE_METHOD_ERROR ? ansi_highlight_red() :
                         m->header->type == SD_BUS_MESSAGE_METHOD_RETURN ? ansi_highlight_green() :
-                        m->header->type != SD_BUS_MESSAGE_SIGNAL ? ansi_highlight() : "", special_glyph(TRIANGULAR_BULLET), ansi_normal(),
-                        ansi_highlight(), bus_message_type_to_string(m->header->type), ansi_normal(),
+                        m->header->type != SD_BUS_MESSAGE_SIGNAL ? ansi_highlight() : "",
+                        special_glyph(TRIANGULAR_BULLET),
+                        ansi_normal(),
+
+                        ansi_highlight(),
+                        bus_message_type_to_string(m->header->type) ?: "(unknown)",
+                        ansi_normal(),
+
                         m->header->endian,
                         m->header->flags,
                         m->header->version,
index 6e404367dbedf94709ccde49ac011e2fd8cb4a0f..697553e74edd36bde43feecb6503864dc35731de 100644 (file)
@@ -75,19 +75,38 @@ static void message_reset_parts(sd_bus_message *m) {
         m->cached_rindex_part_begin = 0;
 }
 
-static void message_reset_containers(sd_bus_message *m) {
-        unsigned i;
+static struct bus_container *message_get_last_container(sd_bus_message *m) {
+        assert(m);
+
+        if (m->n_containers == 0)
+                return &m->root_container;
+
+        assert(m->containers);
+        return m->containers + m->n_containers - 1;
+}
+
+static void message_free_last_container(sd_bus_message *m) {
+        struct bus_container *c;
 
+        c = message_get_last_container(m);
+
+        free(c->signature);
+        free(c->peeked_signature);
+        free(c->offsets);
+
+        /* Move to previous container, but not if we are on root container */
+        if (m->n_containers > 0)
+                m->n_containers--;
+}
+
+static void message_reset_containers(sd_bus_message *m) {
         assert(m);
 
-        for (i = 0; i < m->n_containers; i++) {
-                free(m->containers[i].signature);
-                free(m->containers[i].offsets);
-        }
+        while (m->n_containers > 0)
+                message_free_last_container(m);
 
         m->containers = mfree(m->containers);
-
-        m->n_containers = m->containers_allocated = 0;
+        m->containers_allocated = 0;
         m->root_container.index = 0;
 }
 
@@ -110,10 +129,8 @@ static sd_bus_message* message_free(sd_bus_message *m) {
                 free(m->iovec);
 
         message_reset_containers(m);
-        free(m->root_container.signature);
-        free(m->root_container.offsets);
-
-        free(m->root_container.peeked_signature);
+        assert(m->n_containers == 0);
+        message_free_last_container(m);
 
         bus_creds_done(&m->creds);
         return mfree(m);
@@ -208,7 +225,7 @@ static int message_append_field_string(
         /* dbus1 doesn't allow strings over 32bit, let's enforce this
          * globally, to not risk convertability */
         l = strlen(s);
-        if (l > (size_t) (uint32_t) -1)
+        if (l > UINT32_MAX)
                 return -EINVAL;
 
         /* Signature "(yv)" where the variant contains "s" */
@@ -1088,16 +1105,6 @@ _public_ int sd_bus_message_set_allow_interactive_authorization(sd_bus_message *
         return 0;
 }
 
-static struct bus_container *message_get_container(sd_bus_message *m) {
-        assert(m);
-
-        if (m->n_containers == 0)
-                return &m->root_container;
-
-        assert(m->containers);
-        return m->containers + m->n_containers - 1;
-}
-
 struct bus_body_part *message_append_part(sd_bus_message *m) {
         struct bus_body_part *part;
 
@@ -1188,7 +1195,7 @@ static int message_add_offset(sd_bus_message *m, size_t offset) {
         /* Add offset to current container, unless this is the first
          * item in it, which will have the 0 offset, which we can
          * ignore. */
-        c = message_get_container(m);
+        c = message_get_last_container(m);
 
         if (!c->need_offsets)
                 return 0;
@@ -1360,7 +1367,7 @@ int message_append_basic(sd_bus_message *m, char type, const void *p, const void
         assert_return(bus_type_is_basic(type), -EINVAL);
         assert_return(!m->poisoned, -ESTALE);
 
-        c = message_get_container(m);
+        c = message_get_last_container(m);
 
         if (c->signature && c->signature[c->index]) {
                 /* Container signature is already set */
@@ -1553,7 +1560,7 @@ _public_ int sd_bus_message_append_string_space(
         assert_return(!m->sealed, -EPERM);
         assert_return(!m->poisoned, -ESTALE);
 
-        c = message_get_container(m);
+        c = message_get_last_container(m);
 
         if (c->signature && c->signature[c->index]) {
                 /* Container signature is already set */
@@ -1924,7 +1931,7 @@ _public_ int sd_bus_message_open_container(
                 char type,
                 const char *contents) {
 
-        struct bus_container *c, *w;
+        struct bus_container *c;
         uint32_t *array_size = NULL;
         _cleanup_free_ char *signature = NULL;
         size_t before, begin = 0;
@@ -1942,7 +1949,7 @@ _public_ int sd_bus_message_open_container(
                 return -ENOMEM;
         }
 
-        c = message_get_container(m);
+        c = message_get_last_container(m);
 
         signature = strdup(contents);
         if (!signature) {
@@ -1969,16 +1976,14 @@ _public_ int sd_bus_message_open_container(
                 return r;
 
         /* OK, let's fill it in */
-        w = m->containers + m->n_containers++;
-        w->enclosing = type;
-        w->signature = TAKE_PTR(signature);
-        w->index = 0;
-        w->array_size = array_size;
-        w->before = before;
-        w->begin = begin;
-        w->n_offsets = w->offsets_allocated = 0;
-        w->offsets = NULL;
-        w->need_offsets = need_offsets;
+        m->containers[m->n_containers++] = (struct bus_container) {
+                .enclosing = type,
+                .signature = TAKE_PTR(signature),
+                .array_size = array_size,
+                .before = before,
+                .begin = begin,
+                .need_offsets = need_offsets,
+        };
 
         return 0;
 }
@@ -2169,7 +2174,7 @@ _public_ int sd_bus_message_close_container(sd_bus_message *m) {
         assert_return(m->n_containers > 0, -EINVAL);
         assert_return(!m->poisoned, -ESTALE);
 
-        c = message_get_container(m);
+        c = message_get_last_container(m);
 
         if (c->enclosing != SD_BUS_TYPE_ARRAY)
                 if (c->signature && c->signature[c->index] != 0)
@@ -2439,11 +2444,6 @@ _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
         va_list ap;
         int r;
 
-        assert_return(m, -EINVAL);
-        assert_return(types, -EINVAL);
-        assert_return(!m->sealed, -EPERM);
-        assert_return(!m->poisoned, -ESTALE);
-
         va_start(ap, types);
         r = sd_bus_message_appendv(m, types, ap);
         va_end(ap);
@@ -2673,7 +2673,7 @@ _public_ int sd_bus_message_append_string_memfd(
         if (size > (uint64_t) (uint32_t) -1)
                 return -EINVAL;
 
-        c = message_get_container(m);
+        c = message_get_last_container(m);
         if (c->signature && c->signature[c->index]) {
                 /* Container signature is already set */
 
@@ -3006,7 +3006,7 @@ static bool message_end_of_signature(sd_bus_message *m) {
 
         assert(m);
 
-        c = message_get_container(m);
+        c = message_get_last_container(m);
         return !c->signature || c->signature[c->index] == 0;
 }
 
@@ -3015,7 +3015,7 @@ static bool message_end_of_array(sd_bus_message *m, size_t index) {
 
         assert(m);
 
-        c = message_get_container(m);
+        c = message_get_last_container(m);
         if (c->enclosing != SD_BUS_TYPE_ARRAY)
                 return false;
 
@@ -3110,6 +3110,7 @@ static int container_next_item(sd_bus_message *m, struct bus_container *c, size_
                         assert(alignment > 0);
 
                         *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
+                        assert(c->offsets[c->offset_index+1] >= *rindex);
                         c->item_size = c->offsets[c->offset_index+1] - *rindex;
                 } else {
 
@@ -3149,6 +3150,7 @@ static int container_next_item(sd_bus_message *m, struct bus_container *c, size_
                 assert(alignment > 0);
 
                 *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
+                assert(c->offsets[c->offset_index+1] >= *rindex);
                 c->item_size = c->offsets[c->offset_index+1] - *rindex;
 
                 c->offset_index++;
@@ -3276,7 +3278,7 @@ _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
         if (message_end_of_array(m, m->rindex))
                 return 0;
 
-        c = message_get_container(m);
+        c = message_get_last_container(m);
         if (c->signature[c->index] != type)
                 return -ENXIO;
 
@@ -3287,6 +3289,12 @@ _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
                 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) {
                         bool ok;
 
+                        /* D-Bus spec: The marshalling formats for the string-like types all end
+                         * with a single zero (NUL) byte, but that byte is not considered to be part
+                         * of the text. */
+                        if (c->item_size == 0)
+                                return -EBADMSG;
+
                         r = message_peek_body(m, &rindex, 1, c->item_size, &q);
                         if (r < 0)
                                 return r;
@@ -3381,6 +3389,10 @@ _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
                                 return r;
 
                         l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
+                        if (l == UINT32_MAX)
+                                /* avoid overflow right below */
+                                return -EBADMSG;
+
                         r = message_peek_body(m, &rindex, 1, l+1, &q);
                         if (r < 0)
                                 return r;
@@ -3403,6 +3415,10 @@ _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
                                 return r;
 
                         l = *(uint8_t*) q;
+                        if (l == UINT8_MAX)
+                                /* avoid overflow right below */
+                                return -EBADMSG;
+
                         r = message_peek_body(m, &rindex, 1, l+1, &q);
                         if (r < 0)
                                 return r;
@@ -3494,7 +3510,7 @@ static int bus_message_enter_array(
 
         size_t rindex;
         void *q;
-        int r, alignment;
+        int r;
 
         assert(m);
         assert(c);
@@ -3520,6 +3536,7 @@ static int bus_message_enter_array(
 
         if (!BUS_MESSAGE_IS_GVARIANT(m)) {
                 /* dbus1 */
+                int alignment;
 
                 r = message_peek_body(m, &rindex, 4, 4, &q);
                 if (r < 0)
@@ -3553,7 +3570,8 @@ static int bus_message_enter_array(
                 *n_offsets = 0;
 
         } else {
-                size_t where, p = 0, framing, sz;
+                size_t where, previous = 0, framing, sz;
+                int alignment;
                 unsigned i;
 
                 /* gvariant: variable length array */
@@ -3581,17 +3599,22 @@ static int bus_message_enter_array(
                 if (!*offsets)
                         return -ENOMEM;
 
+                alignment = bus_gvariant_get_alignment(c->signature);
+                assert(alignment > 0);
+
                 for (i = 0; i < *n_offsets; i++) {
-                        size_t x;
+                        size_t x, start;
+
+                        start = ALIGN_TO(previous, alignment);
 
                         x = bus_gvariant_read_word_le((uint8_t*) q + i * sz, sz);
                         if (x > c->item_size - sz)
                                 return -EBADMSG;
-                        if (x < p)
+                        if (x < start)
                                 return -EBADMSG;
 
                         (*offsets)[i] = rindex + x;
-                        p = x;
+                        previous = x;
                 }
 
                 *item_size = (*offsets)[0] - rindex;
@@ -3661,6 +3684,10 @@ static int bus_message_enter_variant(
                         return r;
 
                 l = *(uint8_t*) q;
+                if (l == UINT8_MAX)
+                        /* avoid overflow right below */
+                        return -EBADMSG;
+
                 r = message_peek_body(m, &rindex, 1, l+1, &q);
                 if (r < 0)
                         return r;
@@ -3689,7 +3716,7 @@ static int build_struct_offsets(
                 size_t *n_offsets) {
 
         unsigned n_variable = 0, n_total = 0, v;
-        size_t previous = 0, where;
+        size_t previous, where;
         const char *p;
         size_t sz;
         void *q;
@@ -3768,6 +3795,7 @@ static int build_struct_offsets(
 
         /* Second, loop again and build an offset table */
         p = signature;
+        previous = m->rindex;
         while (*p != 0) {
                 size_t n, offset;
                 int k;
@@ -3781,37 +3809,37 @@ static int build_struct_offsets(
                         memcpy(t, p, n);
                         t[n] = 0;
 
+                        size_t align = bus_gvariant_get_alignment(t);
+                        assert(align > 0);
+
+                        /* The possible start of this member after including alignment */
+                        size_t start = ALIGN_TO(previous, align);
+
                         k = bus_gvariant_get_size(t);
                         if (k < 0) {
                                 size_t x;
 
-                                /* variable size */
+                                /* Variable size */
                                 if (v > 0) {
                                         v--;
 
                                         x = bus_gvariant_read_word_le((uint8_t*) q + v*sz, sz);
                                         if (x >= size)
                                                 return -EBADMSG;
-                                        if (m->rindex + x < previous)
-                                                return -EBADMSG;
                                 } else
-                                        /* The last item's end
-                                         * is determined from
-                                         * the start of the
-                                         * offset array */
+                                        /* The last item's end is determined
+                                         * from the start of the offset array */
                                         x = size - (n_variable * sz);
 
                                 offset = m->rindex + x;
-
-                        } else {
-                                size_t align;
-
-                                /* fixed size */
-                                align = bus_gvariant_get_alignment(t);
-                                assert(align > 0);
-
-                                offset = (*n_offsets == 0 ? m->rindex  : ALIGN_TO((*offsets)[*n_offsets-1], align)) + k;
-                        }
+                                if (offset < start) {
+                                        log_debug("For type %s with alignment %zu, message specifies offset %zu which is smaller than previous end %zu + alignment = %zu",
+                                                  t, align, offset, previous, start);
+                                        return -EBADMSG;
+                                }
+                        } else
+                                /* Fixed size */
+                                offset = start + k;
                 }
 
                 previous = (*offsets)[(*n_offsets)++] = offset;
@@ -3941,10 +3969,10 @@ static int bus_message_enter_dict_entry(
 _public_ int sd_bus_message_enter_container(sd_bus_message *m,
                                             char type,
                                             const char *contents) {
-        struct bus_container *c, *w;
+        struct bus_container *c;
         uint32_t *array_size = NULL;
         _cleanup_free_ char *signature = NULL;
-        size_t before;
+        size_t before, end;
         _cleanup_free_ size_t *offsets = NULL;
         size_t n_offsets = 0, item_size = 0;
         int r;
@@ -4000,7 +4028,7 @@ _public_ int sd_bus_message_enter_container(sd_bus_message *m,
         if (message_end_of_array(m, m->rindex))
                 return 0;
 
-        c = message_get_container(m);
+        c = message_get_last_container(m);
 
         signature = strdup(contents);
         if (!signature)
@@ -4023,28 +4051,26 @@ _public_ int sd_bus_message_enter_container(sd_bus_message *m,
                 return r;
 
         /* OK, let's fill it in */
-        w = m->containers + m->n_containers++;
-        w->enclosing = type;
-        w->signature = TAKE_PTR(signature);
-        w->peeked_signature = NULL;
-        w->index = 0;
-
-        w->before = before;
-        w->begin = m->rindex;
-
-        /* Unary type has fixed size of 1, but virtual size of 0 */
         if (BUS_MESSAGE_IS_GVARIANT(m) &&
             type == SD_BUS_TYPE_STRUCT &&
             isempty(signature))
-                w->end = m->rindex + 0;
+                end = m->rindex + 0;
         else
-                w->end = m->rindex + c->item_size;
-
-        w->array_size = array_size;
-        w->item_size = item_size;
-        w->offsets = TAKE_PTR(offsets);
-        w->n_offsets = n_offsets;
-        w->offset_index = 0;
+                end = m->rindex + c->item_size;
+        
+        m->containers[m->n_containers++] = (struct bus_container) {
+                 .enclosing = type,
+                 .signature = TAKE_PTR(signature),
+
+                 .before = before,
+                 .begin = m->rindex,
+                 /* Unary type has fixed size of 1, but virtual size of 0 */
+                 .end = end,
+                 .array_size = array_size,
+                 .item_size = item_size,
+                 .offsets = TAKE_PTR(offsets),
+                 .n_offsets = n_offsets,
+        };
 
         return 1;
 }
@@ -4058,7 +4084,7 @@ _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
         assert_return(m->sealed, -EPERM);
         assert_return(m->n_containers > 0, -ENXIO);
 
-        c = message_get_container(m);
+        c = message_get_last_container(m);
 
         if (c->enclosing != SD_BUS_TYPE_ARRAY) {
                 if (c->signature && c->signature[c->index] != 0)
@@ -4077,13 +4103,9 @@ _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
                         return -EBUSY;
         }
 
-        free(c->signature);
-        free(c->peeked_signature);
-        free(c->offsets);
-        m->n_containers--;
-
-        c = message_get_container(m);
+        message_free_last_container(m);
 
+        c = message_get_last_container(m);
         saved = c->index;
         c->index = c->saved_index;
         r = container_next_item(m, c, &m->rindex);
@@ -4101,19 +4123,16 @@ static void message_quit_container(sd_bus_message *m) {
         assert(m->sealed);
         assert(m->n_containers > 0);
 
-        c = message_get_container(m);
-
         /* Undo seeks */
+        c = message_get_last_container(m);
         assert(m->rindex >= c->before);
         m->rindex = c->before;
 
         /* Free container */
-        free(c->signature);
-        free(c->offsets);
-        m->n_containers--;
+        message_free_last_container(m);
 
         /* Correct index of new top-level container */
-        c = message_get_container(m);
+        c = message_get_last_container(m);
         c->index = c->saved_index;
 }
 
@@ -4130,7 +4149,7 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char
         if (message_end_of_array(m, m->rindex))
                 goto eof;
 
-        c = message_get_container(m);
+        c = message_get_last_container(m);
 
         if (bus_type_is_basic(c->signature[c->index])) {
                 if (contents)
@@ -4144,20 +4163,20 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char
 
                 if (contents) {
                         size_t l;
-                        char *sig;
 
                         r = signature_element_length(c->signature+c->index+1, &l);
                         if (r < 0)
                                 return r;
 
-                        assert(l >= 1);
+                        /* signature_element_length does verification internally */
 
-                        sig = strndup(c->signature + c->index + 1, l);
-                        if (!sig)
+                        /* The array element must not be empty */
+                        assert(l >= 1);
+                        if (free_and_strndup(&c->peeked_signature,
+                                             c->signature + c->index + 1, l) < 0)
                                 return -ENOMEM;
 
-                        free(c->peeked_signature);
-                        *contents = c->peeked_signature = sig;
+                        *contents = c->peeked_signature;
                 }
 
                 if (type)
@@ -4170,19 +4189,17 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char
 
                 if (contents) {
                         size_t l;
-                        char *sig;
 
                         r = signature_element_length(c->signature+c->index, &l);
                         if (r < 0)
                                 return r;
 
-                        assert(l >= 2);
-                        sig = strndup(c->signature + c->index + 1, l - 2);
-                        if (!sig)
+                        assert(l >= 3);
+                        if (free_and_strndup(&c->peeked_signature,
+                                             c->signature + c->index + 1, l - 2) < 0)
                                 return -ENOMEM;
 
-                        free(c->peeked_signature);
-                        *contents = c->peeked_signature = sig;
+                        *contents = c->peeked_signature;
                 }
 
                 if (type)
@@ -4222,9 +4239,8 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char
                                 if (k > c->item_size)
                                         return -EBADMSG;
 
-                                free(c->peeked_signature);
-                                c->peeked_signature = strndup((char*) q + 1, k - 1);
-                                if (!c->peeked_signature)
+                                if (free_and_strndup(&c->peeked_signature,
+                                                     (char*) q + 1, k - 1) < 0)
                                         return -ENOMEM;
 
                                 if (!signature_is_valid(c->peeked_signature, true))
@@ -4240,6 +4256,10 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char
                                         return r;
 
                                 l = *(uint8_t*) q;
+                                if (l == UINT8_MAX)
+                                        /* avoid overflow right below */
+                                        return -EBADMSG;
+
                                 r = message_peek_body(m, &rindex, 1, l+1, &q);
                                 if (r < 0)
                                         return r;
@@ -4277,11 +4297,10 @@ _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
                 message_reset_containers(m);
                 m->rindex = 0;
 
-                c = message_get_container(m);
+                c = message_get_last_container(m);
         } else {
-                c = message_get_container(m);
+                c = message_get_last_container(m);
 
-                c->offset_index = 0;
                 c->index = 0;
                 m->rindex = c->begin;
         }
@@ -4496,10 +4515,6 @@ _public_ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
         va_list ap;
         int r;
 
-        assert_return(m, -EINVAL);
-        assert_return(m->sealed, -EPERM);
-        assert_return(types, -EINVAL);
-
         va_start(ap, types);
         r = sd_bus_message_readv(m, types, ap);
         va_end(ap);
@@ -4524,7 +4539,7 @@ _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) {
                 if (message_end_of_array(m, m->rindex))
                         return 0;
 
-                c = message_get_container(m);
+                c = message_get_last_container(m);
 
                 r = signature_element_length(c->signature + c->index, &l);
                 if (r < 0)
@@ -4690,7 +4705,7 @@ _public_ int sd_bus_message_read_array(
         if (r <= 0)
                 return r;
 
-        c = message_get_container(m);
+        c = message_get_last_container(m);
 
         if (BUS_MESSAGE_IS_GVARIANT(m)) {
                 align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
@@ -4827,6 +4842,10 @@ static int message_peek_field_string(
                 if (r < 0)
                         return r;
 
+                if (l == UINT32_MAX)
+                        /* avoid overflow right below */
+                        return -EBADMSG;
+
                 r = message_peek_fields(m, ri, 1, l+1, &q);
                 if (r < 0)
                         return r;
@@ -4878,6 +4897,10 @@ static int message_peek_field_signature(
                         return r;
 
                 l = *(uint8_t*) q;
+                if (l == UINT8_MAX)
+                        /* avoid overflow right below */
+                        return -EBADMSG;
+
                 r = message_peek_fields(m, ri, 1, l+1, &q);
                 if (r < 0)
                         return r;
@@ -4959,18 +4982,18 @@ static int message_skip_fields(
 
                 } else if (t == SD_BUS_TYPE_ARRAY) {
 
-                        r = signature_element_length(*signature+1, &l);
+                        r = signature_element_length(*signature + 1, &l);
                         if (r < 0)
                                 return r;
 
                         assert(l >= 1);
                         {
-                                char sig[l-1], *s;
+                                char sig[l + 1], *s = sig;
                                 uint32_t nas;
                                 int alignment;
 
-                                strncpy(sig, *signature + 1, l-1);
-                                s = sig;
+                                strncpy(sig, *signature + 1, l);
+                                sig[l] = '\0';
 
                                 alignment = bus_type_get_alignment(sig[0]);
                                 if (alignment < 0)
@@ -5014,9 +5037,9 @@ static int message_skip_fields(
 
                         assert(l >= 2);
                         {
-                                char sig[l-1], *s;
-                                strncpy(sig, *signature + 1, l-1);
-                                s = sig;
+                                char sig[l + 1], *s = sig;
+                                strncpy(sig, *signature + 1, l);
+                                sig[l] = '\0';
 
                                 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
                                 if (r < 0)
@@ -5025,7 +5048,7 @@ static int message_skip_fields(
 
                         *signature += l;
                 } else
-                        return -EINVAL;
+                        return -EBADMSG;
         }
 }
 
@@ -5056,25 +5079,21 @@ int bus_message_parse_fields(sd_bus_message *m) {
 
                         if (*p == 0) {
                                 size_t l;
-                                char *c;
 
                                 /* We found the beginning of the signature
                                  * string, yay! We require the body to be a
                                  * structure, so verify it and then strip the
                                  * opening/closing brackets. */
 
-                                l = ((char*) m->footer + m->footer_accessible) - p - (1 + sz);
+                                l = (char*) m->footer + m->footer_accessible - p - (1 + sz);
                                 if (l < 2 ||
                                     p[1] != SD_BUS_TYPE_STRUCT_BEGIN ||
                                     p[1 + l - 1] != SD_BUS_TYPE_STRUCT_END)
                                         return -EBADMSG;
 
-                                c = strndup(p + 1 + 1, l - 2);
-                                if (!c)
+                                if (free_and_strndup(&m->root_container.signature,
+                                                     p + 1 + 1, l - 2) < 0)
                                         return -ENOMEM;
-
-                                free(m->root_container.signature);
-                                m->root_container.signature = c;
                                 break;
                         }
 
@@ -5396,6 +5415,8 @@ int bus_message_parse_fields(sd_bus_message *m) {
                                 &m->root_container.item_size,
                                 &m->root_container.offsets,
                                 &m->root_container.n_offsets);
+                if (r == -EINVAL)
+                        return -EBADMSG;
                 if (r < 0)
                         return r;
         }
@@ -5591,7 +5612,7 @@ _public_ const char* sd_bus_message_get_signature(sd_bus_message *m, int complet
 
         assert_return(m, NULL);
 
-        c = complete ? &m->root_container : message_get_container(m);
+        c = complete ? &m->root_container : message_get_last_container(m);
         return strempty(c->signature);
 }
 
index 06ef1ee4cb2b5a36705f9a7ff6d52fe1e623f866..1ecd6e8b7efd7e8b95ca23da329cc23da5a82ddd 100644 (file)
@@ -56,6 +56,12 @@ static int signature_element_length_internal(
                         p += t;
                 }
 
+                if (p - s < 2)
+                        /* D-Bus spec: Empty structures are not allowed; there
+                         * must be at least one type code between the parentheses.
+                         */
+                        return -EINVAL;
+
                 *l = p - s + 1;
                 return 0;
         }
index 975d3f97dd9d03bf9956cadb48b26c27b6e70123..bea722ba06ed3edb3a079b360ab047136ef62a38 100644 (file)
@@ -10,6 +10,8 @@
 #include "refcnt.h"
 #include "tests.h"
 
+static bool use_system_bus = false;
+
 static void test_bus_new(void) {
         _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
 
@@ -22,8 +24,12 @@ static int test_bus_open(void) {
         int r;
 
         r = sd_bus_open_user(&bus);
-        if (IN_SET(r, -ECONNREFUSED, -ENOENT))
-                return r;
+        if (IN_SET(r, -ECONNREFUSED, -ENOENT)) {
+                r = sd_bus_open_system(&bus);
+                if (IN_SET(r, -ECONNREFUSED, -ENOENT))
+                        return r;
+                use_system_bus = true;
+        }
 
         assert_se(r >= 0);
         printf("after open: refcount %u\n", REFCNT_GET(bus->n_ref));
@@ -35,7 +41,7 @@ static void test_bus_new_method_call(void) {
         sd_bus *bus = NULL;
         _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
 
-        assert_se(sd_bus_open_user(&bus) >= 0);
+        assert_se(use_system_bus ? sd_bus_open_system(&bus) >= 0 : sd_bus_open_user(&bus) >= 0);
 
         assert_se(sd_bus_message_new_method_call(bus, &m, "a.service.name", "/an/object/path", "an.interface.name", "AMethodName") >= 0);
 
@@ -49,7 +55,7 @@ static void test_bus_new_signal(void) {
         sd_bus *bus = NULL;
         _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
 
-        assert_se(sd_bus_open_user(&bus) >= 0);
+        assert_se(use_system_bus ? sd_bus_open_system(&bus) >= 0 : sd_bus_open_user(&bus) >= 0);
 
         assert_se(sd_bus_message_new_signal(bus, &m, "/an/object/path", "an.interface.name", "Name") >= 0);
 
index ae418efa8b34c6fb3f3b69cb1a252ac4c55b1526..1a9a35d56b469a27427ca22dc1722cd831d2fb47 100644 (file)
 #include "util.h"
 
 static void test_bus_gvariant_is_fixed_size(void) {
+        log_info("/* %s */", __func__);
+
         assert_se(bus_gvariant_is_fixed_size("") > 0);
-        assert_se(bus_gvariant_is_fixed_size("()") > 0);
+        assert_se(bus_gvariant_is_fixed_size("()") == -EINVAL);
         assert_se(bus_gvariant_is_fixed_size("y") > 0);
         assert_se(bus_gvariant_is_fixed_size("u") > 0);
         assert_se(bus_gvariant_is_fixed_size("b") > 0);
@@ -42,8 +44,10 @@ static void test_bus_gvariant_is_fixed_size(void) {
 }
 
 static void test_bus_gvariant_get_size(void) {
+        log_info("/* %s */", __func__);
+
         assert_se(bus_gvariant_get_size("") == 0);
-        assert_se(bus_gvariant_get_size("()") == 1);
+        assert_se(bus_gvariant_get_size("()") == -EINVAL);
         assert_se(bus_gvariant_get_size("y") == 1);
         assert_se(bus_gvariant_get_size("u") == 4);
         assert_se(bus_gvariant_get_size("b") == 1);
@@ -74,8 +78,10 @@ static void test_bus_gvariant_get_size(void) {
 }
 
 static void test_bus_gvariant_get_alignment(void) {
+        log_info("/* %s */", __func__);
+
         assert_se(bus_gvariant_get_alignment("") == 1);
-        assert_se(bus_gvariant_get_alignment("()") == 1);
+        assert_se(bus_gvariant_get_alignment("()") == -EINVAL);
         assert_se(bus_gvariant_get_alignment("y") == 1);
         assert_se(bus_gvariant_get_alignment("b") == 1);
         assert_se(bus_gvariant_get_alignment("u") == 4);
@@ -122,12 +128,17 @@ static int test_marshal(void) {
         int r;
 
         r = sd_bus_open_user(&bus);
+        if (r < 0)
+                r = sd_bus_open_system(&bus);
         if (r < 0)
                 return log_tests_skipped_errno(r, "Failed to connect to bus");
 
         bus->message_version = 2; /* dirty hack to enable gvariant */
 
-        assert_se(sd_bus_message_new_method_call(bus, &m, "a.service.name", "/an/object/path/which/is/really/really/long/so/that/we/hit/the/eight/bit/boundary/by/quite/some/margin/to/test/this/stuff/that/it/really/works", "an.interface.name", "AMethodName") >= 0);
+        r = sd_bus_message_new_method_call(bus, &m, "a.service.name",
+                                           "/an/object/path/which/is/really/really/long/so/that/we/hit/the/eight/bit/boundary/by/quite/some/margin/to/test/this/stuff/that/it/really/works",
+                                           "an.interface.name", "AMethodName");
+        assert_se(r >= 0);
 
         assert_cc(sizeof(struct bus_header) == 16);
 
@@ -200,7 +211,7 @@ static int test_marshal(void) {
 }
 
 int main(int argc, char *argv[]) {
-        test_setup_logging(LOG_INFO);
+        test_setup_logging(LOG_DEBUG);
 
         test_bus_gvariant_is_fixed_size();
         test_bus_gvariant_get_size();
index 7e113b179e0e06e274731cca9f99ab4dd3bd41ca..d1c674b223afcdcf587d5234ab69d25c9214ceac 100644 (file)
@@ -18,8 +18,8 @@
 #include "bus-label.h"
 #include "bus-message.h"
 #include "bus-util.h"
+#include "escape.h"
 #include "fd-util.h"
-#include "hexdecoct.h"
 #include "log.h"
 #include "tests.h"
 #include "util.h"
@@ -111,7 +111,7 @@ int main(int argc, char *argv[]) {
         uint8_t u, v;
         void *buffer = NULL;
         size_t sz;
-        char *h;
+        _cleanup_free_ char *h = NULL;
         const int32_t integer_array[] = { -1, -2, 0, 1, 2 }, *return_array;
         char *s;
         _cleanup_free_ char *first = NULL, *second = NULL, *third = NULL;
@@ -124,6 +124,8 @@ int main(int argc, char *argv[]) {
         test_setup_logging(LOG_INFO);
 
         r = sd_bus_default_user(&bus);
+        if (r < 0)
+                r = sd_bus_default_system(&bus);
         if (r < 0)
                 return log_tests_skipped("Failed to connect to bus");
 
@@ -152,7 +154,7 @@ int main(int argc, char *argv[]) {
         assert_se(r >= 0);
 
         r = sd_bus_message_append(m, "()");
-        assert_se(r >= 0);
+        assert_se(r == -EINVAL);
 
         r = sd_bus_message_append(m, "ba(ss)", 255, 3, "aaa", "1", "bbb", "2", "ccc", "3");
         assert_se(r >= 0);
@@ -195,11 +197,9 @@ int main(int argc, char *argv[]) {
         r = bus_message_get_blob(m, &buffer, &sz);
         assert_se(r >= 0);
 
-        h = hexmem(buffer, sz);
+        h = cescape_length(buffer, sz);
         assert_se(h);
-
         log_info("message size = %zu, contents =\n%s", sz, h);
-        free(h);
 
 #if HAVE_GLIB
 #ifndef __SANITIZE_ADDRESS__
@@ -296,7 +296,7 @@ int main(int argc, char *argv[]) {
         assert_se(v == 10);
 
         r = sd_bus_message_read(m, "()");
-        assert_se(r > 0);
+        assert_se(r < 0);
 
         r = sd_bus_message_read(m, "ba(ss)", &boolean, 3, &x, &y, &a, &b, &c, &d);
         assert_se(r > 0);
@@ -377,7 +377,7 @@ int main(int argc, char *argv[]) {
 
         assert_se(sd_bus_message_verify_type(m, 'a', "{yv}") > 0);
 
-        r = sd_bus_message_skip(m, "a{yv}y(ty)y(yt)y()");
+        r = sd_bus_message_skip(m, "a{yv}y(ty)y(yt)y");
         assert_se(r >= 0);
 
         assert_se(sd_bus_message_verify_type(m, 'b', NULL) > 0);
index c56b39437bccf89352bcb86763c95a373ea169fc..0949d8dee67bf80fdbeb67569706de330e020d7b 100644 (file)
@@ -81,6 +81,8 @@ int main(int argc, char *argv[]) {
         test_setup_logging(LOG_INFO);
 
         r = sd_bus_open_user(&bus);
+        if (r < 0)
+                r = sd_bus_open_system(&bus);
         if (r < 0)
                 return log_tests_skipped("Failed to connect to bus");
 
index ab59d04e20a03d06f494063ba2adb7f1f6491f95..84648dbc2aef92d774055c780b86fe50574af9e5 100644 (file)
@@ -14,9 +14,9 @@ int main(int argc, char *argv[]) {
         assert_se(signature_is_single("v", false));
         assert_se(signature_is_single("as", false));
         assert_se(signature_is_single("(ss)", false));
-        assert_se(signature_is_single("()", false));
-        assert_se(signature_is_single("(()()()()())", false));
-        assert_se(signature_is_single("(((())))", false));
+        assert_se(!signature_is_single("()", false));
+        assert_se(!signature_is_single("(()()()()())", false));
+        assert_se(!signature_is_single("(((())))", false));
         assert_se(signature_is_single("((((s))))", false));
         assert_se(signature_is_single("{ss}", true));
         assert_se(signature_is_single("a{ss}", false));
@@ -61,7 +61,7 @@ int main(int argc, char *argv[]) {
         assert_se(signature_is_valid("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaas", false));
         assert_se(!signature_is_valid("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaau", false));
 
-        assert_se(signature_is_valid("(((((((((((((((((((((((((((((((())))))))))))))))))))))))))))))))", false));
+        assert_se(signature_is_valid("((((((((((((((((((((((((((((((((s))))))))))))))))))))))))))))))))", false));
         assert_se(!signature_is_valid("((((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))))))", false));
 
         assert_se(namespace_complex_pattern("", ""));
index a2782cd1d50a330c29eb403de8bf955aef21fb1d..68a0010368833fc55180ee6795cc5ba807616872 100644 (file)
@@ -45,6 +45,7 @@ int main(int argc, char *argv[]) {
         _cleanup_(sd_event_unrefp) sd_event *event = NULL;
         _cleanup_(sd_bus_track_unrefp) sd_bus_track *x = NULL, *y = NULL;
         _cleanup_(sd_bus_unrefp) sd_bus *a = NULL, *b = NULL;
+        bool use_system_bus = false;
         const char *unique;
         int r;
 
@@ -54,14 +55,21 @@ int main(int argc, char *argv[]) {
         assert_se(r >= 0);
 
         r = sd_bus_open_user(&a);
-        if (IN_SET(r, -ECONNREFUSED, -ENOENT))
-                return log_tests_skipped("Failed to connect to bus");
+        if (IN_SET(r, -ECONNREFUSED, -ENOENT)) {
+                r = sd_bus_open_system(&a);
+                if (IN_SET(r, -ECONNREFUSED, -ENOENT))
+                        return log_tests_skipped("Failed to connect to bus");
+                use_system_bus = true;
+        }
         assert_se(r >= 0);
 
         r = sd_bus_attach_event(a, event, SD_EVENT_PRIORITY_NORMAL);
         assert_se(r >= 0);
 
-        r = sd_bus_open_user(&b);
+        if (use_system_bus)
+                r = sd_bus_open_system(&b);
+        else
+                r = sd_bus_open_user(&b);
         assert_se(r >= 0);
 
         r = sd_bus_attach_event(b, event, SD_EVENT_PRIORITY_NORMAL);
diff --git a/src/libsystemd/sd-device/test-sd-device.c b/src/libsystemd/sd-device/test-sd-device.c
new file mode 100644 (file)
index 0000000..fc2d02b
--- /dev/null
@@ -0,0 +1,71 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include "device-enumerator-private.h"
+#include "device-private.h"
+#include "device-util.h"
+#include "string-util.h"
+#include "tests.h"
+#include "util.h"
+
+static void test_sd_device_basic(void) {
+        _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
+        sd_device *d;
+
+        assert_se(sd_device_enumerator_new(&e) >= 0);
+        assert_se(sd_device_enumerator_allow_uninitialized(e) >= 0);
+        FOREACH_DEVICE(e, d) {
+                const char *syspath, *devpath, *subsystem, *val;
+                dev_t devnum;
+                usec_t usec;
+                int i, r;
+
+                assert_se(sd_device_get_syspath(d, &syspath) >= 0);
+
+                r = sd_device_get_subsystem(d, &subsystem);
+                assert_se(r >= 0 || r == -ENOENT);
+
+                r = sd_device_get_devtype(d, &val);
+                assert_se(r >= 0 || r == -ENOENT);
+
+                r = sd_device_get_devnum(d, &devnum);
+                assert_se(r >= 0 || r == -ENOENT);
+
+                r = sd_device_get_ifindex(d, &i);
+                assert_se(r >= 0 || r == -ENOENT);
+
+                r = sd_device_get_driver(d, &val);
+                assert_se(r >= 0 || r == -ENOENT);
+
+                assert_se(sd_device_get_devpath(d, &devpath) >= 0);
+
+                r = sd_device_get_devname(d, &val);
+                assert_se(r >= 0 || r == -ENOENT);
+
+                assert_se(sd_device_get_sysname(d, &val) >= 0);
+
+                r = sd_device_get_sysnum(d, &val);
+                assert_se(r >= 0 || r == -ENOENT);
+
+                i = 0;
+                assert_se(sd_device_get_is_initialized(d, &i) >= 0);
+                if (i > 0) {
+                        r = sd_device_get_usec_since_initialized(d, &usec);
+                        assert_se(r >= 0 || r == -ENODATA);
+                }
+
+                r = sd_device_get_sysattr_value(d, "name_assign_type", &val);
+                assert_se(r >= 0 || IN_SET(r, -ENOENT, -EINVAL));
+
+                r = sd_device_get_property_value(d, "ID_NET_DRIVER", &val);
+                assert_se(r >= 0 || r == -ENOENT);
+
+                log_debug("syspath:%s devpath:%s subsystem:%s", syspath, devpath, strempty(subsystem));
+        }
+}
+
+int main(int argc, char **argv) {
+        test_setup_logging(LOG_INFO);
+
+        test_sd_device_basic();
+        return 0;
+}
index 6d55a98ed7d86c76c96ebd764d1c46078491d238..880e127686f37290a4badb8cb66b284328541d7a 100644 (file)
@@ -950,7 +950,7 @@ static void source_disconnect(sd_event_source *s) {
                          * continued to being watched. That's because inotify doesn't really have an API for that: we
                          * can only change watch masks with access to the original inode either by fd or by path. But
                          * paths aren't stable, and keeping an O_PATH fd open all the time would mean wasting an fd
-                         * continously and keeping the mount busy which we can't really do. We could reconstruct the
+                         * continuously and keeping the mount busy which we can't really do. We could reconstruct the
                          * original inode from /proc/self/fdinfo/$INOTIFY_FD (as all watch descriptors are listed
                          * there), but given the need for open_by_handle_at() which is privileged and not universally
                          * available this would be quite an incomplete solution. Hence we go the other way, leave the
@@ -999,6 +999,7 @@ static void source_free(sd_event_source *s) {
         free(s->description);
         free(s);
 }
+DEFINE_TRIVIAL_CLEANUP_FUNC(sd_event_source*, source_free);
 
 static int source_set_pending(sd_event_source *s, bool b) {
         int r;
@@ -1092,7 +1093,7 @@ _public_ int sd_event_add_io(
                 sd_event_io_handler_t callback,
                 void *userdata) {
 
-        sd_event_source *s;
+        _cleanup_(source_freep) sd_event_source *s = NULL;
         int r;
 
         assert_return(e, -EINVAL);
@@ -1115,13 +1116,12 @@ _public_ int sd_event_add_io(
         s->enabled = SD_EVENT_ON;
 
         r = source_io_register(s, s->enabled, events);
-        if (r < 0) {
-                source_free(s);
+        if (r < 0)
                 return r;
-        }
 
         if (ret)
                 *ret = s;
+        TAKE_PTR(s);
 
         return 0;
 }
@@ -1130,7 +1130,7 @@ static void initialize_perturb(sd_event *e) {
         sd_id128_t bootid = {};
 
         /* When we sleep for longer, we try to realign the wakeup to
-           the same time wihtin each minute/second/250ms, so that
+           the same time within each minute/second/250ms, so that
            events all across the system can be coalesced into a single
            CPU wakeup. However, let's take some system-specific
            randomness for this value, so that in a network of systems
@@ -1196,7 +1196,7 @@ _public_ int sd_event_add_time(
                 void *userdata) {
 
         EventSourceType type;
-        sd_event_source *s;
+        _cleanup_(source_freep) sd_event_source *s = NULL;
         struct clock_data *d;
         int r;
 
@@ -1248,20 +1248,17 @@ _public_ int sd_event_add_time(
 
         r = prioq_put(d->earliest, s, &s->time.earliest_index);
         if (r < 0)
-                goto fail;
+                return r;
 
         r = prioq_put(d->latest, s, &s->time.latest_index);
         if (r < 0)
-                goto fail;
+                return r;
 
         if (ret)
                 *ret = s;
+        TAKE_PTR(s);
 
         return 0;
-
-fail:
-        source_free(s);
-        return r;
 }
 
 static int signal_exit_callback(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
@@ -1277,7 +1274,7 @@ _public_ int sd_event_add_signal(
                 sd_event_signal_handler_t callback,
                 void *userdata) {
 
-        sd_event_source *s;
+        _cleanup_(source_freep) sd_event_source *s = NULL;
         struct signal_data *d;
         sigset_t ss;
         int r;
@@ -1317,16 +1314,15 @@ _public_ int sd_event_add_signal(
         e->signal_sources[sig] = s;
 
         r = event_make_signal_data(e, sig, &d);
-        if (r < 0) {
-                source_free(s);
+        if (r < 0)
                 return r;
-        }
 
         /* Use the signal name as description for the event source by default */
         (void) sd_event_source_set_description(s, signal_to_string(sig));
 
         if (ret)
                 *ret = s;
+        TAKE_PTR(s);
 
         return 0;
 }
@@ -1339,7 +1335,7 @@ _public_ int sd_event_add_child(
                 sd_event_child_handler_t callback,
                 void *userdata) {
 
-        sd_event_source *s;
+        _cleanup_(source_freep) sd_event_source *s = NULL;
         int r;
 
         assert_return(e, -EINVAL);
@@ -1369,17 +1365,14 @@ _public_ int sd_event_add_child(
         s->enabled = SD_EVENT_ONESHOT;
 
         r = hashmap_put(e->child_sources, PID_TO_PTR(pid), s);
-        if (r < 0) {
-                source_free(s);
+        if (r < 0)
                 return r;
-        }
 
         e->n_enabled_child_sources++;
 
         r = event_make_signal_data(e, SIGCHLD, NULL);
         if (r < 0) {
                 e->n_enabled_child_sources--;
-                source_free(s);
                 return r;
         }
 
@@ -1387,6 +1380,7 @@ _public_ int sd_event_add_child(
 
         if (ret)
                 *ret = s;
+        TAKE_PTR(s);
 
         return 0;
 }
@@ -1397,7 +1391,7 @@ _public_ int sd_event_add_defer(
                 sd_event_handler_t callback,
                 void *userdata) {
 
-        sd_event_source *s;
+        _cleanup_(source_freep) sd_event_source *s = NULL;
         int r;
 
         assert_return(e, -EINVAL);
@@ -1415,13 +1409,12 @@ _public_ int sd_event_add_defer(
         s->enabled = SD_EVENT_ONESHOT;
 
         r = source_set_pending(s, true);
-        if (r < 0) {
-                source_free(s);
+        if (r < 0)
                 return r;
-        }
 
         if (ret)
                 *ret = s;
+        TAKE_PTR(s);
 
         return 0;
 }
@@ -1432,7 +1425,7 @@ _public_ int sd_event_add_post(
                 sd_event_handler_t callback,
                 void *userdata) {
 
-        sd_event_source *s;
+        _cleanup_(source_freep) sd_event_source *s = NULL;
         int r;
 
         assert_return(e, -EINVAL);
@@ -1454,13 +1447,12 @@ _public_ int sd_event_add_post(
         s->enabled = SD_EVENT_ON;
 
         r = set_put(e->post_sources, s);
-        if (r < 0) {
-                source_free(s);
+        if (r < 0)
                 return r;
-        }
 
         if (ret)
                 *ret = s;
+        TAKE_PTR(s);
 
         return 0;
 }
@@ -1471,7 +1463,7 @@ _public_ int sd_event_add_exit(
                 sd_event_handler_t callback,
                 void *userdata) {
 
-        sd_event_source *s;
+        _cleanup_(source_freep) sd_event_source *s = NULL;
         int r;
 
         assert_return(e, -EINVAL);
@@ -1494,13 +1486,12 @@ _public_ int sd_event_add_exit(
         s->enabled = SD_EVENT_ONESHOT;
 
         r = prioq_put(s->event->exit, s, &s->exit.prioq_index);
-        if (r < 0) {
-                source_free(s);
+        if (r < 0)
                 return r;
-        }
 
         if (ret)
                 *ret = s;
+        TAKE_PTR(s);
 
         return 0;
 }
@@ -1755,7 +1746,7 @@ static uint32_t inode_data_determine_mask(struct inode_data *d) {
          *
          * Note that we add all sources to the mask here, regardless whether enabled, disabled or oneshot. That's
          * because we cannot change the mask anymore after the event source was created once, since the kernel has no
-         * API for that. Hence we need to subscribe to the maximum mask we ever might be interested in, and supress
+         * API for that. Hence we need to subscribe to the maximum mask we ever might be interested in, and suppress
          * events we don't care for client-side. */
 
         LIST_FOREACH(inotify.by_inode_data, s, d->event_sources) {
@@ -1817,11 +1808,10 @@ _public_ int sd_event_add_inotify(
                 sd_event_inotify_handler_t callback,
                 void *userdata) {
 
-        bool rm_inotify = false, rm_inode = false;
         struct inotify_data *inotify_data = NULL;
         struct inode_data *inode_data = NULL;
         _cleanup_close_ int fd = -1;
-        sd_event_source *s;
+        _cleanup_(source_freep) sd_event_source *s = NULL;
         struct stat st;
         int r;
 
@@ -1859,13 +1849,13 @@ _public_ int sd_event_add_inotify(
         /* Allocate an inotify object for this priority, and an inode object within it */
         r = event_make_inotify_data(e, SD_EVENT_PRIORITY_NORMAL, &inotify_data);
         if (r < 0)
-                goto fail;
-        rm_inotify = r > 0;
+                return r;
 
         r = event_make_inode_data(e, inotify_data, st.st_dev, st.st_ino, &inode_data);
-        if (r < 0)
-                goto fail;
-        rm_inode = r > 0;
+        if (r < 0) {
+                event_free_inotify_data(e, inotify_data);
+                return r;
+        }
 
         /* Keep the O_PATH fd around until the first iteration of the loop, so that we can still change the priority of
          * the event source, until then, for which we need the original inode. */
@@ -1878,30 +1868,18 @@ _public_ int sd_event_add_inotify(
         LIST_PREPEND(inotify.by_inode_data, inode_data->event_sources, s);
         s->inotify.inode_data = inode_data;
 
-        rm_inode = rm_inotify = false;
-
         /* Actually realize the watch now */
         r = inode_data_realize_watch(e, inode_data);
         if (r < 0)
-                goto fail;
+                return r;
 
         (void) sd_event_source_set_description(s, path);
 
         if (ret)
                 *ret = s;
+        TAKE_PTR(s);
 
         return 0;
-
-fail:
-        source_free(s);
-
-        if (rm_inode)
-                event_free_inode_data(e, inode_data);
-
-        if (rm_inotify)
-                event_free_inotify_data(e, inotify_data);
-
-        return r;
 }
 
 static sd_event_source* event_source_free(sd_event_source *s) {
index 9d93732d7e524482c572d285bc0b7f624d4fda52..b7cca832d87a9c4474613dfc847652a5ec0b562f 100644 (file)
@@ -284,19 +284,15 @@ _public_ int sd_id128_randomize(sd_id128_t *ret) {
         return 0;
 }
 
-_public_ int sd_id128_get_machine_app_specific(sd_id128_t app_id, sd_id128_t *ret) {
+static int get_app_specific(sd_id128_t base, sd_id128_t app_id, sd_id128_t *ret) {
         _cleanup_(khash_unrefp) khash *h = NULL;
-        sd_id128_t m, result;
+        sd_id128_t result;
         const void *p;
         int r;
 
-        assert_return(ret, -EINVAL);
-
-        r = sd_id128_get_machine(&m);
-        if (r < 0)
-                return r;
+        assert(ret);
 
-        r = khash_new_with_key(&h, "hmac(sha256)", &m, sizeof(m));
+        r = khash_new_with_key(&h, "hmac(sha256)", &base, sizeof(base));
         if (r < 0)
                 return r;
 
@@ -314,3 +310,29 @@ _public_ int sd_id128_get_machine_app_specific(sd_id128_t app_id, sd_id128_t *re
         *ret = make_v4_uuid(result);
         return 0;
 }
+
+_public_ int sd_id128_get_machine_app_specific(sd_id128_t app_id, sd_id128_t *ret) {
+        sd_id128_t id;
+        int r;
+
+        assert_return(ret, -EINVAL);
+
+        r = sd_id128_get_machine(&id);
+        if (r < 0)
+                return r;
+
+        return get_app_specific(id, app_id, ret);
+}
+
+_public_ int sd_id128_get_boot_app_specific(sd_id128_t app_id, sd_id128_t *ret) {
+        sd_id128_t id;
+        int r;
+
+        assert_return(ret, -EINVAL);
+
+        r = sd_id128_get_boot(&id);
+        if (r < 0)
+                return r;
+
+        return get_app_specific(id, app_id, ret);
+}
index 518d3e8f1ff52ba58f6096b1a1f1faa8c3b6a22a..82f49e5ac07f11f17838e87208ec3aa3ea7b386e 100644 (file)
 
 static int dhcp6_lease_address_acquired(sd_dhcp6_client *client, Link *link);
 
-static bool dhcp6_verify_link(Link *link) {
-        if (!link->network) {
-                log_link_info(link, "Link is not managed by us");
+static bool dhcp6_get_prefix_delegation(Link *link) {
+        if (!link->network)
                 return false;
-        }
 
         if (!IN_SET(link->network->router_prefix_delegation,
                             RADV_PREFIX_DELEGATION_DHCP6,
                             RADV_PREFIX_DELEGATION_BOTH)) {
-                log_link_debug(link, "Link does not request DHCPv6 prefix delegation");
                 return false;
         }
 
@@ -50,7 +47,7 @@ static bool dhcp6_enable_prefix_delegation(Link *dhcp6_link) {
                 if (l == dhcp6_link)
                         continue;
 
-                if (!dhcp6_verify_link(l))
+                if (!dhcp6_get_prefix_delegation(l))
                         continue;
 
                 return true;
@@ -134,7 +131,7 @@ int dhcp6_lease_pd_prefix_lost(sd_dhcp6_client *client, Link* link) {
                                      &lifetime_preferred,
                                      &lifetime_valid) >= 0) {
                 _cleanup_free_ char *buf = NULL;
-                _cleanup_free_ Route *route;
+                _cleanup_free_ Route *route = NULL;
 
                 if (pd_prefix_len > 64)
                         continue;
@@ -163,7 +160,7 @@ int dhcp6_lease_pd_prefix_lost(sd_dhcp6_client *client, Link* link) {
                                 log_link_warning_errno(link, r, "Cannot delete unreachable route for DHCPv6 delegated subnet %s/%u: %m",
                                                        strnull(buf),
                                                        pd_prefix_len);
-                                route_free(route);
+
                                 continue;
                         }
                         link = link_ref(link);
@@ -217,7 +214,7 @@ static int dhcp6_pd_prefix_distribute(Link *dhcp6_link, Iterator *i,
                 if (link == dhcp6_link)
                         continue;
 
-                if (!dhcp6_verify_link(link))
+                if (!dhcp6_get_prefix_delegation(link))
                         continue;
 
                 assigned_link = manager_dhcp6_prefix_get(manager, &prefix.in6);
@@ -349,6 +346,70 @@ static int dhcp6_lease_pd_prefix_acquired(sd_dhcp6_client *client, Link *link) {
         return 0;
 }
 
+int dhcp6_request_prefix_delegation(Link *link) {
+        Link *l;
+        Iterator i;
+
+        assert_return(link, -EINVAL);
+        assert_return(link->manager, -EOPNOTSUPP);
+
+        if (dhcp6_get_prefix_delegation(link) <= 0)
+                return 0;
+
+        log_link_debug(link, "Requesting DHCPv6 prefixes to be delegated for new link");
+
+        HASHMAP_FOREACH(l, link->manager->links, i) {
+                int r, enabled;
+
+                if (l == link)
+                        continue;
+
+                if (!l->dhcp6_client)
+                        continue;
+
+                r = sd_dhcp6_client_get_prefix_delegation(l->dhcp6_client, &enabled);
+                if (r < 0) {
+                        log_link_warning_errno(l, r, "Cannot get prefix delegation when adding new link");
+                        continue;
+                }
+
+                if (enabled == 0) {
+                        r = sd_dhcp6_client_set_prefix_delegation(l->dhcp6_client, 1);
+                        if (r < 0) {
+                                log_link_warning_errno(l, r, "Cannot enable prefix delegation when adding new link");
+                                continue;
+                        }
+                }
+
+                r = sd_dhcp6_client_is_running(l->dhcp6_client);
+                if (r <= 0)
+                        continue;
+
+                if (enabled != 0) {
+                        log_link_debug(l, "Requesting re-assignment of delegated prefixes after adding new link");
+                        (void) dhcp6_lease_pd_prefix_acquired(l->dhcp6_client, l);
+
+                        continue;
+                }
+
+                r = sd_dhcp6_client_stop(l->dhcp6_client);
+                if (r < 0) {
+                        log_link_warning_errno(l, r, "Cannot stop DHCPv6 prefix delegation client after adding new link");
+                        continue;
+                }
+
+                r = sd_dhcp6_client_start(l->dhcp6_client);
+                if (r < 0) {
+                        log_link_warning_errno(l, r, "Cannot restart DHCPv6 prefix delegation client after adding new link");
+                        continue;
+                }
+
+                log_link_debug(l, "Restarted DHCPv6 client to acquire prefix delegations after adding new link");
+        }
+
+        return 0;
+}
+
 static int dhcp6_address_handler(sd_netlink *rtnl, sd_netlink_message *m,
                                  void *userdata) {
         _cleanup_(link_unrefp) Link *link = userdata;
index 9b555984826a6a2738d3a58730ed8d5442feef44..d7f8ad3040ed21e545b71070ef091cf71782c6f1 100644 (file)
@@ -1629,18 +1629,6 @@ static int link_acquire_ipv6_conf(Link *link) {
 
         assert(link);
 
-        if (link_dhcp6_enabled(link)) {
-                assert(link->dhcp6_client);
-                assert(in_addr_is_link_local(AF_INET6, (const union in_addr_union*)&link->ipv6ll_address) > 0);
-
-                /* start DHCPv6 client in stateless mode */
-                r = dhcp6_request_address(link, true);
-                if (r < 0 && r != -EBUSY)
-                        return log_link_warning_errno(link, r,  "Could not acquire DHCPv6 lease: %m");
-                else
-                        log_link_debug(link, "Acquiring DHCPv6 lease");
-        }
-
         if (link_ipv6_accept_ra_enabled(link)) {
                 assert(link->ndisc);
 
@@ -1662,6 +1650,8 @@ static int link_acquire_ipv6_conf(Link *link) {
                         return log_link_warning_errno(link, r, "Could not start IPv6 Router Advertisement: %m");
         }
 
+        (void) dhcp6_request_prefix_delegation(link);
+
         return 0;
 }
 
index b686011da405a773aff61d7a21a1be9e42b5cc55..033cca15762e8c917aa946371e8cb913704c614b 100644 (file)
@@ -163,6 +163,7 @@ int ipv4ll_configure(Link *link);
 int dhcp4_configure(Link *link);
 int dhcp4_set_client_identifier(Link *link);
 int dhcp4_set_promote_secondaries(Link *link);
+int dhcp6_request_prefix_delegation(Link *link);
 int dhcp6_configure(Link *link);
 int dhcp6_request_address(Link *link, int ir);
 int dhcp6_lease_pd_prefix_lost(sd_dhcp6_client *client, Link* link);
index bdb1aacf7fdf9d42c3f6d6f8fe24a61775cd2f0d..a949f746c9f7168cb49c7d2ace6ad98e78b616c2 100644 (file)
@@ -718,7 +718,7 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, voi
         union in_addr_union to = {}, from = {};
         RoutingPolicyRule *rule = NULL;
         uint32_t fwmark = 0, table = 0;
-        char *iif = NULL, *oif = NULL;
+        const char *iif = NULL, *oif = NULL;
         Manager *m = userdata;
         uint16_t type;
         int family;
@@ -834,13 +834,13 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, voi
                 return 0;
         }
 
-        r = sd_netlink_message_read_string(message, FRA_IIFNAME, (const char **) &iif);
+        r = sd_netlink_message_read_string(message, FRA_IIFNAME, &iif);
         if (r < 0 && r != -ENODATA) {
                 log_warning_errno(r, "rtnl: could not get FRA_IIFNAME attribute, ignoring: %m");
                 return 0;
         }
 
-        r = sd_netlink_message_read_string(message, FRA_OIFNAME, (const char **) &oif);
+        r = sd_netlink_message_read_string(message, FRA_OIFNAME, &oif);
         if (r < 0 && r != -ENODATA) {
                 log_warning_errno(r, "rtnl: could not get FRA_OIFNAME attribute, ignoring: %m");
                 return 0;
@@ -1470,9 +1470,8 @@ void manager_free(Manager *m) {
         while ((pool = m->address_pools))
                 address_pool_free(pool);
 
-        set_free(m->rules);
-        set_free(m->rules_foreign);
-
+        set_free_with_destructor(m->rules, routing_policy_rule_free);
+        set_free_with_destructor(m->rules_foreign, routing_policy_rule_free);
         set_free_with_destructor(m->rules_saved, routing_policy_rule_free);
 
         sd_netlink_unref(m->rtnl);
index a7c94d1dc49143812adbe65f5b6a59c9a875f84f..ac924596f3df4dd1bce2805ee4782884f69b983d 100644 (file)
@@ -138,7 +138,7 @@ DHCP.UseTimezone,                       config_parse_bool,
 DHCP.IAID,                              config_parse_iaid,                              0,                             offsetof(Network, iaid)
 DHCP.ListenPort,                        config_parse_uint16,                            0,                             offsetof(Network, dhcp_client_port)
 DHCP.RapidCommit,                       config_parse_bool,                              0,                             offsetof(Network, rapid_commit)
-DHCP.ForceDHCPv6PDOtherInformation,    config_parse_bool,                              0,                             offsetof(Network, dhcp6_force_pd_other_information)
+DHCP.ForceDHCPv6PDOtherInformation,     config_parse_bool,                              0,                             offsetof(Network, dhcp6_force_pd_other_information)
 IPv6AcceptRA.UseDNS,                    config_parse_bool,                              0,                             offsetof(Network, ipv6_accept_ra_use_dns)
 IPv6AcceptRA.UseDomains,                config_parse_dhcp_use_domains,                  0,                             offsetof(Network, ipv6_accept_ra_use_domains)
 IPv6AcceptRA.RouteTable,                config_parse_uint32,                            0,                             offsetof(Network, ipv6_accept_ra_route_table)
index 107762d5195a6b8496aaf047013fb3ab447a3ea4..8d7795d72c2f19e2cb4f3943bdaf97e2052342d7 100644 (file)
@@ -80,8 +80,7 @@ void network_apply_anonymize_if_set(Network *network) {
         network->dhcp_client_identifier = DHCP_CLIENT_ID_MAC;
         /* RFC 7844 3.10:
          SHOULD NOT use the Vendor Class Identifier option */
-        /* NOTE: it was not initiallized to any value in network_load_one. */
-        network->dhcp_vendor_class_identifier = false;
+        network->dhcp_vendor_class_identifier = mfree(network->dhcp_vendor_class_identifier);
         /* RFC7844 section 3.6.:
          The client intending to protect its privacy SHOULD only request a
          minimal number of options in the PRL and SHOULD also randomly shuffle
@@ -201,10 +200,6 @@ static int network_load_one(Manager *manager, const char *filename) {
         network->dhcp_client_identifier = DHCP_CLIENT_ID_DUID;
         network->dhcp_route_table = RT_TABLE_MAIN;
         network->dhcp_route_table_set = false;
-        /* NOTE: the following vars were not set to any default,
-         * even if they are commented in the man?
-         * These vars might be overwriten by network_apply_anonymize_if_set */
-        network->dhcp_vendor_class_identifier = false;
         /* NOTE: from man: UseMTU=... Defaults to false*/
         network->dhcp_use_mtu = false;
         /* NOTE: from man: UseTimezone=... Defaults to "no".*/
index 588e618351ca543e85220998d325fa1c36ac216f..bbab393546684b45a30a6b8c98597060ecf1b2f5 100644 (file)
 int routing_policy_rule_new(RoutingPolicyRule **ret) {
         RoutingPolicyRule *rule;
 
-        rule = new0(RoutingPolicyRule, 1);
+        rule = new(RoutingPolicyRule, 1);
         if (!rule)
                 return -ENOMEM;
 
-        rule->family = AF_INET;
-        rule->table = RT_TABLE_MAIN;
+        *rule = (RoutingPolicyRule) {
+                .family = AF_INET,
+                .table = RT_TABLE_MAIN,
+        };
 
         *ret = rule;
         return 0;
@@ -154,8 +156,8 @@ int routing_policy_rule_get(Manager *m,
                             uint8_t tos,
                             uint32_t fwmark,
                             uint32_t table,
-                            char *iif,
-                            char *oif,
+                            const char *iif,
+                            const char *oif,
                             RoutingPolicyRule **ret) {
 
         RoutingPolicyRule rule, *existing;
@@ -171,26 +173,22 @@ int routing_policy_rule_get(Manager *m,
                 .tos = tos,
                 .fwmark = fwmark,
                 .table = table,
-                .iif = iif,
-                .oif = oif
+                .iif = (char*) iif,
+                .oif = (char*) oif
         };
 
-        if (m->rules) {
-                existing = set_get(m->rules, &rule);
-                if (existing) {
-                        if (ret)
-                                *ret = existing;
-                        return 1;
-                }
+        existing = set_get(m->rules, &rule);
+        if (existing) {
+                if (ret)
+                        *ret = existing;
+                return 1;
         }
 
-        if (m->rules_foreign) {
-                existing = set_get(m->rules_foreign, &rule);
-                if (existing) {
-                        if (ret)
-                                *ret = existing;
-                        return 1;
-                }
+        existing = set_get(m->rules_foreign, &rule);
+        if (existing) {
+                if (ret)
+                        *ret = existing;
+                return 1;
         }
 
         return -ENOENT;
@@ -224,15 +222,28 @@ static int routing_policy_rule_add_internal(Manager *m,
                                             uint8_t tos,
                                             uint32_t fwmark,
                                             uint32_t table,
-                                            char *iif,
-                                            char *oif,
+                                            const char *_iif,
+                                            const char *_oif,
                                             RoutingPolicyRule **ret) {
 
         _cleanup_(routing_policy_rule_freep) RoutingPolicyRule *rule = NULL;
+        _cleanup_free_ char *iif = NULL, *oif = NULL;
         int r;
 
         assert_return(rules, -EINVAL);
 
+        if (_iif) {
+                iif = strdup(_iif);
+                if (!iif)
+                        return -ENOMEM;
+        }
+
+        if (_oif) {
+                oif = strdup(_oif);
+                if (!oif)
+                        return -ENOMEM;
+        }
+
         r = routing_policy_rule_new(&rule);
         if (r < 0)
                 return r;
@@ -246,8 +257,8 @@ static int routing_policy_rule_add_internal(Manager *m,
         rule->tos = tos;
         rule->fwmark = fwmark;
         rule->table = table;
-        rule->iif = iif;
-        rule->oif = oif;
+        rule->iif = TAKE_PTR(iif);
+        rule->oif = TAKE_PTR(oif);
 
         r = set_ensure_allocated(rules, &routing_policy_rule_hash_ops);
         if (r < 0)
@@ -274,8 +285,8 @@ int routing_policy_rule_add(Manager *m,
                             uint8_t tos,
                             uint32_t fwmark,
                             uint32_t table,
-                            char *iif,
-                            char *oif,
+                            const char *iif,
+                            const char *oif,
                             RoutingPolicyRule **ret) {
 
         return routing_policy_rule_add_internal(m, &m->rules, family, from, from_prefixlen, to, to_prefixlen, tos, fwmark, table, iif, oif, ret);
@@ -290,8 +301,8 @@ int routing_policy_rule_add_foreign(Manager *m,
                                     uint8_t tos,
                                     uint32_t fwmark,
                                     uint32_t table,
-                                    char *iif,
-                                    char *oif,
+                                    const char *iif,
+                                    const char *oif,
                                     RoutingPolicyRule **ret) {
         return routing_policy_rule_add_internal(m, &m->rules_foreign, family, from, from_prefixlen, to, to_prefixlen, tos, fwmark, table, iif, oif, ret);
 }
@@ -392,9 +403,8 @@ static int routing_policy_rule_new_static(Network *network, const char *filename
         if (r < 0)
                 return r;
 
-        rule->section = n;
+        rule->section = TAKE_PTR(n);
         rule->network = network;
-        n = NULL;
 
         r = hashmap_put(network->rules_by_section, rule->section, rule);
         if (r < 0)
index 7843a54db435a1335bf8ea9ecf59eb12a9f3b4b5..2e7474ef56e4629f2cbc69987d13111ce75cacae 100644 (file)
@@ -54,11 +54,11 @@ int link_routing_policy_rule_remove_handler(sd_netlink *rtnl, sd_netlink_message
 int link_routing_policy_rule_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata);
 
 int routing_policy_rule_add(Manager *m, int family, const union in_addr_union *from, uint8_t from_prefixlen, const union in_addr_union *to, uint8_t to_prefixlen,
-                            uint8_t tos, uint32_t fwmark, uint32_t table, char *iif, char *oif, RoutingPolicyRule **ret);
+                            uint8_t tos, uint32_t fwmark, uint32_t table, const char *iif, const char *oif, RoutingPolicyRule **ret);
 int routing_policy_rule_add_foreign(Manager *m, int family, const union in_addr_union *from, uint8_t from_prefixlen, const union in_addr_union *to, uint8_t to_prefixlen,
-                                    uint8_t tos, uint32_t fwmark, uint32_t table, char *iif, char *oif, RoutingPolicyRule **ret);
+                                    uint8_t tos, uint32_t fwmark, uint32_t table, const char *iif, const char *oif, RoutingPolicyRule **ret);
 int routing_policy_rule_get(Manager *m, int family, const union in_addr_union *from, uint8_t from_prefixlen, const union in_addr_union *to, uint8_t to_prefixlen, uint8_t tos,
-                            uint32_t fwmark, uint32_t table, char *iif, char *oif, RoutingPolicyRule **ret);
+                            uint32_t fwmark, uint32_t table, const char *iif, const char *oif, RoutingPolicyRule **ret);
 int routing_policy_rule_make_local(Manager *m, RoutingPolicyRule *rule);
 int routing_policy_serialize_rules(Set *rules, FILE *f);
 int routing_policy_load_rules(const char *state_file, Set **rules);
index f7ec077f7b8410dd00d1ee085d1bce17dbfd77b7..8732c9e2aa9ab29407ab94ed77352fc54e9400eb 100644 (file)
@@ -59,7 +59,7 @@ int chown_cgroup(pid_t pid, CGroupUnified unified_requested, uid_t uid_shift) {
         if (r < 0)
                 return log_error_errno(r, "Failed to chown() cgroup %s: %m", fs);
 
-        if (unified_requested == CGROUP_UNIFIED_SYSTEMD) {
+        if (unified_requested == CGROUP_UNIFIED_SYSTEMD || (unified_requested == CGROUP_UNIFIED_NONE && cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER) > 0)) {
                 _cleanup_free_ char *lfs = NULL;
                 /* Always propagate access rights from unified to legacy controller */
 
index eb1964bb6d914f6d8d586cd60e61ab0f921e4cbf..e7ef80f7d6715a7b456f7aad22ddf7431f1082ff 100644 (file)
@@ -140,7 +140,7 @@ static int seccomp_add_default_syscall_filter(
                  */
         };
 
-        int r, c = 0;
+        int r;
         size_t i;
         char **p;
 
@@ -148,23 +148,19 @@ static int seccomp_add_default_syscall_filter(
                 if (whitelist[i].capability != 0 && (cap_list_retain & (1ULL << whitelist[i].capability)) == 0)
                         continue;
 
-                r = seccomp_add_syscall_filter_item(ctx, whitelist[i].name, SCMP_ACT_ALLOW, syscall_blacklist);
+                r = seccomp_add_syscall_filter_item(ctx, whitelist[i].name, SCMP_ACT_ALLOW, syscall_blacklist, false);
                 if (r < 0)
-                        /* If the system call is not known on this architecture, then that's fine, let's ignore it */
-                        log_debug_errno(r, "Failed to add rule for system call %s on %s, ignoring: %m", whitelist[i].name, seccomp_arch_to_string(arch));
-                else
-                        c++;
+                        return log_error_errno(r, "Failed to add syscall filter item %s: %m", whitelist[i].name);
         }
 
         STRV_FOREACH(p, syscall_whitelist) {
-                r = seccomp_add_syscall_filter_item(ctx, *p, SCMP_ACT_ALLOW, syscall_blacklist);
+                r = seccomp_add_syscall_filter_item(ctx, *p, SCMP_ACT_ALLOW, syscall_blacklist, false);
                 if (r < 0)
-                        log_debug_errno(r, "Failed to add rule for system call %s on %s, ignoring: %m", *p, seccomp_arch_to_string(arch));
-                else
-                        c++;
+                        log_warning_errno(r, "Failed to add rule for system call %s on %s, ignoring: %m",
+                                          *p, seccomp_arch_to_string(arch));
         }
 
-        return c;
+        return 0;
 }
 
 int setup_seccomp(uint64_t cap_list_retain, char **syscall_whitelist, char **syscall_blacklist) {
index e3bfe851e301861aa8d61ea0d46dfd1162a08a24..1e20f46131cbae4b220f6ecafa389b81f76be619 100644 (file)
@@ -2934,8 +2934,8 @@ static int outer_child(
                         }
                 }
 
-                if (!arg_quiet)
-                        log_info("Selected user namespace base " UID_FMT " and range " UID_FMT ".", arg_uid_shift, arg_uid_range);
+                log_full(arg_quiet ? LOG_DEBUG : LOG_INFO,
+                         "Selected user namespace base " UID_FMT " and range " UID_FMT ".", arg_uid_shift, arg_uid_range);
         }
 
         if (dissected_image) {
@@ -4351,16 +4351,15 @@ int main(int argc, char *argv[]) {
                                                           BTRFS_SNAPSHOT_FALLBACK_IMMUTABLE |
                                                           BTRFS_SNAPSHOT_RECURSIVE |
                                                           BTRFS_SNAPSHOT_QUOTA);
-                                if (r == -EEXIST) {
-                                        if (!arg_quiet)
-                                                log_info("Directory %s already exists, not populating from template %s.", arg_directory, arg_template);
-                                else if (r < 0) {
+                                if (r == -EEXIST)
+                                        log_full(arg_quiet ? LOG_DEBUG : LOG_INFO,
+                                                 "Directory %s already exists, not populating from template %s.", arg_directory, arg_template);
+                                else if (r < 0) {
                                         log_error_errno(r, "Couldn't create snapshot %s from %s: %m", arg_directory, arg_template);
                                         goto finish;
-                                } else {
-                                        if (!arg_quiet)
-                                                log_info("Populated %s from template %s.", arg_directory, arg_template);
-                                }
+                                } else
+                                        log_full(arg_quiet ? LOG_DEBUG : LOG_INFO,
+                                                 "Populated %s from template %s.", arg_directory, arg_template);
                         }
                 }
 
index 4becc8c944dc3e555295fcdb7490b6fcd2235192..8eea70716c00080cb399a440740dd6f65998b03b 100644 (file)
@@ -667,13 +667,25 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
                                 return bus_log_create_error(r);
 
                 } else {
-                        r = in_addr_prefix_from_string_auto(eq, &family, &prefix, &prefixlen);
-                        if (r < 0)
-                                return log_error_errno(r, "Failed to parse IP address prefix: %s", eq);
+                        for (;;) {
+                                _cleanup_free_ char *word = NULL;
 
-                        r = bus_append_ip_address_access(m, family, &prefix, prefixlen);
-                        if (r < 0)
-                                return bus_log_create_error(r);
+                                r = extract_first_word(&eq, &word, NULL, 0);
+                                if (r == 0)
+                                        break;
+                                if (r == -ENOMEM)
+                                        return log_oom();
+                                if (r < 0)
+                                        return log_error_errno(r, "Failed to parse %s: %s", field, eq);
+
+                                r = in_addr_prefix_from_string_auto(word, &family, &prefix, &prefixlen);
+                                if (r < 0)
+                                        return log_error_errno(r, "Failed to parse IP address prefix: %s", word);
+
+                                r = bus_append_ip_address_access(m, family, &prefix, prefixlen);
+                                if (r < 0)
+                                        return bus_log_create_error(r);
+                        }
                 }
 
                 r = sd_bus_message_close_container(m);
@@ -1222,7 +1234,7 @@ static int bus_append_kill_property(sd_bus_message *m, const char *field, const
 
                 return bus_append_parse_boolean(m, field, eq);
 
-        if (STR_IN_SET(field, "KillSignal", "FinalKillSignal"))
+        if (STR_IN_SET(field, "KillSignal", "FinalKillSignal", "WatchdogSignal"))
 
                 return bus_append_signal_from_string(m, field, eq);
 
index 1ecfb77de271c10b740720719eb43e80f52710bf..f24edf579187754fe783db88cb968c15c10098dc 100644 (file)
@@ -1284,7 +1284,7 @@ int dns_name_apply_idna(const char *name, char **ret) {
 
         log_debug("idn2_lookup_u8(\"%s\") failed: %d/%s", name, r, idn2_strerror(r));
         if (r == IDN2_2HYPHEN)
-                /* The name has two hypens — forbidden by IDNA2008 in some cases */
+                /* The name has two hyphens — forbidden by IDNA2008 in some cases */
                 return 0;
         if (IN_SET(r, IDN2_TOO_BIG_DOMAIN, IDN2_TOO_BIG_LABEL))
                 return -ENOSPC;
diff --git a/src/shared/id128-print.c b/src/shared/id128-print.c
new file mode 100644 (file)
index 0000000..eea3ee5
--- /dev/null
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include <stdio.h>
+
+#include "sd-id128.h"
+
+#include "alloc-util.h"
+#include "id128-print.h"
+#include "log.h"
+#include "terminal-util.h"
+
+int id128_pretty_print(sd_id128_t id, bool pretty) {
+        unsigned i;
+        _cleanup_free_ char *man_link = NULL, *mod_link = NULL;
+        const char *on, *off;
+
+        if (!pretty) {
+                printf(SD_ID128_FORMAT_STR "\n",
+                       SD_ID128_FORMAT_VAL(id));
+                return 0;
+        }
+
+        on = ansi_highlight();
+        off = ansi_normal();
+
+        if (terminal_urlify("man:systemd-id128(1)", "systemd-id128(1)", &man_link) < 0)
+                return log_oom();
+
+        if (terminal_urlify("https://docs.python.org/3/library/uuid.html", "uuid", &mod_link) < 0)
+                return log_oom();
+
+        printf("As string:\n"
+               "%s" SD_ID128_FORMAT_STR "%s\n\n"
+               "As UUID:\n"
+               "%s%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x%s\n\n"
+               "As %s macro:\n"
+               "%s#define MESSAGE_XYZ SD_ID128_MAKE(",
+               on, SD_ID128_FORMAT_VAL(id), off,
+               on, SD_ID128_FORMAT_VAL(id), off,
+               man_link,
+               on);
+        for (i = 0; i < 16; i++)
+                printf("%02x%s", id.bytes[i], i != 15 ? "," : "");
+        printf(")%s\n\n", off);
+
+        printf("As Python constant:\n"
+               ">>> import %s\n"
+               ">>> %sMESSAGE_XYZ = uuid.UUID('" SD_ID128_FORMAT_STR "')%s\n",
+               mod_link,
+               on, SD_ID128_FORMAT_VAL(id), off);
+
+        return 0;
+}
+
+int id128_print_new(bool pretty) {
+        sd_id128_t id;
+        int r;
+
+        r = sd_id128_randomize(&id);
+        if (r < 0)
+                return log_error_errno(r, "Failed to generate ID: %m");
+
+        return id128_pretty_print(id, pretty);
+}
diff --git a/src/shared/id128-print.h b/src/shared/id128-print.h
new file mode 100644 (file)
index 0000000..5d50de0
--- /dev/null
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#pragma once
+
+#include <stdbool.h>
+
+#include "sd-id128.h"
+
+int id128_pretty_print(sd_id128_t id, bool pretty);
+int id128_print_new(bool pretty);
index 03773bd02f840c0c6d0f3eda81ce3d0c41daa870..ccb999998cea2e7e075f9a866fcb53aa879f4553 100644 (file)
@@ -1896,10 +1896,10 @@ static int install_context_apply(
                 if (q < 0)
                         return q;
 
-                r = install_info_traverse(scope, c, paths, i, flags, NULL);
-                if (r < 0) {
+                q = install_info_traverse(scope, c, paths, i, flags, NULL);
+                if (q < 0) {
                         unit_file_changes_add(changes, n_changes, r, i->name, NULL);
-                        return r;
+                        return q;
                 }
 
                 /* We can attempt to process a masked unit when a different unit
index 17370f404844c9bd6760284aaeff11f37fe424d8..498b73c7504caecee9a3837da548752c290f7409 100644 (file)
@@ -44,6 +44,8 @@ shared_sources = files('''
         generator.c
         generator.h
         gpt.h
+        id128-print.c
+        id128-print.h
         ima-util.c
         ima-util.h
         import-util.c
index ff3537c5e97fe513b2ec27b1da6e71d4f4d3550b..ca5544146659fb18f96f5eb13aaf73362c886a11 100644 (file)
@@ -858,11 +858,9 @@ const SyscallFilterSet *syscall_filter_set_find(const char *name) {
         return NULL;
 }
 
-static int seccomp_add_syscall_filter_set(scmp_filter_ctx seccomp, const SyscallFilterSet *set, uint32_t action, char **exclude);
-
-int seccomp_add_syscall_filter_item(scmp_filter_ctx *seccomp, const char *name, uint32_t action, char **exclude) {
-        int r;
+static int seccomp_add_syscall_filter_set(scmp_filter_ctx seccomp, const SyscallFilterSet *set, uint32_t action, char **exclude, bool log_missing);
 
+int seccomp_add_syscall_filter_item(scmp_filter_ctx *seccomp, const char *name, uint32_t action, char **exclude, bool log_missing) {
         assert(seccomp);
         assert(name);
 
@@ -878,32 +876,40 @@ int seccomp_add_syscall_filter_item(scmp_filter_ctx *seccomp, const char *name,
                         return -EINVAL;
                 }
 
-                r = seccomp_add_syscall_filter_set(seccomp, other, action, exclude);
-                if (r < 0)
-                        return r;
+                return seccomp_add_syscall_filter_set(seccomp, other, action, exclude, log_missing);
+
         } else {
-                int id;
+                int id, r;
 
                 id = seccomp_syscall_resolve_name(name);
                 if (id == __NR_SCMP_ERROR) {
-                        log_debug("System call %s is not known, ignoring.", name);
+                        if (log_missing)
+                                log_debug("System call %s is not known, ignoring.", name);
                         return 0;
                 }
 
                 r = seccomp_rule_add_exact(seccomp, action, id, 0);
-                if (r < 0)
+                if (r < 0) {
                         /* If the system call is not known on this architecture, then that's fine, let's ignore it */
-                        log_debug_errno(r, "Failed to add rule for system call %s() / %d, ignoring: %m", name, id);
-        }
+                        bool ignore = r == -EDOM;
 
-        return 0;
+                        if (!ignore || log_missing)
+                                log_debug_errno(r, "Failed to add rule for system call %s() / %d%s: %m",
+                                                name, id, ignore ? ", ignoring" : "");
+                        if (!ignore)
+                                return r;
+                }
+
+                return 0;
+        }
 }
 
 static int seccomp_add_syscall_filter_set(
                 scmp_filter_ctx seccomp,
                 const SyscallFilterSet *set,
                 uint32_t action,
-                char **exclude) {
+                char **exclude,
+                bool log_missing) {
 
         const char *sys;
         int r;
@@ -912,7 +918,7 @@ static int seccomp_add_syscall_filter_set(
         assert(set);
 
         NULSTR_FOREACH(sys, set->value) {
-                r = seccomp_add_syscall_filter_item(seccomp, sys, action, exclude);
+                r = seccomp_add_syscall_filter_item(seccomp, sys, action, exclude, log_missing);
                 if (r < 0)
                         return r;
         }
@@ -920,7 +926,7 @@ static int seccomp_add_syscall_filter_set(
         return 0;
 }
 
-int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilterSet *set, uint32_t action) {
+int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilterSet *set, uint32_t action, bool log_missing) {
         uint32_t arch;
         int r;
 
@@ -938,11 +944,9 @@ int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilter
                 if (r < 0)
                         return r;
 
-                r = seccomp_add_syscall_filter_set(seccomp, set, action, NULL);
-                if (r < 0) {
-                        log_debug_errno(r, "Failed to add filter set, ignoring: %m");
-                        continue;
-                }
+                r = seccomp_add_syscall_filter_set(seccomp, set, action, NULL, log_missing);
+                if (r < 0)
+                        return log_debug_errno(r, "Failed to add filter set: %m");
 
                 r = seccomp_load(seccomp);
                 if (IN_SET(r, -EPERM, -EACCES))
@@ -954,7 +958,7 @@ int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilter
         return 0;
 }
 
-int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Hashmap* set, uint32_t action) {
+int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Hashmap* set, uint32_t action, bool log_missing) {
         uint32_t arch;
         int r;
 
@@ -967,7 +971,7 @@ int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Hashmap* set, u
         SECCOMP_FOREACH_LOCAL_ARCH(arch) {
                 _cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
                 Iterator i;
-                void *id, *val;
+                void *syscall_id, *val;
 
                 log_debug("Operating on architecture: %s", seccomp_arch_to_string(arch));
 
@@ -975,20 +979,27 @@ int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Hashmap* set, u
                 if (r < 0)
                         return r;
 
-                HASHMAP_FOREACH_KEY(val, id, set, i) {
+                HASHMAP_FOREACH_KEY(val, syscall_id, set, i) {
                         uint32_t a = action;
-                        int e = PTR_TO_INT(val);
+                        int id = PTR_TO_INT(syscall_id) - 1;
+                        int error = PTR_TO_INT(val);
 
-                        if (action != SCMP_ACT_ALLOW && e >= 0)
-                                a = SCMP_ACT_ERRNO(e);
+                        if (action != SCMP_ACT_ALLOW && error >= 0)
+                                a = SCMP_ACT_ERRNO(error);
 
-                        r = seccomp_rule_add_exact(seccomp, a, PTR_TO_INT(id) - 1, 0);
+                        r = seccomp_rule_add_exact(seccomp, a, id, 0);
                         if (r < 0) {
                                 /* If the system call is not known on this architecture, then that's fine, let's ignore it */
                                 _cleanup_free_ char *n = NULL;
-
-                                n = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, PTR_TO_INT(id) - 1);
-                                log_debug_errno(r, "Failed to add rule for system call %s() / %d, ignoring: %m", strna(n), PTR_TO_INT(id) - 1);
+                                bool ignore;
+
+                                n = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, id);
+                                ignore = r == -EDOM;
+                                if (!ignore || log_missing)
+                                        log_debug_errno(r, "Failed to add rule for system call %s() / %d%s: %m",
+                                                        strna(n), id, ignore ? ", ignoring" : "");
+                                if (!ignore)
+                                        return r;
                         }
                 }
 
index eac857afb9b9f01eafdb22836e0a1c43f2db95b1..d8a36c4e21c2f411f290753d156f30775d06d35a 100644 (file)
@@ -58,10 +58,10 @@ const SyscallFilterSet *syscall_filter_set_find(const char *name);
 
 int seccomp_filter_set_add(Hashmap *s, bool b, const SyscallFilterSet *set);
 
-int seccomp_add_syscall_filter_item(scmp_filter_ctx *ctx, const char *name, uint32_t action, char **exclude);
+int seccomp_add_syscall_filter_item(scmp_filter_ctx *ctx, const char *name, uint32_t action, char **exclude, bool log_missing);
 
-int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilterSet *set, uint32_t action);
-int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Hashmap* set, uint32_t action);
+int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilterSet *set, uint32_t action, bool log_missing);
+int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Hashmap* set, uint32_t action, bool log_missing);
 
 typedef enum SeccompParseFlags {
         SECCOMP_PARSE_INVERT     = 1 << 0,
index 549959edf2e5b023fe7ed9a4b16d70f55cc2da08..58a3e1c32df7a5c61e2bf6e0ebf1fd022f44a1bb 100644 (file)
@@ -1,6 +1,8 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
+#include <stdbool.h>
+
 char* setup_fake_runtime_dir(void);
 const char* get_testdata_dir(void);
 const char* get_catalog_dir(void);
index 212f99cf785f97b6c0d6d9d7aa8fceb993493a5f..849502921d608f9d473ed32cf8b42be3f47b111a 100644 (file)
@@ -5,7 +5,9 @@ _systemd_headers = '''
         sd-bus-protocol.h
         sd-bus-vtable.h
         sd-daemon.h
+        sd-device.h
         sd-event.h
+        sd-hwdb.h
         sd-id128.h
         sd-journal.h
         sd-login.h
@@ -15,8 +17,6 @@ _systemd_headers = '''
 # https://github.com/mesonbuild/meson/issues/1633
 systemd_headers = files(_systemd_headers)
 
-#  sd-device.h
-#  sd-hwdb.h
 #  sd-dhcp6-client.h
 #  sd-dhcp6-lease.h
 #  sd-dhcp-client.h
index 7024ad84d696b35ddc35a573ceb67234446f6c78..43d38f5c7da66bb618699cf28b294be921d5f2de 100644 (file)
@@ -127,6 +127,7 @@ int sd_dhcp6_client_get_address_request(sd_dhcp6_client *client,
                                         int *request);
 int sd_dhcp6_client_set_address_request(sd_dhcp6_client *client,
                                         int request);
+int sd_dhcp6_client_set_transaction_id(sd_dhcp6_client *client, uint32_t transaction_id);
 
 int sd_dhcp6_client_get_lease(
                 sd_dhcp6_client *client,
index 143a0ffb5edcd3737f0962dd93f4eb51826aec62..78cf9462b0cfd1a92bb3a9017a523735ad4b3cc8 100644 (file)
@@ -42,6 +42,7 @@ int sd_id128_randomize(sd_id128_t *ret);
 
 int sd_id128_get_machine(sd_id128_t *ret);
 int sd_id128_get_machine_app_specific(sd_id128_t app_id, sd_id128_t *ret);
+int sd_id128_get_boot_app_specific(sd_id128_t app_id, sd_id128_t *ret);
 int sd_id128_get_boot(sd_id128_t *ret);
 int sd_id128_get_invocation(sd_id128_t *ret);
 
index 2f0e8966abca431c9dadbfbe2e6fabe21ea97be4..ba6c6b1cf8852e41142eaf01768ccc9676cb3706 100644 (file)
 
 _SD_BEGIN_DECLARATIONS;
 
-/* Hey! If you add a new message here, you *must* also update the
- * message catalog with an appropriate explanation */
+/* Hey! If you add a new message here, you *must* also update the message catalog with an appropriate explanation */
 
-/* And if you add a new ID here, make sure to generate a random one
- * with journalctl --new-id128. Do not use any other IDs, and do not
- * count them up manually. */
+/* And if you add a new ID here, make sure to generate a random one with "systemd-id128 new". Do not use any other IDs,
+ * and do not count them up manually. */
 
 #define SD_MESSAGE_JOURNAL_START          SD_ID128_MAKE(f7,73,79,a8,49,0b,40,8b,be,5f,69,40,50,5a,77,7b)
 #define SD_MESSAGE_JOURNAL_START_STR      SD_ID128_MAKE_STR(f7,73,79,a8,49,0b,40,8b,be,5f,69,40,50,5a,77,7b)
index 7e603cf1c0d75b0df2db0c05e3863a29ee67a8da..3d1e28bdf130e349ff0d51bfaecd2168d6c548ae 100644 (file)
@@ -673,6 +673,10 @@ tests += [
         [['src/test/test-bus-util.c'],
          [],
          []],
+
+        [['src/test/test-sd-hwdb.c'],
+         [],
+         []],
 ]
 
 ############################################################
@@ -888,6 +892,10 @@ tests += [
         [['src/libsystemd/sd-login/test-login.c'],
          [],
          []],
+
+        [['src/libsystemd/sd-device/test-sd-device.c'],
+         [],
+         []],
 ]
 
 if cxx.found()
index c3ea5f6469ec38db4019c15d76f1e22e8b8eb842..b5bb535adc010ee6b4974f5f28530018771aa261 100644 (file)
@@ -28,6 +28,8 @@
 #include "util.h"
 #include "virt.h"
 
+static bool can_unshare = true;
+
 typedef void (*test_function_t)(Manager *m);
 
 static void check(Manager *m, Unit *unit, int status_expected, int code_expected) {
@@ -156,7 +158,7 @@ static void test_exec_bindpaths(Manager *m) {
         assert_se(mkdir_p("/tmp/test-exec-bindpaths", 0755) >= 0);
         assert_se(mkdir_p("/tmp/test-exec-bindreadonlypaths", 0755) >= 0);
 
-        test(m, "exec-bindpaths.service", 0, CLD_EXITED);
+        test(m, "exec-bindpaths.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
 
         (void) rm_rf("/tmp/test-exec-bindpaths", REMOVE_ROOT|REMOVE_PHYSICAL);
         (void) rm_rf("/tmp/test-exec-bindreadonlypaths", REMOVE_ROOT|REMOVE_PHYSICAL);
@@ -227,7 +229,7 @@ static void test_exec_ignoresigpipe(Manager *m) {
 static void test_exec_privatetmp(Manager *m) {
         assert_se(touch("/tmp/test-exec_privatetmp") >= 0);
 
-        test(m, "exec-privatetmp-yes.service", 0, CLD_EXITED);
+        test(m, "exec-privatetmp-yes.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
         test(m, "exec-privatetmp-no.service", 0, CLD_EXITED);
 
         unlink("/tmp/test-exec_privatetmp");
@@ -245,9 +247,9 @@ static void test_exec_privatedevices(Manager *m) {
                 return;
         }
 
-        test(m, "exec-privatedevices-yes.service", 0, CLD_EXITED);
+        test(m, "exec-privatedevices-yes.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
         test(m, "exec-privatedevices-no.service", 0, CLD_EXITED);
-        test(m, "exec-privatedevices-disabled-by-prefix.service", 0, CLD_EXITED);
+        test(m, "exec-privatedevices-disabled-by-prefix.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
 
         /* We use capsh to test if the capabilities are
          * properly set, so be sure that it exists */
@@ -283,21 +285,21 @@ static void test_exec_protectkernelmodules(Manager *m) {
 
         test(m, "exec-protectkernelmodules-no-capabilities.service", 0, CLD_EXITED);
         test(m, "exec-protectkernelmodules-yes-capabilities.service", 0, CLD_EXITED);
-        test(m, "exec-protectkernelmodules-yes-mount-propagation.service", 0, CLD_EXITED);
+        test(m, "exec-protectkernelmodules-yes-mount-propagation.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
 }
 
 static void test_exec_readonlypaths(Manager *m) {
 
-        test(m, "exec-readonlypaths-simple.service", 0, CLD_EXITED);
+        test(m, "exec-readonlypaths-simple.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
 
         if (path_is_read_only_fs("/var") > 0) {
                 log_notice("Directory /var is readonly, skipping remaining tests in %s", __func__);
                 return;
         }
 
-        test(m, "exec-readonlypaths.service", 0, CLD_EXITED);
-        test(m, "exec-readonlypaths-mount-propagation.service", 0, CLD_EXITED);
-        test(m, "exec-readonlypaths-with-bindpaths.service", 0, CLD_EXITED);
+        test(m, "exec-readonlypaths.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
+        test(m, "exec-readonlypaths-with-bindpaths.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
+        test(m, "exec-readonlypaths-mount-propagation.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
 }
 
 static void test_exec_readwritepaths(Manager *m) {
@@ -307,7 +309,7 @@ static void test_exec_readwritepaths(Manager *m) {
                 return;
         }
 
-        test(m, "exec-readwritepaths-mount-propagation.service", 0, CLD_EXITED);
+        test(m, "exec-readwritepaths-mount-propagation.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
 }
 
 static void test_exec_inaccessiblepaths(Manager *m) {
@@ -317,26 +319,28 @@ static void test_exec_inaccessiblepaths(Manager *m) {
                 return;
         }
 
-        test(m, "exec-inaccessiblepaths-proc.service", 0, CLD_EXITED);
+        test(m, "exec-inaccessiblepaths-proc.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
 
         if (path_is_read_only_fs("/") > 0) {
                 log_notice("Root directory is readonly, skipping remaining tests in %s", __func__);
                 return;
         }
 
-        test(m, "exec-inaccessiblepaths-mount-propagation.service", 0, CLD_EXITED);
+        test(m, "exec-inaccessiblepaths-mount-propagation.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
 }
 
 static void test_exec_temporaryfilesystem(Manager *m) {
 
-        test(m, "exec-temporaryfilesystem-options.service", 0, CLD_EXITED);
-        test(m, "exec-temporaryfilesystem-ro.service", 0, CLD_EXITED);
-        test(m, "exec-temporaryfilesystem-rw.service", 0, CLD_EXITED);
-        test(m, "exec-temporaryfilesystem-usr.service", 0, CLD_EXITED);
+        test(m, "exec-temporaryfilesystem-options.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
+        test(m, "exec-temporaryfilesystem-ro.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
+        test(m, "exec-temporaryfilesystem-rw.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
+        test(m, "exec-temporaryfilesystem-usr.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
 }
 
 static void test_exec_systemcallfilter(Manager *m) {
 #if HAVE_SECCOMP
+        int r;
+
         if (!is_seccomp_available()) {
                 log_notice("Seccomp not available, skipping %s", __func__);
                 return;
@@ -346,18 +350,34 @@ static void test_exec_systemcallfilter(Manager *m) {
         test(m, "exec-systemcallfilter-not-failing2.service", 0, CLD_EXITED);
         test(m, "exec-systemcallfilter-failing.service", SIGSYS, CLD_KILLED);
         test(m, "exec-systemcallfilter-failing2.service", SIGSYS, CLD_KILLED);
+
+        r = find_binary("python3", NULL);
+        if (r < 0) {
+                log_notice_errno(r, "Skipping remaining tests in %s, could not find python3 binary: %m", __func__);
+                return;
+        }
+
         test(m, "exec-systemcallfilter-with-errno-name.service", errno_from_name("EILSEQ"), CLD_EXITED);
         test(m, "exec-systemcallfilter-with-errno-number.service", 255, CLD_EXITED);
+        test(m, "exec-systemcallfilter-with-errno-multi.service", errno_from_name("EILSEQ"), CLD_EXITED);
 #endif
 }
 
 static void test_exec_systemcallerrornumber(Manager *m) {
 #if HAVE_SECCOMP
+        int r;
+
         if (!is_seccomp_available()) {
                 log_notice("Seccomp not available, skipping %s", __func__);
                 return;
         }
 
+        r = find_binary("python3", NULL);
+        if (r < 0) {
+                log_notice_errno(r, "Skipping %s, could not find python3 binary: %m", __func__);
+                return;
+        }
+
         test(m, "exec-systemcallerrornumber-name.service", errno_from_name("EACCES"), CLD_EXITED);
         test(m, "exec-systemcallerrornumber-number.service", 255, CLD_EXITED);
 #endif
@@ -370,13 +390,13 @@ static void test_exec_restrictnamespaces(Manager *m) {
                 return;
         }
 
-        test(m, "exec-restrictnamespaces-no.service", 0, CLD_EXITED);
+        test(m, "exec-restrictnamespaces-no.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
         test(m, "exec-restrictnamespaces-yes.service", 1, CLD_EXITED);
-        test(m, "exec-restrictnamespaces-mnt.service", 0, CLD_EXITED);
+        test(m, "exec-restrictnamespaces-mnt.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
         test(m, "exec-restrictnamespaces-mnt-blacklist.service", 1, CLD_EXITED);
-        test(m, "exec-restrictnamespaces-merge-and.service", 0, CLD_EXITED);
-        test(m, "exec-restrictnamespaces-merge-or.service", 0, CLD_EXITED);
-        test(m, "exec-restrictnamespaces-merge-all.service", 0, CLD_EXITED);
+        test(m, "exec-restrictnamespaces-merge-and.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
+        test(m, "exec-restrictnamespaces-merge-or.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
+        test(m, "exec-restrictnamespaces-merge-all.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
 #endif
 }
 
@@ -445,14 +465,15 @@ static void test_exec_supplementarygroups(Manager *m) {
 }
 
 static void test_exec_dynamicuser(Manager *m) {
-        test(m, "exec-dynamicuser-fixeduser.service", 0, CLD_EXITED);
+
+        test(m, "exec-dynamicuser-fixeduser.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
         if (check_user_has_group_with_same_name("adm"))
-                test(m, "exec-dynamicuser-fixeduser-adm.service", 0, CLD_EXITED);
+                test(m, "exec-dynamicuser-fixeduser-adm.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
         if (check_user_has_group_with_same_name("games"))
-                test(m, "exec-dynamicuser-fixeduser-games.service", 0, CLD_EXITED);
-        test(m, "exec-dynamicuser-fixeduser-one-supplementarygroup.service", 0, CLD_EXITED);
-        test(m, "exec-dynamicuser-supplementarygroups.service", 0, CLD_EXITED);
-        test(m, "exec-dynamicuser-statedir.service", 0, CLD_EXITED);
+                test(m, "exec-dynamicuser-fixeduser-games.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
+        test(m, "exec-dynamicuser-fixeduser-one-supplementarygroup.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
+        test(m, "exec-dynamicuser-supplementarygroups.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
+        test(m, "exec-dynamicuser-statedir.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
 
         (void) rm_rf("/var/lib/test-dynamicuser-migrate", REMOVE_ROOT|REMOVE_PHYSICAL);
         (void) rm_rf("/var/lib/test-dynamicuser-migrate2", REMOVE_ROOT|REMOVE_PHYSICAL);
@@ -460,7 +481,7 @@ static void test_exec_dynamicuser(Manager *m) {
         (void) rm_rf("/var/lib/private/test-dynamicuser-migrate2", REMOVE_ROOT|REMOVE_PHYSICAL);
 
         test(m, "exec-dynamicuser-statedir-migrate-step1.service", 0, CLD_EXITED);
-        test(m, "exec-dynamicuser-statedir-migrate-step2.service", 0, CLD_EXITED);
+        test(m, "exec-dynamicuser-statedir-migrate-step2.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
 
         (void) rm_rf("/var/lib/test-dynamicuser-migrate", REMOVE_ROOT|REMOVE_PHYSICAL);
         (void) rm_rf("/var/lib/test-dynamicuser-migrate2", REMOVE_ROOT|REMOVE_PHYSICAL);
@@ -618,19 +639,29 @@ static void test_exec_privatenetwork(Manager *m) {
                 return;
         }
 
-        test(m, "exec-privatenetwork-yes.service", 0, CLD_EXITED);
+        test(m, "exec-privatenetwork-yes.service", can_unshare ? 0 : EXIT_NETWORK, CLD_EXITED);
 }
 
 static void test_exec_oomscoreadjust(Manager *m) {
         test(m, "exec-oomscoreadjust-positive.service", 0, CLD_EXITED);
+
+        if (detect_container() > 0) {
+                log_notice("Testing in container, skipping remaining tests in %s", __func__);
+                return;
+        }
         test(m, "exec-oomscoreadjust-negative.service", 0, CLD_EXITED);
 }
 
 static void test_exec_ioschedulingclass(Manager *m) {
         test(m, "exec-ioschedulingclass-none.service", 0, CLD_EXITED);
         test(m, "exec-ioschedulingclass-idle.service", 0, CLD_EXITED);
-        test(m, "exec-ioschedulingclass-realtime.service", 0, CLD_EXITED);
         test(m, "exec-ioschedulingclass-best-effort.service", 0, CLD_EXITED);
+
+        if (detect_container() > 0) {
+                log_notice("Testing in container, skipping remaining tests in %s", __func__);
+                return;
+        }
+        test(m, "exec-ioschedulingclass-realtime.service", 0, CLD_EXITED);
 }
 
 static void test_exec_unsetenvironment(Manager *m) {
@@ -678,6 +709,7 @@ static int run_tests(UnitFileScope scope, const test_function_t *tests) {
 int main(int argc, char *argv[]) {
         _cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
         _cleanup_free_ char *test_execute_path = NULL;
+        _cleanup_hashmap_free_ Hashmap *s = NULL;
         static const test_function_t user_tests[] = {
                 test_exec_basic,
                 test_exec_ambientcapabilities,
@@ -750,9 +782,37 @@ int main(int argc, char *argv[]) {
         assert_se(unsetenv("VAR2") == 0);
         assert_se(unsetenv("VAR3") == 0);
 
+        r = run_tests(UNIT_FILE_USER, user_tests);
+        if (r != 0)
+                return r;
+
+        r = run_tests(UNIT_FILE_SYSTEM, system_tests);
+        if (r != 0)
+                return r;
+
+#if HAVE_SECCOMP
+        /* The following tests are for 1beab8b0d0ff2d7d1436b52d4a0c3d56dc908962. */
+        if (!is_seccomp_available()) {
+                log_notice("Seccomp not available, skipping unshare() filtered tests.");
+                return 0;
+        }
+
+        assert_se(s = hashmap_new(NULL));
+        r = seccomp_syscall_resolve_name("unshare");
+        assert_se(r != __NR_SCMP_ERROR);
+        assert_se(hashmap_put(s, UINT32_TO_PTR(r + 1), INT_TO_PTR(-1)) >= 0);
+        assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EOPNOTSUPP), true) >= 0);
+        assert_se(unshare(CLONE_NEWNS) < 0);
+        assert_se(errno == EOPNOTSUPP);
+
+        can_unshare = false;
+
         r = run_tests(UNIT_FILE_USER, user_tests);
         if (r != 0)
                 return r;
 
         return run_tests(UNIT_FILE_SYSTEM, system_tests);
+#else
+        return 0;
+#endif
 }
index d188c24f7bbe97f511672cf90f3b6f4d6256c6d3..d5f652c938395d3c72e7af72e49a9c7c49aa49c0 100644 (file)
 #include "stdio-util.h"
 #include "string-util.h"
 #include "strv.h"
+#include "tests.h"
 #include "user-util.h"
 #include "util.h"
+#include "virt.h"
+
+static const char *arg_test_dir = NULL;
 
 static void test_chase_symlinks(void) {
         _cleanup_free_ char *result = NULL;
-        char temp[] = "/tmp/test-chase.XXXXXX";
+        char *temp;
         const char *top, *p, *pslash, *q, *qslash;
         struct stat st;
         int r, pfd;
 
+        log_info("/* %s */", __func__);
+
+        temp = strjoina(arg_test_dir ?: "/tmp", "/test-chase.XXXXXX");
         assert_se(mkdtemp(temp));
 
         top = strjoina(temp, "/top");
         assert_se(mkdir(top, 0700) >= 0);
 
         p = strjoina(top, "/dot");
-        assert_se(symlink(".", p) >= 0);
+        if (symlink(".", p) < 0) {
+                assert_se(IN_SET(errno, EINVAL, ENOSYS, ENOTTY, EPERM));
+                log_tests_skipped_errno(errno, "symlink() not possible");
+                goto cleanup;
+        };
 
         p = strjoina(top, "/dotdot");
         assert_se(symlink("..", p) >= 0);
@@ -334,13 +345,17 @@ static void test_chase_symlinks(void) {
         assert_se(streq("/usr", result));
         result = mfree(result);
 
+ cleanup:
         assert_se(rm_rf(temp, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
 }
 
 static void test_unlink_noerrno(void) {
-        char name[] = "/tmp/test-close_nointr.XXXXXX";
+        char *name;
         int fd;
 
+        log_info("/* %s */", __func__);
+
+        name = strjoina(arg_test_dir ?: "/tmp", "/test-close_nointr.XXXXXX");
         fd = mkostemp_safe(name);
         assert_se(fd >= 0);
         assert_se(close_nointr(fd) >= 0);
@@ -356,32 +371,37 @@ static void test_unlink_noerrno(void) {
 }
 
 static void test_readlink_and_make_absolute(void) {
-        char tempdir[] = "/tmp/test-readlink_and_make_absolute";
-        char name[] = "/tmp/test-readlink_and_make_absolute/original";
-        char name2[] = "test-readlink_and_make_absolute/original";
-        char name_alias[] = "/tmp/test-readlink_and_make_absolute-alias";
-        char *r = NULL;
-        _cleanup_free_ char *pwd = NULL;
+        const char *tempdir, *name, *name2, *name_alias;
+        _cleanup_free_ char *r1 = NULL, *r2 = NULL, *pwd = NULL;
+
+        log_info("/* %s */", __func__);
+
+        tempdir = strjoina(arg_test_dir ?: "/tmp", "/test-readlink_and_make_absolute");
+        name = strjoina(tempdir, "/original");
+        name2 = "test-readlink_and_make_absolute/original";
+        name_alias = strjoina(arg_test_dir ?: "/tmp", "/test-readlink_and_make_absolute-alias");
 
         assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid(), MKDIR_WARN_MODE) >= 0);
         assert_se(touch(name) >= 0);
 
-        assert_se(symlink(name, name_alias) >= 0);
-        assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
-        assert_se(streq(r, name));
-        free(r);
-        assert_se(unlink(name_alias) >= 0);
+        if (symlink(name, name_alias) < 0) {
+                assert_se(IN_SET(errno, EINVAL, ENOSYS, ENOTTY, EPERM));
+                log_tests_skipped_errno(errno, "symlink() not possible");
+        } else {
+                assert_se(readlink_and_make_absolute(name_alias, &r1) >= 0);
+                assert_se(streq(r1, name));
+                assert_se(unlink(name_alias) >= 0);
 
-        assert_se(safe_getcwd(&pwd) >= 0);
+                assert_se(safe_getcwd(&pwd) >= 0);
 
-        assert_se(chdir(tempdir) >= 0);
-        assert_se(symlink(name2, name_alias) >= 0);
-        assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
-        assert_se(streq(r, name));
-        free(r);
-        assert_se(unlink(name_alias) >= 0);
+                assert_se(chdir(tempdir) >= 0);
+                assert_se(symlink(name2, name_alias) >= 0);
+                assert_se(readlink_and_make_absolute(name_alias, &r2) >= 0);
+                assert_se(streq(r2, name));
+                assert_se(unlink(name_alias) >= 0);
 
-        assert_se(chdir(pwd) >= 0);
+                assert_se(chdir(pwd) >= 0);
+        }
 
         assert_se(rm_rf(tempdir, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
 }
@@ -389,7 +409,7 @@ static void test_readlink_and_make_absolute(void) {
 static void test_get_files_in_directory(void) {
         _cleanup_strv_free_ char **l = NULL, **t = NULL;
 
-        assert_se(get_files_in_directory("/tmp", &l) >= 0);
+        assert_se(get_files_in_directory(arg_test_dir ?: "/tmp", &l) >= 0);
         assert_se(get_files_in_directory(".", &t) >= 0);
         assert_se(get_files_in_directory(".", NULL) >= 0);
 }
@@ -398,6 +418,8 @@ static void test_var_tmp(void) {
         _cleanup_free_ char *tmpdir_backup = NULL, *temp_backup = NULL, *tmp_backup = NULL;
         const char *tmp_dir = NULL, *t;
 
+        log_info("/* %s */", __func__);
+
         t = getenv("TMPDIR");
         if (t) {
                 tmpdir_backup = strdup(t);
@@ -452,6 +474,8 @@ static void test_var_tmp(void) {
 }
 
 static void test_dot_or_dot_dot(void) {
+        log_info("/* %s */", __func__);
+
         assert_se(!dot_or_dot_dot(NULL));
         assert_se(!dot_or_dot_dot(""));
         assert_se(!dot_or_dot_dot("xxx"));
@@ -464,8 +488,12 @@ static void test_dot_or_dot_dot(void) {
 static void test_access_fd(void) {
         _cleanup_(rmdir_and_freep) char *p = NULL;
         _cleanup_close_ int fd = -1;
+        const char *a;
 
-        assert_se(mkdtemp_malloc("/tmp/access-fd.XXXXXX", &p) >= 0);
+        log_info("/* %s */", __func__);
+
+        a = strjoina(arg_test_dir ?: "/tmp", "/access-fd.XXXXXX");
+        assert_se(mkdtemp_malloc(a, &p) >= 0);
 
         fd = open(p, O_RDONLY|O_DIRECTORY|O_CLOEXEC);
         assert_se(fd >= 0);
@@ -493,16 +521,26 @@ static void test_touch_file(void) {
         struct stat st;
         const char *a;
         usec_t test_mtime;
+        int r;
+
+        log_info("/* %s */", __func__);
 
         test_uid = geteuid() == 0 ? 65534 : getuid();
         test_gid = geteuid() == 0 ? 65534 : getgid();
 
         test_mtime = usec_sub_unsigned(now(CLOCK_REALTIME), USEC_PER_WEEK);
 
-        assert_se(mkdtemp_malloc("/dev/shm/touch-file-XXXXXX", &p) >= 0);
+        a = strjoina(arg_test_dir ?: "/dev/shm", "/touch-file-XXXXXX");
+        assert_se(mkdtemp_malloc(a, &p) >= 0);
 
         a = strjoina(p, "/regular");
-        assert_se(touch_file(a, false, test_mtime, test_uid, test_gid, 0640) >= 0);
+        r = touch_file(a, false, test_mtime, test_uid, test_gid, 0640);
+        if (r < 0) {
+                assert_se(IN_SET(r, -EINVAL, -ENOSYS, -ENOTTY, -EPERM));
+                log_tests_skipped_errno(errno, "touch_file() not possible");
+                return;
+        }
+
         assert_se(lstat(a, &st) >= 0);
         assert_se(st.st_uid == test_uid);
         assert_se(st.st_gid == test_gid);
@@ -542,7 +580,12 @@ static void test_touch_file(void) {
 
         if (geteuid() == 0) {
                 a = strjoina(p, "/cdev");
-                assert_se(mknod(a, 0775 | S_IFCHR, makedev(0, 0)) >= 0);
+                r = mknod(a, 0775 | S_IFCHR, makedev(0, 0));
+                if (r < 0 && errno == EPERM && detect_container() > 0) {
+                        log_notice("Running in unprivileged container? Skipping remaining tests in %s", __func__);
+                        return;
+                }
+                assert_se(r >= 0);
                 assert_se(touch_file(a, false, test_mtime, test_uid, test_gid, 0640) >= 0);
                 assert_se(lstat(a, &st) >= 0);
                 assert_se(st.st_uid == test_uid);
@@ -578,7 +621,9 @@ static void test_unlinkat_deallocate(void) {
         _cleanup_close_ int fd = -1;
         struct stat st;
 
-        assert_se(tempfn_random_child(NULL, "unlink-deallocation", &p) >= 0);
+        log_info("/* %s */", __func__);
+
+        assert_se(tempfn_random_child(arg_test_dir, "unlink-deallocation", &p) >= 0);
 
         fd = open(p, O_WRONLY|O_CLOEXEC|O_CREAT|O_EXCL, 0600);
         assert_se(fd >= 0);
@@ -593,7 +638,8 @@ static void test_unlinkat_deallocate(void) {
         assert_se(unlinkat_deallocate(AT_FDCWD, p, 0) >= 0);
 
         assert_se(fstat(fd, &st) >= 0);
-        assert_se(IN_SET(st.st_size, 0, 6)); /* depending on whether hole punching worked the size will be 6 (it worked) or 0 (we had to resort to truncation) */
+        assert_se(IN_SET(st.st_size, 0, 6)); /* depending on whether hole punching worked the size will be 6
+                                                (it worked) or 0 (we had to resort to truncation) */
         assert_se(st.st_blocks == 0);
         assert_se(st.st_nlink == 0);
 }
@@ -601,13 +647,87 @@ static void test_unlinkat_deallocate(void) {
 static void test_fsync_directory_of_file(void) {
         _cleanup_close_ int fd = -1;
 
-        fd = open_tmpfile_unlinkable(NULL, O_RDWR);
+        log_info("/* %s */", __func__);
+
+        fd = open_tmpfile_unlinkable(arg_test_dir, O_RDWR);
         assert_se(fd >= 0);
 
         assert_se(fsync_directory_of_file(fd) >= 0);
 }
 
+static void test_rename_noreplace(void) {
+        static const char* const table[] = {
+                "/reg",
+                "/dir",
+                "/fifo",
+                "/socket",
+                "/symlink",
+                NULL
+        };
+
+        _cleanup_(rm_rf_physical_and_freep) char *z = NULL;
+        const char *j = NULL;
+        char **a, **b;
+
+        log_info("/* %s */", __func__);
+
+        if (arg_test_dir)
+                j = strjoina(arg_test_dir, "/testXXXXXX");
+        assert_se(mkdtemp_malloc(j, &z) >= 0);
+
+        j = strjoina(z, table[0]);
+        assert_se(touch(j) >= 0);
+
+        j = strjoina(z, table[1]);
+        assert_se(mkdir(j, 0777) >= 0);
+
+        j = strjoina(z, table[2]);
+        (void) mkfifo(j, 0777);
+
+        j = strjoina(z, table[3]);
+        (void) mknod(j, S_IFSOCK | 0777, 0);
+
+        j = strjoina(z, table[4]);
+        (void) symlink("foobar", j);
+
+        STRV_FOREACH(a, (char**) table) {
+                _cleanup_free_ char *x = NULL, *y = NULL;
+
+                x = strjoin(z, *a);
+                assert_se(x);
+
+                if (access(x, F_OK) < 0) {
+                        assert_se(errno == ENOENT);
+                        continue;
+                }
+
+                STRV_FOREACH(b, (char**) table) {
+                        _cleanup_free_ char *w = NULL;
+
+                        w = strjoin(w, *b);
+                        assert_se(w);
+
+                        if (access(w, F_OK) < 0) {
+                                assert_se(errno == ENOENT);
+                                continue;
+                        }
+
+                        assert_se(rename_noreplace(AT_FDCWD, w, AT_FDCWD, y) == -EEXIST);
+                }
+
+                y = strjoin(z, "/somethingelse");
+                assert_se(y);
+
+                assert_se(rename_noreplace(AT_FDCWD, x, AT_FDCWD, y) >= 0);
+                assert_se(rename_noreplace(AT_FDCWD, y, AT_FDCWD, x) >= 0);
+        }
+}
+
 int main(int argc, char *argv[]) {
+        test_setup_logging(LOG_INFO);
+
+        arg_test_dir = argv[1];
+
         test_unlink_noerrno();
         test_get_files_in_directory();
         test_readlink_and_make_absolute();
@@ -618,6 +738,7 @@ int main(int argc, char *argv[]) {
         test_touch_file();
         test_unlinkat_deallocate();
         test_fsync_directory_of_file();
+        test_rename_noreplace();
 
         return 0;
 }
index c0956fa4bb35d6a88f10bba9484ea4a2199920e3..73ea68f372c8be0cf6b586d67a80b43213621f80 100644 (file)
@@ -862,7 +862,7 @@ static void test_with_dropin(const char *root) {
         unit_file_changes_free(changes, n_changes);
         changes = NULL; n_changes = 0;
 
-        assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-4a.service"), &changes, &n_changes) == 1);
+        assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-4a.service"), &changes, &n_changes) == 2);
         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-3.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
         assert_se(n_changes == 2);
         assert_se(changes[0].type == UNIT_FILE_SYMLINK);
index 3d63493117260ff24ad3155368d6b37945bd536c..921c304deced330a506268e228452536371f7396 100644 (file)
@@ -405,12 +405,17 @@ static void test_rename_process_now(const char *p, int ret) {
         log_info("comm = <%s>", comm);
         assert_se(strneq(comm, p, TASK_COMM_LEN-1));
 
-        assert_se(get_process_cmdline(0, 0, false, &cmdline) >= 0);
+        r = get_process_cmdline(0, 0, false, &cmdline);
+        assert_se(r >= 0);
         /* we cannot expect cmdline to be renamed properly without privileges */
         if (geteuid() == 0) {
-                log_info("cmdline = <%s>", cmdline);
-                assert_se(strneq(p, cmdline, STRLEN("test-process-util")));
-                assert_se(startswith(p, cmdline));
+                if (r == 0 && detect_container() > 0)
+                        log_info("cmdline = <%s> (not verified, Running in unprivileged container?)", cmdline);
+                else {
+                        log_info("cmdline = <%s>", cmdline);
+                        assert_se(strneq(p, cmdline, STRLEN("test-process-util")));
+                        assert_se(startswith(p, cmdline));
+                }
         } else
                 log_info("cmdline = <%s> (not verified)", cmdline);
 }
diff --git a/src/test/test-sd-hwdb.c b/src/test/test-sd-hwdb.c
new file mode 100644 (file)
index 0000000..b67a853
--- /dev/null
@@ -0,0 +1,74 @@
+#include "sd-hwdb.h"
+
+#include "alloc-util.h"
+#include "errno.h"
+#include "tests.h"
+
+static int test_failed_enumerate(void) {
+        _cleanup_(sd_hwdb_unrefp) sd_hwdb *hwdb;
+        const char *key, *value;
+        int r;
+
+        log_info("/* %s */", __func__);
+
+        r = sd_hwdb_new(&hwdb);
+        if (r == -ENOENT)
+                return r;
+        assert_se(r == 0);
+
+        assert_se(sd_hwdb_seek(hwdb, "no-such-modalias-should-exist") == 0);
+
+        assert_se(sd_hwdb_enumerate(hwdb, &key, &value) == 0);
+        assert_se(sd_hwdb_enumerate(hwdb, &key, NULL) == -EINVAL);
+        assert_se(sd_hwdb_enumerate(hwdb, NULL, &value) == -EINVAL);
+
+        return 0;
+}
+
+#define DELL_MODALIAS \
+        "evdev:atkbd:dmi:bvnXXX:bvrYYY:bdZZZ:svnDellXXX:pnYYY"
+
+static void test_basic_enumerate(void) {
+        _cleanup_(sd_hwdb_unrefp) sd_hwdb *hwdb;
+        const char *key, *value;
+        size_t len1 = 0, len2 = 0;
+        int r;
+
+        log_info("/* %s */", __func__);
+
+        assert_se(sd_hwdb_new(&hwdb) == 0);
+
+        assert_se(sd_hwdb_seek(hwdb, DELL_MODALIAS) == 0);
+
+        for (;;) {
+                r = sd_hwdb_enumerate(hwdb, &key, &value);
+                assert(IN_SET(r, 0, 1));
+                if (r == 0)
+                        break;
+                assert(key);
+                assert(value);
+                log_debug("A: \"%s\" → \"%s\"", key, value);
+                len1 += strlen(key) + strlen(value);
+        }
+
+        SD_HWDB_FOREACH_PROPERTY(hwdb, DELL_MODALIAS, key, value) {
+                log_debug("B: \"%s\" → \"%s\"", key, value);
+                len2 += strlen(key) + strlen(value);
+        }
+
+        assert_se(len1 == len2);
+}
+
+int main(int argc, char *argv[]) {
+        int r;
+
+        test_setup_logging(LOG_DEBUG);
+
+        r = test_failed_enumerate();
+        if (r < 0)
+                return log_tests_skipped_errno(r, "cannot open hwdb");
+
+        test_basic_enumerate();
+
+        return 0;
+}
index b2ac392dac206a8e18818c48d645450dc80dc1b9..00cd216a4bdd5e96b21c67366caca348d45edf76 100644 (file)
@@ -36,6 +36,8 @@ static void test_seccomp_arch_to_string(void) {
         uint32_t a, b;
         const char *name;
 
+        log_info("/* %s */", __func__);
+
         a = seccomp_arch_native();
         assert_se(a > 0);
         name = seccomp_arch_to_string(a);
@@ -47,6 +49,8 @@ static void test_seccomp_arch_to_string(void) {
 static void test_architecture_table(void) {
         const char *n, *n2;
 
+        log_info("/* %s */", __func__);
+
         NULSTR_FOREACH(n,
                        "native\0"
                        "x86\0"
@@ -75,6 +79,8 @@ static void test_architecture_table(void) {
 }
 
 static void test_syscall_filter_set_find(void) {
+        log_info("/* %s */", __func__);
+
         assert_se(!syscall_filter_set_find(NULL));
         assert_se(!syscall_filter_set_find(""));
         assert_se(!syscall_filter_set_find("quux"));
@@ -89,6 +95,8 @@ static void test_filter_sets(void) {
         unsigned i;
         int r;
 
+        log_info("/* %s */", __func__);
+
         if (!is_seccomp_available()) {
                 log_notice("Seccomp not available, skipping %s", __func__);
                 return;
@@ -109,11 +117,11 @@ static void test_filter_sets(void) {
                 if (pid == 0) { /* Child? */
                         int fd;
 
-                        /* if we look at the default set (or one that includes it), whitelist instead of blacklist */
+                        /* If we look at the default set (or one that includes it), whitelist instead of blacklist */
                         if (IN_SET(i, SYSCALL_FILTER_SET_DEFAULT, SYSCALL_FILTER_SET_SYSTEM_SERVICE))
-                                r = seccomp_load_syscall_filter_set(SCMP_ACT_ERRNO(EUCLEAN), syscall_filter_sets + i, SCMP_ACT_ALLOW);
+                                r = seccomp_load_syscall_filter_set(SCMP_ACT_ERRNO(EUCLEAN), syscall_filter_sets + i, SCMP_ACT_ALLOW, true);
                         else
-                                r = seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + i, SCMP_ACT_ERRNO(EUCLEAN));
+                                r = seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + i, SCMP_ACT_ERRNO(EUCLEAN), true);
                         if (r < 0)
                                 _exit(EXIT_FAILURE);
 
@@ -133,11 +141,45 @@ static void test_filter_sets(void) {
         }
 }
 
+static void test_filter_sets_ordered(void) {
+        size_t i;
+
+        log_info("/* %s */", __func__);
+
+        /* Ensure "@default" always remains at the beginning of the list */
+        assert_se(SYSCALL_FILTER_SET_DEFAULT == 0);
+        assert_se(streq(syscall_filter_sets[0].name, "@default"));
+
+        for (i = 0; i < _SYSCALL_FILTER_SET_MAX; i++) {
+                const char *k, *p = NULL;
+
+                /* Make sure each group has a description */
+                assert_se(!isempty(syscall_filter_sets[0].help));
+
+                /* Make sure the groups are ordered alphabetically, except for the first entry */
+                assert_se(i < 2 || strcmp(syscall_filter_sets[i-1].name, syscall_filter_sets[i].name) < 0);
+
+                NULSTR_FOREACH(k, syscall_filter_sets[i].value) {
+
+                        /* Ensure each syscall list is in itself ordered, but groups before names */
+                        assert_se(!p ||
+                                  (*p == '@' && *k != '@') ||
+                                  (((*p == '@' && *k == '@') ||
+                                    (*p != '@' && *k != '@')) &&
+                                   strcmp(p, k) < 0));
+
+                        p = k;
+                }
+        }
+}
+
 static void test_restrict_namespace(void) {
         char *s = NULL;
         unsigned long ul;
         pid_t pid;
 
+        log_info("/* %s */", __func__);
+
         assert_se(namespace_flags_to_string(0, &s) == 0 && streq(s, ""));
         s = mfree(s);
         assert_se(namespace_flags_to_string(CLONE_NEWNS, &s) == 0 && streq(s, "mnt"));
@@ -232,6 +274,8 @@ static void test_restrict_namespace(void) {
 static void test_protect_sysctl(void) {
         pid_t pid;
 
+        log_info("/* %s */", __func__);
+
         if (!is_seccomp_available()) {
                 log_notice("Seccomp not available, skipping %s", __func__);
                 return;
@@ -272,6 +316,8 @@ static void test_protect_sysctl(void) {
 static void test_restrict_address_families(void) {
         pid_t pid;
 
+        log_info("/* %s */", __func__);
+
         if (!is_seccomp_available()) {
                 log_notice("Seccomp not available, skipping %s", __func__);
                 return;
@@ -359,6 +405,8 @@ static void test_restrict_address_families(void) {
 static void test_restrict_realtime(void) {
         pid_t pid;
 
+        log_info("/* %s */", __func__);
+
         if (!is_seccomp_available()) {
                 log_notice("Seccomp not available, skipping %s", __func__);
                 return;
@@ -404,6 +452,8 @@ static void test_restrict_realtime(void) {
 static void test_memory_deny_write_execute_mmap(void) {
         pid_t pid;
 
+        log_info("/* %s */", __func__);
+
         if (!is_seccomp_available()) {
                 log_notice("Seccomp not available, skipping %s", __func__);
                 return;
@@ -452,6 +502,8 @@ static void test_memory_deny_write_execute_shmat(void) {
         int shmid;
         pid_t pid;
 
+        log_info("/* %s */", __func__);
+
         if (!is_seccomp_available()) {
                 log_notice("Seccomp not available, skipping %s", __func__);
                 return;
@@ -502,6 +554,8 @@ static void test_memory_deny_write_execute_shmat(void) {
 static void test_restrict_archs(void) {
         pid_t pid;
 
+        log_info("/* %s */", __func__);
+
         if (!is_seccomp_available()) {
                 log_notice("Seccomp not available, skipping %s", __func__);
                 return;
@@ -540,6 +594,8 @@ static void test_restrict_archs(void) {
 static void test_load_syscall_filter_set_raw(void) {
         pid_t pid;
 
+        log_info("/* %s */", __func__);
+
         if (!is_seccomp_available()) {
                 log_notice("Seccomp not available, skipping %s", __func__);
                 return;
@@ -558,7 +614,7 @@ static void test_load_syscall_filter_set_raw(void) {
                 assert_se(access("/", F_OK) >= 0);
                 assert_se(poll(NULL, 0, 0) == 0);
 
-                assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, NULL, SCMP_ACT_KILL) >= 0);
+                assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, NULL, SCMP_ACT_KILL, true) >= 0);
                 assert_se(access("/", F_OK) >= 0);
                 assert_se(poll(NULL, 0, 0) == 0);
 
@@ -569,7 +625,7 @@ static void test_load_syscall_filter_set_raw(void) {
                 assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_faccessat + 1), INT_TO_PTR(-1)) >= 0);
 #endif
 
-                assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUCLEAN)) >= 0);
+                assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUCLEAN), true) >= 0);
 
                 assert_se(access("/", F_OK) < 0);
                 assert_se(errno == EUCLEAN);
@@ -585,7 +641,7 @@ static void test_load_syscall_filter_set_raw(void) {
                 assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_faccessat + 1), INT_TO_PTR(EILSEQ)) >= 0);
 #endif
 
-                assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUCLEAN)) >= 0);
+                assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUCLEAN), true) >= 0);
 
                 assert_se(access("/", F_OK) < 0);
                 assert_se(errno == EILSEQ);
@@ -601,7 +657,7 @@ static void test_load_syscall_filter_set_raw(void) {
                 assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_ppoll + 1), INT_TO_PTR(-1)) >= 0);
 #endif
 
-                assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUNATCH)) >= 0);
+                assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUNATCH), true) >= 0);
 
                 assert_se(access("/", F_OK) < 0);
                 assert_se(errno == EILSEQ);
@@ -618,7 +674,7 @@ static void test_load_syscall_filter_set_raw(void) {
                 assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_ppoll + 1), INT_TO_PTR(EILSEQ)) >= 0);
 #endif
 
-                assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUNATCH)) >= 0);
+                assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUNATCH), true) >= 0);
 
                 assert_se(access("/", F_OK) < 0);
                 assert_se(errno == EILSEQ);
@@ -636,6 +692,8 @@ static void test_lock_personality(void) {
         unsigned long current;
         pid_t pid;
 
+        log_info("/* %s */", __func__);
+
         if (!is_seccomp_available()) {
                 log_notice("Seccomp not available, skipping %s", __func__);
                 return;
@@ -683,44 +741,14 @@ static void test_lock_personality(void) {
         assert_se(wait_for_terminate_and_check("lockpersonalityseccomp", pid, WAIT_LOG) == EXIT_SUCCESS);
 }
 
-static void test_filter_sets_ordered(void) {
-        size_t i;
-
-        /* Ensure "@default" always remains at the beginning of the list */
-        assert_se(SYSCALL_FILTER_SET_DEFAULT == 0);
-        assert_se(streq(syscall_filter_sets[0].name, "@default"));
-
-        for (i = 0; i < _SYSCALL_FILTER_SET_MAX; i++) {
-                const char *k, *p = NULL;
-
-                /* Make sure each group has a description */
-                assert_se(!isempty(syscall_filter_sets[0].help));
-
-                /* Make sure the groups are ordered alphabetically, except for the first entry */
-                assert_se(i < 2 || strcmp(syscall_filter_sets[i-1].name, syscall_filter_sets[i].name) < 0);
-
-                NULSTR_FOREACH(k, syscall_filter_sets[i].value) {
-
-                        /* Ensure each syscall list is in itself ordered, but groups before names */
-                        assert_se(!p ||
-                                  (*p == '@' && *k != '@') ||
-                                  (((*p == '@' && *k == '@') ||
-                                    (*p != '@' && *k != '@')) &&
-                                   strcmp(p, k) < 0));
-
-                        p = k;
-                }
-        }
-}
-
 int main(int argc, char *argv[]) {
-
         test_setup_logging(LOG_DEBUG);
 
         test_seccomp_arch_to_string();
         test_architecture_table();
         test_syscall_filter_set_find();
         test_filter_sets();
+        test_filter_sets_ordered();
         test_restrict_namespace();
         test_protect_sysctl();
         test_restrict_address_families();
@@ -730,7 +758,6 @@ int main(int argc, char *argv[]) {
         test_restrict_archs();
         test_load_syscall_filter_set_raw();
         test_lock_personality();
-        test_filter_sets_ordered();
 
         return 0;
 }
index a9f261839cb4207938c6d1c621d578f0536ad9ec..8c1f91d4ef0bef17a89a15d7cea9abecfeacda60 100644 (file)
@@ -5,6 +5,7 @@
 #include "macro.h"
 #include "string-util.h"
 #include "strv.h"
+#include "tests.h"
 #include "utf8.h"
 
 static void test_string_erase(void) {
@@ -30,6 +31,64 @@ static void test_string_erase(void) {
         assert_se(x[9] == '\0');
 }
 
+static void test_free_and_strndup_one(char **t, const char *src, size_t l, const char *expected, bool change) {
+        int r;
+
+        log_debug("%s: \"%s\", \"%s\", %zd (expect \"%s\", %s)",
+                  __func__, strnull(*t), strnull(src), l, strnull(expected), yes_no(change));
+
+        r = free_and_strndup(t, src, l);
+        assert_se(streq_ptr(*t, expected));
+        assert_se(r == change); /* check that change occurs only when necessary */
+}
+
+static void test_free_and_strndup(void) {
+        static const struct test_case {
+                const char *src;
+                size_t len;
+                const char *expected;
+        } cases[] = {
+                     {"abc", 0, ""},
+                     {"abc", 0, ""},
+                     {"abc", 1, "a"},
+                     {"abc", 2, "ab"},
+                     {"abc", 3, "abc"},
+                     {"abc", 4, "abc"},
+                     {"abc", 5, "abc"},
+                     {"abc", 5, "abc"},
+                     {"abc", 4, "abc"},
+                     {"abc", 3, "abc"},
+                     {"abc", 2, "ab"},
+                     {"abc", 1, "a"},
+                     {"abc", 0, ""},
+
+                     {"", 0, ""},
+                     {"", 1, ""},
+                     {"", 2, ""},
+                     {"", 0, ""},
+                     {"", 1, ""},
+                     {"", 2, ""},
+                     {"", 2, ""},
+                     {"", 1, ""},
+                     {"", 0, ""},
+
+                     {NULL, 0, NULL},
+
+                     {"foo", 3, "foo"},
+                     {"foobar", 6, "foobar"},
+        };
+
+        _cleanup_free_ char *t = NULL;
+        const char *prev_expected = t;
+
+        for (unsigned i = 0; i < ELEMENTSOF(cases); i++) {
+                test_free_and_strndup_one(&t,
+                                          cases[i].src, cases[i].len, cases[i].expected,
+                                          !streq_ptr(cases[i].expected, prev_expected));
+                prev_expected = t;
+        }
+}
+
 static void test_ascii_strcasecmp_n(void) {
 
         assert_se(ascii_strcasecmp_n("", "", 0) == 0);
@@ -520,7 +579,10 @@ static void test_memory_startswith_no_case(void) {
 }
 
 int main(int argc, char *argv[]) {
+        test_setup_logging(LOG_DEBUG);
+
         test_string_erase();
+        test_free_and_strndup();
         test_ascii_strcasecmp_n();
         test_ascii_strcasecmp_nn();
         test_cellescape();
index d35daf53dca326548df5b1bf0aad4f4dba8ae165..9849530ac88c33c0ac03d177da9114224a2d51fc 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "alloc-util.h"
 #include "string-util.h"
+#include "strv.h"
 #include "utf8.h"
 #include "util.h"
 
@@ -87,15 +88,25 @@ static void test_utf8_escaping_printable(void) {
 }
 
 static void test_utf16_to_utf8(void) {
-        char *a = NULL;
-        const uint16_t utf16[] = { htole16('a'), htole16(0xd800), htole16('b'), htole16(0xdc00), htole16('c'), htole16(0xd801), htole16(0xdc37) };
-        const char utf8[] = { 'a', 'b', 'c', 0xf0, 0x90, 0x90, 0xb7, 0 };
+        const char16_t utf16[] = { htole16('a'), htole16(0xd800), htole16('b'), htole16(0xdc00), htole16('c'), htole16(0xd801), htole16(0xdc37) };
+        static const char utf8[] = { 'a', 'b', 'c', 0xf0, 0x90, 0x90, 0xb7 };
+        _cleanup_free_ char16_t *b = NULL;
+        _cleanup_free_ char *a = NULL;
 
-        a = utf16_to_utf8(utf16, 14);
+        /* Convert UTF-16 to UTF-8, filtering embedded bad chars */
+        a = utf16_to_utf8(utf16, sizeof(utf16));
         assert_se(a);
-        assert_se(streq(a, utf8));
+        assert_se(memcmp(a, utf8, sizeof(utf8)) == 0);
+
+        /* Convert UTF-8 to UTF-16, and back */
+        b = utf8_to_utf16(utf8, sizeof(utf8));
+        assert_se(b);
 
         free(a);
+        a = utf16_to_utf8(b, char16_strlen(b) * 2);
+        assert_se(a);
+        assert_se(strlen(a) == sizeof(utf8));
+        assert_se(memcmp(a, utf8, sizeof(utf8)) == 0);
 }
 
 static void test_utf8_n_codepoints(void) {
@@ -116,6 +127,28 @@ static void test_utf8_console_width(void) {
         assert_se(utf8_console_width("\xF1") == (size_t) -1);
 }
 
+static void test_utf8_to_utf16(void) {
+        const char *p;
+
+        FOREACH_STRING(p,
+                       "abc",
+                       "zażółcić gęślą jaźń",
+                       "串",
+                       "",
+                       "…👊🔪💐…") {
+
+                _cleanup_free_ char16_t *a = NULL;
+                _cleanup_free_ char *b = NULL;
+
+                a = utf8_to_utf16(p, strlen(p));
+                assert_se(a);
+
+                b = utf16_to_utf8(a, char16_strlen(a) * 2);
+                assert_se(b);
+                assert_se(streq(p, b));
+        }
+}
+
 int main(int argc, char *argv[]) {
         test_utf8_is_valid();
         test_utf8_is_printable();
@@ -127,6 +160,7 @@ int main(int argc, char *argv[]) {
         test_utf16_to_utf8();
         test_utf8_n_codepoints();
         test_utf8_console_width();
+        test_utf8_to_utf16();
 
         return 0;
 }
index 51c0cea7feb2cbd41825ec928a559b3ad8af4607..d5cf82ed7ac340fdcbd381fcd26db375246e3bb7 100644 (file)
@@ -56,6 +56,25 @@ static const char* const netdev_feature_table[_NET_DEV_FEAT_MAX] = {
         [NET_DEV_FEAT_TSO6] = "tx-tcp6-segmentation",
 };
 
+static const char* const advertise_table[_NET_DEV_ADVERTISE_MAX] = {
+        [NET_DEV_ADVERTISE_10BASET_HALF]        = "10baset-half",
+        [NET_DEV_ADVERTISE_10BASET_FULL]        = "10baset-full",
+        [NET_DEV_ADVERTISE_100BASET_HALF]       = "100baset-half",
+        [NET_DEV_ADVERTISE_100BASET_FULL]       = "100baset-full",
+        [NET_DEV_ADVERTISE_1000BASET_HALF]      = "1000baset-half",
+        [NET_DEV_ADVERTISE_1000BASET_FULL]      = "1000baset-full",
+        [NET_DEV_ADVERTISE_10000BASET_FULL]     = "10000baset-full",
+        [NET_DEV_ADVERTISE_2500BASEX_FULL]      = "2500basex-full",
+        [NET_DEV_ADVERTISE_1000BASEKX_FULL]     = "1000basekx-full",
+        [NET_DEV_ADVERTISE_10000BASEKX4_FULL]   = "10000basekx4-full",
+        [NET_DEV_ADVERTISE_10000BASEKR_FULL]    = "10000basekr-full",
+        [NET_DEV_ADVERTISE_10000BASER_FEC]      = "10000baser-fec",
+        [NET_DEV_ADVERTISE_20000BASEMLD2_Full]  = "20000basemld2-full",
+        [NET_DEV_ADVERTISE_20000BASEKR2_Full]   = "20000basekr2-full",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(advertise, NetDevAdvertise);
+
 int ethtool_connect(int *ret) {
         int fd;
 
@@ -501,6 +520,8 @@ static int set_sset(int fd, struct ifreq *ifr, const struct ethtool_link_usettin
         ecmd.phy_address = u->base.phy_address;
         ecmd.autoneg = u->base.autoneg;
         ecmd.mdio_support = u->base.mdio_support;
+        ecmd.eth_tp_mdix = u->base.eth_tp_mdix;
+        ecmd.eth_tp_mdix_ctrl = u->base.eth_tp_mdix_ctrl;
 
         ifr->ifr_data = (void *) &ecmd;
 
@@ -517,7 +538,6 @@ static int set_sset(int fd, struct ifreq *ifr, const struct ethtool_link_usettin
  * link mode; if the link is down, the speed is 0, %SPEED_UNKNOWN or the highest
  * enabled speed and @duplex is %DUPLEX_UNKNOWN or the best enabled duplex mode.
  */
-
 int ethtool_set_glinksettings(int *fd, const char *ifname, struct link_config *link) {
         _cleanup_free_ struct ethtool_link_usettings *u = NULL;
         struct ifreq ifr = {};
@@ -554,6 +574,13 @@ int ethtool_set_glinksettings(int *fd, const char *ifname, struct link_config *l
 
         u->base.autoneg = link->autonegotiation;
 
+        if (link->advertise) {
+                uint32_t advertise[ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32] = {};
+
+                advertise[0] = link->advertise;
+                memcpy(&u->link_modes.advertising, advertise, ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBYTES);
+        }
+
         if (u->base.cmd == ETHTOOL_GLINKSETTINGS)
                 r = set_slinksettings(*fd, &ifr, u);
         else
@@ -665,3 +692,56 @@ int ethtool_set_channels(int *fd, const char *ifname, netdev_channels *channels)
 
         return 0;
 }
+
+int config_parse_advertise(const char *unit,
+                           const char *filename,
+                           unsigned line,
+                           const char *section,
+                           unsigned section_line,
+                           const char *lvalue,
+                           int ltype,
+                           const char *rvalue,
+                           void *data,
+                           void *userdata) {
+        link_config *config = data;
+        NetDevAdvertise mode, a = 0;
+        const char *p;
+        int r;
+
+        assert(filename);
+        assert(section);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if (isempty(rvalue)) {
+                /* Empty string resets the value. */
+                config->advertise = 0;
+                return 0;
+        }
+
+        for (p = rvalue;;) {
+                _cleanup_free_ char *w = NULL;
+
+                r = extract_first_word(&p, &w, NULL, 0);
+                if (r == -ENOMEM)
+                        return log_oom();
+                if (r < 0) {
+                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to split advertise modes '%s', ignoring: %m", rvalue);
+                        break;
+                }
+                if (r == 0)
+                        break;
+
+                mode = advertise_from_string(w);
+                if (mode == _NET_DEV_ADVERTISE_INVALID) {
+                        log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse advertise mode, ignoring: %s", w);
+                        continue;
+                }
+                a |= mode;
+        }
+
+        config->advertise |= a;
+
+        return 0;
+}
index 2aa067a32b54ac76eb3cdd099602ed2f95ea9ad3..208bf75061c33c532cfc1918a1cdc7a69a2d2748 100644 (file)
@@ -53,7 +53,27 @@ typedef enum NetDevPort {
         _NET_DEV_PORT_INVALID = -1
 } NetDevPort;
 
+typedef enum NetDevAdvertise {
+        NET_DEV_ADVERTISE_10BASET_HALF        =  1 << ETHTOOL_LINK_MODE_10baseT_Half_BIT,
+        NET_DEV_ADVERTISE_10BASET_FULL        =  1 << ETHTOOL_LINK_MODE_10baseT_Full_BIT,
+        NET_DEV_ADVERTISE_100BASET_HALF       =  1 << ETHTOOL_LINK_MODE_100baseT_Half_BIT,
+        NET_DEV_ADVERTISE_100BASET_FULL       =  1 << ETHTOOL_LINK_MODE_100baseT_Full_BIT,
+        NET_DEV_ADVERTISE_1000BASET_HALF      =  1 << ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
+        NET_DEV_ADVERTISE_1000BASET_FULL      =  1 << ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+        NET_DEV_ADVERTISE_10000BASET_FULL     =  1 << ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
+        NET_DEV_ADVERTISE_2500BASEX_FULL      =  1 << ETHTOOL_LINK_MODE_2500baseX_Full_BIT,
+        NET_DEV_ADVERTISE_1000BASEKX_FULL     =  1 << ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
+        NET_DEV_ADVERTISE_10000BASEKX4_FULL   =  1 << ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
+        NET_DEV_ADVERTISE_10000BASEKR_FULL    =  1 << ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
+        NET_DEV_ADVERTISE_10000BASER_FEC      =  1 << ETHTOOL_LINK_MODE_10000baseR_FEC_BIT,
+        NET_DEV_ADVERTISE_20000BASEMLD2_Full  =  1 << ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT,
+        NET_DEV_ADVERTISE_20000BASEKR2_Full   =  1 << ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT,
+        _NET_DEV_ADVERTISE_MAX,
+        _NET_DEV_ADVERTISE_INVALID = -1,
+} NetDevAdvertise;
+
 #define ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32    (SCHAR_MAX)
+#define ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBYTES  (4 * ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32)
 
 /* layout of the struct passed from/to userland */
 struct ethtool_link_usettings {
@@ -96,7 +116,11 @@ WakeOnLan wol_from_string(const char *wol) _pure_;
 const char *port_to_string(NetDevPort port) _const_;
 NetDevPort port_from_string(const char *port) _pure_;
 
+const char *advertise_to_string(NetDevAdvertise advertise) _const_;
+NetDevAdvertise advertise_from_string(const char *advertise) _pure_;
+
 int config_parse_duplex(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_wol(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_port(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_channel(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_advertise(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
index 5640fa051376820cc3be5c2761511bf1fe39dc14..2bc18bff56a76acf2453de3f5177a9e8b86065b2 100644 (file)
@@ -51,3 +51,4 @@ Link.RxChannels,                 config_parse_channel,       0,
 Link.TxChannels,                 config_parse_channel,       0,                             0
 Link.OtherChannels,              config_parse_channel,       0,                             0
 Link.CombinedChannels,           config_parse_channel,       0,                             0
+Link.Advertise,                  config_parse_advertise,     0,                             0
index e9f7e7429f63b73e24b36f732b0ab80a20bcd8eb..fd1c205d120d6362929003434c828ab7b17f49f7 100644 (file)
@@ -376,13 +376,21 @@ int link_config_apply(link_config_ctx *ctx, link_config *config,
                 if (config->port != _NET_DEV_PORT_INVALID)
                         log_warning_errno(r,  "Could not set port (%s) of %s: %m", port_to_string(config->port), old_name);
 
-                speed = DIV_ROUND_UP(config->speed, 1000000);
-                if (r == -EOPNOTSUPP)
-                        r = ethtool_set_speed(&ctx->ethtool_fd, old_name, speed, config->duplex);
+                if (config->advertise)
+                        log_warning_errno(r, "Could not set advertise mode to 0x%X: %m", config->advertise);
 
-                if (r < 0)
-                        log_warning_errno(r, "Could not set speed or duplex of %s to %u Mbps (%s): %m",
-                                          old_name, speed, duplex_to_string(config->duplex));
+                if (config->speed) {
+
+                        speed = DIV_ROUND_UP(config->speed, 1000000);
+                        if (r == -EOPNOTSUPP) {
+                                r = ethtool_set_speed(&ctx->ethtool_fd, old_name, speed, config->duplex);
+                                if (r < 0)
+                                        log_warning_errno(r, "Could not set speed of %s to %u Mbps: %m", old_name, speed);
+                        }
+                }
+
+                if (config->duplex !=_DUP_INVALID)
+                        log_warning_errno(r, "Could not set duplex of %s to (%s): %m", old_name, duplex_to_string(config->duplex));
         }
 
         r = ethtool_set_wol(&ctx->ethtool_fd, old_name, config->wol);
index 3f78785faa4390c8f03c5259e676c646e43380d8..ca6c8ddabe7b7bd5ee0a83b756c81f0ab591ca85 100644 (file)
@@ -54,6 +54,7 @@ struct link_config {
         size_t speed;
         Duplex duplex;
         int autonegotiation;
+        uint32_t advertise;
         WakeOnLan wol;
         NetDevPort port;
         int features[_NET_DEV_FEAT_MAX];
index d61826c6600875d10f5ce1e0ee4ca885b1ae240f..834172c388953a763b0b02eab762dee2bb768c7e 100644 (file)
@@ -222,6 +222,7 @@ static int dev_pci_onboard(struct udev_device *dev, struct netnames *names) {
         const char *attr, *port_name;
         size_t l;
         char *s;
+        int r;
 
         /* ACPI _DSM  — device specific method for naming a PCI or PCI Express device */
         attr = udev_device_get_sysattr_value(names->pcidev, "acpi_index");
@@ -231,9 +232,9 @@ static int dev_pci_onboard(struct udev_device *dev, struct netnames *names) {
         if (!attr)
                 return -ENOENT;
 
-        idx = strtoul(attr, NULL, 0);
-        if (idx <= 0)
-                return -EINVAL;
+        r = safe_atolu(attr, &idx);
+        if (r < 0)
+                return r;
 
         /* Some BIOSes report rubbish indexes that are excessively high (2^24-1 is an index VMware likes to report for
          * example). Let's define a cut-off where we don't consider the index reliable anymore. We pick some arbitrary
@@ -317,15 +318,14 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) {
                  * provide the port number in the 'dev_id' sysfs attribute instead of 'dev_port',
                  * which thus stays initialized as 0. */
                 if (dev_port == 0) {
-                        unsigned long type;
-
                         attr = udev_device_get_sysattr_value(dev, "type");
-                        /* The 'type' attribute always exists. */
-                        type = strtoul(attr, NULL, 10);
-                        if (type == ARPHRD_INFINIBAND) {
-                                attr = udev_device_get_sysattr_value(dev, "dev_id");
-                                if (attr)
-                                        dev_port = strtoul(attr, NULL, 16);
+                        if (attr) {
+                                unsigned long type = strtoul(attr, NULL, 10);
+                                if (type == ARPHRD_INFINIBAND) {
+                                        attr = udev_device_get_sysattr_value(dev, "dev_id");
+                                        if (attr)
+                                                dev_port = strtoul(attr, NULL, 16);
+                                }
                         }
                 }
         }
diff --git a/test/fuzz-regressions/.gitattributes b/test/fuzz-regressions/.gitattributes
deleted file mode 100644 (file)
index 7b1b3e1..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/*/*       -whitespace
diff --git a/test/fuzz-regressions/meson.build b/test/fuzz-regressions/meson.build
deleted file mode 100644 (file)
index 80b062d..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1+
-
-sanitize_address = custom_target(
-        'sanitize-address-fuzzers',
-        output : 'sanitize-address-fuzzers',
-        command : [meson_build_sh,
-                   meson.source_root(),
-                   '@OUTPUT@',
-                   'fuzzers',
-                   '-Db_lundef=false -Db_sanitize=address'])
-
-sanitizers = [['address', sanitize_address]]
-
-fuzz_regression_tests = '''
-        fuzz-dns-packet/issue-7888
-        fuzz-dns-packet/oss-fuzz-5465
-        fuzz-journal-remote/crash-5a8f03d4c3a46fcded39527084f437e8e4b54b76
-        fuzz-journal-remote/crash-96dee870ea66d03e89ac321eee28ea63a9b9aa45
-        fuzz-journal-remote/oss-fuzz-8659
-        fuzz-journal-remote/oss-fuzz-8686
-        fuzz-journald-syslog/github-9795
-        fuzz-journald-syslog/github-9820
-        fuzz-journald-syslog/github-9827
-        fuzz-journald-syslog/github-9829
-        fuzz-unit-file/oss-fuzz-6884
-        fuzz-unit-file/oss-fuzz-6885
-        fuzz-unit-file/oss-fuzz-6886
-        fuzz-unit-file/oss-fuzz-6892
-        fuzz-unit-file/oss-fuzz-6897
-        fuzz-unit-file/oss-fuzz-6897-evverx
-        fuzz-unit-file/oss-fuzz-6908
-        fuzz-unit-file/oss-fuzz-6917
-        fuzz-unit-file/oss-fuzz-6977
-        fuzz-unit-file/oss-fuzz-6977-unminimized
-        fuzz-unit-file/oss-fuzz-7004
-        fuzz-unit-file/oss-fuzz-8064
-        fuzz-unit-file/oss-fuzz-8827
-        fuzz-unit-file/oss-fuzz-10007
-'''.split()
diff --git a/test/fuzz/fuzz-bus-message/crash-26bba7182dedc8848939931d9fcefcb7922f2e56 b/test/fuzz/fuzz-bus-message/crash-26bba7182dedc8848939931d9fcefcb7922f2e56
new file mode 100644 (file)
index 0000000..f1bf322
Binary files /dev/null and b/test/fuzz/fuzz-bus-message/crash-26bba7182dedc8848939931d9fcefcb7922f2e56 differ
diff --git a/test/fuzz/fuzz-bus-message/crash-29ed3c202e0ffade3cad42c8bbeb6cc68a21eb8e b/test/fuzz/fuzz-bus-message/crash-29ed3c202e0ffade3cad42c8bbeb6cc68a21eb8e
new file mode 100644 (file)
index 0000000..4488f0a
Binary files /dev/null and b/test/fuzz/fuzz-bus-message/crash-29ed3c202e0ffade3cad42c8bbeb6cc68a21eb8e differ
diff --git a/test/fuzz/fuzz-bus-message/crash-32bf69483cbd4f2e6d46c25a2f92a472109aee45 b/test/fuzz/fuzz-bus-message/crash-32bf69483cbd4f2e6d46c25a2f92a472109aee45
new file mode 100644 (file)
index 0000000..aa0c6ff
Binary files /dev/null and b/test/fuzz/fuzz-bus-message/crash-32bf69483cbd4f2e6d46c25a2f92a472109aee45 differ
diff --git a/test/fuzz/fuzz-bus-message/crash-37449529b1ad867f0c2671fa80aca5d7812a2b70 b/test/fuzz/fuzz-bus-message/crash-37449529b1ad867f0c2671fa80aca5d7812a2b70
new file mode 100644 (file)
index 0000000..6a20265
Binary files /dev/null and b/test/fuzz/fuzz-bus-message/crash-37449529b1ad867f0c2671fa80aca5d7812a2b70 differ
diff --git a/test/fuzz/fuzz-bus-message/crash-4162a61a79e4c5a832ca5232212f75fa560a1f75 b/test/fuzz/fuzz-bus-message/crash-4162a61a79e4c5a832ca5232212f75fa560a1f75
new file mode 100644 (file)
index 0000000..5faf330
Binary files /dev/null and b/test/fuzz/fuzz-bus-message/crash-4162a61a79e4c5a832ca5232212f75fa560a1f75 differ
diff --git a/test/fuzz/fuzz-bus-message/crash-4f0211eb269e28db941961061494bfdbf3345e54 b/test/fuzz/fuzz-bus-message/crash-4f0211eb269e28db941961061494bfdbf3345e54
new file mode 100644 (file)
index 0000000..865b295
Binary files /dev/null and b/test/fuzz/fuzz-bus-message/crash-4f0211eb269e28db941961061494bfdbf3345e54 differ
diff --git a/test/fuzz/fuzz-bus-message/crash-603dfd98252375ac7dbced53c2ec312671939a36 b/test/fuzz/fuzz-bus-message/crash-603dfd98252375ac7dbced53c2ec312671939a36
new file mode 100644 (file)
index 0000000..b3fee9e
Binary files /dev/null and b/test/fuzz/fuzz-bus-message/crash-603dfd98252375ac7dbced53c2ec312671939a36 differ
diff --git a/test/fuzz/fuzz-bus-message/crash-b88ad9ecf4aacf4a0caca5b5543953265367f084 b/test/fuzz/fuzz-bus-message/crash-b88ad9ecf4aacf4a0caca5b5543953265367f084
new file mode 100644 (file)
index 0000000..5246965
Binary files /dev/null and b/test/fuzz/fuzz-bus-message/crash-b88ad9ecf4aacf4a0caca5b5543953265367f084 differ
diff --git a/test/fuzz/fuzz-bus-message/crash-c1b37b4729b42c0c05b23cba4eed5d8102498a1e b/test/fuzz/fuzz-bus-message/crash-c1b37b4729b42c0c05b23cba4eed5d8102498a1e
new file mode 100644 (file)
index 0000000..2ae1a87
Binary files /dev/null and b/test/fuzz/fuzz-bus-message/crash-c1b37b4729b42c0c05b23cba4eed5d8102498a1e differ
diff --git a/test/fuzz/fuzz-bus-message/crash-d8f3941c74219b4c03532c9b244d5ea539c61af5 b/test/fuzz/fuzz-bus-message/crash-d8f3941c74219b4c03532c9b244d5ea539c61af5
new file mode 100644 (file)
index 0000000..26262e1
Binary files /dev/null and b/test/fuzz/fuzz-bus-message/crash-d8f3941c74219b4c03532c9b244d5ea539c61af5 differ
diff --git a/test/fuzz/fuzz-bus-message/crash-e1b811da5ca494e494b77c6bd8e1c2f2989425c5 b/test/fuzz/fuzz-bus-message/crash-e1b811da5ca494e494b77c6bd8e1c2f2989425c5
new file mode 100644 (file)
index 0000000..9d3fa00
Binary files /dev/null and b/test/fuzz/fuzz-bus-message/crash-e1b811da5ca494e494b77c6bd8e1c2f2989425c5 differ
diff --git a/test/fuzz/fuzz-bus-message/leak-c09c0e2256d43bc5e2d02748c8d8760e7bc25d20 b/test/fuzz/fuzz-bus-message/leak-c09c0e2256d43bc5e2d02748c8d8760e7bc25d20
new file mode 100644 (file)
index 0000000..c371824
Binary files /dev/null and b/test/fuzz/fuzz-bus-message/leak-c09c0e2256d43bc5e2d02748c8d8760e7bc25d20 differ
diff --git a/test/fuzz/fuzz-bus-message/message1 b/test/fuzz/fuzz-bus-message/message1
new file mode 100644 (file)
index 0000000..2df70fd
Binary files /dev/null and b/test/fuzz/fuzz-bus-message/message1 differ
diff --git a/test/fuzz/fuzz-bus-message/timeout-08ee8f6446a4064db064e8e0b3d220147f7d0b5b b/test/fuzz/fuzz-bus-message/timeout-08ee8f6446a4064db064e8e0b3d220147f7d0b5b
new file mode 100644 (file)
index 0000000..c975f90
Binary files /dev/null and b/test/fuzz/fuzz-bus-message/timeout-08ee8f6446a4064db064e8e0b3d220147f7d0b5b differ
diff --git a/test/fuzz/fuzz-dhcp6-client/crash-4003c06fce43a11fbd22f02584df2807ac333eae b/test/fuzz/fuzz-dhcp6-client/crash-4003c06fce43a11fbd22f02584df2807ac333eae
new file mode 100644 (file)
index 0000000..630ee66
Binary files /dev/null and b/test/fuzz/fuzz-dhcp6-client/crash-4003c06fce43a11fbd22f02584df2807ac333eae differ
diff --git a/test/fuzz/fuzz-dhcp6-client/crash-6e88fcb6b85c9436bcbe05219aa8e550194645ef b/test/fuzz/fuzz-dhcp6-client/crash-6e88fcb6b85c9436bcbe05219aa8e550194645ef
new file mode 100644 (file)
index 0000000..44883be
Binary files /dev/null and b/test/fuzz/fuzz-dhcp6-client/crash-6e88fcb6b85c9436bcbe05219aa8e550194645ef differ
diff --git a/test/fuzz/fuzz-dhcp6-client/oss-fuzz-10746 b/test/fuzz/fuzz-dhcp6-client/oss-fuzz-10746
new file mode 100644 (file)
index 0000000..41c0da0
Binary files /dev/null and b/test/fuzz/fuzz-dhcp6-client/oss-fuzz-10746 differ
diff --git a/test/fuzz/fuzz-ndisc-rs/timeout-2815b773c712fa33bea62f541dfa3017c64ea2f1 b/test/fuzz/fuzz-ndisc-rs/timeout-2815b773c712fa33bea62f541dfa3017c64ea2f1
new file mode 100644 (file)
index 0000000..410cf38
Binary files /dev/null and b/test/fuzz/fuzz-ndisc-rs/timeout-2815b773c712fa33bea62f541dfa3017c64ea2f1 differ
diff --git a/test/fuzz/fuzz-ndisc-rs/timeout-61fff7fd1e5dcc07e1b656baab29065ce634ad5b b/test/fuzz/fuzz-ndisc-rs/timeout-61fff7fd1e5dcc07e1b656baab29065ce634ad5b
new file mode 100644 (file)
index 0000000..04e871f
Binary files /dev/null and b/test/fuzz/fuzz-ndisc-rs/timeout-61fff7fd1e5dcc07e1b656baab29065ce634ad5b differ
similarity index 99%
rename from test/fuzz-corpus/unit-file/directives.service
rename to test/fuzz/fuzz-unit-file/directives.service
index c2334d3b19f2c77268e57f9ff20514982cc7109d..b9c1b467b0d5cfd5fec2a5a2f5b99a6c2cb03bc7 100644 (file)
@@ -769,6 +769,7 @@ KeyringMode=
 KillExcludeUsers=
 KillOnlyUsers=
 KillSignal=
+WatchdogSignal=
 KillUserProcesses=
 LOCATION=
 LidSwitchIgnoreInhibited=
diff --git a/test/fuzz/meson.build b/test/fuzz/meson.build
new file mode 100644 (file)
index 0000000..56d0f69
--- /dev/null
@@ -0,0 +1,33 @@
+# SPDX-License-Identifier: LGPL-2.1+
+
+sanitize_address = custom_target(
+        'sanitize-address-fuzzers',
+        output : 'sanitize-address-fuzzers',
+        command : [meson_build_sh,
+                   meson.source_root(),
+                   '@OUTPUT@',
+                   'fuzzers',
+                   '-Db_lundef=false -Db_sanitize=address'])
+
+sanitizers = [['address', sanitize_address]]
+
+if git.found()
+        out = run_command(
+                git,
+                '--git-dir=@0@/.git'.format(meson.source_root()),
+                 'ls-files', ':/test/fuzz/*/*')
+else
+        out = run_command(
+                'sh', '-c', 'ls @0@/*/*'.format(meson.current_source_dir()))
+endif
+
+fuzz_regression_tests = []
+foreach p : out.stdout().split()
+        # Remove the last entry which is ''.
+        #
+        # Also, backslashes get mangled, so skip test. See
+        # https://github.com/mesonbuild/meson/issues/1564.
+        if not p.contains('\\')
+                fuzz_regression_tests += p
+        endif
+endforeach
index 9750ff22b944a2409e22dbbba976fdc5a02573ad..7e8f2cfa907653dd46d422b484fd6f6627eee04f 100644 (file)
@@ -134,6 +134,7 @@ test_data_files = '''
         test-execute/exec-systemcallfilter-system-user-nfsnobody.service
         test-execute/exec-systemcallfilter-system-user-nobody.service
         test-execute/exec-systemcallfilter-system-user.service
+        test-execute/exec-systemcallfilter-with-errno-multi.service
         test-execute/exec-systemcallfilter-with-errno-name.service
         test-execute/exec-systemcallfilter-with-errno-number.service
         test-execute/exec-temporaryfilesystem-options.service
@@ -256,4 +257,4 @@ if conf.get('ENABLE_HWDB') == 1
         endif
 endif
 
-subdir('fuzz-regressions')
+subdir('fuzz')
index de1a6e73035df3854738018ee6b4c5119d1c35d9..bd7881d2865f798975c8c2f75963241aa21c396e 100644 (file)
@@ -2,7 +2,8 @@
 Description=Test DynamicUser with User= and SupplementaryGroups=
 
 [Service]
-ExecStart=/bin/sh -x -c 'test "$$(id -G)" = "1" && test "$$(id -g)" = "1" && test "$$(id -u)" = "1"'
+ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "1" && HAVE=1; done; test "$$HAVE" -eq 1'
+ExecStart=/bin/sh -x -c 'test "$$(id -g)" = "1" && test "$$(id -u)" = "1"'
 Type=oneshot
 User=1
 DynamicUser=yes
index 1d84af02ed808f4aa0e1bf49cd03a79bb365d600..f28078f2422138e85373160c991e156136489213 100644 (file)
@@ -2,7 +2,8 @@
 Description=Test DynamicUser with User=
 
 [Service]
-ExecStart=/bin/sh -x -c 'test "$$(id -G)" = "1" && test "$$(id -g)" = "1" && test "$$(id -u)" = "1"'
+ExecStart=/bin/sh -x -c 'HAVE=0; for g in $$(id -G); do test "$$g" = "1" && HAVE=1; done; test "$$HAVE" -eq 1'
+ExecStart=/bin/sh -x -c 'test "$$(id -g)" = "1" && test "$$(id -u)" = "1"'
 Type=oneshot
 User=1
 DynamicUser=yes
index a47b7fab78166afba75d1ef4b71fe4d5d7f86734..9ee6154f953b01116a7a5eb0fd4f12aab56b9970 100644 (file)
@@ -2,7 +2,9 @@
 Description=Test DynamicUser with SupplementaryGroups=
 
 [Service]
-ExecStart=/bin/sh -x -c 'test "$$(id -G | cut -d " " --complement -f 1)" = "1 2 3"'
+ExecStart=/bin/sh -x -c 'HAVE=; for g in $$(id -G); do test "$$g" = "1" && HAVE=1; done; test "$$HAVE" -eq 1'
+ExecStart=/bin/sh -x -c 'HAVE=; for g in $$(id -G); do test "$$g" = "2" && HAVE=1; done; test "$$HAVE" -eq 1'
+ExecStart=/bin/sh -x -c 'HAVE=; for g in $$(id -G); do test "$$g" = "3" && HAVE=1; done; test "$$HAVE" -eq 1'
 Type=oneshot
 DynamicUser=yes
 SupplementaryGroups=1 2 3
index a49c9d26a11b95f899513ebe8c8e7b6753a9cad7..1c565b412276d087aed6e8328f2311130419de42 100644 (file)
@@ -2,6 +2,10 @@
 Description=Test for Supplementary Group with multiple groups without Group and User
 
 [Service]
-ExecStart=/bin/sh -x -c 'test "$$(id -G)" = "0 1 2 3" && test "$$(id -g)" = "0" && test "$$(id -u)" = "0"'
+ExecStart=/bin/sh -x -c 'HAVE=; for g in $$(id -G); do test "$$g" = "0" && HAVE=1; done; test "$$HAVE" -eq 1'
+ExecStart=/bin/sh -x -c 'HAVE=; for g in $$(id -G); do test "$$g" = "1" && HAVE=1; done; test "$$HAVE" -eq 1'
+ExecStart=/bin/sh -x -c 'HAVE=; for g in $$(id -G); do test "$$g" = "2" && HAVE=1; done; test "$$HAVE" -eq 1'
+ExecStart=/bin/sh -x -c 'HAVE=; for g in $$(id -G); do test "$$g" = "3" && HAVE=1; done; test "$$HAVE" -eq 1'
+ExecStart=/bin/sh -x -c 'test "$$(id -g)" = "0" && test "$$(id -u)" = "0"'
 Type=oneshot
 SupplementaryGroups=1 2 3
index 5c62c1d63918b195f61334f2d09ba7b16b720d62..45bcf79222147fe5e261e0747704db9cce6628e8 100644 (file)
@@ -2,7 +2,10 @@
 Description=Test for Supplementary Group with multiple groups and Group=1
 
 [Service]
-ExecStart=/bin/sh -x -c 'test "$$(id -G)" = "1 2 3" && test "$$(id -g)" = "1" && test "$$(id -u)" = "0"'
+ExecStart=/bin/sh -x -c 'HAVE=; for g in $$(id -G); do test "$$g" = "1" && HAVE=1; done; test "$$HAVE" -eq 1'
+ExecStart=/bin/sh -x -c 'HAVE=; for g in $$(id -G); do test "$$g" = "2" && HAVE=1; done; test "$$HAVE" -eq 1'
+ExecStart=/bin/sh -x -c 'HAVE=; for g in $$(id -G); do test "$$g" = "3" && HAVE=1; done; test "$$HAVE" -eq 1'
+ExecStart=/bin/sh -x -c 'test "$$(id -g)" = "1" && test "$$(id -u)" = "0"'
 Type=oneshot
 Group=1
 SupplementaryGroups=1 2 3
index 00523e383b307281318a521338eab96e0fc4da02..62e56a2c23be18e77a63fce2f29fe93c0ba6938c 100644 (file)
@@ -2,7 +2,9 @@
 Description=Test for Supplementary Group with multiple groups and Uid=1
 
 [Service]
-ExecStart=/bin/sh -x -c 'test "$$(id -G)" = "1 2 3" && test "$$(id -g)" = "1" && test "$$(id -u)" = "1"'
+ExecStart=/bin/sh -x -c 'HAVE=; for g in $$(id -G); do test "$$g" = "1" && HAVE=1; done; test "$$HAVE" -eq 1'
+ExecStart=/bin/sh -x -c 'HAVE=; for g in $$(id -G); do test "$$g" = "2" && HAVE=1; done; test "$$HAVE" -eq 1'
+ExecStart=/bin/sh -x -c 'HAVE=; for g in $$(id -G); do test "$$g" = "3" && HAVE=1; done; test "$$HAVE" -eq 1'
 Type=oneshot
 User=1
 SupplementaryGroups=1 2 3
index ed6276d3036f1411c53a4e336f42549468fe0fc8..97f9f9c786e8528b3e9ce15c48bfc02dbb407fbb 100644 (file)
@@ -2,7 +2,8 @@
 Description=Test for Supplementary Group with only one group and uid 1
 
 [Service]
-ExecStart=/bin/sh -x -c 'test "$$(id -G)" = "1" && test "$$(id -g)" = "1" && test "$$(id -u)" = "1"'
+ExecStart=/bin/sh -x -c 'HAVE=; for g in $$(id -G); do test "$$g" = "1" && HAVE=1; done; test "$$HAVE" -eq 1'
+ExecStart=/bin/sh -x -c 'test "$$(id -g)" = "1" && test "$$(id -u)" = "1"'
 Type=oneshot
 User=1
 Group=1
index ee502b3d3773d816a0513cd39253d79cd4c9a3db..f9b721696bd690b2d2e3d71a01621e115a850bda 100644 (file)
@@ -2,7 +2,8 @@
 Description=Test for Supplementary Group with only one group
 
 [Service]
-ExecStart=/bin/sh -x -c 'test "$$(id -G)" = "1" && test "$$(id -g)" = "1" && test "$$(id -u)" = "0"'
+ExecStart=/bin/sh -x -c 'HAVE=; for g in $$(id -G); do test "$$g" = "1" && HAVE=1; done; test "$$HAVE" -eq 1'
+ExecStart=/bin/sh -x -c 'test "$$(id -g)" = "1" && test "$$(id -u)" = "0"'
 Type=oneshot
 Group=1
 SupplementaryGroups=1
index 43a9a981f24369319d35bd2931e1d3b3e94d89a6..4dee6af748424efc939bda08e0af06a84ea7b5e8 100644 (file)
@@ -2,6 +2,7 @@
 Description=Test for Supplementary Group
 
 [Service]
-ExecStart=/bin/sh -x -c 'test "$$(id -G)" = "0 1"'
+ExecStart=/bin/sh -x -c 'HAVE=; for g in $$(id -G); do test "$$g" = "0" && HAVE=1; done; test "$$HAVE" -eq 1'
+ExecStart=/bin/sh -x -c 'HAVE=; for g in $$(id -G); do test "$$g" = "1" && HAVE=1; done; test "$$HAVE" -eq 1'
 Type=oneshot
 SupplementaryGroups=1
diff --git a/test/test-execute/exec-systemcallfilter-with-errno-multi.service b/test/test-execute/exec-systemcallfilter-with-errno-multi.service
new file mode 100644 (file)
index 0000000..951e7ac
--- /dev/null
@@ -0,0 +1,9 @@
+[Unit]
+Description=Test for SystemCallFilter updating errno
+# test for issue #9939 which is fixed by a5404992cc7724ebf7572a0aa89d9fdb26ce0b62 (#9942)
+
+[Service]
+ExecStart=/usr/bin/python3 -c 'import os\ntry: os.uname()\nexcept Exception as e: exit(e.errno)'
+Type=oneshot
+SystemCallFilter=~uname:ENOENT uname:EILSEQ
+SystemCallErrorNumber=EACCES
index a5e8fc4dbc61015e77d59b72adab582169814ff6..c18293e403e651b1823dcf0f5624972ccb2e3c3a 100644 (file)
@@ -2,7 +2,7 @@
 Description=Test for UMask
 
 [Service]
-ExecStart=/bin/sh -x -c 'touch /tmp/test-exec-umask; mode=$$(stat -c %%a /tmp/test-exec-umask); test "$$mode" = "600"'
+ExecStart=/bin/sh -x -c 'rm /tmp/test-exec-umask; touch /tmp/test-exec-umask; mode=$$(stat -c %%a /tmp/test-exec-umask); test "$$mode" = "600"'
 Type=oneshot
 UMask=0177
 PrivateTmp=yes
index 487f5e9b9466729336e5128d97a4f89c265da90e..bf0573dd42279e5f96a8e8a4319791833f3baf47 100644 (file)
@@ -2,6 +2,6 @@
 Description=Test for UMask default
 
 [Service]
-ExecStart=/bin/sh -x -c 'touch /tmp/test-exec-umask; mode=$$(stat -c %%a /tmp/test-exec-umask); test "$$mode" = "644"'
+ExecStart=/bin/sh -x -c 'rm /tmp/test-exec-umask; touch /tmp/test-exec-umask; mode=$$(stat -c %%a /tmp/test-exec-umask); test "$$mode" = "644"'
 Type=oneshot
 PrivateTmp=yes
diff --git a/test/test-network/conf/11-dummy.netdev b/test/test-network/conf/11-dummy.netdev
new file mode 100644 (file)
index 0000000..6797eb4
--- /dev/null
@@ -0,0 +1,3 @@
+[NetDev]
+Name=test1
+Kind=dummy
diff --git a/test/test-network/conf/12-dummy.netdev b/test/test-network/conf/12-dummy.netdev
new file mode 100644 (file)
index 0000000..a7fdc0f
--- /dev/null
@@ -0,0 +1,3 @@
+[NetDev]
+Name=dummy98
+Kind=dummy
diff --git a/test/test-network/conf/21-macvlan.netdev b/test/test-network/conf/21-macvlan.netdev
new file mode 100644 (file)
index 0000000..e9a3c5b
--- /dev/null
@@ -0,0 +1,3 @@
+[NetDev]
+Name=macvlan99
+Kind=macvlan
diff --git a/test/test-network/conf/21-macvtap.netdev b/test/test-network/conf/21-macvtap.netdev
new file mode 100644 (file)
index 0000000..2c23aac
--- /dev/null
@@ -0,0 +1,3 @@
+[NetDev]
+Name=macvtap99
+Kind=macvtap
diff --git a/test/test-network/conf/21-vlan.netdev b/test/test-network/conf/21-vlan.netdev
new file mode 100644 (file)
index 0000000..fe9801c
--- /dev/null
@@ -0,0 +1,10 @@
+[NetDev]
+Name=vlan99
+Kind=vlan
+
+[VLAN]
+Id=99
+GVRP=true
+MVRP=true
+LooseBinding=true
+ReorderHeader=true
diff --git a/test/test-network/conf/21-vlan.network b/test/test-network/conf/21-vlan.network
new file mode 100644 (file)
index 0000000..a4fa1de
--- /dev/null
@@ -0,0 +1,5 @@
+[Match]
+Name=test1
+
+[Network]
+VLAN=vlan99
diff --git a/test/test-network/conf/23-active-slave.network b/test/test-network/conf/23-active-slave.network
new file mode 100644 (file)
index 0000000..59a6596
--- /dev/null
@@ -0,0 +1,6 @@
+[Match]
+Name=dummy98
+
+[Network]
+Bond=bond199
+ActiveSlave=true
diff --git a/test/test-network/conf/23-bond199.network b/test/test-network/conf/23-bond199.network
new file mode 100644 (file)
index 0000000..31e5d12
--- /dev/null
@@ -0,0 +1,2 @@
+[Match]
+Name=bond199
diff --git a/test/test-network/conf/23-emit-lldp.network b/test/test-network/conf/23-emit-lldp.network
new file mode 100644 (file)
index 0000000..de35045
--- /dev/null
@@ -0,0 +1,5 @@
+[Match]
+Name=veth-peer
+
+[Network]
+EmitLLDP=yes
diff --git a/test/test-network/conf/23-primary-slave.network b/test/test-network/conf/23-primary-slave.network
new file mode 100644 (file)
index 0000000..380ae26
--- /dev/null
@@ -0,0 +1,6 @@
+[Match]
+Name=dummy98
+
+[Network]
+Bond=bond199
+PrimarySlave=true
diff --git a/test/test-network/conf/23-test1-bond199.network b/test/test-network/conf/23-test1-bond199.network
new file mode 100644 (file)
index 0000000..6e7c28d
--- /dev/null
@@ -0,0 +1,6 @@
+[Match]
+Name=test1
+
+[Network]
+Bond=bond199
+PrimarySlave=true
diff --git a/test/test-network/conf/24-lldp.network b/test/test-network/conf/24-lldp.network
new file mode 100644 (file)
index 0000000..fbdfb1b
--- /dev/null
@@ -0,0 +1,5 @@
+[Match]
+Name=veth99
+
+[Network]
+LLDP=yes
diff --git a/test/test-network/conf/24-search-domain.network b/test/test-network/conf/24-search-domain.network
new file mode 100644 (file)
index 0000000..970b130
--- /dev/null
@@ -0,0 +1,7 @@
+[Match]
+Name=dummy98
+
+[Network]
+Address=192.168.42.100
+DNS=192.168.42.1
+Domains= one two three four five six seven eight nine ten
diff --git a/test/test-network/conf/25-address-link-section.network b/test/test-network/conf/25-address-link-section.network
new file mode 100644 (file)
index 0000000..759e83c
--- /dev/null
@@ -0,0 +1,5 @@
+[Match]
+Name=dummy98
+
+[Link]
+MACAddress=00:01:02:aa:bb:cc
diff --git a/test/test-network/conf/25-address-section-miscellaneous.network b/test/test-network/conf/25-address-section-miscellaneous.network
new file mode 100644 (file)
index 0000000..3a37d03
--- /dev/null
@@ -0,0 +1,10 @@
+[Match]
+Name=dummy98
+
+[Address]
+Address=10.2.3.4/16
+PreferredLifetime=0
+Scope=link
+
+[Address]
+Address=2001:0db8:0:f101::1/64
diff --git a/test/test-network/conf/25-address-section.network b/test/test-network/conf/25-address-section.network
new file mode 100644 (file)
index 0000000..d0fae69
--- /dev/null
@@ -0,0 +1,11 @@
+[Match]
+Name=dummy98
+
+[Address]
+Address=10.2.3.4/16
+Peer=10.2.3.5/16
+Label=32
+
+[Address]
+Address=10.6.7.8/16
+Label=33
diff --git a/test/test-network/conf/25-bond-active-backup-slave.netdev b/test/test-network/conf/25-bond-active-backup-slave.netdev
new file mode 100644 (file)
index 0000000..1bbbf75
--- /dev/null
@@ -0,0 +1,6 @@
+[NetDev]
+Name=bond199
+Kind=bond
+
+[Bond]
+Mode=active-backup
diff --git a/test/test-network/conf/25-bond.netdev b/test/test-network/conf/25-bond.netdev
new file mode 100644 (file)
index 0000000..1059910
--- /dev/null
@@ -0,0 +1,13 @@
+[NetDev]
+Name=bond99
+Kind=bond
+
+[Bond]
+Mode=802.3ad
+TransmitHashPolicy=layer3+4
+MIIMonitorSec=1s
+LACPTransmitRate=fast
+UpDelaySec=2s
+DownDelaySec=2s
+ResendIGMP=4
+MinLinks=1
diff --git a/test/test-network/conf/25-bridge.netdev b/test/test-network/conf/25-bridge.netdev
new file mode 100644 (file)
index 0000000..e23abd5
--- /dev/null
@@ -0,0 +1,13 @@
+[NetDev]
+Name=bridge99
+Kind=bridge
+
+[Bridge]
+HelloTimeSec=9
+MaxAgeSec=9
+ForwardDelaySec=9
+AgeingTimeSec=9
+Priority=9
+MulticastQuerier= true
+MulticastSnooping=true
+STP=true
diff --git a/test/test-network/conf/25-geneve.netdev b/test/test-network/conf/25-geneve.netdev
new file mode 100644 (file)
index 0000000..279d713
--- /dev/null
@@ -0,0 +1,12 @@
+[NetDev]
+Name=geneve99
+Kind=geneve
+
+[GENEVE]
+Id=99
+Remote=192.168.22.1
+TTL=1
+UDPChecksum=true
+UDP6ZeroChecksumTx=true
+UDP6ZeroChecksumRx=true
+DestinationPort=6082
diff --git a/test/test-network/conf/25-gre-tunnel.netdev b/test/test-network/conf/25-gre-tunnel.netdev
new file mode 100644 (file)
index 0000000..94d9320
--- /dev/null
@@ -0,0 +1,7 @@
+[NetDev]
+Name=gretun99
+Kind=gre
+
+[Tunnel]
+Local=10.65.223.238
+Remote=10.65.223.239
diff --git a/test/test-network/conf/25-gretap-tunnel.netdev b/test/test-network/conf/25-gretap-tunnel.netdev
new file mode 100644 (file)
index 0000000..769e765
--- /dev/null
@@ -0,0 +1,7 @@
+[NetDev]
+Name=gretap99
+Kind=gretap
+
+[Tunnel]
+Local=10.65.223.238
+Remote=10.65.223.239
diff --git a/test/test-network/conf/25-ip6gre-tunnel.netdev b/test/test-network/conf/25-ip6gre-tunnel.netdev
new file mode 100644 (file)
index 0000000..b16e0b4
--- /dev/null
@@ -0,0 +1,7 @@
+[NetDev]
+Name=ip6gretap99
+Kind=ip6gretap
+
+[Tunnel]
+Local=2a00:ffde:4567:edde::4987
+Remote=2001:473:fece:cafe::5179
diff --git a/test/test-network/conf/25-ip6tnl-tunnel.netdev b/test/test-network/conf/25-ip6tnl-tunnel.netdev
new file mode 100644 (file)
index 0000000..713e685
--- /dev/null
@@ -0,0 +1,8 @@
+[NetDev]
+Name=ip6tnl99
+Kind=ip6tnl
+
+[Tunnel]
+Mode=ip6ip6
+Local=2a00:ffde:4567:edde::4987
+Remote=2001:473:fece:cafe::5179
diff --git a/test/test-network/conf/25-ipip-tunnel-independent.netdev b/test/test-network/conf/25-ipip-tunnel-independent.netdev
new file mode 100644 (file)
index 0000000..36ff8d9
--- /dev/null
@@ -0,0 +1,9 @@
+[NetDev]
+Name=ipiptun99
+Kind=ipip
+MTUBytes=1480
+
+[Tunnel]
+Local=192.168.223.238
+Remote=192.169.224.239
+Independent=true
diff --git a/test/test-network/conf/25-ipip-tunnel.netdev b/test/test-network/conf/25-ipip-tunnel.netdev
new file mode 100644 (file)
index 0000000..159ac72
--- /dev/null
@@ -0,0 +1,8 @@
+[NetDev]
+Name=ipiptun99
+Kind=ipip
+MTUBytes=1480
+
+[Tunnel]
+Local=192.168.223.238
+Remote=192.169.224.239
diff --git a/test/test-network/conf/25-ipv6-address-label-section.network b/test/test-network/conf/25-ipv6-address-label-section.network
new file mode 100644 (file)
index 0000000..945b7dc
--- /dev/null
@@ -0,0 +1,6 @@
+[Match]
+Name=dummy98
+
+[IPv6AddressLabel]
+Label=4444
+Prefix=2004:da8:1:0::/64
diff --git a/test/test-network/conf/25-ipvlan.netdev b/test/test-network/conf/25-ipvlan.netdev
new file mode 100644 (file)
index 0000000..9921b78
--- /dev/null
@@ -0,0 +1,6 @@
+[NetDev]
+Name=ipvlan99
+Kind=ipvlan
+
+[IPVLAN]
+Mode=L2
diff --git a/test/test-network/conf/25-link-section-unmanaged.network b/test/test-network/conf/25-link-section-unmanaged.network
new file mode 100644 (file)
index 0000000..4fe4916
--- /dev/null
@@ -0,0 +1,6 @@
+[Match]
+Name=dummy98
+
+[Link]
+MACAddress=00:01:02:aa:bb:cc
+Unmanaged=true
diff --git a/test/test-network/conf/25-route-section.network b/test/test-network/conf/25-route-section.network
new file mode 100644 (file)
index 0000000..c9c7a72
--- /dev/null
@@ -0,0 +1,8 @@
+[Match]
+Name=dummy98
+
+[Network]
+Address=192.168.0.15/24
+
+[Route]
+Gateway=192.168.0.1
diff --git a/test/test-network/conf/25-route-tcp-window-settings.network b/test/test-network/conf/25-route-tcp-window-settings.network
new file mode 100644 (file)
index 0000000..e77a721
--- /dev/null
@@ -0,0 +1,10 @@
+[Match]
+Name=test1
+
+[Route]
+Destination=192.168.1.1
+InitialCongestionWindow=20
+
+[Route]
+Destination=192.168.1.2
+InitialAdvertisedReceiveWindow=30
diff --git a/test/test-network/conf/25-route-type.network b/test/test-network/conf/25-route-type.network
new file mode 100644 (file)
index 0000000..9a10413
--- /dev/null
@@ -0,0 +1,14 @@
+[Match]
+Name=dummy98
+
+[Route]
+Type=blackhole
+Destination=202.54.1.2
+
+[Route]
+Type=unreachable
+Destination=202.54.1.3
+
+[Route]
+Type=prohibit
+Destination=202.54.1.4
diff --git a/test/test-network/conf/25-sit-tunnel.netdev b/test/test-network/conf/25-sit-tunnel.netdev
new file mode 100644 (file)
index 0000000..406d74b
--- /dev/null
@@ -0,0 +1,7 @@
+[NetDev]
+Name=sittun99
+Kind=sit
+
+[Tunnel]
+Local=10.65.223.238
+Remote=10.65.223.239
diff --git a/test/test-network/conf/25-sysctl.network b/test/test-network/conf/25-sysctl.network
new file mode 100644 (file)
index 0000000..2452fb7
--- /dev/null
@@ -0,0 +1,10 @@
+[Match]
+Name=dummy98
+
+[Network]
+IPForward=true
+IPv6PrivacyExtensions=true
+IPv6DuplicateAddressDetection=3
+IPv6HopLimit=5
+IPv4ProxyARP=true
+IPv6ProxyNDP=true
diff --git a/test/test-network/conf/25-tap.netdev b/test/test-network/conf/25-tap.netdev
new file mode 100644 (file)
index 0000000..bf5e7fe
--- /dev/null
@@ -0,0 +1,7 @@
+[NetDev]
+Name=tap99
+Kind=tap
+
+[Tap]
+MultiQueue=true
+PacketInfo=true
diff --git a/test/test-network/conf/25-tun.netdev b/test/test-network/conf/25-tun.netdev
new file mode 100644 (file)
index 0000000..380ab21
--- /dev/null
@@ -0,0 +1,7 @@
+[NetDev]
+Name=tun99
+Kind=tun
+
+[Tun]
+MultiQueue=true
+PacketInfo=true
diff --git a/test/test-network/conf/25-vcan.netdev b/test/test-network/conf/25-vcan.netdev
new file mode 100644 (file)
index 0000000..ff19795
--- /dev/null
@@ -0,0 +1,3 @@
+[NetDev]
+Name=vcan99
+Kind=vcan
diff --git a/test/test-network/conf/25-veth.netdev b/test/test-network/conf/25-veth.netdev
new file mode 100644 (file)
index 0000000..9ae4ad5
--- /dev/null
@@ -0,0 +1,8 @@
+[NetDev]
+Name=veth99
+Kind=veth
+MACAddress=12:34:56:78:9a:bc
+
+[Peer]
+Name=veth-peer
+MACAddress=12:34:56:78:9a:bd
diff --git a/test/test-network/conf/25-vrf.netdev b/test/test-network/conf/25-vrf.netdev
new file mode 100644 (file)
index 0000000..bf949ec
--- /dev/null
@@ -0,0 +1,6 @@
+[NetDev]
+Name=vrf99
+Kind=vrf
+
+[VRF]
+TableId=42
diff --git a/test/test-network/conf/25-vti-tunnel.netdev b/test/test-network/conf/25-vti-tunnel.netdev
new file mode 100644 (file)
index 0000000..cec6259
--- /dev/null
@@ -0,0 +1,7 @@
+[NetDev]
+Name=vtitun99
+Kind=vti
+
+[Tunnel]
+Local=10.65.223.238
+Remote=10.65.223.239
diff --git a/test/test-network/conf/25-vti6-tunnel.netdev b/test/test-network/conf/25-vti6-tunnel.netdev
new file mode 100644 (file)
index 0000000..d150c9c
--- /dev/null
@@ -0,0 +1,7 @@
+[NetDev]
+Name=vti6tun99
+Kind=vti6
+
+[Tunnel]
+Local=2a00:ffde:4567:edde::4987
+Remote=2001:473:fece:cafe::5179
diff --git a/test/test-network/conf/25-vxlan.netdev b/test/test-network/conf/25-vxlan.netdev
new file mode 100644 (file)
index 0000000..819a583
--- /dev/null
@@ -0,0 +1,16 @@
+[NetDev]
+Name=vxlan99
+Kind=vxlan
+
+[VXLAN]
+Id=999
+L2MissNotification=true
+L3MissNotification=true
+RouteShortCircuit=true
+UDPChecksum=true
+UDP6ZeroChecksumTx=true
+UDP6ZeroChecksumRx=true
+RemoteChecksumTx=true
+RemoteChecksumRx=true
+GroupPolicyExtension=true
+DestinationPort=5555
diff --git a/test/test-network/conf/26-bridge-slave-interface-1.network b/test/test-network/conf/26-bridge-slave-interface-1.network
new file mode 100644 (file)
index 0000000..84f221d
--- /dev/null
@@ -0,0 +1,11 @@
+[Match]
+Name=dummy98
+
+[Network]
+Bridge=bridge99
+
+[Bridge]
+Cost=400
+HairPin = true
+FastLeave = true
+UnicastFlood = true
diff --git a/test/test-network/conf/26-bridge-slave-interface-2.network b/test/test-network/conf/26-bridge-slave-interface-2.network
new file mode 100644 (file)
index 0000000..45ec2de
--- /dev/null
@@ -0,0 +1,5 @@
+[Match]
+Name=test1
+
+[Network]
+Bridge=bridge99
diff --git a/test/test-network/conf/26-bridge.netdev b/test/test-network/conf/26-bridge.netdev
new file mode 100644 (file)
index 0000000..9b31e06
--- /dev/null
@@ -0,0 +1,3 @@
+[NetDev]
+Name=bridge99
+Kind=bridge
diff --git a/test/test-network/conf/bridge99.network b/test/test-network/conf/bridge99.network
new file mode 100644 (file)
index 0000000..39e48ce
--- /dev/null
@@ -0,0 +1,6 @@
+[Match]
+Name=bridge99
+
+[Network]
+Address=192.168.0.15/24
+Gateway=192.168.0.1
diff --git a/test/test-network/conf/configure-without-carrier.network b/test/test-network/conf/configure-without-carrier.network
new file mode 100644 (file)
index 0000000..5bd9d7e
--- /dev/null
@@ -0,0 +1,7 @@
+[Match]
+Name=test1
+
+[Network]
+Address=192.168.0.15/24
+Gateway=192.168.0.1
+ConfigureWithoutCarrier=true
diff --git a/test/test-network/conf/dhcp-client-anonymize.network b/test/test-network/conf/dhcp-client-anonymize.network
new file mode 100644 (file)
index 0000000..a910cba
--- /dev/null
@@ -0,0 +1,16 @@
+[Match]
+Name=veth99
+
+[Network]
+DHCP=ipv4
+IPv6AcceptRA=false
+
+[DHCP]
+Anonymize=true
+UseMTU=true
+UseRoutes=true
+SendHostname=true
+UseHostname=true
+Hostname=test-hostname
+ClientIdentifier=mac
+VendorClassIdentifier=SusantVendorTest
diff --git a/test/test-network/conf/dhcp-client-critical-connection.network b/test/test-network/conf/dhcp-client-critical-connection.network
new file mode 100644 (file)
index 0000000..0e65dec
--- /dev/null
@@ -0,0 +1,9 @@
+[Match]
+Name=veth99
+
+[Network]
+DHCP=ipv4
+IPv6AcceptRA=false
+
+[DHCP]
+CriticalConnection=true
diff --git a/test/test-network/conf/dhcp-client-ipv4-dhcp-settings.network b/test/test-network/conf/dhcp-client-ipv4-dhcp-settings.network
new file mode 100644 (file)
index 0000000..5c4ca22
--- /dev/null
@@ -0,0 +1,15 @@
+[Match]
+Name=veth99
+
+[Network]
+DHCP=ipv4
+IPv6AcceptRA=false
+
+[DHCP]
+UseMTU=true
+UseRoutes=true
+SendHostname=true
+UseHostname=true
+Hostname=test-hostname
+ClientIdentifier=mac
+VendorClassIdentifier=SusantVendorTest
diff --git a/test/test-network/conf/dhcp-client-ipv4-only-ipv6-disabled.network b/test/test-network/conf/dhcp-client-ipv4-only-ipv6-disabled.network
new file mode 100644 (file)
index 0000000..c980bf9
--- /dev/null
@@ -0,0 +1,6 @@
+[Match]
+Name=veth99
+
+[Network]
+DHCP=ipv4
+IPv6AcceptRA=false
diff --git a/test/test-network/conf/dhcp-client-ipv4-only.network b/test/test-network/conf/dhcp-client-ipv4-only.network
new file mode 100644 (file)
index 0000000..9bc019a
--- /dev/null
@@ -0,0 +1,5 @@
+[Match]
+Name=veth99
+
+[Network]
+DHCP=ipv4
diff --git a/test/test-network/conf/dhcp-client-ipv6-only.network b/test/test-network/conf/dhcp-client-ipv6-only.network
new file mode 100644 (file)
index 0000000..1f70c3b
--- /dev/null
@@ -0,0 +1,5 @@
+[Match]
+Name=veth99
+
+[Network]
+DHCP=ipv6
diff --git a/test/test-network/conf/dhcp-client-ipv6-rapid-commit.network b/test/test-network/conf/dhcp-client-ipv6-rapid-commit.network
new file mode 100644 (file)
index 0000000..52fa587
--- /dev/null
@@ -0,0 +1,8 @@
+[Match]
+Name=veth99
+
+[Network]
+DHCP=ipv6
+
+[DHCP]
+RapidCommit=false
diff --git a/test/test-network/conf/dhcp-client-listen-port.network b/test/test-network/conf/dhcp-client-listen-port.network
new file mode 100644 (file)
index 0000000..73ac364
--- /dev/null
@@ -0,0 +1,8 @@
+[Match]
+Name=veth99
+
+[Network]
+DHCP=yes
+
+[DHCP]
+ListenPort=5555
diff --git a/test/test-network/conf/dhcp-client-route-metric.network b/test/test-network/conf/dhcp-client-route-metric.network
new file mode 100644 (file)
index 0000000..aa04aae
--- /dev/null
@@ -0,0 +1,10 @@
+[Match]
+Name=veth99
+
+[Network]
+DHCP=ipv4
+IPv6AcceptRA=false
+
+[DHCP]
+UseRoutes=true
+RouteMetric=24
diff --git a/test/test-network/conf/dhcp-client-route-table.network b/test/test-network/conf/dhcp-client-route-table.network
new file mode 100644 (file)
index 0000000..75f16aa
--- /dev/null
@@ -0,0 +1,10 @@
+[Match]
+Name=veth99
+
+[Network]
+DHCP=ipv4
+IPv6AcceptRA=false
+
+[DHCP]
+UseRoutes=true
+RouteTable=12
diff --git a/test/test-network/conf/dhcp-client-timezone-router.network b/test/test-network/conf/dhcp-client-timezone-router.network
new file mode 100644 (file)
index 0000000..6316f9c
--- /dev/null
@@ -0,0 +1,8 @@
+[Match]
+Name=veth99
+
+[Network]
+IPv6AcceptRA=false
+DHCP=ipv4
+UseRoutes=true
+UseTimezone=true
diff --git a/test/test-network/conf/dhcp-client.network b/test/test-network/conf/dhcp-client.network
new file mode 100644 (file)
index 0000000..5629bc4
--- /dev/null
@@ -0,0 +1,5 @@
+[Match]
+Name=veth99
+
+[Network]
+DHCP=yes
diff --git a/test/test-network/conf/dhcp-server-timezone-router.network b/test/test-network/conf/dhcp-server-timezone-router.network
new file mode 100644 (file)
index 0000000..3ebbf05
--- /dev/null
@@ -0,0 +1,13 @@
+[Match]
+Name=veth-peer
+
+[Network]
+IPv6AcceptRA=false
+Address=192.168.5.1/24
+DHCPServer=yes
+
+[DHCPServer]
+PoolOffset=10
+PoolSize=50
+EmitRouter=yes
+Timezone=Europe/Berlin
diff --git a/test/test-network/conf/dhcp-server-veth-peer.network b/test/test-network/conf/dhcp-server-veth-peer.network
new file mode 100644 (file)
index 0000000..7b38e72
--- /dev/null
@@ -0,0 +1,6 @@
+[Match]
+Name=veth-peer
+
+[Network]
+Address=2600::1
+Address=192.168.5.1/24
diff --git a/test/test-network/conf/dhcp-server.network b/test/test-network/conf/dhcp-server.network
new file mode 100644 (file)
index 0000000..9e49691
--- /dev/null
@@ -0,0 +1,12 @@
+[Match]
+Name=veth-peer
+
+[Network]
+Address=192.168.5.1/24
+DHCPServer=yes
+
+[DHCPServer]
+PoolOffset=10
+PoolSize=50
+DNS=192.168.5.1
+NTP=192.168.5.1
diff --git a/test/test-network/conf/dhcp-v4-server-veth-peer.network b/test/test-network/conf/dhcp-v4-server-veth-peer.network
new file mode 100644 (file)
index 0000000..5c91d65
--- /dev/null
@@ -0,0 +1,6 @@
+[Match]
+Name=veth-peer
+
+[Network]
+Address=192.168.0.1
+Address=192.168.5.1
diff --git a/test/test-network/conf/gretap.network b/test/test-network/conf/gretap.network
new file mode 100644 (file)
index 0000000..88b9250
--- /dev/null
@@ -0,0 +1,5 @@
+[Match]
+Name=dummy98
+
+[Network]
+Tunnel=gretap99
diff --git a/test/test-network/conf/gretun.network b/test/test-network/conf/gretun.network
new file mode 100644 (file)
index 0000000..376074c
--- /dev/null
@@ -0,0 +1,5 @@
+[Match]
+Name=dummy98
+
+[Network]
+Tunnel=gretun99
diff --git a/test/test-network/conf/ip6gretap.network b/test/test-network/conf/ip6gretap.network
new file mode 100644 (file)
index 0000000..cad0bae
--- /dev/null
@@ -0,0 +1,5 @@
+[Match]
+Name=dummy98
+
+[Network]
+Tunnel=ip6gretap99
diff --git a/test/test-network/conf/ip6tnl.network b/test/test-network/conf/ip6tnl.network
new file mode 100644 (file)
index 0000000..41e3448
--- /dev/null
@@ -0,0 +1,5 @@
+[Match]
+Name=dummy98
+
+[Network]
+Tunnel=ip6tnl99
diff --git a/test/test-network/conf/ipip.network b/test/test-network/conf/ipip.network
new file mode 100644 (file)
index 0000000..4ce6714
--- /dev/null
@@ -0,0 +1,5 @@
+[Match]
+Name=dummy98
+
+[Network]
+Tunnel=ipiptun99
diff --git a/test/test-network/conf/ipv6-prefix-veth.network b/test/test-network/conf/ipv6-prefix-veth.network
new file mode 100644 (file)
index 0000000..3d2acec
--- /dev/null
@@ -0,0 +1,5 @@
+[Match]
+Name=veth99
+
+[Network]
+IPv6AcceptRA=true
diff --git a/test/test-network/conf/ipv6-prefix.network b/test/test-network/conf/ipv6-prefix.network
new file mode 100644 (file)
index 0000000..c1932a8
--- /dev/null
@@ -0,0 +1,10 @@
+[Match]
+Name=veth-peer
+
+[Network]
+IPv6PrefixDelegation=yes
+
+[IPv6Prefix]
+Prefix=2002:da8:1:0::/64
+PreferredLifetimeSec=1000s
+ValidLifetimeSec=2100s
diff --git a/test/test-network/conf/ipvlan.network b/test/test-network/conf/ipvlan.network
new file mode 100644 (file)
index 0000000..d053220
--- /dev/null
@@ -0,0 +1,5 @@
+[Match]
+Name=test1
+
+[Network]
+IPVLAN=ipvlan99
diff --git a/test/test-network/conf/macvlan.network b/test/test-network/conf/macvlan.network
new file mode 100644 (file)
index 0000000..a41c1f9
--- /dev/null
@@ -0,0 +1,5 @@
+[Match]
+Name=test1
+
+[Network]
+MACVLAN=macvlan99
diff --git a/test/test-network/conf/macvtap.network b/test/test-network/conf/macvtap.network
new file mode 100644 (file)
index 0000000..6ee99ab
--- /dev/null
@@ -0,0 +1,5 @@
+[Match]
+Name=test1
+
+[Network]
+MACVTAP=macvtap99
diff --git a/test/test-network/conf/routing-policy-rule.network b/test/test-network/conf/routing-policy-rule.network
new file mode 100644 (file)
index 0000000..46b87c5
--- /dev/null
@@ -0,0 +1,10 @@
+[Match]
+Name=test1
+
+[RoutingPolicyRule]
+TypeOfService=0x08
+Table=7
+From= 192.168.100.18
+Priority=111
+IncomingInterface=test1
+OutgoingInterface=test1
diff --git a/test/test-network/conf/sit.network b/test/test-network/conf/sit.network
new file mode 100644 (file)
index 0000000..84e5af0
--- /dev/null
@@ -0,0 +1,5 @@
+[Match]
+Name=dummy98
+
+[Network]
+Tunnel=sittun99
diff --git a/test/test-network/conf/test-static.network b/test/test-network/conf/test-static.network
new file mode 100644 (file)
index 0000000..636c55c
--- /dev/null
@@ -0,0 +1,6 @@
+[Match]
+Name=dummy98
+
+[Network]
+Address=192.168.0.15/24
+Gateway=192.168.0.1
diff --git a/test/test-network/conf/vti.network b/test/test-network/conf/vti.network
new file mode 100644 (file)
index 0000000..7fbad6a
--- /dev/null
@@ -0,0 +1,5 @@
+[Match]
+Name=dummy98
+
+[Network]
+Tunnel=vtitun99
diff --git a/test/test-network/conf/vti6.network b/test/test-network/conf/vti6.network
new file mode 100644 (file)
index 0000000..49a9d11
--- /dev/null
@@ -0,0 +1,5 @@
+[Match]
+Name=dummy98
+
+[Network]
+Tunnel=vti6tun99
diff --git a/test/test-network/conf/vxlan.network b/test/test-network/conf/vxlan.network
new file mode 100644 (file)
index 0000000..80b4055
--- /dev/null
@@ -0,0 +1,5 @@
+[Match]
+Name=test1
+
+[Network]
+VXLAN=vxlan99
diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py
new file mode 100755 (executable)
index 0000000..fc347c6
--- /dev/null
@@ -0,0 +1,854 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: LGPL-2.1+
+# systemd-networkd tests
+
+import os
+import sys
+import unittest
+import subprocess
+import time
+import shutil
+import signal
+import socket
+import threading
+from shutil import copytree
+
+network_unit_file_path='/var/run/systemd/network'
+networkd_ci_path='/var/run/networkd-ci'
+network_sysctl_ipv6_path='/proc/sys/net/ipv6/conf'
+network_sysctl_ipv4_path='/proc/sys/net/ipv4/conf'
+
+dnsmasq_config_file='/var/run/networkd-ci/test-dnsmasq.conf'
+dnsmasq_pid_file='/var/run/networkd-ci/test-test-dnsmasq.pid'
+dnsmasq_log_file='/var/run/networkd-ci/test-dnsmasq-log-file'
+
+def setUpModule():
+
+    os.makedirs(network_unit_file_path, exist_ok=True)
+    os.makedirs(networkd_ci_path, exist_ok=True)
+
+    shutil.rmtree(networkd_ci_path)
+    copytree(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'conf'), networkd_ci_path)
+
+def tearDownModule():
+    shutil.rmtree(networkd_ci_path)
+
+class Utilities():
+    dhcp_server_data = []
+
+    def read_link_attr(self, link, dev, attribute):
+        with open(os.path.join(os.path.join(os.path.join('/sys/class/net/', link), dev), attribute)) as f:
+            return f.readline().strip()
+
+    def link_exits(self, link):
+        return os.path.exists(os.path.join('/sys/class/net', link))
+
+    def link_remove(self, links):
+        for link in links:
+            if os.path.exists(os.path.join('/sys/class/net', link)):
+                subprocess.call(['ip', 'link', 'del', 'dev', link])
+
+    def read_ipv6_sysctl_attr(self, link, attribute):
+        with open(os.path.join(os.path.join(network_sysctl_ipv6_path, link), attribute)) as f:
+            return f.readline().strip()
+
+    def read_ipv4_sysctl_attr(self, link, attribute):
+        with open(os.path.join(os.path.join(network_sysctl_ipv4_path, link), attribute)) as f:
+            return f.readline().strip()
+
+    def copy_unit_to_networkd_unit_path(self, *units):
+        for unit in units:
+            shutil.copy(os.path.join(networkd_ci_path, unit), network_unit_file_path)
+
+    def remove_unit_from_networkd_path(self, units):
+        for unit in units:
+            if (os.path.exists(os.path.join(network_unit_file_path, unit))):
+                os.remove(os.path.join(network_unit_file_path, unit))
+
+    def start_dnsmasq(self):
+        subprocess.check_call('dnsmasq -8 /var/run/networkd-ci/test-dnsmasq-log-file --log-queries=extra --log-dhcp --pid-file=/var/run/networkd-ci/test-test-dnsmasq.pid --conf-file=/dev/null --interface=veth-peer --enable-ra --dhcp-range=2600::10,2600::20 --dhcp-range=192.168.5.10,192.168.5.200 -R --dhcp-leasefile=/var/run/networkd-ci/lease --dhcp-option=26,1492 --dhcp-option=option:router,192.168.5.1 --dhcp-option=33,192.168.5.4,192.168.5.5', shell=True)
+
+        time.sleep(10)
+
+    def stop_dnsmasq(self, pid_file):
+        if os.path.exists(pid_file):
+            with open(pid_file, 'r') as f:
+                pid = f.read().rstrip(' \t\r\n\0')
+                os.kill(int(pid), signal.SIGTERM)
+
+            os.remove(pid_file)
+
+    def search_words_in_file(self, word):
+        if os.path.exists(dnsmasq_log_file):
+            with open (dnsmasq_log_file) as in_file:
+                contents = in_file.read()
+                print(contents)
+                for part in contents.split():
+                    if word in part:
+                        in_file.close()
+                        print("%s, %s" % (word, part))
+                        return True
+        return False
+
+    def remove_lease_file(self):
+        if os.path.exists(os.path.join(networkd_ci_path, 'lease')):
+            os.remove(os.path.join(networkd_ci_path, 'lease'))
+
+    def remove_log_file(self):
+        if os.path.exists(dnsmasq_log_file):
+            os.remove(dnsmasq_log_file)
+
+    def start_networkd(self):
+        subprocess.check_call('systemctl restart systemd-networkd', shell=True)
+        time.sleep(5)
+
+global ip
+global port
+
+class DHCPServer(threading.Thread):
+    def __init__(self, name):
+        threading.Thread.__init__(self)
+        self.name = name
+
+    def run(self):
+        self.start_dhcp_server()
+
+    def start_dhcp_server(self):
+        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+
+        server_address = ('0.0.0.0', 67)
+        sock.bind(server_address)
+
+        print('Starting DHCP Server ...\n')
+        data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
+
+        global ip
+        ip = addr[0]
+
+        global port
+        port = addr[1]
+        sock.close()
+
+class NetworkdNetDevTests(unittest.TestCase, Utilities):
+
+    links =['bridge99', 'bond99', 'bond99', 'vlan99', 'test1', 'macvtap99',
+            'macvlan99', 'ipvlan99', 'vxlan99', 'veth99', 'vrf99', 'tun99',
+            'tap99', 'vcan99', 'geneve99', 'dummy98', 'ipiptun99', 'sittun99',
+            'gretap99', 'vtitun99', 'vti6tun99','ip6tnl99', 'gretun99', 'ip6gretap99']
+
+    units = ['25-bridge.netdev', '25-bond.netdev', '21-vlan.netdev', '11-dummy.netdev', '21-vlan.network',
+             '21-macvtap.netdev', 'macvtap.network', '21-macvlan.netdev', 'macvlan.network', 'vxlan.network',
+             '25-vxlan.netdev', '25-ipvlan.netdev', 'ipvlan.network', '25-veth.netdev', '25-vrf.netdev',
+             '25-tun.netdev', '25-tun.netdev', '25-vcan.netdev', '25-geneve.netdev', '25-ipip-tunnel.netdev',
+             '25-ip6tnl-tunnel.netdev', '25-ip6gre-tunnel.netdev','25-sit-tunnel.netdev', '25-gre-tunnel.netdev',
+             '25-gretap-tunnel.netdev', '25-vti-tunnel.netdev', '25-vti6-tunnel.netdev', '12-dummy.netdev',
+             'gre.network', 'ipip.network', 'ip6gretap.network', 'gretun.network', 'ip6tnl.network', '25-tap.netdev',
+             'vti6.network', 'vti.network', 'gretap.network', 'sit.network', '25-ipip-tunnel-independent.netdev']
+
+    def setUp(self):
+        self.link_remove(self.links)
+
+    def tearDown(self):
+        self.link_remove(self.links)
+        self.remove_unit_from_networkd_path(self.units)
+
+    def test_bridge(self):
+        self.copy_unit_to_networkd_unit_path('25-bridge.netdev')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('bridge99'))
+
+        self.assertEqual('900', self.read_link_attr('bridge99', 'bridge', 'hello_time'))
+        self.assertEqual('900', self.read_link_attr('bridge99', 'bridge', 'max_age'))
+        self.assertEqual('900', self.read_link_attr('bridge99', 'bridge','forward_delay'))
+        self.assertEqual('900', self.read_link_attr('bridge99', 'bridge','ageing_time'))
+        self.assertEqual('9',   self.read_link_attr('bridge99', 'bridge','priority'))
+        self.assertEqual('1',   self.read_link_attr('bridge99', 'bridge','multicast_querier'))
+        self.assertEqual('1',   self.read_link_attr('bridge99', 'bridge','multicast_snooping'))
+        self.assertEqual('1',   self.read_link_attr('bridge99', 'bridge','stp_state'))
+
+    def test_bond(self):
+        self.copy_unit_to_networkd_unit_path('25-bond.netdev')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('bond99'))
+
+        self.assertEqual('802.3ad 4',  self.read_link_attr('bond99', 'bonding', 'mode'))
+        self.assertEqual('layer3+4 1', self.read_link_attr('bond99', 'bonding', 'xmit_hash_policy'))
+        self.assertEqual('1000',       self.read_link_attr('bond99', 'bonding', 'miimon'))
+        self.assertEqual('fast 1',     self.read_link_attr('bond99', 'bonding', 'lacp_rate'))
+        self.assertEqual('2000',       self.read_link_attr('bond99', 'bonding', 'updelay'))
+        self.assertEqual('2000',       self.read_link_attr('bond99', 'bonding', 'downdelay'))
+        self.assertEqual('4',          self.read_link_attr('bond99', 'bonding', 'resend_igmp'))
+        self.assertEqual('1',          self.read_link_attr('bond99', 'bonding', 'min_links'))
+
+    def test_vlan(self):
+        self.copy_unit_to_networkd_unit_path('21-vlan.netdev', '11-dummy.netdev', '21-vlan.network')
+
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('vlan99'))
+
+        output = subprocess.check_output(['ip', '-d', 'link', 'show', 'vlan99']).rstrip().decode('utf-8')
+        self.assertTrue(output, 'REORDER_HDR')
+        self.assertTrue(output, 'LOOSE_BINDING')
+        self.assertTrue(output, 'GVRP')
+        self.assertTrue(output, 'MVRP')
+        self.assertTrue(output, '99')
+
+    def test_macvtap(self):
+        self.copy_unit_to_networkd_unit_path('21-macvtap.netdev', '11-dummy.netdev', 'macvtap.network')
+
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('macvtap99'))
+
+    def test_macvlan(self):
+        self.copy_unit_to_networkd_unit_path('21-macvlan.netdev', '11-dummy.netdev', 'macvlan.network')
+
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('macvlan99'))
+
+    def test_ipvlan(self):
+        self.copy_unit_to_networkd_unit_path('25-ipvlan.netdev', '11-dummy.netdev', 'ipvlan.network')
+
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('ipvlan99'))
+
+    def test_veth(self):
+        self.copy_unit_to_networkd_unit_path('25-veth.netdev')
+
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('veth99'))
+
+    def test_dummy(self):
+        self.copy_unit_to_networkd_unit_path('11-dummy.netdev')
+
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('test1'))
+
+    def test_tun(self):
+        self.copy_unit_to_networkd_unit_path('25-tun.netdev')
+
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('tun99'))
+
+    def test_tap(self):
+        self.copy_unit_to_networkd_unit_path('25-tap.netdev')
+
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('tap99'))
+
+    def test_vrf(self):
+        self.copy_unit_to_networkd_unit_path('25-vrf.netdev')
+
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('vrf99'))
+
+    def test_vcan(self):
+        self.copy_unit_to_networkd_unit_path('25-vcan.netdev')
+
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('vcan99'))
+
+    def test_geneve(self):
+        self.copy_unit_to_networkd_unit_path('25-geneve.netdev')
+
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('geneve99'))
+
+        output = subprocess.check_output(['ip', '-d', 'link', 'show', 'geneve99']).rstrip().decode('utf-8')
+        self.assertTrue(output, '192.168.22.1')
+        self.assertTrue(output, '6082')
+        self.assertTrue(output, 'udpcsum')
+        self.assertTrue(output, 'udp6zerocsumrx')
+
+    def test_ipip_tunnel(self):
+        self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-ipip-tunnel.netdev', 'ipip.network')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('dummy98'))
+        self.assertTrue(self.link_exits('ipiptun99'))
+
+    def test_gre_tunnel(self):
+        self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-gre-tunnel.netdev', 'gretun.network')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('dummy98'))
+        self.assertTrue(self.link_exits('gretun99'))
+
+    def test_gretap_tunnel(self):
+        self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-gretap-tunnel.netdev', 'gretap.network')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('dummy98'))
+        self.assertTrue(self.link_exits('gretap99'))
+
+    def test_ip6gretap_tunnel(self):
+        self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-ip6gre-tunnel.netdev', 'ip6gretap.network')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('dummy98'))
+        self.assertTrue(self.link_exits('ip6gretap99'))
+
+    def test_vti_tunnel(self):
+        self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-vti-tunnel.netdev', 'vti.network')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('dummy98'))
+        self.assertTrue(self.link_exits('vtitun99'))
+
+    def test_vti6_tunnel(self):
+        self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-vti6-tunnel.netdev', 'vti6.network')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('dummy98'))
+        self.assertTrue(self.link_exits('vti6tun99'))
+
+    def test_ip6tnl_tunnel(self):
+        self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-ip6tnl-tunnel.netdev', 'ip6tnl.network')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('dummy98'))
+        self.assertTrue(self.link_exits('ip6tnl99'))
+
+    def test_sit_tunnel(self):
+        self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-sit-tunnel.netdev', 'sit.network')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('dummy98'))
+        self.assertTrue(self.link_exits('sittun99'))
+
+    def test_tunnel_independent(self):
+        self.copy_unit_to_networkd_unit_path('25-ipip-tunnel-independent.netdev')
+
+        self.start_networkd()
+        self.assertTrue(self.link_exits('ipiptun99'))
+
+    def test_vxlan(self):
+        self.copy_unit_to_networkd_unit_path('25-vxlan.netdev', 'vxlan.network','11-dummy.netdev')
+
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('vxlan99'))
+
+        output = subprocess.check_output(['ip', '-d', 'link', 'show', 'vxlan99']).rstrip().decode('utf-8')
+        self.assertRegex(output, "999")
+        self.assertRegex(output, '5555')
+        self.assertRegex(output, 'l2miss')
+        self.assertRegex(output, 'l3miss')
+        self.assertRegex(output, 'udpcsum')
+        self.assertRegex(output, 'udp6zerocsumtx')
+        self.assertRegex(output, 'udp6zerocsumrx')
+        self.assertRegex(output, 'remcsumtx')
+        self.assertRegex(output, 'remcsumrx')
+        self.assertRegex(output, 'gbp')
+
+class NetworkdNetWorkTests(unittest.TestCase, Utilities):
+    links = ['dummy98', 'test1', 'bond199']
+
+    units = ['12-dummy.netdev', 'test-static.network', 'configure-without-carrier.network', '11-dummy.netdev',
+             '23-primary-slave.network', '23-test1-bond199.network', '11-dummy.netdev', '23-bond199.network',
+             '25-bond-active-backup-slave.netdev', '12-dummy.netdev', '23-active-slave.network',
+             'routing-policy-rule.network', '25-address-section.network', '25-address-section-miscellaneous.network',
+             '25-route-section.network', '25-route-type.network', '25-route-tcp-window-settings.network',
+             '25-address-link-section.network', '25-ipv6-address-label-section.network', '25-link-section-unmanaged.network',
+             '25-sysctl.network']
+
+    def setUp(self):
+        self.link_remove(self.links)
+
+    def tearDown(self):
+        self.link_remove(self.links)
+        self.remove_unit_from_networkd_path(self.units)
+
+    def test_static_address(self):
+        self.copy_unit_to_networkd_unit_path('12-dummy.netdev', 'test-static.network')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('dummy98'))
+        output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, '192.168.0.15')
+        self.assertRegex(output, '192.168.0.1')
+        self.assertRegex(output, 'routable')
+
+    def test_configure_without_carrier(self):
+        self.copy_unit_to_networkd_unit_path('configure-without-carrier.network', '11-dummy.netdev')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('test1'))
+        output = subprocess.check_output(['networkctl', 'status', 'test1']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, '192.168.0.15')
+        self.assertRegex(output, '192.168.0.1')
+        self.assertRegex(output, 'routable')
+
+    def test_bond_active_slave(self):
+        self.copy_unit_to_networkd_unit_path('23-active-slave.network', '23-bond199.network', '25-bond-active-backup-slave.netdev', '12-dummy.netdev')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('dummy98'))
+        self.assertTrue(self.link_exits('bond199'))
+        output = subprocess.check_output(['ip', '-d', 'link', 'show', 'bond199']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, 'active_slave dummy98')
+
+    def test_bond_primary_slave(self):
+        self.copy_unit_to_networkd_unit_path('23-primary-slave.network', '23-test1-bond199.network', '25-bond-active-backup-slave.netdev', '11-dummy.netdev')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('test1'))
+        self.assertTrue(self.link_exits('bond199'))
+        output = subprocess.check_output(['ip', '-d', 'link', 'show', 'bond199']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, 'primary test1')
+
+    def test_routing_policy_rule(self):
+        self.copy_unit_to_networkd_unit_path('routing-policy-rule.network', '11-dummy.netdev')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('test1'))
+        output = subprocess.check_output(['ip', 'rule']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, '111')
+        self.assertRegex(output, 'from 192.168.100.18')
+        self.assertRegex(output, 'tos 0x08')
+        self.assertRegex(output, 'iif test1')
+        self.assertRegex(output, 'oif test1')
+        self.assertRegex(output, 'lookup 7')
+
+    def test_address_preferred_lifetime_zero_ipv6(self):
+        self.copy_unit_to_networkd_unit_path('25-address-section-miscellaneous.network', '12-dummy.netdev')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('dummy98'))
+
+        output = subprocess.check_output(['ip', 'address', 'show', 'dummy98']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, 'inet 10.2.3.4/16 brd 10.2.255.255 scope link deprecated dummy98')
+        self.assertRegex(output, 'inet6 2001:db8:0:f101::1/64 scope global')
+
+    def test_ip_route(self):
+        self.copy_unit_to_networkd_unit_path('25-route-section.network', '12-dummy.netdev')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('dummy98'))
+
+        output = subprocess.check_output(['ip', 'route', 'list', 'dev', 'dummy98']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, '192.168.0.1')
+        self.assertRegex(output, 'static')
+        self.assertRegex(output, '192.168.0.0/24')
+
+    def test_ip_route_blackhole_unreachable_prohibit(self):
+        self.copy_unit_to_networkd_unit_path('25-route-type.network', '12-dummy.netdev')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('dummy98'))
+
+        output = subprocess.check_output(['ip', 'route', 'list']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, 'blackhole')
+        self.assertRegex(output, 'unreachable')
+        self.assertRegex(output, 'prohibit')
+
+        subprocess.call(['ip', 'route', 'del', 'blackhole', '202.54.1.2'])
+        subprocess.call(['ip', 'route', 'del', 'unreachable', '202.54.1.3'])
+        subprocess.call(['ip', 'route', 'del', 'prohibit', '202.54.1.4'])
+
+    def test_ip_route_tcp_window(self):
+        self.copy_unit_to_networkd_unit_path('25-route-tcp-window-settings.network', '11-dummy.netdev')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('test1'))
+
+        output = subprocess.check_output(['ip', 'route', 'list']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, 'initcwnd 20')
+        self.assertRegex(output, 'initrwnd 30')
+
+    def test_ip_link_mac_address(self):
+        self.copy_unit_to_networkd_unit_path('25-address-link-section.network', '12-dummy.netdev')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('dummy98'))
+
+        output = subprocess.check_output(['ip', 'link', 'show', 'dummy98']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, '00:01:02:aa:bb:cc')
+
+    def test_ip_link_unmanaged(self):
+        self.copy_unit_to_networkd_unit_path('25-link-section-unmanaged.network', '12-dummy.netdev')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('dummy98'))
+
+        output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, 'unmanaged')
+
+    def test_ipv6_address_label(self):
+        self.copy_unit_to_networkd_unit_path('25-ipv6-address-label-section.network', '12-dummy.netdev')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('dummy98'))
+
+        output = subprocess.check_output(['ip', 'addrlabel', 'list']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, '2004:da8:1::/64')
+
+    def test_sysctl(self):
+        self.copy_unit_to_networkd_unit_path('25-sysctl.network', '12-dummy.netdev')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('dummy98'))
+
+        self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'forwarding'), '1')
+        self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'use_tempaddr'), '2')
+        self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'dad_transmits'), '3')
+        self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'hop_limit'), '5')
+        self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'proxy_ndp'), '1')
+        self.assertEqual(self.read_ipv4_sysctl_attr('dummy98', 'forwarding'),'1')
+        self.assertEqual(self.read_ipv4_sysctl_attr('dummy98', 'proxy_arp'), '1')
+
+class NetworkdNetWorkBrideTests(unittest.TestCase, Utilities):
+    links = ['dummy98', 'test1', 'bridge99']
+
+    units = ['11-dummy.netdev', '12-dummy.netdev', '26-bridge.netdev', '26-bridge-slave-interface-1.network',
+             '26-bridge-slave-interface-2.network', 'bridge99.network']
+
+    def setUp(self):
+        self.link_remove(self.links)
+
+    def tearDown(self):
+        self.link_remove(self.links)
+        self.remove_unit_from_networkd_path(self.units)
+
+    def test_bridge_property(self):
+        self.copy_unit_to_networkd_unit_path('11-dummy.netdev', '12-dummy.netdev', '26-bridge.netdev',
+                                             '26-bridge-slave-interface-1.network', '26-bridge-slave-interface-2.network',
+                                             'bridge99.network')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('dummy98'))
+        self.assertTrue(self.link_exits('test1'))
+        self.assertTrue(self.link_exits('bridge99'))
+
+        output = subprocess.check_output(['ip', '-d', 'link', 'show', 'test1']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, 'master')
+        self.assertRegex(output, 'bridge')
+
+        output = subprocess.check_output(['ip', '-d', 'link', 'show', 'dummy98']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, 'master')
+        self.assertRegex(output, 'bridge')
+
+        output = subprocess.check_output(['ip', 'addr', 'show', 'bridge99']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, '192.168.0.15')
+        self.assertRegex(output, '192.168.0.1')
+
+        output = subprocess.check_output(['bridge', '-d', 'link', 'show', 'dummy98']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, 'cost 400')
+        self.assertRegex(output, 'hairpin on')
+        self.assertRegex(output, 'flood on')
+        self.assertRegex(output, 'fastleave on')
+
+class NetworkdNetWorkLLDPTests(unittest.TestCase, Utilities):
+    links = ['veth99']
+
+    units = ['23-emit-lldp.network', '24-lldp.network', '25-veth.netdev']
+
+    def setUp(self):
+        self.link_remove(self.links)
+
+    def tearDown(self):
+        self.link_remove(self.links)
+        self.remove_unit_from_networkd_path(self.units)
+
+    def test_lldp(self):
+        self.copy_unit_to_networkd_unit_path('23-emit-lldp.network', '24-lldp.network', '25-veth.netdev')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('veth99'))
+
+        output = subprocess.check_output(['networkctl', 'lldp']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, 'veth-peer')
+        self.assertRegex(output, 'veth99')
+
+class NetworkdNetworkRATests(unittest.TestCase, Utilities):
+    links = ['veth99']
+
+    units = ['25-veth.netdev', 'ipv6-prefix.network', 'ipv6-prefix-veth.network']
+
+    def setUp(self):
+        self.link_remove(self.links)
+
+    def tearDown(self):
+        self.link_remove(self.links)
+        self.remove_unit_from_networkd_path(self.units)
+
+    def test_ipv6_prefix_delegation(self):
+        self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'ipv6-prefix.network', 'ipv6-prefix-veth.network')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('veth99'))
+
+        output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, '2002:da8:1:0')
+
+class NetworkdNetworkDHCPServerTests(unittest.TestCase, Utilities):
+    links = ['veth99', 'dummy98']
+
+    units = ['25-veth.netdev', 'dhcp-client.network', 'dhcp-server.network', '12-dummy.netdev', '24-search-domain.network',
+             'dhcp-client-timezone-router.network', 'dhcp-server-timezone-router.network']
+
+    def setUp(self):
+        self.link_remove(self.links)
+
+    def tearDown(self):
+        self.link_remove(self.links)
+        self.remove_unit_from_networkd_path(self.units)
+
+    def test_dhcp_server(self):
+        self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-client.network', 'dhcp-server.network')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('veth99'))
+
+        time.sleep(5)
+
+        output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, '192.168.5.*')
+        self.assertRegex(output, 'Gateway: 192.168.5.1')
+        self.assertRegex(output, 'DNS: 192.168.5.1')
+        self.assertRegex(output, 'NTP: 192.168.5.1')
+
+    def test_domain(self):
+        self.copy_unit_to_networkd_unit_path( '12-dummy.netdev', '24-search-domain.network')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('dummy98'))
+
+        output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, 'Address: 192.168.42.100')
+        self.assertRegex(output, 'DNS: 192.168.42.1')
+        self.assertRegex(output, 'Search Domains: one')
+
+    def test_emit_router_timezone(self):
+        self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-client-timezone-router.network', 'dhcp-server-timezone-router.network')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('veth99'))
+
+        output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, 'Gateway: 192.168.5.*')
+        self.assertRegex(output, '192.168.5.*')
+        self.assertRegex(output, 'Europe/Berlin')
+
+class NetworkdNetworkDHCPClientTests(unittest.TestCase, Utilities):
+    links = ['veth99', 'dummy98']
+
+    units = ['25-veth.netdev', 'dhcp-server-veth-peer.network','dhcp-client-ipv6-only.network',
+             'dhcp-client-ipv4-only-ipv6-disabled.network', 'dhcp-client-ipv4-only.network',
+             'dhcp-client-ipv4-dhcp-settings.network', 'dhcp-client-anonymize.network',
+             'dhcp-client-ipv6-rapid-commit.network', 'dhcp-client-route-table.network',
+             'dhcp-v4-server-veth-peer.network', 'dhcp-client-listen-port.network',
+             'dhcp-client-route-metric.network', 'dhcp-client-critical-connection.network']
+
+    def setUp(self):
+        self.link_remove(self.links)
+        self.stop_dnsmasq(dnsmasq_pid_file)
+
+    def tearDown(self):
+        self.link_remove(self.links)
+        self.remove_unit_from_networkd_path(self.units)
+        self.stop_dnsmasq(dnsmasq_pid_file)
+        self.remove_lease_file()
+        self.remove_log_file()
+
+    def test_dhcp_client_ipv6_only(self):
+        self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network','dhcp-client-ipv6-only.network')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('veth99'))
+
+        self.start_dnsmasq()
+
+        output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, '2600::')
+        self.assertNotRegex(output, '192.168.5')
+
+    def test_dhcp_client_ipv4_only(self):
+        self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network','dhcp-client-ipv4-only-ipv6-disabled.network')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('veth99'))
+
+        self.start_dnsmasq()
+
+        output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
+        print(output)
+        self.assertNotRegex(output, '2600::')
+        self.assertRegex(output, '192.168.5')
+
+    def test_dhcp_client_ipv4_ipv6(self):
+        self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-only.network',
+                                             'dhcp-client-ipv4-only.network')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('veth99'))
+
+        self.start_dnsmasq()
+
+        output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, '2600::')
+        self.assertRegex(output, '192.168.5')
+
+    def test_dhcp_client_settings(self):
+        self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv4-dhcp-settings.network')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('veth99'))
+
+        self.start_dnsmasq()
+
+        output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, '12:34:56:78:9a:bc')
+        self.assertRegex(output, '192.168.5')
+        self.assertRegex(output, '1492')
+
+        output = subprocess.check_output(['ip', 'route']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, 'default.*dev veth99 proto dhcp')
+
+        self.search_words_in_file('vendor class: SusantVendorTest')
+        self.search_words_in_file('client MAC address: 12:34:56:78:9a:bc')
+        self.search_words_in_file('client provides name: test-hostname')
+        self.search_words_in_file('26:mtu')
+
+    def test_dhcp6_client_settings_rapidcommit_true(self):
+        self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-only.network')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('veth99'))
+
+        self.start_dnsmasq()
+
+        output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, '12:34:56:78:9a:bc')
+
+        self.assertTrue(self.search_words_in_file('14:rapid-commit'))
+
+    def test_dhcp6_client_settings_rapidcommit_false(self):
+        self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-rapid-commit.network')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('veth99'))
+
+        self.start_dnsmasq()
+
+        output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, '12:34:56:78:9a:bc')
+
+        self.assertFalse(self.search_words_in_file('14:rapid-commit'))
+
+    def test_dhcp_client_settings_anonymize(self):
+        self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-anonymize.network')
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('veth99'))
+
+        self.start_dnsmasq()
+        self.assertFalse(self.search_words_in_file('VendorClassIdentifier=SusantVendorTest'))
+        self.assertFalse(self.search_words_in_file('test-hostname'))
+        self.assertFalse(self.search_words_in_file('26:mtu'))
+
+    def test_dhcp_client_listen_port(self):
+        self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-listen-port.network')
+        dh_server = DHCPServer("dhcp_server")
+        dh_server.start()
+
+        self.start_networkd()
+
+        self.assertTrue(self.link_exits('veth99'))
+
+        global port
+        global ip
+
+        self.assertRegex(str(port), '5555')
+        self.assertRegex(str(ip), '0.0.0.0')
+
+        dh_server.join()
+
+    def test_dhcp_route_table_id(self):
+        self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-route-table.network')
+        self.start_networkd()
+        self.start_dnsmasq()
+
+        self.assertTrue(self.link_exits('veth99'))
+
+        output = subprocess.check_output(['ip', 'route', 'show', 'table', '12']).rstrip().decode('utf-8')
+        print(output)
+
+        self.assertRegex(output, 'veth99 proto dhcp')
+        self.assertRegex(output, '192.168.5.1')
+
+    def test_dhcp_route_metric(self):
+        self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-route-metric.network')
+        self.start_networkd()
+        self.start_dnsmasq()
+
+        self.assertTrue(self.link_exits('veth99'))
+
+        output = subprocess.check_output(['ip', 'route', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
+        print(output)
+
+        self.assertRegex(output, 'metric 24')
+
+    def test_dhcp_route_criticalconnection_true(self):
+        self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-critical-connection.network')
+        self.start_networkd()
+        self.start_dnsmasq()
+
+        self.assertTrue(self.link_exits('veth99'))
+
+        output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
+        print(output)
+
+        self.assertRegex(output, '192.168.5.*')
+        # Stoping dnsmasq as networkd won't be allowed to renew the DHCP lease.
+        self.stop_dnsmasq(dnsmasq_pid_file)
+
+        # Sleep for 120 sec as the dnsmasq minimum lease time can only be set to 120
+        time.sleep(125)
+
+        output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, '192.168.5.*')
+
+if __name__ == '__main__':
+    unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout,
+                                                     verbosity=3))
diff --git a/tools/make-index-md.sh b/tools/make-index-md.sh
new file mode 100755 (executable)
index 0000000..1c0dc36
--- /dev/null
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+set -eu
+
+cd "$@"/docs/
+(
+        echo "# systemd Documentation"
+
+        for f in *.md ; do
+                if [ "x$f" != "xindex.md" ] ; then
+                        t=`grep "^# " "$f" | head -n 1 | sed -e 's/^#\s*//'`
+                        echo -e "\n* [$t]($f)"
+                fi
+        done
+) > index.md
index 2db5b4cc44c13e8ad16c2b82e731be705c2518f7..4d11e81ed60988b8d63152d0bdb826906a5ebb2a 100755 (executable)
@@ -35,8 +35,10 @@ fi
 meson $build -D$fuzzflag -Db_lundef=false
 ninja -C $build fuzzers
 
-for d in "$(dirname "$0")/../test/fuzz-corpus/"*; do
-        zip -jqr $OUT/fuzz-$(basename "$d")_seed_corpus.zip "$d"
+# The seed corpus is a separate flat archive for each fuzzer,
+# with a fixed name ${fuzzer}_seed_corpus.zip.
+for d in "$(dirname "$0")/../test/fuzz/fuzz-"*; do
+        zip -jqr $OUT/$(basename "$d")_seed_corpus.zip "$d"
 done
 
 # get fuzz-dns-packet corpus
index d686ca634c4c030f3350ade929025ecb6dbff5df..248d597540e06e9dfa4c2b368091b19a0b02dd67 100644 (file)
@@ -11,7 +11,7 @@
 Description=Dispatch Password Requests to Console Directory Watch
 Documentation=man:systemd-ask-password-console.service(8)
 DefaultDependencies=no
-Conflicts=shutdown.target
+Conflicts=shutdown.target emergency.service
 After=plymouth-start.service
 Before=paths.target shutdown.target cryptsetup.target
 ConditionPathExists=!/run/plymouth/pid
index 6923d68df0730fe9a840617dfe7c3aaa63082d85..60fa7c320009cae82d764499150d3156d37fee91 100644 (file)
@@ -11,7 +11,7 @@
 Description=Dispatch Password Requests to Console
 Documentation=man:systemd-ask-password-console.service(8)
 DefaultDependencies=no
-Conflicts=shutdown.target
+Conflicts=shutdown.target emergency.service
 After=plymouth-start.service systemd-vconsole-setup.service
 Before=shutdown.target
 ConditionPathExists=!/run/plymouth/pid
index 5a356b97d0a6653c39862216352dc523d2b68894..193a9b311e0581a36d04b4b940aed4d85fb715d0 100644 (file)
@@ -11,7 +11,7 @@
 Description=Forward Password Requests to Wall Directory Watch
 Documentation=man:systemd-ask-password-console.service(8)
 DefaultDependencies=no
-Conflicts=shutdown.target
+Conflicts=shutdown.target emergency.service
 Before=paths.target shutdown.target cryptsetup.target
 
 [Path]