mirror of
https://github.com/systemd/systemd.git
synced 2024-12-25 01:34:28 +03:00
Merge pull request #244 from poettering/sdbus-suppress-local
sd-bus: suppress installing local bus matches server side
This commit is contained in:
commit
9d8a5fd3e6
@ -141,6 +141,7 @@ struct sd_bus_slot {
|
||||
void *userdata;
|
||||
BusSlotType type:5;
|
||||
bool floating:1;
|
||||
bool match_added:1;
|
||||
char *description;
|
||||
|
||||
LIST_FIELDS(sd_bus_slot, slots);
|
||||
|
@ -1149,3 +1149,40 @@ void bus_match_dump(struct bus_match_node *node, unsigned level) {
|
||||
for (c = node->child; c; c = c->next)
|
||||
bus_match_dump(c, level + 1);
|
||||
}
|
||||
|
||||
enum bus_match_scope bus_match_get_scope(const struct bus_match_component *components, unsigned n_components) {
|
||||
bool found_driver = false;
|
||||
unsigned i;
|
||||
|
||||
if (n_components <= 0)
|
||||
return BUS_MATCH_GENERIC;
|
||||
|
||||
assert(components);
|
||||
|
||||
/* Checks whether the specified match can only match the
|
||||
* pseudo-service for local messages, which we detect by
|
||||
* sender, interface or path. If a match is not restricted to
|
||||
* local messages, then we check if it only matches on the
|
||||
* driver. */
|
||||
|
||||
for (i = 0; i < n_components; i++) {
|
||||
const struct bus_match_component *c = components + i;
|
||||
|
||||
if (c->type == BUS_MATCH_SENDER) {
|
||||
if (streq_ptr(c->value_str, "org.freedesktop.DBus.Local"))
|
||||
return BUS_MATCH_LOCAL;
|
||||
|
||||
if (streq_ptr(c->value_str, "org.freedesktop.DBus"))
|
||||
found_driver = true;
|
||||
}
|
||||
|
||||
if (c->type == BUS_MATCH_INTERFACE && streq_ptr(c->value_str, "org.freedesktop.DBus.Local"))
|
||||
return BUS_MATCH_LOCAL;
|
||||
|
||||
if (c->type == BUS_MATCH_PATH && streq_ptr(c->value_str, "/org/freedesktop/DBus/Local"))
|
||||
return BUS_MATCH_LOCAL;
|
||||
}
|
||||
|
||||
return found_driver ? BUS_MATCH_DRIVER : BUS_MATCH_GENERIC;
|
||||
|
||||
}
|
||||
|
@ -73,6 +73,12 @@ struct bus_match_component {
|
||||
char *value_str;
|
||||
};
|
||||
|
||||
enum bus_match_scope {
|
||||
BUS_MATCH_GENERIC,
|
||||
BUS_MATCH_LOCAL,
|
||||
BUS_MATCH_DRIVER,
|
||||
};
|
||||
|
||||
int bus_match_run(sd_bus *bus, struct bus_match_node *root, sd_bus_message *m);
|
||||
|
||||
int bus_match_add(struct bus_match_node *root, struct bus_match_component *components, unsigned n_components, struct match_callback *callback);
|
||||
@ -90,3 +96,5 @@ enum bus_match_node_type bus_match_node_type_from_string(const char *k, size_t n
|
||||
int bus_match_parse(const char *match, struct bus_match_component **_components, unsigned *_n_components);
|
||||
void bus_match_parse_free(struct bus_match_component *components, unsigned n_components);
|
||||
char *bus_match_to_string(struct bus_match_component *components, unsigned n_components);
|
||||
|
||||
enum bus_match_scope bus_match_get_scope(const struct bus_match_component *components, unsigned n_components);
|
||||
|
@ -89,7 +89,7 @@ void bus_slot_disconnect(sd_bus_slot *slot) {
|
||||
|
||||
case BUS_MATCH_CALLBACK:
|
||||
|
||||
if (slot->bus->bus_client)
|
||||
if (slot->match_added)
|
||||
bus_remove_match_internal(slot->bus, slot->match_callback.match_string, slot->match_callback.cookie);
|
||||
|
||||
slot->bus->match_callbacks_modified = true;
|
||||
|
@ -2952,22 +2952,35 @@ _public_ int sd_bus_add_match(
|
||||
s->match_callback.cookie = ++bus->match_cookie;
|
||||
|
||||
if (bus->bus_client) {
|
||||
enum bus_match_scope scope;
|
||||
|
||||
if (!bus->is_kernel) {
|
||||
/* When this is not a kernel transport, we
|
||||
* store the original match string, so that we
|
||||
* can use it to remove the match again */
|
||||
scope = bus_match_get_scope(components, n_components);
|
||||
|
||||
s->match_callback.match_string = strdup(match);
|
||||
if (!s->match_callback.match_string) {
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
/* Do not install server-side matches for matches
|
||||
* against the local service, interface or bus
|
||||
* path. Also, when on kdbus don't install driver
|
||||
* matches server side. */
|
||||
if (scope == BUS_MATCH_GENERIC ||
|
||||
(!bus->is_kernel && scope == BUS_MATCH_DRIVER)) {
|
||||
|
||||
if (!bus->is_kernel) {
|
||||
/* When this is not a kernel transport, we
|
||||
* store the original match string, so that we
|
||||
* can use it to remove the match again */
|
||||
|
||||
s->match_callback.match_string = strdup(match);
|
||||
if (!s->match_callback.match_string) {
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
r = bus_add_match_internal(bus, s->match_callback.match_string, components, n_components, s->match_callback.cookie);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
r = bus_add_match_internal(bus, s->match_callback.match_string, components, n_components, s->match_callback.cookie);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
||||
s->match_added = true;
|
||||
}
|
||||
}
|
||||
|
||||
bus->match_callbacks_modified = true;
|
||||
|
@ -77,6 +77,15 @@ static int match_add(sd_bus_slot *slots, struct bus_match_node *root, const char
|
||||
return r;
|
||||
}
|
||||
|
||||
static void test_match_scope(const char *match, enum bus_match_scope scope) {
|
||||
struct bus_match_component *components = NULL;
|
||||
unsigned n_components = 0;
|
||||
|
||||
assert_se(bus_match_parse(match, &components, &n_components) >= 0);
|
||||
assert_se(bus_match_get_scope(components, n_components) == scope);
|
||||
bus_match_parse_free(components, n_components);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
struct bus_match_node root = {
|
||||
.type = BUS_MATCH_ROOT,
|
||||
@ -142,5 +151,12 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
bus_match_free(&root);
|
||||
|
||||
test_match_scope("interface='foobar'", BUS_MATCH_GENERIC);
|
||||
test_match_scope("", BUS_MATCH_GENERIC);
|
||||
test_match_scope("interface='org.freedesktop.DBus.Local'", BUS_MATCH_LOCAL);
|
||||
test_match_scope("sender='org.freedesktop.DBus.Local'", BUS_MATCH_LOCAL);
|
||||
test_match_scope("member='gurke',path='/org/freedesktop/DBus/Local'", BUS_MATCH_LOCAL);
|
||||
test_match_scope("arg2='piep',sender='org.freedesktop.DBus',member='waldo'", BUS_MATCH_DRIVER);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user