mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-23 17:34:00 +03:00
bus: fake client side creds in the proxy to the caller's creds
This commit is contained in:
parent
515c883021
commit
8a0e0ed9dd
@ -358,6 +358,40 @@ static int process_hello(sd_bus *a, sd_bus *b, sd_bus_message *m, bool *got_hell
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int getpeersec(int fd, char **ret) {
|
||||
socklen_t n = 64;
|
||||
char *s;
|
||||
int r;
|
||||
|
||||
assert(fd >= 0);
|
||||
assert(ret);
|
||||
|
||||
s = new0(char, n);
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
|
||||
r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
|
||||
if (r < 0) {
|
||||
free(s);
|
||||
|
||||
if (errno != ERANGE)
|
||||
return r;
|
||||
|
||||
s = new0(char, n);
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
|
||||
r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
|
||||
if (r < 0) {
|
||||
free(s);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
*ret = s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
_cleanup_bus_unref_ sd_bus *a = NULL, *b = NULL;
|
||||
@ -365,6 +399,8 @@ int main(int argc, char *argv[]) {
|
||||
int r, in_fd, out_fd;
|
||||
bool got_hello = false;
|
||||
bool is_unix;
|
||||
struct ucred ucred = {};
|
||||
_cleanup_free_ char *peersec = NULL;
|
||||
|
||||
log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
|
||||
log_parse_environment();
|
||||
@ -390,6 +426,20 @@ int main(int argc, char *argv[]) {
|
||||
sd_is_socket(in_fd, AF_UNIX, 0, 0) > 0 &&
|
||||
sd_is_socket(out_fd, AF_UNIX, 0, 0) > 0;
|
||||
|
||||
if (is_unix) {
|
||||
socklen_t l = sizeof(ucred);
|
||||
|
||||
r = getsockopt(in_fd, SOL_SOCKET, SO_PEERCRED, &ucred, &l);
|
||||
if (r < 0) {
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
assert(l == sizeof(ucred));
|
||||
|
||||
getpeersec(in_fd, &peersec);
|
||||
}
|
||||
|
||||
r = sd_bus_new(&a);
|
||||
if (r < 0) {
|
||||
log_error("Failed to allocate bus: %s", strerror(-r));
|
||||
@ -408,6 +458,18 @@ int main(int argc, char *argv[]) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (ucred.pid > 0) {
|
||||
a->fake_creds.pid = ucred.pid;
|
||||
a->fake_creds.uid = ucred.uid;
|
||||
a->fake_creds.gid = ucred.gid;
|
||||
a->fake_creds_valid = true;
|
||||
}
|
||||
|
||||
if (peersec) {
|
||||
a->fake_label = peersec;
|
||||
peersec = NULL;
|
||||
}
|
||||
|
||||
r = sd_bus_start(a);
|
||||
if (r < 0) {
|
||||
log_error("Failed to start bus client: %s", strerror(-r));
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "bus-error.h"
|
||||
#include "bus-match.h"
|
||||
#include "bus-kernel.h"
|
||||
#include "kdbus.h"
|
||||
|
||||
struct reply_callback {
|
||||
sd_bus_message_handler_t callback;
|
||||
@ -161,6 +162,7 @@ struct sd_bus {
|
||||
bool filter_callbacks_modified:1;
|
||||
bool nodes_modified:1;
|
||||
bool trusted:1;
|
||||
bool fake_creds_valid:1;
|
||||
|
||||
int use_memfd;
|
||||
|
||||
@ -259,6 +261,9 @@ struct sd_bus {
|
||||
|
||||
sd_bus **default_bus_ptr;
|
||||
pid_t tid;
|
||||
|
||||
struct kdbus_creds fake_creds;
|
||||
char *fake_label;
|
||||
};
|
||||
|
||||
#define BUS_DEFAULT_TIMEOUT ((usec_t) (25 * USEC_PER_SEC))
|
||||
|
@ -317,7 +317,9 @@ fail:
|
||||
}
|
||||
|
||||
int bus_kernel_take_fd(sd_bus *b) {
|
||||
struct kdbus_cmd_hello hello;
|
||||
struct kdbus_cmd_hello *hello;
|
||||
struct kdbus_item *item;
|
||||
size_t l, sz;
|
||||
int r;
|
||||
|
||||
assert(b);
|
||||
@ -327,13 +329,38 @@ int bus_kernel_take_fd(sd_bus *b) {
|
||||
|
||||
b->use_memfd = 1;
|
||||
|
||||
zero(hello);
|
||||
hello.size = sizeof(hello);
|
||||
hello.conn_flags = b->hello_flags;
|
||||
hello.attach_flags = b->attach_flags;
|
||||
hello.pool_size = KDBUS_POOL_SIZE;
|
||||
sz = ALIGN8(offsetof(struct kdbus_cmd_hello, items));
|
||||
|
||||
r = ioctl(b->input_fd, KDBUS_CMD_HELLO, &hello);
|
||||
if (b->fake_creds_valid)
|
||||
sz += ALIGN8(offsetof(struct kdbus_item, creds));
|
||||
|
||||
if (b->fake_label) {
|
||||
l = strlen(b->fake_label);
|
||||
sz += ALIGN8(offsetof(struct kdbus_item, str) + l + 1);
|
||||
}
|
||||
|
||||
hello = alloca0(sz);
|
||||
hello->size = sz;
|
||||
hello->conn_flags = b->hello_flags;
|
||||
hello->attach_flags = b->attach_flags;
|
||||
hello->pool_size = KDBUS_POOL_SIZE;
|
||||
|
||||
item = hello->items;
|
||||
|
||||
if (b->fake_creds_valid) {
|
||||
item->size = offsetof(struct kdbus_item, creds) + sizeof(struct kdbus_creds);
|
||||
item->type = KDBUS_ITEM_CREDS;
|
||||
item->creds = b->fake_creds;
|
||||
|
||||
item = KDBUS_ITEM_NEXT(item);
|
||||
}
|
||||
|
||||
if (b->fake_label) {
|
||||
item->size = offsetof(struct kdbus_item, str) + l + 1;
|
||||
memcpy(item->str, b->fake_label, l+1);
|
||||
}
|
||||
|
||||
r = ioctl(b->input_fd, KDBUS_CMD_HELLO, hello);
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
@ -347,26 +374,26 @@ int bus_kernel_take_fd(sd_bus *b) {
|
||||
|
||||
/* The higher 32bit of both flags fields are considered
|
||||
* 'incompatible flags'. Refuse them all for now. */
|
||||
if (hello.bus_flags > 0xFFFFFFFFULL ||
|
||||
hello.conn_flags > 0xFFFFFFFFULL)
|
||||
if (hello->bus_flags > 0xFFFFFFFFULL ||
|
||||
hello->conn_flags > 0xFFFFFFFFULL)
|
||||
return -ENOTSUP;
|
||||
|
||||
if (hello.bloom_size != BLOOM_SIZE)
|
||||
if (hello->bloom_size != BLOOM_SIZE)
|
||||
return -ENOTSUP;
|
||||
|
||||
if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello.id) < 0)
|
||||
if (asprintf(&b->unique_name, ":1.%llu", (unsigned long long) hello->id) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
b->unique_id = hello.id;
|
||||
b->unique_id = hello->id;
|
||||
|
||||
b->is_kernel = true;
|
||||
b->bus_client = true;
|
||||
b->can_fds = !!(hello.conn_flags & KDBUS_HELLO_ACCEPT_FD);
|
||||
b->can_fds = !!(hello->conn_flags & KDBUS_HELLO_ACCEPT_FD);
|
||||
b->message_version = 2;
|
||||
b->message_endian = BUS_NATIVE_ENDIAN;
|
||||
|
||||
/* the kernel told us the UUID of the underlying bus */
|
||||
memcpy(b->server_id.bytes, hello.id128, sizeof(b->server_id.bytes));
|
||||
memcpy(b->server_id.bytes, hello->id128, sizeof(b->server_id.bytes));
|
||||
|
||||
return bus_start_running(b);
|
||||
}
|
||||
|
@ -141,6 +141,7 @@ static void bus_free(sd_bus *b) {
|
||||
free(b->address);
|
||||
free(b->kernel);
|
||||
free(b->machine);
|
||||
free(b->fake_label);
|
||||
|
||||
free(b->exec_path);
|
||||
strv_free(b->exec_argv);
|
||||
|
Loading…
Reference in New Issue
Block a user