From 59cb9b12abc7efb714d15d357c96bd86ef2ddafc Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 19 Mar 2025 01:32:12 +0900 Subject: [PATCH 1/5] initctl: fix error handling Fixes a bug introduced by cc090ca7fec93cd6b41bd7a756cd5fe32df44764 (v246). --- src/initctl/initctl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/initctl/initctl.c b/src/initctl/initctl.c index 8ed5f1e264..f0f722ac3e 100644 --- a/src/initctl/initctl.c +++ b/src/initctl/initctl.c @@ -318,8 +318,7 @@ static int run(int argc, char *argv[]) { n = sd_listen_fds(true); if (n < 0) - return log_error_errno(errno, - "Failed to read listening file descriptors from environment: %m"); + return log_error_errno(n, "Failed to read listening file descriptors from environment: %m"); if (n <= 0 || n > SERVER_FD_MAX) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), From a65d2de6d163daae715aa2a05869dbe65d2a0f01 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 19 Mar 2025 01:33:09 +0900 Subject: [PATCH 2/5] sd-varlink: fix overwrite of loop count Fixes a bug introduced by 206504a594492f4b97259bbe345dde4e520df7dc (v255). --- src/libsystemd/sd-varlink/sd-varlink.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libsystemd/sd-varlink/sd-varlink.c b/src/libsystemd/sd-varlink/sd-varlink.c index 222ccaac5d..c910a41354 100644 --- a/src/libsystemd/sd-varlink/sd-varlink.c +++ b/src/libsystemd/sd-varlink/sd-varlink.c @@ -3753,7 +3753,7 @@ _public_ int sd_varlink_server_add_connection_stdio(sd_varlink_server *s, sd_var _public_ int sd_varlink_server_listen_name(sd_varlink_server *s, const char *name) { _cleanup_strv_free_ char **names = NULL; - int r, n = 0; + int r, m, n = 0; assert_return(s, -EINVAL); assert_return(name, -EINVAL); @@ -3764,11 +3764,11 @@ _public_ int sd_varlink_server_listen_name(sd_varlink_server *s, const char *nam * See https://varlink.org/#activation for the environment variables this is backed by and the * recommended "varlink" identifier in $LISTEN_FDNAMES. */ - r = sd_listen_fds_with_names(/* unset_environment= */ false, &names); - if (r < 0) - return r; + m = sd_listen_fds_with_names(/* unset_environment= */ false, &names); + if (m < 0) + return m; - for (int i = 0; i < r; i++) { + for (int i = 0; i < m; i++) { int b, fd; socklen_t l = sizeof(b); From d50b9cbe5604f5dc6a5d7a02178f70b985c6162c Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 19 Mar 2025 01:35:13 +0900 Subject: [PATCH 3/5] vmspawn: do not use r for loop count In a future, we may call some functions and r may be used for storing error code of them. Let's not use r for the maximum number of loop count. --- src/vmspawn/vmspawn.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vmspawn/vmspawn.c b/src/vmspawn/vmspawn.c index 849dd617dc..d616f2c7ab 100644 --- a/src/vmspawn/vmspawn.c +++ b/src/vmspawn/vmspawn.c @@ -2513,11 +2513,11 @@ static int run(int argc, char *argv[]) { glyph(GLYPH_LIGHT_SHADE), ansi_grey(), ansi_highlight(), ansi_grey(), ansi_normal()); } - r = sd_listen_fds_with_names(true, &names); - if (r < 0) - return log_error_errno(r, "Failed to get passed file descriptors: %m"); + int n = sd_listen_fds_with_names(true, &names); + if (n < 0) + return log_error_errno(n, "Failed to get passed file descriptors: %m"); - for (int i = 0; i < r; i++) { + for (int i = 0; i < n; i++) { int fd = SD_LISTEN_FDS_START + i; if (streq(names[i], "kvm")) kvm_device_fd = fd; From 024bb0c63e56672d7ff43072bc76b5dbf5192248 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 19 Mar 2025 01:33:54 +0900 Subject: [PATCH 4/5] oomd: do not ignore failure in sd_lisen_fds() Also, use -EBADF for an invalid file descriptor. --- src/oom/oomd.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/oom/oomd.c b/src/oom/oomd.c index 518ddc47c1..53c4948a73 100644 --- a/src/oom/oomd.c +++ b/src/oom/oomd.c @@ -115,10 +115,12 @@ static int run(int argc, char *argv[]) { * requirements do not have a reliable means to check for in code. */ int n = sd_listen_fds(0); + if (n < 0) + return log_error_errno(n, "Failed to determine number of listening fds: %m"); if (n > 1) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Received too many file descriptors"); - int fd = n == 1 ? SD_LISTEN_FDS_START : -1; + int fd = n == 1 ? SD_LISTEN_FDS_START : -EBADF; /* SwapTotal is always available in /proc/meminfo and defaults to 0, even on swap-disabled kernels. */ r = get_proc_field("/proc/meminfo", "SwapTotal", WHITESPACE, &swap); From b8d5303733e846ed39604731aab4d1f0fd245f3d Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 19 Mar 2025 01:38:18 +0900 Subject: [PATCH 5/5] nspawn: make failure in sd_listen_fds() critical Also, drop doubled call of sd_listen_fds(). --- src/nspawn/nspawn.c | 13 +++++-------- src/shared/fdset.c | 15 +++++++++++---- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 87cae525ca..3004bfc1b7 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -5970,7 +5970,7 @@ static int run(int argc, char *argv[]) { bool remove_directory = false, remove_image = false, veth_created = false; _cleanup_close_ int master = -EBADF, userns_fd = -EBADF, mount_fd = -EBADF; _cleanup_fdset_free_ FDSet *fds = NULL; - int r, n_fd_passed, ret = EXIT_SUCCESS; + int r, ret = EXIT_SUCCESS; char veth_name[IFNAMSIZ] = ""; struct ExposeArgs expose_args = {}; _cleanup_(release_lock_file) LockFile tree_global_lock = LOCK_FILE_INIT, tree_local_lock = LOCK_FILE_INIT; @@ -6057,13 +6057,10 @@ static int run(int argc, char *argv[]) { * so just turning this off here means we only turn it off in nspawn itself, not any children. */ (void) ignore_signals(SIGPIPE); - n_fd_passed = sd_listen_fds(false); - if (n_fd_passed > 0) { - r = fdset_new_listen_fds(&fds, false); - if (r < 0) { - log_error_errno(r, "Failed to collect file descriptors: %m"); - goto finish; - } + r = fdset_new_listen_fds(&fds, /* unset = */ false); + if (r < 0) { + log_error_errno(r, "Failed to collect file descriptors: %m"); + goto finish; } /* The "default" umask. This is appropriate for most file and directory diff --git a/src/shared/fdset.c b/src/shared/fdset.c index 42092ada25..7f4b15b179 100644 --- a/src/shared/fdset.c +++ b/src/shared/fdset.c @@ -254,25 +254,32 @@ int fdset_cloexec(FDSet *fds, bool b) { int fdset_new_listen_fds(FDSet **ret, bool unset) { _cleanup_(fdset_shallow_freep) FDSet *s = NULL; - int n, fd, r; + int n, r; assert(ret); /* Creates an fdset and fills in all passed file descriptors */ + n = sd_listen_fds(unset); + if (n < 0) + return n; + if (n == 0) { + *ret = NULL; + return 0; + } + s = fdset_new(); if (!s) return -ENOMEM; - n = sd_listen_fds(unset); - for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd++) { + for (int fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd++) { r = fdset_put(s, fd); if (r < 0) return r; } *ret = TAKE_PTR(s); - return 0; + return n; } int fdset_to_array(FDSet *fds, int **ret) {