diff --git a/src/core/exec-invoke.c b/src/core/exec-invoke.c index 4f935c1439..7c16ffc7f0 100644 --- a/src/core/exec-invoke.c +++ b/src/core/exec-invoke.c @@ -1638,8 +1638,16 @@ static int apply_syscall_filter(const ExecContext *c, const ExecParameters *p) { action = negative_action; } - /* Sending over exec_fd or handoff_timestamp_fd requires write() syscall. */ + /* Sending over exec_fd or handoff_timestamp_fd requires write() syscall. + * + * Note: this mutates c->syscall_filter despite the 'const ExecContext *c' qualifier. + * That is intentional and safe here because apply_syscall_filter() runs only in the + * post-fork child, which holds a private copy of the address space; the hashmap + * change is never visible to the manager process. */ if (p->exec_fd >= 0 || p->handoff_timestamp_fd >= 0) { + if (c->syscall_allow_list) + log_debug("SystemCallFilter= allow-list in effect; adding 'write' syscall required for exec handoff."); + r = seccomp_filter_set_add_by_name(c->syscall_filter, c->syscall_allow_list, "write"); if (r < 0) return r; @@ -4133,12 +4141,22 @@ static int apply_root_directory( assert(exit_status); if (params->flags & EXEC_APPLY_CHROOT) - if (!needs_mount_ns && context->root_directory) + if (!needs_mount_ns && context->root_directory) { if (chroot(runtime->ephemeral_copy ?: context->root_directory) < 0) { *exit_status = EXIT_CHROOT; return -errno; } + /* chroot(2) changes only the process root, not cwd. Move cwd into the new root + * immediately so that a subsequent apply_working_directory() failure that is + * silently ignored via working_directory_missing_ok cannot leave cwd pointing + * at a pre-chroot dentry outside the new root. */ + if (chdir("/") < 0) { + *exit_status = EXIT_CHROOT; + return -errno; + } + } + return 0; } diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index 5675c7d787..c6e73dbab0 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -1350,7 +1350,7 @@ int sd_dhcp_client_attach_event(sd_dhcp_client *client, sd_event *event, int64_t else { r = sd_event_default(&client->event); if (r < 0) - return 0; + return r; } client->event_priority = priority; diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c index 5e71d63de5..b78d1c29ec 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -182,12 +182,12 @@ int sd_dhcp6_client_add_vendor_option(sd_dhcp6_client *client, sd_dhcp6_option * } r = ordered_set_ensure_put(&client->vendor_options, &dhcp6_option_hash_ops, v); - if (r < 0) + if (r <= 0) return r; sd_dhcp6_option_ref(v); - return 1; + return r; } static int client_ensure_duid(sd_dhcp6_client *client) { @@ -541,11 +541,11 @@ int sd_dhcp6_client_add_option(sd_dhcp6_client *client, sd_dhcp6_option *v) { assert_return(v, -EINVAL); r = ordered_hashmap_ensure_put(&client->extra_options, &dhcp6_option_hash_ops, UINT_TO_PTR(v->option), v); - if (r < 0) + if (r <= 0) return r; sd_dhcp6_option_ref(v); - return 0; + return r; } static void client_set_state(sd_dhcp6_client *client, DHCP6State state) { @@ -1507,7 +1507,7 @@ int sd_dhcp6_client_attach_event(sd_dhcp6_client *client, sd_event *event, int64 else { r = sd_event_default(&client->event); if (r < 0) - return 0; + return r; } client->event_priority = priority; diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c index b6a55a5095..51e12d4528 100644 --- a/src/libsystemd-network/sd-ndisc.c +++ b/src/libsystemd-network/sd-ndisc.c @@ -137,7 +137,7 @@ int sd_ndisc_attach_event(sd_ndisc *nd, sd_event *event, int64_t priority) { else { r = sd_event_default(&nd->event); if (r < 0) - return 0; + return r; } nd->event_priority = priority; diff --git a/src/libsystemd-network/sd-radv.c b/src/libsystemd-network/sd-radv.c index 948f7bc382..df5fcc6c02 100644 --- a/src/libsystemd-network/sd-radv.c +++ b/src/libsystemd-network/sd-radv.c @@ -58,7 +58,7 @@ int sd_radv_attach_event(sd_radv *ra, sd_event *event, int64_t priority) { else { r = sd_event_default(&ra->event); if (r < 0) - return 0; + return r; } ra->event_priority = priority; diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 17c14db3ff..e00dce3fbd 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -717,7 +717,7 @@ static int acquire_sig_for_roothash( ssize_t n = pread(fd, buf, partition_size, partition_offset); if (n < 0) - return -ENOMEM; + return -errno; if ((uint64_t) n != partition_size) return -EIO; @@ -1417,8 +1417,8 @@ static int dissect_image( r = acquire_sig_for_roothash( fd, - start * 512, - size * 512, + (uint64_t) start * 512, + (uint64_t) size * 512, &root_hash, /* ret_root_hash_sig= */ NULL); if (r < 0) @@ -5509,7 +5509,7 @@ int mountfsd_make_directory( _cleanup_close_ int fd = open(parent, O_DIRECTORY|O_CLOEXEC); if (fd < 0) - return log_debug_errno(r, "Failed to open '%s': %m", parent); + return log_debug_errno(errno, "Failed to open '%s': %m", parent); return mountfsd_make_directory_fd(vl, fd, dirname, mode, flags, ret_directory_fd); }