diff options
Diffstat (limited to 'src')
79 files changed, 806 insertions, 443 deletions
diff --git a/src/basic/chase.c b/src/basic/chase.c index 373252b645..983901f714 100644 --- a/src/basic/chase.c +++ b/src/basic/chase.c @@ -325,7 +325,11 @@ int chaseat(int dir_fd, const char *path, ChaseFlags flags, char **ret_path, int return r; if (FLAGS_SET(flags, CHASE_MKDIR_0755) && !isempty(todo)) { - child = xopenat(fd, first, O_DIRECTORY|O_CREAT|O_EXCL|O_NOFOLLOW|O_CLOEXEC, 0755); + child = xopenat(fd, + first, + O_DIRECTORY|O_CREAT|O_EXCL|O_NOFOLLOW|O_CLOEXEC, + /* xopen_flags = */ 0, + 0755); if (child < 0) return child; } else if (FLAGS_SET(flags, CHASE_PARENT) && isempty(todo)) { @@ -628,6 +632,7 @@ int chase_and_open(const char *path, const char *root, ChaseFlags chase_flags, i /* Shortcut this call if none of the special features of this call are requested */ return RET_NERRNO(xopenat(AT_FDCWD, path, open_flags | (FLAGS_SET(chase_flags, CHASE_NOFOLLOW) ? O_NOFOLLOW : 0), + /* xopen_flags = */ 0, mode)); r = chase(path, root, CHASE_PARENT|chase_flags, &p, &path_fd); @@ -645,7 +650,7 @@ int chase_and_open(const char *path, const char *root, ChaseFlags chase_flags, i return r; } - r = xopenat(path_fd, strempty(fname), open_flags|O_NOFOLLOW, mode); + r = xopenat(path_fd, strempty(fname), open_flags|O_NOFOLLOW, /* xopen_flags = */ 0, mode); if (r < 0) return r; @@ -834,6 +839,7 @@ int chase_and_openat(int dir_fd, const char *path, ChaseFlags chase_flags, int o /* Shortcut this call if none of the special features of this call are requested */ return RET_NERRNO(xopenat(dir_fd, path, open_flags | (FLAGS_SET(chase_flags, CHASE_NOFOLLOW) ? O_NOFOLLOW : 0), + /* xopen_flags = */ 0, mode)); r = chaseat(dir_fd, path, chase_flags|CHASE_PARENT, &p, &path_fd); @@ -846,7 +852,7 @@ int chase_and_openat(int dir_fd, const char *path, ChaseFlags chase_flags, int o return r; } - r = xopenat(path_fd, strempty(fname), open_flags|O_NOFOLLOW, mode); + r = xopenat(path_fd, strempty(fname), open_flags|O_NOFOLLOW, /* xopen_flags = */ 0, mode); if (r < 0) return r; diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c index 1e1413dc80..04a6531dcb 100644 --- a/src/basic/fs-util.c +++ b/src/basic/fs-util.c @@ -14,6 +14,7 @@ #include "fileio.h" #include "fs-util.h" #include "hostname-util.h" +#include "label.h" #include "lock-util.h" #include "log.h" #include "macro.h" @@ -1034,7 +1035,7 @@ int open_mkdir_at(int dirfd, const char *path, int flags, mode_t mode) { path = fname; } - fd = xopenat(dirfd, path, flags|O_CREAT|O_DIRECTORY|O_NOFOLLOW, mode); + fd = xopenat(dirfd, path, flags|O_CREAT|O_DIRECTORY|O_NOFOLLOW, /* xopen_flags = */ 0, mode); if (IN_SET(fd, -ELOOP, -ENOTDIR)) return -EEXIST; if (fd < 0) @@ -1090,7 +1091,7 @@ int openat_report_new(int dirfd, const char *pathname, int flags, mode_t mode, b } } -int xopenat(int dir_fd, const char *path, int flags, mode_t mode) { +int xopenat(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags, mode_t mode) { _cleanup_close_ int fd = -EBADF; bool made = false; int r; @@ -1099,14 +1100,20 @@ int xopenat(int dir_fd, const char *path, int flags, mode_t mode) { assert(path); if (isempty(path)) { - assert(!FLAGS_SET(flags, O_CREAT|O_EXCL)); - return fd_reopen(dir_fd, flags & ~O_NOFOLLOW); + assert(!FLAGS_SET(open_flags, O_CREAT|O_EXCL)); + return fd_reopen(dir_fd, open_flags & ~O_NOFOLLOW); } - if (FLAGS_SET(flags, O_DIRECTORY|O_CREAT)) { + if (FLAGS_SET(open_flags, O_CREAT) && FLAGS_SET(xopen_flags, XO_LABEL)) { + r = label_ops_pre(dir_fd, path, FLAGS_SET(open_flags, O_DIRECTORY) ? S_IFDIR : S_IFREG); + if (r < 0) + return r; + } + + if (FLAGS_SET(open_flags, O_DIRECTORY|O_CREAT)) { r = RET_NERRNO(mkdirat(dir_fd, path, mode)); if (r == -EEXIST) { - if (FLAGS_SET(flags, O_EXCL)) + if (FLAGS_SET(open_flags, O_EXCL)) return -EEXIST; made = false; @@ -1115,10 +1122,17 @@ int xopenat(int dir_fd, const char *path, int flags, mode_t mode) { else made = true; - flags &= ~(O_EXCL|O_CREAT); + if (FLAGS_SET(xopen_flags, XO_LABEL)) { + r = label_ops_post(dir_fd, path); + if (r < 0) + return r; + } + + open_flags &= ~(O_EXCL|O_CREAT); + xopen_flags &= ~XO_LABEL; } - fd = RET_NERRNO(openat(dir_fd, path, flags, mode)); + fd = RET_NERRNO(openat(dir_fd, path, open_flags, mode)); if (fd < 0) { if (IN_SET(fd, /* We got ENOENT? then someone else immediately removed it after we @@ -1137,10 +1151,24 @@ int xopenat(int dir_fd, const char *path, int flags, mode_t mode) { return fd; } + if (FLAGS_SET(open_flags, O_CREAT) && FLAGS_SET(xopen_flags, XO_LABEL)) { + r = label_ops_post(dir_fd, path); + if (r < 0) + return r; + } + return TAKE_FD(fd); } -int xopenat_lock(int dir_fd, const char *path, int flags, mode_t mode, LockType locktype, int operation) { +int xopenat_lock( + int dir_fd, + const char *path, + int open_flags, + XOpenFlags xopen_flags, + mode_t mode, + LockType locktype, + int operation) { + _cleanup_close_ int fd = -EBADF; int r; @@ -1150,13 +1178,13 @@ int xopenat_lock(int dir_fd, const char *path, int flags, mode_t mode, LockType /* POSIX/UNPOSIX locks don't work on directories (errno is set to -EBADF so let's return early with * the same error here). */ - if (FLAGS_SET(flags, O_DIRECTORY) && locktype != LOCK_BSD) + if (FLAGS_SET(open_flags, O_DIRECTORY) && locktype != LOCK_BSD) return -EBADF; for (;;) { struct stat st; - fd = xopenat(dir_fd, path, flags, mode); + fd = xopenat(dir_fd, path, open_flags, xopen_flags, mode); if (fd < 0) return fd; diff --git a/src/basic/fs-util.h b/src/basic/fs-util.h index cf381dfc26..a19836d138 100644 --- a/src/basic/fs-util.h +++ b/src/basic/fs-util.h @@ -132,6 +132,10 @@ int open_mkdir_at(int dirfd, const char *path, int flags, mode_t mode); int openat_report_new(int dirfd, const char *pathname, int flags, mode_t mode, bool *ret_newly_created); -int xopenat(int dir_fd, const char *path, int flags, mode_t mode); +typedef enum XOpenFlags { + XO_LABEL = 1 << 0, +} XOpenFlags; -int xopenat_lock(int dir_fd, const char *path, int flags, mode_t mode, LockType locktype, int operation); +int xopenat(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags, mode_t mode); + +int xopenat_lock(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags, mode_t mode, LockType locktype, int operation); diff --git a/src/basic/label.c b/src/basic/label.c new file mode 100644 index 0000000000..f134e77589 --- /dev/null +++ b/src/basic/label.c @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include <errno.h> +#include <stddef.h> + +#include "label.h" + +static const LabelOps *label_ops = NULL; + +int label_ops_set(const LabelOps *ops) { + if (label_ops) + return -EBUSY; + + label_ops = ops; + return 0; +} + +int label_ops_pre(int dir_fd, const char *path, mode_t mode) { + if (!label_ops || !label_ops->pre) + return 0; + + return label_ops->pre(dir_fd, path, mode); +} + +int label_ops_post(int dir_fd, const char *path) { + if (!label_ops || !label_ops->post) + return 0; + + return label_ops->post(dir_fd, path); +} diff --git a/src/basic/label.h b/src/basic/label.h new file mode 100644 index 0000000000..9644e435a3 --- /dev/null +++ b/src/basic/label.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include <sys/types.h> + +typedef struct LabelOps { + int (*pre)(int dir_fd, const char *path, mode_t mode); + int (*post)(int dir_fd, const char *path); +} LabelOps; + +int label_ops_set(const LabelOps *label_ops); + +int label_ops_pre(int dir_fd, const char *path, mode_t mode); +int label_ops_post(int dir_fd, const char *path); diff --git a/src/basic/lock-util.c b/src/basic/lock-util.c index 8ca30a50f0..3614fbe37c 100644 --- a/src/basic/lock-util.c +++ b/src/basic/lock-util.c @@ -37,7 +37,13 @@ int make_lock_file_at(int dir_fd, const char *p, int operation, LockFile *ret) { if (!t) return -ENOMEM; - fd = xopenat_lock(dfd, p, O_CREAT|O_RDWR|O_NOFOLLOW|O_CLOEXEC|O_NOCTTY, 0600, LOCK_UNPOSIX, operation); + fd = xopenat_lock(dfd, + p, + O_CREAT|O_RDWR|O_NOFOLLOW|O_CLOEXEC|O_NOCTTY, + /* xopen_flags = */ 0, + 0600, + LOCK_UNPOSIX, + operation); if (fd < 0) return fd == -EAGAIN ? -EBUSY : fd; diff --git a/src/basic/meson.build b/src/basic/meson.build index ee94337140..9358a40001 100644 --- a/src/basic/meson.build +++ b/src/basic/meson.build @@ -44,6 +44,7 @@ basic_sources = files( 'inotify-util.c', 'io-util.c', 'ioprio-util.c', + 'label.c', 'limits-util.c', 'locale-util.c', 'lock-util.c', diff --git a/src/basic/stat-util.c b/src/basic/stat-util.c index 843cc025dc..633d9479dd 100644 --- a/src/basic/stat-util.c +++ b/src/basic/stat-util.c @@ -464,7 +464,7 @@ int xstatfsat(int dir_fd, const char *path, struct statfs *ret) { assert(path); assert(ret); - fd = xopenat(dir_fd, path, O_PATH|O_CLOEXEC|O_NOCTTY, 0); + fd = xopenat(dir_fd, path, O_PATH|O_CLOEXEC|O_NOCTTY, /* xopen_flags = */ 0, /* mode = */ 0); if (fd < 0) return fd; diff --git a/src/basic/user-util.c b/src/basic/user-util.c index 3325aabe4d..6bdf26b42a 100644 --- a/src/basic/user-util.c +++ b/src/basic/user-util.c @@ -127,7 +127,7 @@ char* getlogname_malloc(void) { return uid_to_name(uid); } -char *getusername_malloc(void) { +char* getusername_malloc(void) { const char *e; e = secure_getenv("USER"); @@ -171,7 +171,7 @@ const char* default_root_shell_at(int rfd) { return "/bin/sh"; } -const char *default_root_shell(const char *root) { +const char* default_root_shell(const char *root) { _cleanup_close_ int rfd = -EBADF; rfd = open(empty_to_root(root), O_CLOEXEC | O_DIRECTORY | O_PATH); @@ -847,7 +847,7 @@ bool valid_gecos(const char *d) { return true; } -char *mangle_gecos(const char *d) { +char* mangle_gecos(const char *d) { char *mangled; /* Makes sure the provided string becomes valid as a GEGOS field, by dropping bad chars. glibc's @@ -1059,7 +1059,7 @@ int is_this_me(const char *username) { return uid == getuid(); } -const char *get_home_root(void) { +const char* get_home_root(void) { const char *e; /* For debug purposes allow overriding where we look for home dirs */ diff --git a/src/basic/user-util.h b/src/basic/user-util.h index c82941dd81..8b829a9ae2 100644 --- a/src/basic/user-util.h +++ b/src/basic/user-util.h @@ -103,7 +103,7 @@ typedef enum ValidUserFlags { bool valid_user_group_name(const char *u, ValidUserFlags flags); bool valid_gecos(const char *d); -char *mangle_gecos(const char *d); +char* mangle_gecos(const char *d); bool valid_home(const char *p); static inline bool valid_shell(const char *p) { @@ -136,7 +136,7 @@ const char* default_root_shell(const char *root); int is_this_me(const char *username); -const char *get_home_root(void); +const char* get_home_root(void); static inline bool hashed_password_is_locked_or_invalid(const char *password) { return password && password[0] != '$'; diff --git a/src/boot/bootctl-status.c b/src/boot/bootctl-status.c index 3da6478259..b51bd2681e 100644 --- a/src/boot/bootctl-status.c +++ b/src/boot/bootctl-status.c @@ -319,7 +319,7 @@ int verb_status(int argc, char *argv[], void *userdata) { dev_t esp_devid = 0, xbootldr_devid = 0; int r, k; - r = acquire_esp(/* unprivileged_mode= */ geteuid() != 0, /* graceful= */ false, NULL, NULL, NULL, &esp_uuid, &esp_devid); + r = acquire_esp(/* unprivileged_mode= */ -1, /* graceful= */ false, NULL, NULL, NULL, &esp_uuid, &esp_devid); if (arg_print_esp_path) { if (r == -EACCES) /* If we couldn't acquire the ESP path, log about access errors (which is the only * error the find_esp_and_warn() won't log on its own) */ @@ -330,7 +330,7 @@ int verb_status(int argc, char *argv[], void *userdata) { puts(arg_esp_path); } - r = acquire_xbootldr(/* unprivileged_mode= */ geteuid() != 0, &xbootldr_uuid, &xbootldr_devid); + r = acquire_xbootldr(/* unprivileged_mode= */ -1, &xbootldr_uuid, &xbootldr_devid); if (arg_print_dollar_boot_path) { if (r == -EACCES) return log_error_errno(r, "Failed to determine XBOOTLDR partition: %m"); @@ -770,13 +770,13 @@ int verb_list(int argc, char *argv[], void *userdata) { * Here we're interested in the latter but not the former, hence request the mode, and log about * EACCES. */ - r = acquire_esp(/* unprivileged_mode= */ geteuid() != 0, /* graceful= */ false, NULL, NULL, NULL, NULL, &esp_devid); + r = acquire_esp(/* unprivileged_mode= */ -1, /* graceful= */ false, NULL, NULL, NULL, NULL, &esp_devid); if (r == -EACCES) /* We really need the ESP path for this call, hence also log about access errors */ return log_error_errno(r, "Failed to determine ESP location: %m"); if (r < 0) return r; - r = acquire_xbootldr(/* unprivileged_mode= */ geteuid() != 0, NULL, &xbootldr_devid); + r = acquire_xbootldr(/* unprivileged_mode= */ -1, NULL, &xbootldr_devid); if (r == -EACCES) return log_error_errno(r, "Failed to determine XBOOTLDR partition: %m"); if (r < 0) diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c index 65608f5e83..da55ad8e0d 100644 --- a/src/boot/bootctl.c +++ b/src/boot/bootctl.c @@ -64,7 +64,7 @@ STATIC_DESTRUCTOR_REGISTER(arg_efi_boot_option_description, freep); STATIC_DESTRUCTOR_REGISTER(arg_image_policy, image_policy_freep); int acquire_esp( - bool unprivileged_mode, + int unprivileged_mode, bool graceful, uint32_t *ret_part, uint64_t *ret_pstart, @@ -101,7 +101,7 @@ int acquire_esp( } int acquire_xbootldr( - bool unprivileged_mode, + int unprivileged_mode, sd_id128_t *ret_uuid, dev_t *ret_devid) { diff --git a/src/boot/bootctl.h b/src/boot/bootctl.h index dd98b959c2..e395b3324a 100644 --- a/src/boot/bootctl.h +++ b/src/boot/bootctl.h @@ -42,5 +42,5 @@ static inline const char *arg_dollar_boot_path(void) { return arg_xbootldr_path ?: arg_esp_path; } -int acquire_esp(bool unprivileged_mode, bool graceful, uint32_t *ret_part, uint64_t *ret_pstart, uint64_t *ret_psize, sd_id128_t *ret_uuid, dev_t *ret_devid); -int acquire_xbootldr(bool unprivileged_mode, sd_id128_t *ret_uuid, dev_t *ret_devid); +int acquire_esp(int unprivileged_mode, bool graceful, uint32_t *ret_part, uint64_t *ret_pstart, uint64_t *ret_psize, sd_id128_t *ret_uuid, dev_t *ret_devid); +int acquire_xbootldr(int unprivileged_mode, sd_id128_t *ret_uuid, dev_t *ret_devid); diff --git a/src/boot/efi/proto/tcg.h b/src/boot/efi/proto/tcg.h index af6989c854..d8802ae0e3 100644 --- a/src/boot/efi/proto/tcg.h +++ b/src/boot/efi/proto/tcg.h @@ -54,7 +54,7 @@ typedef struct { uint8_t Digest[20]; } Digest; uint32_t EventSize; - uint8_t Event[0]; + uint8_t Event[]; } _packed_ TCG_PCR_EVENT; typedef struct { diff --git a/src/core/automount.c b/src/core/automount.c index 5df697bf22..3254275d6b 100644 --- a/src/core/automount.c +++ b/src/core/automount.c @@ -21,7 +21,7 @@ #include "format-util.h" #include "fstab-util.h" #include "io-util.h" -#include "label.h" +#include "label-util.h" #include "mkdir-label.h" #include "mount-util.h" #include "mount.h" diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 4ec5dfa587..839b1676c8 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -3142,7 +3142,9 @@ static int on_cgroup_empty_event(sd_event_source *s, void *userdata) { unit_add_to_gc_queue(u); - if (UNIT_VTABLE(u)->notify_cgroup_empty) + if (IN_SET(unit_active_state(u), UNIT_INACTIVE, UNIT_FAILED)) + unit_prune_cgroup(u); + else if (UNIT_VTABLE(u)->notify_cgroup_empty) UNIT_VTABLE(u)->notify_cgroup_empty(u); return 0; diff --git a/src/core/execute.c b/src/core/execute.c index 5e327465da..b2804e52e9 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -65,7 +65,7 @@ #include "hexdecoct.h" #include "io-util.h" #include "ioprio-util.h" -#include "label.h" +#include "label-util.h" #include "log.h" #include "macro.h" #include "manager.h" diff --git a/src/core/kmod-setup.c b/src/core/kmod-setup.c index c09e17f568..a99309f5c2 100644 --- a/src/core/kmod-setup.c +++ b/src/core/kmod-setup.c @@ -107,6 +107,27 @@ static bool has_virtio_console(void) { return r > 0; } +static bool has_virtio_vsock(void) { + int r; + + /* Directory traversal might be slow, hence let's do a cheap check first if it's even worth it */ + if (detect_vm() == VIRTUALIZATION_NONE) + return false; + + r = recurse_dir_at( + AT_FDCWD, + "/sys/devices/pci0000:00", + /* statx_mask= */ 0, + /* n_depth_max= */ 3, + RECURSE_DIR_ENSURE_TYPE, + match_modalias_recurse_dir_cb, + STRV_MAKE("virtio:d00000013v")); + if (r < 0) + log_debug_errno(r, "Failed to determine whether host has virtio-vsock device, ignoring: %m"); + + return r > 0; +} + static bool in_qemu(void) { return IN_SET(detect_vm(), VIRTUALIZATION_KVM, VIRTUALIZATION_QEMU); } @@ -124,35 +145,38 @@ int kmod_setup(void) { } kmod_table[] = { /* This one we need to load explicitly, since auto-loading on use doesn't work * before udev created the ghost device nodes, and we need it earlier than that. */ - { "autofs4", "/sys/class/misc/autofs", true, false, NULL }, + { "autofs4", "/sys/class/misc/autofs", true, false, NULL }, /* This one we need to load explicitly, since auto-loading of IPv6 is not done when * we try to configure ::1 on the loopback device. */ - { "ipv6", "/sys/module/ipv6", false, true, NULL }, + { "ipv6", "/sys/module/ipv6", false, true, NULL }, /* This should never be a module */ - { "unix", "/proc/net/unix", true, true, NULL }, + { "unix", "/proc/net/unix", true, true, NULL }, #if HAVE_LIBIPTC /* netfilter is needed by networkd, nspawn among others, and cannot be autoloaded */ - { "ip_tables", "/proc/net/ip_tables_names", false, false, NULL }, + { "ip_tables", "/proc/net/ip_tables_names", false, false, NULL }, #endif /* virtio_rng would be loaded by udev later, but real entropy might be needed very early */ - { "virtio_rng", NULL, false, false, has_virtio_rng }, + { "virtio_rng", NULL, false, false, has_virtio_rng }, /* we want early logging to hvc consoles if possible, and make sure systemd-getty-generator * can rely on all consoles being probed already.*/ - { "virtio_console", NULL, false, false, has_virtio_console }, + { "virtio_console", NULL, false, false, has_virtio_console }, + + /* Make sure we can send sd-notify messages over vsock as early as possible. */ + { "vmw_vsock_virtio_transport", NULL, false, false, has_virtio_vsock }, /* qemu_fw_cfg would be loaded by udev later, but we want to import credentials from it super early */ - { "qemu_fw_cfg", "/sys/firmware/qemu_fw_cfg", false, false, in_qemu }, + { "qemu_fw_cfg", "/sys/firmware/qemu_fw_cfg", false, false, in_qemu }, /* dmi-sysfs is needed to import credentials from it super early */ - { "dmi-sysfs", "/sys/firmware/dmi/entries", false, false, NULL }, + { "dmi-sysfs", "/sys/firmware/dmi/entries", false, false, NULL }, #if HAVE_TPM2 /* Make sure the tpm subsystem is available which ConditionSecurity=tpm2 depends on. */ - { "tpm", "/sys/class/tpmrm", false, false, efi_has_tpm2 }, + { "tpm", "/sys/class/tpmrm", false, false, efi_has_tpm2 }, #endif }; _cleanup_(kmod_unrefp) struct kmod_ctx *ctx = NULL; diff --git a/src/core/main.c b/src/core/main.c index 08d416bc14..c69f9b9afe 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -2849,8 +2849,8 @@ int main(int argc, char *argv[]) { goto finish; } - if (mac_selinux_init() < 0) { - error_message = "Failed to initialize SELinux support"; + if (mac_init() < 0) { + error_message = "Failed to initialize MAC support"; goto finish; } @@ -2922,8 +2922,8 @@ int main(int argc, char *argv[]) { * operate. */ capability_ambient_set_apply(0, /* also_inherit= */ false); - if (mac_selinux_init() < 0) { - error_message = "Failed to initialize SELinux support"; + if (mac_init() < 0) { + error_message = "Failed to initialize MAC support"; goto finish; } } diff --git a/src/core/manager.c b/src/core/manager.c index f8d469ebf6..78d1a032e6 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -54,7 +54,7 @@ #include "inotify-util.h" #include "install.h" #include "io-util.h" -#include "label.h" +#include "label-util.h" #include "load-fragment.h" #include "locale-setup.h" #include "log.h" diff --git a/src/core/namespace.c b/src/core/namespace.c index 1116ece59d..b00f27e08f 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -22,7 +22,7 @@ #include "fd-util.h" #include "format-util.h" #include "glyph-util.h" -#include "label.h" +#include "label-util.h" #include "list.h" #include "lock-util.h" #include "loop-util.h" diff --git a/src/core/scope.c b/src/core/scope.c index 761eb5ea56..72253421e2 100644 --- a/src/core/scope.c +++ b/src/core/scope.c @@ -629,11 +629,6 @@ static void scope_notify_cgroup_empty_event(Unit *u) { if (IN_SET(s->state, SCOPE_RUNNING, SCOPE_ABANDONED, SCOPE_STOP_SIGTERM, SCOPE_STOP_SIGKILL)) scope_enter_dead(s, SCOPE_SUCCESS); - - /* If the cgroup empty notification comes when the unit is not active, we must have failed to clean - * up the cgroup earlier and should do it now. */ - if (IN_SET(s->state, SCOPE_DEAD, SCOPE_FAILED)) - unit_prune_cgroup(u); } static void scope_notify_cgroup_oom_event(Unit *u, bool managed_oom) { diff --git a/src/core/service.c b/src/core/service.c index 533d7d3771..38f8745674 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -3648,12 +3648,7 @@ static void service_notify_cgroup_empty_event(Unit *u) { /* If the cgroup empty notification comes when the unit is not active, we must have failed to clean * up the cgroup earlier and should do it now. */ - case SERVICE_DEAD: - case SERVICE_FAILED: - case SERVICE_DEAD_BEFORE_AUTO_RESTART: - case SERVICE_FAILED_BEFORE_AUTO_RESTART: case SERVICE_AUTO_RESTART: - case SERVICE_DEAD_RESOURCES_PINNED: unit_prune_cgroup(u); break; diff --git a/src/core/socket.c b/src/core/socket.c index a6477de5a0..7c596182c2 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -26,7 +26,7 @@ #include "in-addr-util.h" #include "io-util.h" #include "ip-protocol-list.h" -#include "label.h" +#include "label-util.h" #include "log.h" #include "mkdir-label.h" #include "parse-util.h" diff --git a/src/core/transaction.c b/src/core/transaction.c index c3d6ffccc1..65a00bd928 100644 --- a/src/core/transaction.c +++ b/src/core/transaction.c @@ -325,6 +325,8 @@ static char* merge_unit_ids(const char* unit_log_field, char * const* pairs) { _cleanup_free_ char *ans = NULL; size_t size = 0; + assert(unit_log_field); + STRV_FOREACH_PAIR(unit_id, job_type, pairs) { size_t next; diff --git a/src/core/unit.c b/src/core/unit.c index 90f87a95f5..8b4fb0fce4 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -32,7 +32,7 @@ #include "id128-util.h" #include "install.h" #include "io-util.h" -#include "label.h" +#include "label-util.h" #include "load-dropin.h" #include "load-fragment.h" #include "log.h" @@ -441,6 +441,9 @@ bool unit_may_gc(Unit *u) { if (u->perpetual) return false; + if (u->in_cgroup_empty_queue) + return false; + if (sd_bus_track_count(u->bus_track) > 0) return false; diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c index 2d33a967ca..45e0abc63d 100644 --- a/src/dissect/dissect.c +++ b/src/dissect/dissect.c @@ -96,6 +96,8 @@ static int help(void) { _cleanup_free_ char *link = NULL; int r; + pager_open(arg_pager_flags); + r = terminal_urlify_man("systemd-dissect", "1", &link); if (r < 0) return log_oom(); diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c index 36ab0148b9..97b1c61748 100644 --- a/src/hostname/hostnamed.c +++ b/src/hostname/hostnamed.c @@ -1524,7 +1524,7 @@ static int run(int argc, char *argv[]) { umask(0022); - r = mac_selinux_init(); + r = mac_init(); if (r < 0) return r; diff --git a/src/hwdb/hwdb.c b/src/hwdb/hwdb.c index edc5dfc1f5..4287b1f066 100644 --- a/src/hwdb/hwdb.c +++ b/src/hwdb/hwdb.c @@ -124,7 +124,7 @@ static int run(int argc, char *argv[]) { if (r <= 0) return r; - r = mac_selinux_init(); + r = mac_init(); if (r < 0) return r; diff --git a/src/journal-remote/journal-remote-write.c b/src/journal-remote/journal-remote-write.c index 2d8188ec62..515ea2681e 100644 --- a/src/journal-remote/journal-remote-write.c +++ b/src/journal-remote/journal-remote-write.c @@ -28,19 +28,20 @@ int writer_new(RemoteServer *server, Writer **ret) { assert(server); assert(ret); - w = new0(Writer, 1); + w = new(Writer, 1); if (!w) return -ENOMEM; - w->n_ref = 1; - w->metrics = server->metrics; + *w = (Writer) { + .n_ref = 1, + .metrics = server->metrics, + .server = server, + }; w->mmap = mmap_cache_new(); if (!w->mmap) return -ENOMEM; - w->server = server; - if (is_dir(server->output, /* follow = */ true) > 0) { w->output = strdup(server->output); if (!w->output) diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index c53f2d5847..4f9c1f4780 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -65,6 +65,7 @@ #include "rlimit-util.h" #include "set.h" #include "sigbus.h" +#include "signal-util.h" #include "static-destruct.h" #include "stdio-util.h" #include "string-table.h" @@ -115,7 +116,7 @@ static char *arg_verify_key = NULL; static usec_t arg_interval = DEFAULT_FSS_INTERVAL_USEC; static bool arg_force = false; #endif -static usec_t arg_since, arg_until; +static usec_t arg_since = 0, arg_until = 0; static bool arg_since_set = false, arg_until_set = false; static char **arg_syslog_identifier = NULL; static char **arg_system_units = NULL; @@ -1047,7 +1048,10 @@ static int parse_argv(int argc, char *argv[]) { assert_not_reached(); } - if (arg_follow && !arg_no_tail && !arg_since && arg_lines == ARG_LINES_DEFAULT) + if (arg_no_tail) + arg_lines = ARG_LINES_ALL; + + if (arg_follow && !arg_since_set && arg_lines == ARG_LINES_DEFAULT) arg_lines = 10; if (arg_follow && !arg_merge && !arg_boot) { @@ -2058,51 +2062,295 @@ static int sync_journal(void) { return simple_varlink_call("--sync", "io.systemd.Journal.Synchronize"); } -static int wait_for_change(sd_journal *j, int poll_fd) { - struct pollfd pollfds[] = { - { .fd = poll_fd, .events = POLLIN }, - { .fd = STDOUT_FILENO }, - }; - usec_t timeout; +static int action_list_fields(sd_journal *j) { + const void *data; + size_t size; + int r, n_shown = 0; + + assert(arg_field); + + r = sd_journal_set_data_threshold(j, 0); + if (r < 0) + return log_error_errno(r, "Failed to unset data size threshold: %m"); + + r = sd_journal_query_unique(j, arg_field); + if (r < 0) + return log_error_errno(r, "Failed to query unique data objects: %m"); + + SD_JOURNAL_FOREACH_UNIQUE(j, data, size) { + const void *eq; + + if (arg_lines >= 0 && n_shown >= arg_lines) + break; + + eq = memchr(data, '=', size); + if (eq) + printf("%.*s\n", (int) (size - ((const uint8_t*) eq - (const uint8_t*) data + 1)), (const char*) eq + 1); + else + printf("%.*s\n", (int) size, (const char*) data); + + n_shown++; + } + + return 0; +} + +static int update_cursor(sd_journal *j) { + _cleanup_free_ char *cursor = NULL; int r; assert(j); - assert(poll_fd >= 0); - /* Much like sd_journal_wait() but also keeps an eye on STDOUT, and exits as soon as we see a POLLHUP on that, - * i.e. when it is closed. */ + if (!arg_show_cursor && !arg_cursor_file) + return 0; - r = sd_journal_get_timeout(j, &timeout); + r = sd_journal_get_cursor(j, &cursor); + if (r == -EADDRNOTAVAIL) + return 0; if (r < 0) - return log_error_errno(r, "Failed to determine journal waiting time: %m"); + return log_error_errno(r, "Failed to get cursor: %m"); - r = ppoll_usec(pollfds, ELEMENTSOF(pollfds), timeout); - if (r == -EINTR) - return 0; + if (arg_show_cursor) + printf("-- cursor: %s\n", cursor); + + if (arg_cursor_file) { + r = write_string_file(arg_cursor_file, cursor, WRITE_STRING_FILE_CREATE | WRITE_STRING_FILE_ATOMIC); + if (r < 0) + return log_error_errno(r, "Failed to write new cursor to %s: %m", arg_cursor_file); + } + + return 0; +} + +typedef struct Context { + sd_journal *journal; + bool need_seek; + bool since_seeked; + bool ellipsized; + bool previous_boot_id_valid; + sd_id128_t previous_boot_id; + sd_id128_t previous_boot_id_output; + dual_timestamp previous_ts_output; +} Context; + +static int show(Context *c) { + sd_journal *j; + int r, n_shown = 0; + + assert(c); + + j = ASSERT_PTR(c->journal); + + while (arg_lines < 0 || n_shown < arg_lines || arg_follow) { + int flags; + size_t highlight[2] = {}; + + if (c->need_seek) { + r = sd_journal_step_one(j, !arg_reverse); + if (r < 0) + return log_error_errno(r, "Failed to iterate through journal: %m"); + if (r == 0) + break; + } + + if (arg_until_set && !arg_reverse && (arg_lines < 0 || arg_since_set)) { + /* If --lines= is set, we usually rely on the n_shown to tell us + * when to stop. However, if --since= is set too, we may end up + * having less than --lines= to output. In this case let's also + * check if the entry is in range. */ + + usec_t usec; + + r = sd_journal_get_realtime_usec(j, &usec); + if (r < 0) + return log_error_errno(r, "Failed to determine timestamp: %m"); + if (usec > arg_until) + break; + } + + if (arg_since_set && (arg_reverse || !c->since_seeked)) { + usec_t usec; + + r = sd_journal_get_realtime_usec(j, &usec); + if (r < 0) + return log_error_errno(r, "Failed to determine timestamp: %m"); + + if (usec < arg_since) { + if (arg_reverse) + break; /* Reached the earliest entry */ + + /* arg_lines >= 0 (!since_seeked): + * We jumped arg_lines back and it seems to be too much */ + r = sd_journal_seek_realtime_usec(j, arg_since); + if (r < 0) + return log_error_errno(r, "Failed to seek to date: %m"); + c->since_seeked = true; + + c->need_seek = true; + continue; + } + c->since_seeked = true; /* We're surely within the range of --since now */ + } + + if (!arg_merge && !arg_quiet) { + sd_id128_t boot_id; + + r = sd_journal_get_monotonic_usec(j, NULL, &boot_id); + if (r >= 0) { + if (c->previous_boot_id_valid && + !sd_id128_equal(boot_id, c->previous_boot_id)) + printf("%s-- Boot "SD_ID128_FORMAT_STR" --%s\n", + ansi_highlight(), SD_ID128_FORMAT_VAL(boot_id), ansi_normal()); + + c->previous_boot_id = boot_id; + c->previous_boot_id_valid = true; + } + } + + if (arg_compiled_pattern) { + const void *message; + size_t len; + + r = sd_journal_get_data(j, "MESSAGE", &message, &len); + if (r < 0) { + if (r == -ENOENT) { + c->need_seek = true; + continue; + } + + return log_error_errno(r, "Failed to get MESSAGE field: %m"); + } + + assert_se(message = startswith(message, "MESSAGE=")); + + r = pattern_matches_and_log(arg_compiled_pattern, message, + len - strlen("MESSAGE="), highlight); + if (r < 0) + return r; + if (r == 0) { + c->need_seek = true; + continue; + } + } + + flags = + arg_all * OUTPUT_SHOW_ALL | + arg_full * OUTPUT_FULL_WIDTH | + colors_enabled() * OUTPUT_COLOR | + arg_catalog * OUTPUT_CATALOG | + arg_utc * OUTPUT_UTC | + arg_no_hostname * OUTPUT_NO_HOSTNAME; + + r = show_journal_entry(stdout, j, arg_output, 0, flags, + arg_output_fields, highlight, &c->ellipsized, + &c->previous_ts_output, &c->previous_boot_id_output); + c->need_seek = true; + if (r == -EADDRNOTAVAIL) + break; + if (r < 0) + return r; + + n_shown++; + + /* If journalctl take a long time to process messages, and during that time journal file + * rotation occurs, a journalctl client will keep those rotated files open until it calls + * sd_journal_process(), which typically happens as a result of calling sd_journal_wait() below + * in the "following" case. By periodically calling sd_journal_process() during the processing + * loop we shrink the window of time a client instance has open file descriptors for rotated + * (deleted) journal files. */ + if ((n_shown % PROCESS_INOTIFY_INTERVAL) == 0) { + r = sd_journal_process(j); + if (r < 0) + return log_error_errno(r, "Failed to process inotify events: %m"); + } + } + + return n_shown; +} + +static int show_and_fflush(Context *c, sd_event_source *s) { + int r; + + assert(c); + assert(s); + + r = show(c); + if (r < 0) + return sd_event_exit(sd_event_source_get_event(s), r); + + fflush(stdout); + return 0; +} + +static int on_journal_event(sd_event_source *s, int fd, uint32_t revents, void *userdata) { + Context *c = ASSERT_PTR(userdata); + int r; + + assert(s); + + r = sd_journal_process(c->journal); + if (r < 0) { + log_error_errno(r, "Failed to process journal events: %m"); + return sd_event_exit(sd_event_source_get_event(s), r); + } + + return show_and_fflush(c, s); +} + +static int on_first_event(sd_event_source *s, void *userdata) { + return show_and_fflush(userdata, s); +} + +static int on_signal(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) { + assert(s); + assert(si); + assert(IN_SET(si->ssi_signo, SIGTERM, SIGINT)); + + return sd_event_exit(sd_event_source_get_event(s), si->ssi_signo); +} + +static int setup_event(Context *c, int fd, sd_event **ret) { + _cleanup_(sd_event_unrefp) sd_event *e = NULL; + int r; + + assert(arg_follow); + assert(c); + assert(fd >= 0); + assert(ret); + + r = sd_event_default(&e); if (r < 0) - return log_error_errno(r, "Couldn't wait for journal event: %m"); + return log_error_errno(r, "Failed to allocate sd_event object: %m"); + + (void) sd_event_add_signal(e, NULL, SIGTERM | SD_EVENT_SIGNAL_PROCMASK, on_signal, NULL); + (void) sd_event_add_signal(e, NULL, SIGINT | SD_EVENT_SIGNAL_PROCMASK, on_signal, NULL); - if (pollfds[1].revents & (POLLHUP|POLLERR)) /* STDOUT has been closed? */ - return log_debug_errno(SYNTHETIC_ERRNO(ECANCELED), - "Standard output has been closed."); + r = sd_event_add_io(e, NULL, fd, EPOLLIN, &on_journal_event, c); + if (r < 0) + return log_error_errno(r, "Failed to add io event source for journal: %m"); - r = sd_journal_process(j); + /* Also keeps an eye on STDOUT, and exits as soon as we see a POLLHUP on that, i.e. when it is closed. */ + r = sd_event_add_io(e, NULL, STDOUT_FILENO, EPOLLHUP|EPOLLERR, NULL, INT_TO_PTR(-ECANCELED)); if (r < 0) - return log_error_errno(r, "Failed to process journal events: %m"); + return log_error_errno(r, "Failed to add io event source for stdout: %m"); + + if (arg_lines != 0 || arg_since_set) { + r = sd_event_add_defer(e, NULL, on_first_event, c); + if (r < 0) + return log_error_errno(r, "Failed to add defer event source: %m"); + } + *ret = TAKE_PTR(e); return 0; } static int run(int argc, char *argv[]) { + bool need_seek = false, since_seeked = false, use_cursor = false, after_cursor = false; _cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL; _cleanup_(umount_and_freep) char *mounted_dir = NULL; - bool previous_boot_id_valid = false, first_line = true, ellipsized = false, need_seek = false, since_seeked = false; - bool use_cursor = false, after_cursor = false; _cleanup_(sd_journal_closep) sd_journal *j = NULL; - sd_id128_t previous_boot_id = SD_ID128_NULL, previous_boot_id_output = SD_ID128_NULL; - dual_timestamp previous_ts_output = DUAL_TIMESTAMP_NULL; _cleanup_close_ int machine_fd = -EBADF; - int n_shown = 0, r, poll_fd = -EBADF; + int n_shown, r, poll_fd = -EBADF; setlocale(LC_ALL, ""); log_setup(); @@ -2381,37 +2629,8 @@ static int run(int argc, char *argv[]) { log_debug("Journal filter: %s", filter); } - if (arg_action == ACTION_LIST_FIELDS) { - const void *data; - size_t size; - - assert(arg_field); - - r = sd_journal_set_data_threshold(j, 0); - if (r < 0) - return log_error_errno(r, "Failed to unset data size threshold: %m"); - - r = sd_journal_query_unique(j, arg_field); - if (r < 0) - return log_error_errno(r, "Failed to query unique data objects: %m"); - - SD_JOURNAL_FOREACH_UNIQUE(j, data, size) { - const void *eq; - - if (arg_lines >= 0 && n_shown >= arg_lines) - break; - - eq = memchr(data, '=', size); - if (eq) - printf("%.*s\n", (int) (size - ((const uint8_t*) eq - (const uint8_t*) data + 1)), (const char*) eq + 1); - else - printf("%.*s\n", (int) size, (const char*) data); - - n_shown++; - } - - return 0; - } + if (arg_action == ACTION_LIST_FIELDS) + return action_list_fields(j); /* Opening the fd now means the first sd_journal_wait() will actually wait */ if (arg_follow) { @@ -2540,169 +2759,53 @@ static int run(int argc, char *argv[]) { } } - for (;;) { - while (arg_lines < 0 || n_shown < arg_lines || (arg_follow && !first_line)) { - int flags; - size_t highlight[2] = {}; - - if (need_seek) { - if (!arg_reverse) - r = sd_journal_next(j); - else - r = sd_journal_previous(j); - if (r < 0) - return log_error_errno(r, "Failed to iterate through journal: %m"); - if (r == 0) - break; - } - - if (arg_until_set && !arg_reverse && (arg_lines < 0 || arg_since_set)) { - /* If --lines= is set, we usually rely on the n_shown to tell us - * when to stop. However, if --since= is set too, we may end up - * having less than --lines= to output. In this case let's also - * check if the entry is in range. */ - - usec_t usec; - - r = sd_journal_get_realtime_usec(j, &usec); - if (r < 0) - return log_error_errno(r, "Failed to determine timestamp: %m"); - if (usec > arg_until) - break; - } - - if (arg_since_set && (arg_reverse || !since_seeked)) { - usec_t usec; - - r = sd_journal_get_realtime_usec(j, &usec); - if (r < 0) - return log_error_errno(r, "Failed to determine timestamp: %m"); - - if (usec < arg_since) { - if (arg_reverse) - break; /* Reached the earliest entry */ - - /* arg_lines >= 0 (!since_seeked): - * We jumped arg_lines back and it seems to be too much */ - r = sd_journal_seek_realtime_usec(j, arg_since); - if (r < 0) - return log_error_errno(r, "Failed to seek to date: %m"); - since_seeked = true; - - need_seek = true; - continue; - } - since_seeked = true; /* We're surely within the range of --since now */ - } - - if (!arg_merge && !arg_quiet) { - sd_id128_t boot_id; - - r = sd_journal_get_monotonic_usec(j, NULL, &boot_id); - if (r >= 0) { - if (previous_boot_id_valid && - !sd_id128_equal(boot_id, previous_boot_id)) - printf("%s-- Boot "SD_ID128_FORMAT_STR" --%s\n", - ansi_highlight(), SD_ID128_FORMAT_VAL(boot_id), ansi_normal()); - - previous_boot_id = boot_id; - previous_boot_id_valid = true; - } - } - - if (arg_compiled_pattern) { - const void *message; - size_t len; - - r = sd_journal_get_data(j, "MESSAGE", &message, &len); - if (r < 0) { - if (r == -ENOENT) { - need_seek = true; - continue; - } - - return log_error_errno(r, "Failed to get MESSAGE field: %m"); - } - - assert_se(message = startswith(message, "MESSAGE=")); - - r = pattern_matches_and_log(arg_compiled_pattern, message, - len - strlen("MESSAGE="), highlight); - if (r < 0) - return r; - if (r == 0) { - need_seek = true; - continue; - } - } + Context c = { + .journal = j, + .need_seek = need_seek, + .since_seeked = since_seeked, + }; - flags = - arg_all * OUTPUT_SHOW_ALL | - arg_full * OUTPUT_FULL_WIDTH | - colors_enabled() * OUTPUT_COLOR | - arg_catalog * OUTPUT_CATALOG | - arg_utc * OUTPUT_UTC | - arg_no_hostname * OUTPUT_NO_HOSTNAME; - - r = show_journal_entry(stdout, j, arg_output, 0, flags, - arg_output_fields, highlight, &ellipsized, - &previous_ts_output, &previous_boot_id_output); - need_seek = true; - if (r == -EADDRNOTAVAIL) - break; - if (r < 0) - return r; + if (arg_follow) { + _cleanup_(sd_event_unrefp) sd_event *e = NULL; + int sig; - n_shown++; + assert(poll_fd >= 0); - /* If journalctl take a long time to process messages, and during that time journal file - * rotation occurs, a journalctl client will keep those rotated files open until it calls - * sd_journal_process(), which typically happens as a result of calling sd_journal_wait() below - * in the "following" case. By periodically calling sd_journal_process() during the processing - * loop we shrink the window of time a client instance has open file descriptors for rotated - * (deleted) journal files. */ - if ((n_shown % PROCESS_INOTIFY_INTERVAL) == 0) { - r = sd_journal_process(j); - if (r < 0) - return log_error_errno(r, "Failed to process inotify events: %m"); - } - } + r = setup_event(&c, poll_fd, &e); + if (r < 0) + return r; - if (!arg_follow) { - if (n_shown == 0 && !arg_quiet) - printf("-- No entries --\n"); - break; - } + r = sd_event_loop(e); + if (r < 0) + return r; + sig = r; - fflush(stdout); + /* unref signal event sources. */ + e = sd_event_unref(e); - r = wait_for_change(j, poll_fd); + r = update_cursor(j); if (r < 0) return r; - first_line = false; + /* re-send the original signal. */ + assert(SIGNAL_VALID(sig)); + if (raise(sig) < 0) + log_error("Failed to raise the original signal SIG%s, ignoring: %m", signal_to_string(sig)); + + return 0; } - if (arg_show_cursor || arg_cursor_file) { - _cleanup_free_ char *cursor = NULL; + r = show(&c); + if (r < 0) + return r; + n_shown = r; - r = sd_journal_get_cursor(j, &cursor); - if (r < 0 && r != -EADDRNOTAVAIL) - return log_error_errno(r, "Failed to get cursor: %m"); - if (r >= 0) { - if (arg_show_cursor) - printf("-- cursor: %s\n", cursor); + if (n_shown == 0 && !arg_quiet) + printf("-- No entries --\n"); - if (arg_cursor_file) { - r = write_string_file(arg_cursor_file, cursor, - WRITE_STRING_FILE_CREATE | - WRITE_STRING_FILE_ATOMIC); - if (r < 0) - return log_error_errno(r, "Failed to write new cursor to %s: %m", - arg_cursor_file); - } - } - } + r = update_cursor(j); + if (r < 0) + return r; if (arg_compiled_pattern && n_shown == 0) /* --grep was used, no error was thrown, but the pattern didn't diff --git a/src/libsystemd-network/fuzz-dhcp-server.c b/src/libsystemd-network/fuzz-dhcp-server.c index ad00654a91..192e209a2f 100644 --- a/src/libsystemd-network/fuzz-dhcp-server.c +++ b/src/libsystemd-network/fuzz-dhcp-server.c @@ -19,30 +19,32 @@ ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags) { static int add_lease(sd_dhcp_server *server, const struct in_addr *server_address, uint8_t i) { _cleanup_(dhcp_lease_freep) DHCPLease *lease = NULL; - static const uint8_t chaddr[] = {3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3}; int r; assert(server); - lease = new0(DHCPLease, 1); + lease = new(DHCPLease, 1); if (!lease) return -ENOMEM; - lease->client_id.data = malloc(2); + *lease = (DHCPLease) { + .address = htobe32(UINT32_C(10) << 24 | i), + .chaddr = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + .expiration = UINT64_MAX, + .gateway = server_address->s_addr, + .hlen = ETH_ALEN, + .htype = ARPHRD_ETHER, + + .client_id.length = 2, + }; + + lease->client_id.data = new(uint8_t, lease->client_id.length); if (!lease->client_id.data) return -ENOMEM; - lease->client_id.length = 2; lease->client_id.data[0] = 2; lease->client_id.data[1] = i; - lease->address = htobe32(UINT32_C(10) << 24 | i); - lease->gateway = server_address->s_addr; - lease->expiration = UINT64_MAX; - lease->htype = ARPHRD_ETHER; - lease->hlen = ETH_ALEN; - memcpy(lease->chaddr, chaddr, ETH_ALEN); - lease->server = server; /* This must be set just before hashmap_put(). */ r = hashmap_ensure_put(&server->bound_leases_by_client_id, &dhcp_lease_hash_ops, &lease->client_id, lease); @@ -54,22 +56,18 @@ static int add_lease(sd_dhcp_server *server, const struct in_addr *server_addres return r; TAKE_PTR(lease); - return 0; } static int add_static_lease(sd_dhcp_server *server, uint8_t i) { uint8_t id[2] = { 2, i }; - int r; assert(server); - r = sd_dhcp_server_set_static_lease( + return sd_dhcp_server_set_static_lease( server, &(struct in_addr) { .s_addr = htobe32(UINT32_C(10) << 24 | i)}, id, ELEMENTSOF(id)); - - return r; } int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym index 35352dc832..936a3577f5 100644 --- a/src/libsystemd/libsystemd.sym +++ b/src/libsystemd/libsystemd.sym @@ -825,4 +825,5 @@ global: sd_event_trim_memory; sd_pid_notify_barrier; sd_event_source_leave_ratelimit; + sd_journal_step_one; } LIBSYSTEMD_253; diff --git a/src/libsystemd/sd-daemon/sd-daemon.c b/src/libsystemd/sd-daemon/sd-daemon.c index 8538b7ab82..c4472d204e 100644 --- a/src/libsystemd/sd-daemon/sd-daemon.c +++ b/src/libsystemd/sd-daemon/sd-daemon.c @@ -450,13 +450,11 @@ static int vsock_bind_privileged_port(int fd) { return r; } -_public_ int sd_pid_notify_with_fds( +static int pid_notify_with_fds_internal( pid_t pid, - int unset_environment, const char *state, const int *fds, unsigned n_fds) { - SocketAddress address; struct iovec iovec; struct msghdr msghdr = { @@ -470,15 +468,11 @@ _public_ int sd_pid_notify_with_fds( bool send_ucred; int r; - if (!state) { - r = -EINVAL; - goto finish; - } + if (!state) + return -EINVAL; - if (n_fds > 0 && !fds) { - r = -EINVAL; - goto finish; - } + if (n_fds > 0 && !fds) + return -EINVAL; e = getenv("NOTIFY_SOCKET"); if (!e) @@ -489,46 +483,38 @@ _public_ int sd_pid_notify_with_fds( if (r == -EPROTO) r = socket_address_parse_vsock(&address, e); if (r < 0) - goto finish; + return r; msghdr.msg_namelen = address.size; /* If we didn't get an address (which is a normal pattern when specifying VSOCK tuples) error out, * we always require a specific CID. */ - if (address.sockaddr.vm.svm_family == AF_VSOCK && address.sockaddr.vm.svm_cid == VMADDR_CID_ANY) { - r = -EINVAL; - goto finish; - } + if (address.sockaddr.vm.svm_family == AF_VSOCK && address.sockaddr.vm.svm_cid == VMADDR_CID_ANY) + return -EINVAL; /* At the time of writing QEMU does not yet support AF_VSOCK + SOCK_DGRAM and returns * ENODEV. Fallback to SOCK_SEQPACKET in that case. */ fd = socket(address.sockaddr.sa.sa_family, SOCK_DGRAM|SOCK_CLOEXEC, 0); if (fd < 0) { - if (!(ERRNO_IS_NOT_SUPPORTED(errno) || errno == ENODEV) || address.sockaddr.sa.sa_family != AF_VSOCK) { - r = -errno; - goto finish; - } + if (!(ERRNO_IS_NOT_SUPPORTED(errno) || errno == ENODEV) || address.sockaddr.sa.sa_family != AF_VSOCK) + return log_debug_errno(errno, "Failed to open datagram notify socket to '%s': %m", e); fd = socket(address.sockaddr.sa.sa_family, SOCK_SEQPACKET|SOCK_CLOEXEC, 0); - if (fd < 0) { - r = -errno; - goto finish; - } + if (fd < 0) + return log_debug_errno(errno, "Failed to open sequential packet socket to '%s': %m", e); r = vsock_bind_privileged_port(fd); if (r < 0 && !ERRNO_IS_PRIVILEGE(r)) - goto finish; + return log_debug_errno(r, "Failed to bind socket to privileged port: %m"); - if (connect(fd, &address.sockaddr.sa, address.size) < 0) { - r = -errno; - goto finish; - } + if (connect(fd, &address.sockaddr.sa, address.size) < 0) + return log_debug_errno(errno, "Failed to connect socket to '%s': %m", e); msghdr.msg_name = NULL; msghdr.msg_namelen = 0; } else if (address.sockaddr.sa.sa_family == AF_VSOCK) { r = vsock_bind_privileged_port(fd); if (r < 0 && !ERRNO_IS_PRIVILEGE(r)) - goto finish; + return log_debug_errno(r, "Failed to bind socket to privileged port: %m"); } (void) fd_inc_sndbuf(fd, SNDBUF_SIZE); @@ -575,10 +561,8 @@ _public_ int sd_pid_notify_with_fds( } /* First try with fake ucred data, as requested */ - if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) >= 0) { - r = 1; - goto finish; - } + if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) >= 0) + return 1; /* If that failed, try with our own ucred instead */ if (send_ucred) { @@ -586,15 +570,24 @@ _public_ int sd_pid_notify_with_fds( if (msghdr.msg_controllen == 0) msghdr.msg_control = NULL; - if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) >= 0) { - r = 1; - goto finish; - } + if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) >= 0) + return 1; } - r = -errno; + return log_debug_errno(errno, "Failed to send notify message to '%s': %m", e); +} + +_public_ int sd_pid_notify_with_fds( + pid_t pid, + int unset_environment, + const char *state, + const int *fds, + unsigned n_fds) { + + int r; + + r = pid_notify_with_fds_internal(pid, state, fds, n_fds); -finish: if (unset_environment) assert_se(unsetenv("NOTIFY_SOCKET") == 0); diff --git a/src/libsystemd/sd-id128/id128-util.c b/src/libsystemd/sd-id128/id128-util.c index 76c9d1c051..edadd86eaa 100644 --- a/src/libsystemd/sd-id128/id128-util.c +++ b/src/libsystemd/sd-id128/id128-util.c @@ -119,7 +119,7 @@ int id128_read_at(int dir_fd, const char *path, Id128Flag f, sd_id128_t *ret) { assert(dir_fd >= 0 || dir_fd == AT_FDCWD); assert(path); - fd = xopenat(dir_fd, path, O_RDONLY|O_CLOEXEC|O_NOCTTY, 0); + fd = xopenat(dir_fd, path, O_RDONLY|O_CLOEXEC|O_NOCTTY, /* xopen_flags = */ 0, /* mode = */ 0); if (fd < 0) return fd; @@ -165,7 +165,7 @@ int id128_write_at(int dir_fd, const char *path, Id128Flag f, sd_id128_t id) { assert(dir_fd >= 0 || dir_fd == AT_FDCWD); assert(path); - fd = xopenat(dir_fd, path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_TRUNC, 0444); + fd = xopenat(dir_fd, path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_TRUNC, /* xopen_flags = */ 0, 0444); if (fd < 0) return fd; diff --git a/src/libsystemd/sd-journal/sd-journal.c b/src/libsystemd/sd-journal/sd-journal.c index 47532e2cbc..957817bfab 100644 --- a/src/libsystemd/sd-journal/sd-journal.c +++ b/src/libsystemd/sd-journal/sd-journal.c @@ -979,6 +979,16 @@ _public_ int sd_journal_previous(sd_journal *j) { return real_journal_next(j, DIRECTION_UP); } +_public_ int sd_journal_step_one(sd_journal *j, int advanced) { + assert_return(j, -EINVAL); + + if (j->current_location.type == LOCATION_HEAD) + return sd_journal_next(j); + if (j->current_location.type == LOCATION_TAIL) + return sd_journal_previous(j); + return real_journal_next(j, advanced ? DIRECTION_DOWN : DIRECTION_UP); +} + static int real_journal_next_skip(sd_journal *j, direction_t direction, uint64_t skip) { int c = 0, r; diff --git a/src/locale/localed.c b/src/locale/localed.c index 63ff69d7d3..9e5b7b03c0 100644 --- a/src/locale/localed.c +++ b/src/locale/localed.c @@ -657,7 +657,7 @@ static int run(int argc, char *argv[]) { umask(0022); - r = mac_selinux_init(); + r = mac_init(); if (r < 0) return r; diff --git a/src/login/logind-user.c b/src/login/logind-user.c index 6161af9a74..7a6056086a 100644 --- a/src/login/logind-user.c +++ b/src/login/logind-user.c @@ -17,7 +17,7 @@ #include "format-util.h" #include "fs-util.h" #include "hashmap.h" -#include "label.h" +#include "label-util.h" #include "limits-util.h" #include "logind-dbus.h" #include "logind-user-dbus.h" diff --git a/src/login/logind.c b/src/login/logind.c index cfb3ef500c..8323bcc0cb 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -1194,7 +1194,7 @@ static int run(int argc, char *argv[]) { umask(0022); - r = mac_selinux_init(); + r = mac_init(); if (r < 0) return r; diff --git a/src/login/user-runtime-dir.c b/src/login/user-runtime-dir.c index 5a16d1684d..ed8a80e6ed 100644 --- a/src/login/user-runtime-dir.c +++ b/src/login/user-runtime-dir.c @@ -10,7 +10,7 @@ #include "dev-setup.h" #include "format-util.h" #include "fs-util.h" -#include "label.h" +#include "label-util.h" #include "limits-util.h" #include "main-func.h" #include "mkdir-label.h" @@ -202,7 +202,7 @@ static int run(int argc, char *argv[]) { umask(0022); - r = mac_selinux_init(); + r = mac_init(); if (r < 0) return r; diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c index 197d0cfa1c..8d7d464a4a 100644 --- a/src/machine/machinectl.c +++ b/src/machine/machinectl.c @@ -1462,7 +1462,7 @@ static int edit_settings(int argc, char *argv[], void *userdata) { return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Edit is only supported on the host machine."); - r = mac_selinux_init(); + r = mac_init(); if (r < 0) return r; diff --git a/src/network/wait-online/manager.c b/src/network/wait-online/manager.c index 2e845aa19f..9213795f54 100644 --- a/src/network/wait-online/manager.c +++ b/src/network/wait-online/manager.c @@ -162,12 +162,13 @@ bool manager_configured(Manager *m) { return true; } - /* With '--any' : no interface is ready - * Without '--any': all interfaces are ready */ + /* With '--any' : no interface is ready → return false + * Without '--any': all interfaces are ready → return true */ return !m->any; } /* wait for all links networkd manages */ + bool has_online = false; HASHMAP_FOREACH(l, m->links_by_index) { if (manager_ignore_link(m, l)) { log_link_debug(l, "link is ignored"); @@ -179,13 +180,20 @@ bool manager_configured(Manager *m) { _LINK_OPERSTATE_INVALID }); if (r < 0 && !m->any) /* Unlike the above loop, unmanaged interfaces are ignored here. */ return false; - if (r > 0 && m->any) - return true; + if (r > 0) { + if (m->any) + return true; + has_online = true; + } } - /* With '--any' : no interface is ready - * Without '--any': all interfaces are ready or unmanaged */ - return !m->any; + /* With '--any' : no interface is ready → return false + * Without '--any': all interfaces are ready or unmanaged + * + * In this stage, drivers for interfaces may not be loaded yet, and there may be only lo. + * To avoid that wait-online exits earlier than that drivers are loaded, let's request at least one + * managed online interface exists. See issue #27822. */ + return !m->any && has_online; } static int manager_process_link(sd_netlink *rtnl, sd_netlink_message *mm, void *userdata) { diff --git a/src/nspawn/nspawn-mount.c b/src/nspawn/nspawn-mount.c index fcf5c710f1..0a85b5d89a 100644 --- a/src/nspawn/nspawn-mount.c +++ b/src/nspawn/nspawn-mount.c @@ -9,7 +9,7 @@ #include "fd-util.h" #include "format-util.h" #include "fs-util.h" -#include "label.h" +#include "label-util.h" #include "mkdir-label.h" #include "mount-util.h" #include "mountpoint-util.h" diff --git a/src/oom/test-oomd-util.c b/src/oom/test-oomd-util.c index ef99d924bb..dc659b6551 100644 --- a/src/oom/test-oomd-util.c +++ b/src/oom/test-oomd-util.c @@ -204,7 +204,7 @@ static void test_oomd_update_cgroup_contexts_between_hashmaps(void) { } static void test_oomd_system_context_acquire(void) { - _cleanup_(unlink_tempfilep) char path[] = "/oomdgetsysctxtestXXXXXX"; + _cleanup_(unlink_tempfilep) char path[] = "/tmp/oomdgetsysctxtestXXXXXX"; _cleanup_close_ int fd = -EBADF; OomdSystemContext ctx; diff --git a/src/resolve/resolved-resolv-conf.c b/src/resolve/resolved-resolv-conf.c index 5749aa1dc3..52e31d2fd3 100644 --- a/src/resolve/resolved-resolv-conf.c +++ b/src/resolve/resolved-resolv-conf.c @@ -10,7 +10,7 @@ #include "fd-util.h" #include "fileio.h" #include "fs-util.h" -#include "label.h" +#include "label-util.h" #include "ordered-set.h" #include "resolved-conf.h" #include "resolved-dns-server.h" diff --git a/src/resolve/resolved.c b/src/resolve/resolved.c index f9d3281509..1625c5189d 100644 --- a/src/resolve/resolved.c +++ b/src/resolve/resolved.c @@ -38,7 +38,7 @@ static int run(int argc, char *argv[]) { umask(0022); - r = mac_selinux_init(); + r = mac_init(); if (r < 0) return r; diff --git a/src/shared/btrfs-util.c b/src/shared/btrfs-util.c index 7909184f2d..16295a5823 100644 --- a/src/shared/btrfs-util.c +++ b/src/shared/btrfs-util.c @@ -223,7 +223,7 @@ int btrfs_get_block_device_at(int dir_fd, const char *path, dev_t *ret) { assert(path); assert(ret); - fd = xopenat(dir_fd, path, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY, 0); + fd = xopenat(dir_fd, path, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY, /* xopen_flags = */ 0, /* mode = */ 0); if (fd < 0) return fd; diff --git a/src/shared/creds-util.c b/src/shared/creds-util.c index 59f580775d..efc36e2d6d 100644 --- a/src/shared/creds-util.c +++ b/src/shared/creds-util.c @@ -342,6 +342,9 @@ int get_credential_host_secret(CredentialSecretFlags flags, void **ret, size_t * filename = "credential.secret"; } + assert(dirname); + assert(filename); + mkdir_parents(dirname, 0755); dfd = open_mkdir_at(AT_FDCWD, dirname, O_CLOEXEC, 0755); if (dfd < 0) diff --git a/src/shared/dev-setup.c b/src/shared/dev-setup.c index e0db777c96..7dca6ad7d4 100644 --- a/src/shared/dev-setup.c +++ b/src/shared/dev-setup.c @@ -6,7 +6,7 @@ #include "alloc-util.h" #include "dev-setup.h" -#include "label.h" +#include "label-util.h" #include "log.h" #include "mkdir-label.h" #include "nulstr-util.h" diff --git a/src/shared/find-esp.c b/src/shared/find-esp.c index c4cf508517..d9336f4431 100644 --- a/src/shared/find-esp.c +++ b/src/shared/find-esp.c @@ -31,7 +31,7 @@ typedef enum VerifyESPFlags { static int verify_esp_blkid( dev_t devid, - bool searching, + VerifyESPFlags flags, uint32_t *ret_part, uint64_t *ret_pstart, uint64_t *ret_psize, @@ -44,6 +44,7 @@ static int verify_esp_blkid( #if HAVE_BLKID _cleanup_(blkid_free_probep) blkid_probe b = NULL; _cleanup_free_ char *node = NULL; + bool searching = FLAGS_SET(flags, VERIFY_ESP_SEARCHING); const char *v; int r; @@ -65,9 +66,9 @@ static int verify_esp_blkid( r = blkid_do_safeprobe(b); if (r == -2) return log_error_errno(SYNTHETIC_ERRNO(ENODEV), "File system \"%s\" is ambiguous.", node); - else if (r == 1) + if (r == 1) return log_error_errno(SYNTHETIC_ERRNO(ENODEV), "File system \"%s\" does not contain a label.", node); - else if (r != 0) + if (r != 0) return log_error_errno(errno ?: SYNTHETIC_ERRNO(EIO), "Failed to probe file system \"%s\": %m", node); r = blkid_probe_lookup_value(b, "TYPE", &v, NULL); @@ -146,12 +147,13 @@ static int verify_esp_blkid( static int verify_esp_udev( dev_t devid, - bool searching, + VerifyESPFlags flags, uint32_t *ret_part, uint64_t *ret_pstart, uint64_t *ret_psize, sd_id128_t *ret_uuid) { + bool searching = FLAGS_SET(flags, VERIFY_ESP_SEARCHING); _cleanup_(sd_device_unrefp) sd_device *d = NULL; sd_id128_t uuid = SD_ID128_NULL; uint64_t pstart = 0, psize = 0; @@ -240,10 +242,11 @@ static int verify_esp_udev( static int verify_fsroot_dir( int dir_fd, const char *path, - bool searching, - bool unprivileged_mode, + VerifyESPFlags flags, dev_t *ret_dev) { + bool searching = FLAGS_SET(flags, VERIFY_ESP_SEARCHING), + unprivileged_mode = FLAGS_SET(flags, VERIFY_ESP_UNPRIVILEGED_MODE); _cleanup_free_ char *f = NULL; STRUCT_NEW_STATX_DEFINE(sxa); STRUCT_NEW_STATX_DEFINE(sxb); @@ -377,7 +380,7 @@ static int verify_esp( relax_checks || detect_container() > 0; - r = verify_fsroot_dir(pfd, p, searching, unprivileged_mode, relax_checks ? NULL : &devid); + r = verify_fsroot_dir(pfd, p, flags, relax_checks ? NULL : &devid); if (r < 0) return r; @@ -392,9 +395,9 @@ static int verify_esp( * however blkid can't work if we have no privileges to access block devices directly, which is why * we use udev in that case. */ if (unprivileged_mode) - r = verify_esp_udev(devid, searching, ret_part, ret_pstart, ret_psize, ret_uuid); + r = verify_esp_udev(devid, flags, ret_part, ret_pstart, ret_psize, ret_uuid); else - r = verify_esp_blkid(devid, searching, ret_part, ret_pstart, ret_psize, ret_uuid); + r = verify_esp_blkid(devid, flags, ret_part, ret_pstart, ret_psize, ret_uuid); if (r < 0) return r; @@ -425,7 +428,7 @@ finish: int find_esp_and_warn_at( int rfd, const char *path, - bool unprivileged_mode, + int unprivileged_mode, char **ret_path, uint32_t *ret_part, uint64_t *ret_pstart, @@ -433,7 +436,7 @@ int find_esp_and_warn_at( sd_id128_t *ret_uuid, dev_t *ret_devid) { - VerifyESPFlags flags = (unprivileged_mode ? VERIFY_ESP_UNPRIVILEGED_MODE : 0); + VerifyESPFlags flags; int r; /* This logs about all errors except: @@ -444,6 +447,10 @@ int find_esp_and_warn_at( assert(rfd >= 0 || rfd == AT_FDCWD); + if (unprivileged_mode < 0) + unprivileged_mode = geteuid() != 0; + flags = unprivileged_mode > 0 ? VERIFY_ESP_UNPRIVILEGED_MODE : 0; + r = dir_fd_is_root_or_cwd(rfd); if (r < 0) return log_error_errno(r, "Failed to check if directory file descriptor is root: %m"); @@ -509,7 +516,7 @@ int find_esp_and_warn_at( int find_esp_and_warn( const char *root, const char *path, - bool unprivileged_mode, + int unprivileged_mode, char **ret_path, uint32_t *ret_part, uint64_t *ret_pstart, @@ -560,12 +567,13 @@ int find_esp_and_warn( static int verify_xbootldr_blkid( dev_t devid, - bool searching, + VerifyESPFlags flags, sd_id128_t *ret_uuid) { sd_id128_t uuid = SD_ID128_NULL; #if HAVE_BLKID + bool searching = FLAGS_SET(flags, VERIFY_ESP_SEARCHING); _cleanup_(blkid_free_probep) blkid_probe b = NULL; _cleanup_free_ char *node = NULL; const char *type, *v; @@ -644,9 +652,10 @@ static int verify_xbootldr_blkid( static int verify_xbootldr_udev( dev_t devid, - bool searching, + VerifyESPFlags flags, sd_id128_t *ret_uuid) { + bool searching = FLAGS_SET(flags, VERIFY_ESP_SEARCHING); _cleanup_(sd_device_unrefp) sd_device *d = NULL; sd_id128_t uuid = SD_ID128_NULL; const char *node, *type, *v; @@ -718,15 +727,16 @@ static int verify_xbootldr_udev( static int verify_xbootldr( int rfd, const char *path, - bool searching, - bool unprivileged_mode, + VerifyESPFlags flags, char **ret_path, sd_id128_t *ret_uuid, dev_t *ret_devid) { _cleanup_free_ char *p = NULL; _cleanup_close_ int pfd = -EBADF; - bool relax_checks; + bool searching = FLAGS_SET(flags, VERIFY_ESP_SEARCHING), + unprivileged_mode = FLAGS_SET(flags, VERIFY_ESP_UNPRIVILEGED_MODE), + relax_checks; dev_t devid = 0; int r; @@ -743,7 +753,7 @@ static int verify_xbootldr( getenv_bool("SYSTEMD_RELAX_XBOOTLDR_CHECKS") > 0 || detect_container() > 0; - r = verify_fsroot_dir(pfd, p, searching, unprivileged_mode, relax_checks ? NULL : &devid); + r = verify_fsroot_dir(pfd, p, flags, relax_checks ? NULL : &devid); if (r < 0) return r; @@ -751,9 +761,9 @@ static int verify_xbootldr( goto finish; if (unprivileged_mode) - r = verify_xbootldr_udev(devid, searching, ret_uuid); + r = verify_xbootldr_udev(devid, flags, ret_uuid); else - r = verify_xbootldr_blkid(devid, searching, ret_uuid); + r = verify_xbootldr_blkid(devid, flags, ret_uuid); if (r < 0) return r; @@ -778,19 +788,25 @@ finish: int find_xbootldr_and_warn_at( int rfd, const char *path, - bool unprivileged_mode, + int unprivileged_mode, char **ret_path, sd_id128_t *ret_uuid, dev_t *ret_devid) { + VerifyESPFlags flags = 0; int r; /* Similar to find_esp_and_warn(), but finds the XBOOTLDR partition. Returns the same errors. */ assert(rfd >= 0 || rfd == AT_FDCWD); + if (unprivileged_mode < 0) + unprivileged_mode = geteuid() != 0; + if (unprivileged_mode) + flags |= VERIFY_ESP_UNPRIVILEGED_MODE; + if (path) - return verify_xbootldr(rfd, path, /* searching= */ false, unprivileged_mode, ret_path, ret_uuid, ret_devid); + return verify_xbootldr(rfd, path, flags, ret_path, ret_uuid, ret_devid); path = getenv("SYSTEMD_XBOOTLDR_PATH"); if (path) { @@ -822,7 +838,7 @@ int find_xbootldr_and_warn_at( return 0; } - r = verify_xbootldr(rfd, "/boot", /* searching= */ true, unprivileged_mode, ret_path, ret_uuid, ret_devid); + r = verify_xbootldr(rfd, "/boot", flags | VERIFY_ESP_SEARCHING, ret_path, ret_uuid, ret_devid); if (r < 0) { if (!IN_SET(r, -ENOENT, -EADDRNOTAVAIL, -ENOTDIR)) /* This one is not it */ return r; @@ -836,7 +852,7 @@ int find_xbootldr_and_warn_at( int find_xbootldr_and_warn( const char *root, const char *path, - bool unprivileged_mode, + int unprivileged_mode, char **ret_path, sd_id128_t *ret_uuid, dev_t *ret_devid) { diff --git a/src/shared/find-esp.h b/src/shared/find-esp.h index 94f320195b..2e132a74aa 100644 --- a/src/shared/find-esp.h +++ b/src/shared/find-esp.h @@ -8,8 +8,8 @@ #include "sd-id128.h" -int find_esp_and_warn_at(int rfd, const char *path, bool unprivileged_mode, char **ret_path, uint32_t *ret_part, uint64_t *ret_pstart, uint64_t *ret_psize, sd_id128_t *ret_uuid, dev_t *ret_devid); -int find_esp_and_warn(const char *root, const char *path, bool unprivileged_mode, char **ret_path, uint32_t *ret_part, uint64_t *ret_pstart, uint64_t *ret_psize, sd_id128_t *ret_uuid, dev_t *ret_devid); +int find_esp_and_warn_at(int rfd, const char *path, int unprivileged_mode, char **ret_path, uint32_t *ret_part, uint64_t *ret_pstart, uint64_t *ret_psize, sd_id128_t *ret_uuid, dev_t *ret_devid); +int find_esp_and_warn(const char *root, const char *path, int unprivileged_mode, char **ret_path, uint32_t *ret_part, uint64_t *ret_pstart, uint64_t *ret_psize, sd_id128_t *ret_uuid, dev_t *ret_devid); -int find_xbootldr_and_warn_at(int rfd, const char *path, bool unprivileged_mode, char **ret_path, sd_id128_t *ret_uuid, dev_t *ret_devid); -int find_xbootldr_and_warn(const char *root, const char *path, bool unprivileged_mode, char **ret_path, sd_id128_t *ret_uuid, dev_t *ret_devid); +int find_xbootldr_and_warn_at(int rfd, const char *path, int unprivileged_mode, char **ret_path, sd_id128_t *ret_uuid, dev_t *ret_devid); +int find_xbootldr_and_warn(const char *root, const char *path, int unprivileged_mode, char **ret_path, sd_id128_t *ret_uuid, dev_t *ret_devid); diff --git a/src/shared/hwdb-util.c b/src/shared/hwdb-util.c index 785611f8c4..a2fbcd7078 100644 --- a/src/shared/hwdb-util.c +++ b/src/shared/hwdb-util.c @@ -11,7 +11,7 @@ #include "fs-util.h" #include "hwdb-internal.h" #include "hwdb-util.h" -#include "label.h" +#include "label-util.h" #include "mkdir-label.h" #include "nulstr-util.h" #include "path-util.h" diff --git a/src/shared/label.c b/src/shared/label-util.c index 66fcc0a31f..3316c9ed37 100644 --- a/src/shared/label.c +++ b/src/shared/label-util.c @@ -7,6 +7,7 @@ #include "btrfs-util.h" #include "fs-util.h" #include "label.h" +#include "label-util.h" #include "macro.h" #include "selinux-util.h" #include "smack-util.h" @@ -115,3 +116,15 @@ int btrfs_subvol_make_label(const char *path) { return mac_smack_fix(path, 0); } + +int mac_init(void) { + int r; + + assert(!(mac_selinux_use() && mac_smack_use())); + + r = mac_selinux_init(); + if (r < 0) + return r; + + return mac_smack_init(); +} diff --git a/src/shared/label.h b/src/shared/label-util.h index 2f899e2bdd..2f8c539618 100644 --- a/src/shared/label.h +++ b/src/shared/label-util.h @@ -24,3 +24,5 @@ static inline int symlink_atomic_label(const char *from, const char *to) { int mknod_label(const char *pathname, mode_t mode, dev_t dev); int btrfs_subvol_make_label(const char *path); + +int mac_init(void); diff --git a/src/shared/loop-util.c b/src/shared/loop-util.c index 5418871093..3e51c93ede 100644 --- a/src/shared/loop-util.c +++ b/src/shared/loop-util.c @@ -677,9 +677,9 @@ int loop_device_make_by_path_at( direct_flags = FLAGS_SET(loop_flags, LO_FLAGS_DIRECT_IO) ? O_DIRECT : 0; rdwr_flags = open_flags >= 0 ? open_flags : O_RDWR; - fd = xopenat(dir_fd, path, basic_flags|direct_flags|rdwr_flags, 0); + fd = xopenat(dir_fd, path, basic_flags|direct_flags|rdwr_flags, /* xopen_flags = */ 0, /* mode = */ 0); if (fd < 0 && direct_flags != 0) /* If we had O_DIRECT on, and things failed with that, let's immediately try again without */ - fd = xopenat(dir_fd, path, basic_flags|rdwr_flags, 0); + fd = xopenat(dir_fd, path, basic_flags|rdwr_flags, /* xopen_flags = */ 0, /* mode = */ 0); else direct = direct_flags != 0; if (fd < 0) { @@ -689,9 +689,9 @@ int loop_device_make_by_path_at( if (open_flags >= 0 || !(ERRNO_IS_PRIVILEGE(r) || r == -EROFS)) return r; - fd = xopenat(dir_fd, path, basic_flags|direct_flags|O_RDONLY, 0); + fd = xopenat(dir_fd, path, basic_flags|direct_flags|O_RDONLY, /* xopen_flags = */ 0, /* mode = */ 0); if (fd < 0 && direct_flags != 0) /* as above */ - fd = xopenat(dir_fd, path, basic_flags|O_RDONLY, 0); + fd = xopenat(dir_fd, path, basic_flags|O_RDONLY, /* xopen_flags = */ 0, /* mode = */ 0); else direct = direct_flags != 0; if (fd < 0) @@ -818,7 +818,8 @@ static LoopDevice* loop_device_free(LoopDevice *d) { /* Now that the block device is released, let's also try to remove it */ if (control >= 0) { - useconds_t delay = 5 * USEC_PER_MSEC; + useconds_t delay = 5 * USEC_PER_MSEC; /* A total delay of 5090 ms between 39 attempts, + * (4*5 + 5*10 + 5*20 + … + 3*640) = 5090. */ for (unsigned attempt = 1;; attempt++) { if (ioctl(control, LOOP_CTL_REMOVE, d->nr) >= 0) diff --git a/src/shared/loopback-setup.c b/src/shared/loopback-setup.c index 5dbc4b1af2..a02baf8399 100644 --- a/src/shared/loopback-setup.c +++ b/src/shared/loopback-setup.c @@ -114,9 +114,15 @@ static int add_ipv6_address(sd_netlink *rtnl, struct state *s) { if (r < 0) return r; - r = sd_rtnl_message_addr_set_flags(req, IFA_F_PERMANENT); + uint32_t flags = IFA_F_PERMANENT|IFA_F_NOPREFIXROUTE; + r = sd_rtnl_message_addr_set_flags(req, flags & 0xffu); /* rtnetlink wants low 8 bit of flags via regular flags field… */ if (r < 0) return r; + if ((flags & ~0xffu) != 0) { + r = sd_netlink_message_append_u32(req, IFA_FLAGS, flags); /* …and the rest of the flags via IFA_FLAGS */ + if (r < 0) + return r; + } r = sd_rtnl_message_addr_set_scope(req, RT_SCOPE_HOST); if (r < 0) @@ -134,22 +140,22 @@ static int add_ipv6_address(sd_netlink *rtnl, struct state *s) { return 0; } -static bool check_loopback(sd_netlink *rtnl) { +static int check_loopback(sd_netlink *rtnl) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL; unsigned flags; int r; r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, LOOPBACK_IFINDEX); if (r < 0) - return false; + return r; r = sd_netlink_call(rtnl, req, USEC_INFINITY, &reply); if (r < 0) - return false; + return r; r = sd_rtnl_message_link_get_flags(reply, &flags); if (r < 0) - return false; + return r; return flags & IFF_UP; } @@ -170,9 +176,11 @@ int loopback_setup(void) { }; int r; + /* Note, we, generally assume callers ignore the return code here (except test cases), hence only log add LOG_WARN level. */ + r = sd_netlink_open(&rtnl); if (r < 0) - return log_error_errno(r, "Failed to open netlink: %m"); + return log_warning_errno(r, "Failed to open netlink, ignoring: %m"); /* Note that we add the IP addresses here explicitly even though the kernel does that too implicitly when * setting up the loopback device. The reason we do this here a second time (and possibly race against the @@ -182,35 +190,42 @@ int loopback_setup(void) { r = add_ipv4_address(rtnl, &state_4); if (r < 0) - return log_error_errno(r, "Failed to enqueue IPv4 loopback address add request: %m"); + return log_warning_errno(r, "Failed to enqueue IPv4 loopback address add request, ignoring: %m"); r = add_ipv6_address(rtnl, &state_6); if (r < 0) - return log_error_errno(r, "Failed to enqueue IPv6 loopback address add request: %m"); + return log_warning_errno(r, "Failed to enqueue IPv6 loopback address add request, ignoring: %m"); r = start_loopback(rtnl, &state_up); if (r < 0) - return log_error_errno(r, "Failed to enqueue loopback interface start request: %m"); + return log_warning_errno(r, "Failed to enqueue loopback interface start request, ignoring: %m"); while (state_4.n_messages + state_6.n_messages + state_up.n_messages > 0) { r = sd_netlink_wait(rtnl, LOOPBACK_SETUP_TIMEOUT_USEC); if (r < 0) - return log_error_errno(r, "Failed to wait for netlink event: %m"); + return log_warning_errno(r, "Failed to wait for netlink event, ignoring: %m"); r = sd_netlink_process(rtnl, NULL); if (r < 0) - return log_warning_errno(r, "Failed to process netlink event: %m"); + return log_warning_errno(r, "Failed to process netlink event, ignoring: %m"); } /* Note that we don't really care whether the addresses could be added or not */ if (state_up.rcode != 0) { - /* If we lack the permissions to configure the loopback device, - * but we find it to be already configured, let's exit cleanly, - * in order to supported unprivileged containers. */ - if (ERRNO_IS_PRIVILEGE(state_up.rcode) && check_loopback(rtnl)) - return 0; - return log_warning_errno(state_up.rcode, "Failed to configure loopback network device: %m"); + /* If we lack the permissions to configure the loopback device, but we find it to be already + * configured, let's exit cleanly, in order to supported unprivileged containers. */ + if (ERRNO_IS_PRIVILEGE(state_up.rcode)) { + r = check_loopback(rtnl); + if (r < 0) + log_debug_errno(r, "Failed to check if loopback device might already be up, ignoring: %m"); + else if (r > 0) { + log_debug("Configuring loopback failed, but device is already up, suppressing failure."); + return 0; + } + } + + return log_warning_errno(state_up.rcode, "Failed to configure loopback network device, ignoring: %m"); } return 0; diff --git a/src/shared/machine-pool.c b/src/shared/machine-pool.c index fb0b2f5adc..b372de40a3 100644 --- a/src/shared/machine-pool.c +++ b/src/shared/machine-pool.c @@ -3,7 +3,7 @@ #include <errno.h> #include "btrfs-util.h" -#include "label.h" +#include "label-util.h" #include "machine-pool.h" #include "missing_magic.h" #include "stat-util.h" diff --git a/src/shared/meson.build b/src/shared/meson.build index 021ba517f8..31241bc08d 100644 --- a/src/shared/meson.build +++ b/src/shared/meson.build @@ -96,7 +96,7 @@ shared_sources = files( 'kernel-image.c', 'keyring-util.c', 'killall.c', - 'label.c', + 'label-util.c', 'libcrypt-util.c', 'libfido2-util.c', 'libmount-util.c', diff --git a/src/shared/mount-setup.c b/src/shared/mount-setup.c index 6162a58d9a..fd14cd8598 100644 --- a/src/shared/mount-setup.c +++ b/src/shared/mount-setup.c @@ -17,7 +17,7 @@ #include "fd-util.h" #include "fileio.h" #include "fs-util.h" -#include "label.h" +#include "label-util.h" #include "log.h" #include "macro.h" #include "mkdir-label.h" diff --git a/src/shared/mount-util.c b/src/shared/mount-util.c index 7a06cc75ae..81b681afa7 100644 --- a/src/shared/mount-util.c +++ b/src/shared/mount-util.c @@ -22,7 +22,7 @@ #include "glyph-util.h" #include "hashmap.h" #include "initrd-util.h" -#include "label.h" +#include "label-util.h" #include "libmount-util.h" #include "missing_mount.h" #include "missing_syscall.h" diff --git a/src/shared/selinux-util.c b/src/shared/selinux-util.c index cc00a85952..a38a56f434 100644 --- a/src/shared/selinux-util.c +++ b/src/shared/selinux-util.c @@ -20,6 +20,7 @@ #include "alloc-util.h" #include "errno-util.h" #include "fd-util.h" +#include "label.h" #include "log.h" #include "macro.h" #include "mallinfo-util.h" @@ -54,6 +55,15 @@ static bool have_status_page = false; : -ERRNO_VALUE(_e); \ _enforcing ? _r : 0; \ }) + +static int mac_selinux_label_pre(int dir_fd, const char *path, mode_t mode) { + return mac_selinux_create_file_prepare_at(dir_fd, path, mode); +} + +static int mac_selinux_label_post(int dir_fd, const char *path) { + mac_selinux_create_file_clear(); + return 0; +} #endif bool mac_selinux_use(void) { @@ -128,6 +138,10 @@ static int open_label_db(void) { int mac_selinux_init(void) { #if HAVE_SELINUX + static const LabelOps label_ops = { + .pre = mac_selinux_label_pre, + .post = mac_selinux_label_post, + }; int r; if (initialized) @@ -152,6 +166,10 @@ int mac_selinux_init(void) { return r; } + r = label_ops_set(&label_ops); + if (r < 0) + return r; + /* Save the current policyload sequence number, so mac_selinux_maybe_reload() does not trigger on * first call without any actual change. */ last_policyload = selinux_status_policyload(); diff --git a/src/shared/selinux-util.h b/src/shared/selinux-util.h index e9771a28fe..238550ef52 100644 --- a/src/shared/selinux-util.h +++ b/src/shared/selinux-util.h @@ -7,7 +7,7 @@ #include <sys/types.h> #include "macro.h" -#include "label.h" +#include "label-util.h" #if HAVE_SELINUX #include <selinux/selinux.h> diff --git a/src/shared/smack-util.c b/src/shared/smack-util.c index 8c28dd91d7..1f88e724d0 100644 --- a/src/shared/smack-util.c +++ b/src/shared/smack-util.c @@ -15,6 +15,7 @@ #include "errno-util.h" #include "fd-util.h" #include "fileio.h" +#include "label.h" #include "log.h" #include "macro.h" #include "path-util.h" @@ -288,3 +289,23 @@ int renameat_and_apply_smack_floor_label(int fdf, const char *from, int fdt, con return 0; #endif } + +static int mac_smack_label_pre(int dir_fd, const char *path, mode_t mode) { + return 0; +} + +static int mac_smack_label_post(int dir_fd, const char *path) { + return mac_smack_fix_full(dir_fd, path, NULL, 0); +} + +int mac_smack_init(void) { + static const LabelOps label_ops = { + .pre = mac_smack_label_pre, + .post = mac_smack_label_post, + }; + + if (!mac_smack_use()) + return 0; + + return label_ops_set(&label_ops); +} diff --git a/src/shared/smack-util.h b/src/shared/smack-util.h index 17b31c6c25..f6ed2ece38 100644 --- a/src/shared/smack-util.h +++ b/src/shared/smack-util.h @@ -10,7 +10,7 @@ #include <stdbool.h> #include <sys/types.h> -#include "label.h" +#include "label-util.h" #include "macro.h" #define SMACK_FLOOR_LABEL "_" @@ -28,6 +28,7 @@ typedef enum SmackAttr { } SmackAttr; bool mac_smack_use(void); +int mac_smack_init(void); int mac_smack_fix_full(int atfd, const char *inode_path, const char *label_path, LabelFixFlags flags); static inline int mac_smack_fix(const char *path, LabelFixFlags flags) { diff --git a/src/systemctl/systemctl-edit.c b/src/systemctl/systemctl-edit.c index 561b01a67a..aff823d773 100644 --- a/src/systemctl/systemctl-edit.c +++ b/src/systemctl/systemctl-edit.c @@ -333,7 +333,7 @@ int verb_edit(int argc, char *argv[], void *userdata) { if (r < 0) return r; - r = mac_selinux_init(); + r = mac_init(); if (r < 0) return r; diff --git a/src/systemd/sd-journal.h b/src/systemd/sd-journal.h index 24e67663b9..4af540400d 100644 --- a/src/systemd/sd-journal.h +++ b/src/systemd/sd-journal.h @@ -93,6 +93,7 @@ void sd_journal_close(sd_journal *j); int sd_journal_previous(sd_journal *j); int sd_journal_next(sd_journal *j); +int sd_journal_step_one(sd_journal *j, int advanced); int sd_journal_previous_skip(sd_journal *j, uint64_t skip); int sd_journal_next_skip(sd_journal *j, uint64_t skip); diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c index 12adad516e..cfa4823df7 100644 --- a/src/sysusers/sysusers.c +++ b/src/sysusers/sysusers.c @@ -2178,7 +2178,7 @@ static int run(int argc, char *argv[]) { umask(0022); - r = mac_selinux_init(); + r = mac_init(); if (r < 0) return r; diff --git a/src/test/test-dlopen.c b/src/test/test-dlopen.c index 35981ebc3b..9c315373b4 100644 --- a/src/test/test-dlopen.c +++ b/src/test/test-dlopen.c @@ -6,10 +6,14 @@ #include "macro.h" int main(int argc, char **argv) { - void *handle; + void *handles[argc - 1]; + int i; - assert_se(handle = dlopen(argv[1], RTLD_NOW)); - assert_se(dlclose(handle) == 0); + for (i = 0; i < argc - 1; i++) + assert_se(handles[i] = dlopen(argv[i + 1], RTLD_NOW)); + + for (i--; i >= 0; i--) + assert_se(dlclose(handles[i]) == 0); return EXIT_SUCCESS; } diff --git a/src/test/test-execute.c b/src/test/test-execute.c index ae6227c492..a07c837e3f 100644 --- a/src/test/test-execute.c +++ b/src/test/test-execute.c @@ -206,6 +206,17 @@ static bool is_inaccessible_available(void) { return true; } +static void start_parent_slices(Unit *unit) { + Unit *slice; + + slice = UNIT_GET_SLICE(unit); + if (slice) { + start_parent_slices(slice); + int r = unit_start(slice, NULL); + assert_se(r >= 0 || r == -EALREADY); + } +} + static void _test(const char *file, unsigned line, const char *func, Manager *m, const char *unit_name, int status_expected, int code_expected) { Unit *unit; @@ -213,6 +224,9 @@ static void _test(const char *file, unsigned line, const char *func, assert_se(unit_name); assert_se(manager_load_startable_unit_or_warn(m, unit_name, NULL, &unit) >= 0); + /* We need to start the slices as well otherwise the slice cgroups might be pruned + * in on_cgroup_empty_event. */ + start_parent_slices(unit); assert_se(unit_start(unit, NULL) >= 0); check_main_result(file, line, func, m, unit, status_expected, code_expected); } diff --git a/src/test/test-fs-util.c b/src/test/test-fs-util.c index fa33b807b2..873052e24d 100644 --- a/src/test/test-fs-util.c +++ b/src/test/test-fs-util.c @@ -680,26 +680,26 @@ TEST(xopenat) { /* Test that xopenat() creates directories if O_DIRECTORY is specified. */ - assert_se((fd = xopenat(tfd, "abc", O_DIRECTORY|O_CREAT|O_EXCL|O_CLOEXEC, 0755)) >= 0); + assert_se((fd = xopenat(tfd, "abc", O_DIRECTORY|O_CREAT|O_EXCL|O_CLOEXEC, 0, 0755)) >= 0); assert_se((fd_verify_directory(fd) >= 0)); fd = safe_close(fd); - assert_se(xopenat(tfd, "abc", O_DIRECTORY|O_CREAT|O_EXCL|O_CLOEXEC, 0755) == -EEXIST); + assert_se(xopenat(tfd, "abc", O_DIRECTORY|O_CREAT|O_EXCL|O_CLOEXEC, 0, 0755) == -EEXIST); - assert_se((fd = xopenat(tfd, "abc", O_DIRECTORY|O_CREAT|O_CLOEXEC, 0755)) >= 0); + assert_se((fd = xopenat(tfd, "abc", O_DIRECTORY|O_CREAT|O_CLOEXEC, 0, 0755)) >= 0); assert_se((fd_verify_directory(fd) >= 0)); fd = safe_close(fd); /* Test that xopenat() creates regular files if O_DIRECTORY is not specified. */ - assert_se((fd = xopenat(tfd, "def", O_CREAT|O_EXCL|O_CLOEXEC, 0644)) >= 0); + assert_se((fd = xopenat(tfd, "def", O_CREAT|O_EXCL|O_CLOEXEC, 0, 0644)) >= 0); assert_se(fd_verify_regular(fd) >= 0); fd = safe_close(fd); /* Test that we can reopen an existing fd with xopenat() by specifying an empty path. */ - assert_se((fd = xopenat(tfd, "def", O_PATH|O_CLOEXEC, 0)) >= 0); - assert_se((fd2 = xopenat(fd, "", O_RDWR|O_CLOEXEC, 0644)) >= 0); + assert_se((fd = xopenat(tfd, "def", O_PATH|O_CLOEXEC, 0, 0)) >= 0); + assert_se((fd2 = xopenat(fd, "", O_RDWR|O_CLOEXEC, 0, 0644)) >= 0); } TEST(xopenat_lock) { @@ -713,11 +713,11 @@ TEST(xopenat_lock) { * and close the file descriptor and still properly create the directory and acquire the lock in * another process. */ - fd = xopenat_lock(tfd, "abc", O_CREAT|O_DIRECTORY|O_CLOEXEC, 0755, LOCK_BSD, LOCK_EX); + fd = xopenat_lock(tfd, "abc", O_CREAT|O_DIRECTORY|O_CLOEXEC, 0, 0755, LOCK_BSD, LOCK_EX); assert_se(fd >= 0); assert_se(faccessat(tfd, "abc", F_OK, 0) >= 0); assert_se(fd_verify_directory(fd) >= 0); - assert_se(xopenat_lock(tfd, "abc", O_DIRECTORY|O_CLOEXEC, 0755, LOCK_BSD, LOCK_EX|LOCK_NB) == -EAGAIN); + assert_se(xopenat_lock(tfd, "abc", O_DIRECTORY|O_CLOEXEC, 0, 0755, LOCK_BSD, LOCK_EX|LOCK_NB) == -EAGAIN); pid_t pid = fork(); assert_se(pid >= 0); @@ -725,11 +725,11 @@ TEST(xopenat_lock) { if (pid == 0) { safe_close(fd); - fd = xopenat_lock(tfd, "abc", O_CREAT|O_DIRECTORY|O_CLOEXEC, 0755, LOCK_BSD, LOCK_EX); + fd = xopenat_lock(tfd, "abc", O_CREAT|O_DIRECTORY|O_CLOEXEC, 0, 0755, LOCK_BSD, LOCK_EX); assert_se(fd >= 0); assert_se(faccessat(tfd, "abc", F_OK, 0) >= 0); assert_se(fd_verify_directory(fd) >= 0); - assert_se(xopenat_lock(tfd, "abc", O_DIRECTORY|O_CLOEXEC, 0755, LOCK_BSD, LOCK_EX|LOCK_NB) == -EAGAIN); + assert_se(xopenat_lock(tfd, "abc", O_DIRECTORY|O_CLOEXEC, 0, 0755, LOCK_BSD, LOCK_EX|LOCK_NB) == -EAGAIN); _exit(EXIT_SUCCESS); } @@ -748,8 +748,8 @@ TEST(xopenat_lock) { assert_se(wait_for_terminate(pid, &si) >= 0); assert_se(si.si_code == CLD_EXITED); - assert_se(xopenat_lock(tfd, "abc", 0, 0755, LOCK_POSIX, LOCK_EX) == -EBADF); - assert_se(xopenat_lock(tfd, "def", O_DIRECTORY, 0755, LOCK_POSIX, LOCK_EX) == -EBADF); + assert_se(xopenat_lock(tfd, "abc", 0, 0, 0755, LOCK_POSIX, LOCK_EX) == -EBADF); + assert_se(xopenat_lock(tfd, "def", O_DIRECTORY, 0, 0755, LOCK_POSIX, LOCK_EX) == -EBADF); } static int intro(void) { diff --git a/src/test/test-loopback.c b/src/test/test-loopback.c index 58d8c29dbb..c18f07cfed 100644 --- a/src/test/test-loopback.c +++ b/src/test/test-loopback.c @@ -1,20 +1,44 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ +#include <sched.h> #include <stdio.h> #include <string.h> +#include "errno-util.h" #include "log.h" #include "loopback-setup.h" #include "tests.h" -int main(int argc, char* argv[]) { +TEST_RET(loopback_setup) { int r; - test_setup_logging(LOG_DEBUG); + if (unshare(CLONE_NEWUSER | CLONE_NEWNET) < 0) { + if (ERRNO_IS_PRIVILEGE(errno) || ERRNO_IS_NOT_SUPPORTED(errno)) { + log_notice("Skipping test, lacking privileges or namespaces not supported"); + return EXIT_TEST_SKIP; + } + return log_error_errno(errno, "Failed to create user+network namespace: %m"); + } r = loopback_setup(); if (r < 0) - log_error_errno(r, "loopback: %m"); + return log_error_errno(r, "loopback: %m"); - return r >= 0 ? EXIT_SUCCESS : EXIT_FAILURE; + log_info("> ipv6 main"); + system("ip -6 route show table main"); + log_info("> ipv6 local"); + system("ip -6 route show table local"); + log_info("> ipv4 main"); + system("ip -4 route show table main"); + log_info("> ipv4 local"); + system("ip -4 route show table local"); + + return EXIT_SUCCESS; +} + +static int intro(void) { + log_show_color(true); + return EXIT_SUCCESS; } + +DEFINE_TEST_MAIN_WITH_INTRO(LOG_INFO, intro); diff --git a/src/test/udev-rule-runner.c b/src/test/udev-rule-runner.c index 0b5938802a..f7ba143325 100644 --- a/src/test/udev-rule-runner.c +++ b/src/test/udev-rule-runner.c @@ -117,7 +117,7 @@ static int run(int argc, char *argv[]) { log_debug("version %s", GIT_VERSION); - r = mac_selinux_init(); + r = mac_init(); if (r < 0) return r; diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c index ad483301ef..ad1d492d6b 100644 --- a/src/timedate/timedated.c +++ b/src/timedate/timedated.c @@ -392,7 +392,7 @@ static int context_write_data_local_rtc(Context *c) { } } - r = mac_selinux_init(); + r = mac_init(); if (r < 0) return r; diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index e16f26d8d5..1cb8f06b3e 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -41,7 +41,7 @@ #include "glob-util.h" #include "hexdecoct.h" #include "io-util.h" -#include "label.h" +#include "label-util.h" #include "log.h" #include "macro.h" #include "main-func.h" @@ -800,7 +800,11 @@ static int dir_cleanup( cutoff_nsec, sub_path, age_by_file, false)) continue; - fd = xopenat(dirfd(d), de->d_name, O_RDONLY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME, 0); + fd = xopenat(dirfd(d), + de->d_name, + O_RDONLY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME, + /* xopen_flags = */ 0, + /* mode = */ 0); if (fd < 0 && fd != -ENOENT) log_warning_errno(fd, "Opening file \"%s\" failed, ignoring: %m", sub_path); if (fd >= 0 && flock(fd, LOCK_EX|LOCK_NB) < 0 && errno == EAGAIN) { @@ -4326,7 +4330,7 @@ static int run(int argc, char *argv[]) { umask(0022); - r = mac_selinux_init(); + r = mac_init(); if (r < 0) return r; diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c index e49e959cd8..098e8ed0cc 100644 --- a/src/udev/udev-node.c +++ b/src/udev/udev-node.c @@ -15,7 +15,7 @@ #include "format-util.h" #include "fs-util.h" #include "hexdecoct.h" -#include "label.h" +#include "label-util.h" #include "mkdir-label.h" #include "parse-util.h" #include "path-util.h" diff --git a/src/udev/udevadm.c b/src/udev/udevadm.c index b803f7bb0f..51dc041a29 100644 --- a/src/udev/udevadm.c +++ b/src/udev/udevadm.c @@ -130,7 +130,7 @@ static int run(int argc, char *argv[]) { if (r <= 0) return r; - r = mac_selinux_init(); + r = mac_init(); if (r < 0) return r; diff --git a/src/udev/udevd.c b/src/udev/udevd.c index b3aabcaa1f..cf00576cfb 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -2019,7 +2019,7 @@ int run_udevd(int argc, char *argv[]) { /* set umask before creating any file/directory */ umask(022); - r = mac_selinux_init(); + r = mac_init(); if (r < 0) return r; diff --git a/src/update-done/update-done.c b/src/update-done/update-done.c index 6518830717..f448b3b1d1 100644 --- a/src/update-done/update-done.c +++ b/src/update-done/update-done.c @@ -48,7 +48,7 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } - r = mac_selinux_init(); + r = mac_init(); if (r < 0) return EXIT_FAILURE; diff --git a/src/user-sessions/user-sessions.c b/src/user-sessions/user-sessions.c index 37867ee3ed..58054f89fb 100644 --- a/src/user-sessions/user-sessions.c +++ b/src/user-sessions/user-sessions.c @@ -25,7 +25,7 @@ static int run(int argc, char *argv[]) { umask(0022); - r = mac_selinux_init(); + r = mac_init(); if (r < 0) return r; |