diff options
author | Luca Boccassi <bluca@debian.org> | 2024-11-06 14:51:10 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-06 14:51:10 +0100 |
commit | d99fe076b58db267b4400415c5b570eb06acb753 (patch) | |
tree | c22387b4263c23998883316408fa746002d64cb5 | |
parent | core/manager: silence false-positive warning by coverity (diff) | |
parent | use report_errno_and_exit() in src/core/exec-invoke.c (diff) | |
download | systemd-d99fe076b58db267b4400415c5b570eb06acb753.tar.xz systemd-d99fe076b58db267b4400415c5b570eb06acb753.zip |
introduce report_errno_and_exit() helper (#35028)
This is a follow for https://github.com/systemd/systemd/pull/34853. In
particular, this comment
https://github.com/systemd/systemd/pull/34853#discussion_r1825837705.
-rw-r--r-- | src/basic/process-util.c | 16 | ||||
-rw-r--r-- | src/basic/process-util.h | 2 | ||||
-rw-r--r-- | src/core/exec-invoke.c | 25 | ||||
-rw-r--r-- | src/machine/operation.c | 15 | ||||
-rw-r--r-- | src/machine/operation.h | 2 | ||||
-rw-r--r-- | src/shared/dissect-image.c | 13 | ||||
-rw-r--r-- | src/shared/elf-util.c | 16 | ||||
-rw-r--r-- | src/shared/mount-util.c | 24 | ||||
-rw-r--r-- | src/shutdown/umount.c | 6 |
9 files changed, 45 insertions, 74 deletions
diff --git a/src/basic/process-util.c b/src/basic/process-util.c index 75bc65652e..ee0edfaf94 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -35,6 +35,7 @@ #include "fileio.h" #include "fs-util.h" #include "hostname-util.h" +#include "io-util.h" #include "locale-util.h" #include "log.h" #include "macro.h" @@ -2238,3 +2239,18 @@ static const char* const sched_policy_table[] = { }; DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX); + +_noreturn_ void report_errno_and_exit(int errno_fd, int error) { + int r; + + if (error >= 0) + _exit(EXIT_SUCCESS); + + assert(errno_fd >= 0); + + r = loop_write(errno_fd, &error, sizeof(error)); + if (r < 0) + log_debug_errno(r, "Failed to write errno to errno_fd=%d: %m", errno_fd); + + _exit(EXIT_FAILURE); +} diff --git a/src/basic/process-util.h b/src/basic/process-util.h index cb6d47a5bb..0763b64cff 100644 --- a/src/basic/process-util.h +++ b/src/basic/process-util.h @@ -273,3 +273,5 @@ int posix_spawn_wrapper( int proc_dir_open(DIR **ret); int proc_dir_read(DIR *d, pid_t *ret); int proc_dir_read_pidref(DIR *d, PidRef *ret); + +_noreturn_ void report_errno_and_exit(int errno_fd, int error); diff --git a/src/core/exec-invoke.c b/src/core/exec-invoke.c index 120067a774..2f8924cd01 100644 --- a/src/core/exec-invoke.c +++ b/src/core/exec-invoke.c @@ -2165,10 +2165,8 @@ static int setup_private_users(PrivateUsers private_users, uid_t ouid, gid_t ogi errno_pipe[0] = safe_close(errno_pipe[0]); /* Wait until the parent unshared the user namespace */ - if (read(unshare_ready_fd, &c, sizeof(c)) < 0) { - r = -errno; - goto child_fail; - } + if (read(unshare_ready_fd, &c, sizeof(c)) < 0) + report_errno_and_exit(errno_pipe[1], -errno); /* Disable the setgroups() system call in the child user namespace, for good. */ a = procfs_file_alloca(ppid, "setgroups"); @@ -2176,14 +2174,14 @@ static int setup_private_users(PrivateUsers private_users, uid_t ouid, gid_t ogi if (fd < 0) { if (errno != ENOENT) { r = log_debug_errno(errno, "Failed to open %s: %m", a); - goto child_fail; + report_errno_and_exit(errno_pipe[1], r); } /* If the file is missing the kernel is too old, let's continue anyway. */ } else { if (write(fd, "deny\n", 5) < 0) { r = log_debug_errno(errno, "Failed to write \"deny\" to %s: %m", a); - goto child_fail; + report_errno_and_exit(errno_pipe[1], r); } fd = safe_close(fd); @@ -2194,12 +2192,14 @@ static int setup_private_users(PrivateUsers private_users, uid_t ouid, gid_t ogi fd = open(a, O_WRONLY|O_CLOEXEC); if (fd < 0) { r = log_debug_errno(errno, "Failed to open %s: %m", a); - goto child_fail; + report_errno_and_exit(errno_pipe[1], r); } + if (write(fd, gid_map, strlen(gid_map)) < 0) { r = log_debug_errno(errno, "Failed to write GID map to %s: %m", a); - goto child_fail; + report_errno_and_exit(errno_pipe[1], r); } + fd = safe_close(fd); /* The write the UID map */ @@ -2207,18 +2207,15 @@ static int setup_private_users(PrivateUsers private_users, uid_t ouid, gid_t ogi fd = open(a, O_WRONLY|O_CLOEXEC); if (fd < 0) { r = log_debug_errno(errno, "Failed to open %s: %m", a); - goto child_fail; + report_errno_and_exit(errno_pipe[1], r); } + if (write(fd, uid_map, strlen(uid_map)) < 0) { r = log_debug_errno(errno, "Failed to write UID map to %s: %m", a); - goto child_fail; + report_errno_and_exit(errno_pipe[1], r); } _exit(EXIT_SUCCESS); - - child_fail: - (void) write(errno_pipe[1], &r, sizeof(r)); - _exit(EXIT_FAILURE); } errno_pipe[1] = safe_close(errno_pipe[1]); diff --git a/src/machine/operation.c b/src/machine/operation.c index 0b2139acf0..7d7bfa5062 100644 --- a/src/machine/operation.c +++ b/src/machine/operation.c @@ -154,18 +154,3 @@ Operation *operation_free(Operation *o) { return mfree(o); } - -_noreturn_ void report_errno_and_exit(int errno_fd, int r) { - if (r >= 0) - _exit(EXIT_SUCCESS); - - assert(errno_fd >= 0); - - ssize_t n = write(errno_fd, &r, sizeof(r)); - if (n < 0) - log_debug_errno(errno, "Failed to write operation's errno: %m"); - if (n != sizeof(r)) - log_debug_errno(SYNTHETIC_ERRNO(EIO), "Sent unexpectedly short message"); - - _exit(EXIT_FAILURE); -} diff --git a/src/machine/operation.h b/src/machine/operation.h index ee9149854a..75bf918c2b 100644 --- a/src/machine/operation.h +++ b/src/machine/operation.h @@ -39,5 +39,3 @@ static inline int operation_new_with_bus_reply(Manager *manager, Machine *machin static inline int operation_new_with_varlink_reply(Manager *manager, Machine *machine, pid_t child, sd_varlink *link, int errno_fd, Operation **ret) { return operation_new(manager, machine, child, /* message = */ NULL, link, errno_fd, ret); } - -void report_errno_and_exit(int errno_fd, int r); diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index f12a93d0dc..f9418754a8 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -3522,7 +3522,7 @@ int dissected_image_acquire_metadata( r = detach_mount_namespace_userns(userns_fd); if (r < 0) { log_debug_errno(r, "Failed to detach mount namespace: %m"); - goto inner_fail; + report_errno_and_exit(error_pipe[1], r); } r = dissected_image_mount( @@ -3537,7 +3537,7 @@ int dissected_image_acquire_metadata( DISSECT_IMAGE_USR_NO_ROOT); if (r < 0) { log_debug_errno(r, "Failed to mount dissected image: %m"); - goto inner_fail; + report_errno_and_exit(error_pipe[1], r); } for (unsigned k = 0; k < _META_MAX; k++) { @@ -3609,7 +3609,7 @@ int dissected_image_acquire_metadata( r = loop_write(fds[2*k+1], &found, sizeof(found)); if (r < 0) - goto inner_fail; + report_errno_and_exit(error_pipe[1], r); goto next; } @@ -3629,18 +3629,13 @@ int dissected_image_acquire_metadata( r = copy_bytes(fd, fds[2*k+1], UINT64_MAX, 0); if (r < 0) - goto inner_fail; + report_errno_and_exit(error_pipe[1], r); next: fds[2*k+1] = safe_close(fds[2*k+1]); } _exit(EXIT_SUCCESS); - - inner_fail: - /* Let parent know the error */ - (void) write(error_pipe[1], &r, sizeof(r)); - _exit(EXIT_FAILURE); } error_pipe[1] = safe_close(error_pipe[1]); diff --git a/src/shared/elf-util.c b/src/shared/elf-util.c index 69439b61ef..a3ff1fd3fb 100644 --- a/src/shared/elf-util.c +++ b/src/shared/elf-util.c @@ -827,12 +827,12 @@ int parse_elf_object(int fd, const char *executable, const char *root, bool fork if (fork_disable_dump) { r = RET_NERRNO(prctl(PR_SET_DUMPABLE, 0)); if (r < 0) - goto child_fail; + report_errno_and_exit(error_pipe[1], r); } r = parse_elf(fd, executable, root, ret ? &buf : NULL, ret_package_metadata ? &package_metadata : NULL); if (r < 0) - goto child_fail; + report_errno_and_exit(error_pipe[1], r); if (buf) { size_t len = strlen(buf); @@ -853,7 +853,7 @@ int parse_elf_object(int fd, const char *executable, const char *root, bool fork if (r == -EAGAIN) log_warning("Write failed, backtrace will be truncated."); else if (r < 0) - goto child_fail; + report_errno_and_exit(error_pipe[1], r); return_pipe[1] = safe_close(return_pipe[1]); } @@ -866,10 +866,8 @@ int parse_elf_object(int fd, const char *executable, const char *root, bool fork (void) fcntl(json_pipe[1], F_SETPIPE_SZ, COREDUMP_PIPE_MAX); json_out = take_fdopen(&json_pipe[1], "w"); - if (!json_out) { - r = -errno; - goto child_fail; - } + if (!json_out) + report_errno_and_exit(error_pipe[1], -errno); r = sd_json_variant_dump(package_metadata, SD_JSON_FORMAT_FLUSH, json_out, NULL); if (r < 0) @@ -877,10 +875,6 @@ int parse_elf_object(int fd, const char *executable, const char *root, bool fork } _exit(EXIT_SUCCESS); - - child_fail: - (void) write(error_pipe[1], &r, sizeof(r)); - _exit(EXIT_FAILURE); } error_pipe[1] = safe_close(error_pipe[1]); diff --git a/src/shared/mount-util.c b/src/shared/mount-util.c index 8ef952a035..f04235001d 100644 --- a/src/shared/mount-util.c +++ b/src/shared/mount-util.c @@ -1011,26 +1011,18 @@ static int mount_in_namespace_legacy( r = path_extract_filename(mount_outside, &mount_outside_fn); if (r < 0) { log_debug_errno(r, "Failed to extract filename from propagation file or directory '%s': %m", mount_outside); - goto child_fail; + report_errno_and_exit(errno_pipe_fd[1], r); } mount_inside = path_join(incoming_path, mount_outside_fn); - if (!mount_inside) { - r = log_oom_debug(); - goto child_fail; - } + if (!mount_inside) + report_errno_and_exit(errno_pipe_fd[1], log_oom_debug()); r = mount_nofollow_verbose(LOG_DEBUG, mount_inside, dest, NULL, MS_MOVE, NULL); if (r < 0) - goto child_fail; + report_errno_and_exit(errno_pipe_fd[1], r); _exit(EXIT_SUCCESS); - - child_fail: - (void) write(errno_pipe_fd[1], &r, sizeof(r)); - errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]); - - _exit(EXIT_FAILURE); } errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]); @@ -1224,14 +1216,8 @@ static int mount_in_namespace( r = mount_exchange_graceful(new_mount_fd, dest, /* mount_beneath= */ true); } - if (r < 0) { - (void) write(errno_pipe_fd[1], &r, sizeof(r)); - errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]); - _exit(EXIT_FAILURE); - } - - _exit(EXIT_SUCCESS); + report_errno_and_exit(errno_pipe_fd[1], r); } errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]); diff --git a/src/shutdown/umount.c b/src/shutdown/umount.c index ca6d36e054..4bc01c75e0 100644 --- a/src/shutdown/umount.c +++ b/src/shutdown/umount.c @@ -274,8 +274,7 @@ static int remount_with_timeout(MountPoint *m, bool last_try) { "Failed to remount '%s' read-only: %m", m->path); - (void) write(pfd[1], &r, sizeof(r)); /* try to send errno up */ - _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS); + report_errno_and_exit(pfd[1], r); } pfd[1] = safe_close(pfd[1]); @@ -337,8 +336,7 @@ static int umount_with_timeout(MountPoint *m, bool last_try) { log_umount_blockers(m->path); } - (void) write(pfd[1], &r, sizeof(r)); /* try to send errno up */ - _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS); + report_errno_and_exit(pfd[1], r); } pfd[1] = safe_close(pfd[1]); |