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
This commit is contained in:
Ryan Wilson
2024-09-30 09:52:55 -07:00
parent 615279f369
commit f88813b71a

View File

@@ -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;