diff options
Diffstat (limited to 'src/bus-proxyd')
-rw-r--r-- | src/bus-proxyd/bus-xml-policy.c | 6 | ||||
-rw-r--r-- | src/bus-proxyd/driver.c | 102 | ||||
-rw-r--r-- | src/bus-proxyd/proxy.c | 13 | ||||
-rw-r--r-- | src/bus-proxyd/proxy.h | 13 | ||||
-rw-r--r-- | src/bus-proxyd/synthesize.c | 19 |
5 files changed, 109 insertions, 44 deletions
diff --git a/src/bus-proxyd/bus-xml-policy.c b/src/bus-proxyd/bus-xml-policy.c index dab5acbcb4..9a3b451c56 100644 --- a/src/bus-proxyd/bus-xml-policy.c +++ b/src/bus-proxyd/bus-xml-policy.c @@ -586,10 +586,8 @@ static int file_load(Policy *p, const char *path) { case POLICY_ITEM_SEND: case POLICY_ITEM_RECV: - if (streq(name, "*")) { - free(name); - name = NULL; - } + if (streq(name, "*")) + name = mfree(name); break; diff --git a/src/bus-proxyd/driver.c b/src/bus-proxyd/driver.c index 1cb5ea5008..951f515808 100644 --- a/src/bus-proxyd/driver.c +++ b/src/bus-proxyd/driver.c @@ -71,6 +71,27 @@ static int get_creds_by_message(sd_bus *bus, sd_bus_message *m, uint64_t mask, s return get_creds_by_name(bus, name, mask, _creds, error); } +static int driver_activation(sd_bus_message *reply, void *userdata, sd_bus_error *error) { + _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + ProxyActivation *activation = userdata; + + /* + * The org.freedesktop.DBus.Peer.Ping() call returned. We don't care + * whether this succeeded, failed, was not implemented or timed out. We + * cannot assume that the target reacts to this properly. Hence, just + * send the reply to the activation request and be done. + */ + + m = activation->request; /* claim reference */ + + --activation->proxy->n_activations; + LIST_REMOVE(activations_by_proxy, activation->proxy->activations, activation); + sd_bus_slot_unref(activation->slot); + free(activation); + + return synthetic_reply_method_return(m, "u", BUS_START_REPLY_SUCCESS); +} + int bus_proxy_process_driver(Proxy *p, sd_bus *a, sd_bus *b, sd_bus_message *m, SharedPolicy *sp, const struct ucred *ucred, Set *owned_names) { int r; @@ -441,27 +462,29 @@ int bus_proxy_process_driver(Proxy *p, sd_bus *a, sd_bus *b, sd_bus_message *m, name_list = (struct kdbus_info *) ((uint8_t *) a->kdbus_buffer + cmd.offset); KDBUS_FOREACH(name, name_list, cmd.list_size) { - const char *entry_name = NULL; struct kdbus_item *item; char *n; - KDBUS_ITEM_FOREACH(item, name, items) - if (item->type == KDBUS_ITEM_OWNED_NAME) - entry_name = item->name.name; - - if (!streq_ptr(entry_name, arg0)) - continue; - - if (asprintf(&n, ":1.%llu", (unsigned long long) name->id) < 0) { - err = -ENOMEM; - break; + KDBUS_ITEM_FOREACH(item, name, items) { + if (item->type == KDBUS_ITEM_OWNED_NAME) { + if (!streq_ptr(item->name.name, arg0)) + continue; + + if (asprintf(&n, ":1.%llu", (unsigned long long) name->id) < 0) { + err = -ENOMEM; + break; + } + + r = strv_consume(&owners, n); + if (r < 0) { + err = r; + break; + } + } } - r = strv_consume(&owners, n); - if (r < 0) { - err = r; + if (err < 0) break; - } } r = bus_kernel_cmd_free(a, cmd.offset); @@ -585,7 +608,9 @@ int bus_proxy_process_driver(Proxy *p, sd_bus *a, sd_bus *b, sd_bus_message *m, } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "StartServiceByName")) { _cleanup_bus_message_unref_ sd_bus_message *msg = NULL; + ProxyActivation *activation; const char *name; + uint64_t cookie; uint32_t flags; if (!sd_bus_message_has_signature(m, "su")) @@ -604,21 +629,46 @@ int bus_proxy_process_driver(Proxy *p, sd_bus *a, sd_bus *b, sd_bus_message *m, if (r != -ESRCH) return synthetic_reply_method_errno(m, r, NULL); - r = sd_bus_message_new_method_call( - a, - &msg, - name, - "/", - "org.freedesktop.DBus.Peer", - "Ping"); + if (p->n_activations >= PROXY_ACTIVATIONS_MAX) + return synthetic_reply_method_errno(m, -EMFILE, NULL); + + r = sd_bus_message_get_cookie(m, &cookie); + if (r < 0) + return synthetic_reply_method_errno(m, r, NULL); + + r = sd_bus_message_new_method_call(a, + &msg, + name, + "/", + "org.freedesktop.DBus.Peer", + "Ping"); if (r < 0) return synthetic_reply_method_errno(m, r, NULL); - r = sd_bus_send(a, msg, NULL); + r = bus_message_seal(msg, cookie, BUS_DEFAULT_TIMEOUT); if (r < 0) return synthetic_reply_method_errno(m, r, NULL); - return synthetic_reply_method_return(m, "u", BUS_START_REPLY_SUCCESS); + activation = new0(ProxyActivation, 1); + if (!activation) + return synthetic_reply_method_errno(m, -ENOMEM, NULL); + + r = sd_bus_call_async(a, + &activation->slot, + msg, + driver_activation, + activation, + 0); + if (r < 0) { + free(activation); + return synthetic_reply_method_errno(m, r, NULL); + } + + activation->proxy = p; + activation->request = sd_bus_message_ref(m); + LIST_PREPEND(activations_by_proxy, p->activations, activation); + ++p->n_activations; + return 1; } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "UpdateActivationEnvironment")) { _cleanup_bus_message_unref_ sd_bus_message *msg = NULL; @@ -657,8 +707,8 @@ int bus_proxy_process_driver(Proxy *p, sd_bus *a, sd_bus *b, sd_bus_message *m, if (r < 0) return synthetic_reply_method_errno(m, r, NULL); - if (!args) - return synthetic_reply_method_errno(m, -EINVAL, NULL); + if (strv_isempty(args)) /* nothing to do? */ + return synthetic_reply_method_return(m, NULL); r = sd_bus_message_new_method_call( a, diff --git a/src/bus-proxyd/proxy.c b/src/bus-proxyd/proxy.c index c37b09b9c0..df361ac400 100644 --- a/src/bus-proxyd/proxy.c +++ b/src/bus-proxyd/proxy.c @@ -261,9 +261,18 @@ int proxy_new(Proxy **out, int in_fd, int out_fd, const char *destination) { } Proxy *proxy_free(Proxy *p) { + ProxyActivation *activation; + if (!p) return NULL; + while ((activation = p->activations)) { + LIST_REMOVE(activations_by_proxy, p->activations, activation); + sd_bus_message_unref(activation->request); + sd_bus_slot_unref(activation->slot); + free(activation); + } + sd_bus_flush_close_unref(p->local_bus); sd_bus_flush_close_unref(p->destination_bus); set_free_free(p->owned_names); @@ -644,6 +653,10 @@ static int process_hello(Proxy *p, sd_bus_message *m) { if (r < 0) return log_error_errno(r, "Failed to append sender to NameAcquired message: %m"); + r = sd_bus_message_set_destination(n, p->destination_bus->unique_name); + if (r < 0) + return log_error_errno(r, "Failed to set destination for NameAcquired message: %m"); + r = bus_seal_synthetic_message(p->local_bus, n); if (r < 0) return log_error_errno(r, "Failed to seal NameAcquired message: %m"); diff --git a/src/bus-proxyd/proxy.h b/src/bus-proxyd/proxy.h index ccb951c109..6aac650ac9 100644 --- a/src/bus-proxyd/proxy.h +++ b/src/bus-proxyd/proxy.h @@ -25,6 +25,9 @@ #include "bus-xml-policy.h" typedef struct Proxy Proxy; +typedef struct ProxyActivation ProxyActivation; + +#define PROXY_ACTIVATIONS_MAX (16) /* max parallel activation requests */ struct Proxy { sd_bus *local_bus; @@ -37,12 +40,22 @@ struct Proxy { Set *owned_names; SharedPolicy *policy; + LIST_HEAD(ProxyActivation, activations); + size_t n_activations; + bool got_hello : 1; bool queue_overflow : 1; bool message_matched : 1; bool synthetic_matched : 1; }; +struct ProxyActivation { + LIST_FIELDS(ProxyActivation, activations_by_proxy); + Proxy *proxy; + sd_bus_message *request; + sd_bus_slot *slot; +}; + int proxy_new(Proxy **out, int in_fd, int out_fd, const char *dest); Proxy *proxy_free(Proxy *p); diff --git a/src/bus-proxyd/synthesize.c b/src/bus-proxyd/synthesize.c index 3ecedfd575..15d99103f6 100644 --- a/src/bus-proxyd/synthesize.c +++ b/src/bus-proxyd/synthesize.c @@ -214,22 +214,13 @@ int synthesize_name_acquired(Proxy *p, sd_bus *a, sd_bus *b, sd_bus_message *m) if (r < 0) return r; - r = bus_seal_synthetic_message(b, n); + r = sd_bus_message_set_destination(n, a->unique_name); if (r < 0) return r; - /* - * Make sure to only forward NameLost/NameAcquired messages if they - * match an installed MATCH rule of the local client. We really must - * not send messages the client doesn't expect. - */ - - r = bus_match_run(b, &b->match_callbacks, n); - if (r >= 0 && p->message_matched) - r = sd_bus_send(b, n, NULL); - - p->message_matched = false; - p->synthetic_matched = false; + r = bus_seal_synthetic_message(b, n); + if (r < 0) + return r; - return r; + return sd_bus_send(b, n, NULL); } |