From: Ryan Wilson Date: Mon, 30 Sep 2024 16:52:55 +0000 (-0700) Subject: busctl: Support file descriptors in busctl X-Git-Tag: v257-rc1~298^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f88813b71a6fcd92bf04c6adcb54e7cd7551f7e2;p=thirdparty%2Fsystemd.git busctl: Support file descriptors in busctl Previously using file descriptors as input arguments in busctl was unsupported with "UNIX file descriptor not supported as type." We fix this by parsing the file descriptor as an integer and verifying it is an available file descriptor in busctl. Fixes: #14954 Replaces: #34551 --- diff --git a/src/busctl/busctl.c b/src/busctl/busctl.c index 1b0b72085e6..beff530b924 100644 --- a/src/busctl/busctl.c +++ b/src/busctl/busctl.c @@ -17,6 +17,7 @@ #include "capsule-util.h" #include "escape.h" #include "fd-util.h" +#include "fdset.h" #include "fileio.h" #include "format-table.h" #include "glyph-util.h" @@ -1477,12 +1478,13 @@ static int status(int argc, char **argv, void *userdata) { return 0; } -static int message_append_cmdline(sd_bus_message *m, const char *signature, char ***x) { +static int message_append_cmdline(sd_bus_message *m, const char *signature, FDSet **passed_fdset, char ***x) { char **p; int r; assert(m); assert(signature); + assert(passed_fdset); assert(x); p = *x; @@ -1631,7 +1633,7 @@ static int message_append_cmdline(sd_bus_message *m, const char *signature, char return bus_log_create_error(r); for (unsigned i = 0; i < n; i++) { - r = message_append_cmdline(m, s, &p); + r = message_append_cmdline(m, s, passed_fdset, &p); if (r < 0) return r; } @@ -1648,7 +1650,7 @@ static int message_append_cmdline(sd_bus_message *m, const char *signature, char if (r < 0) return bus_log_create_error(r); - r = message_append_cmdline(m, v, &p); + r = message_append_cmdline(m, v, passed_fdset, &p); if (r < 0) return r; @@ -1680,7 +1682,7 @@ static int message_append_cmdline(sd_bus_message *m, const char *signature, char if (r < 0) return bus_log_create_error(r); - r = message_append_cmdline(m, s, &p); + r = message_append_cmdline(m, s, passed_fdset, &p); if (r < 0) return r; } @@ -1691,9 +1693,25 @@ static int message_append_cmdline(sd_bus_message *m, const char *signature, char break; } - case SD_BUS_TYPE_UNIX_FD: - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "UNIX file descriptor not supported as type."); + case SD_BUS_TYPE_UNIX_FD: { + int fd; + + fd = parse_fd(v); + if (fd < 0) + return log_error_errno(fd, "Failed to parse '%s' as a file descriptor: %m", v); + + if (!*passed_fdset) { + r = fdset_new_fill(/* filter_cloexec= */ 0, passed_fdset); + if (r < 0) + return log_error_errno(r, "Failed to create fd set: %m"); + } + + if (!fdset_contains(*passed_fdset, fd)) + return log_error_errno(SYNTHETIC_ERRNO(EBADF), "Failed to find file descriptor '%s' among passed file descriptors.", v); + + r = sd_bus_message_append_basic(m, t, &fd); + break; + } default: return log_error_errno(SYNTHETIC_ERRNO(EINVAL), @@ -2049,6 +2067,7 @@ static int call(int argc, char **argv, void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL; + _cleanup_fdset_free_ FDSet *passed_fdset = NULL; int r; r = acquire_bus(false, &bus); @@ -2085,7 +2104,7 @@ static int call(int argc, char **argv, void *userdata) { p = argv+6; - r = message_append_cmdline(m, argv[5], &p); + r = message_append_cmdline(m, argv[5], &passed_fdset, &p); if (r < 0) return r; @@ -2151,6 +2170,7 @@ static int call(int argc, char **argv, void *userdata) { static int emit_signal(int argc, char **argv, void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; + _cleanup_fdset_free_ FDSet *passed_fdset = NULL; int r; r = acquire_bus(false, &bus); @@ -2176,7 +2196,7 @@ static int emit_signal(int argc, char **argv, void *userdata) { p = argv+5; - r = message_append_cmdline(m, argv[4], &p); + r = message_append_cmdline(m, argv[4], &passed_fdset, &p); if (r < 0) return r; @@ -2265,6 +2285,7 @@ static int set_property(int argc, char **argv, void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_fdset_free_ FDSet *passed_fdset = NULL; char **p; int r; @@ -2286,7 +2307,7 @@ static int set_property(int argc, char **argv, void *userdata) { return bus_log_create_error(r); p = argv + 6; - r = message_append_cmdline(m, argv[5], &p); + r = message_append_cmdline(m, argv[5], &passed_fdset, &p); if (r < 0) return r;