From 1d03923a974aa18d2d1eaaf5d1d2f5fa19dc669f Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 17 Jan 2022 12:48:31 +0100 Subject: [PATCH] pulse-server: use object serial as index Use the lower 32 bits of the object serial as the index. When there is an overflow, use an invalid index, which will probably result in a protocol error. --- src/modules/module-protocol-pulse/collect.c | 17 ++++++++++++++++- src/modules/module-protocol-pulse/collect.h | 1 + src/modules/module-protocol-pulse/manager.c | 5 ++++- src/modules/module-protocol-pulse/manager.h | 1 + .../module-protocol-pulse/pulse-server.c | 8 ++++++-- 5 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/modules/module-protocol-pulse/collect.c b/src/modules/module-protocol-pulse/collect.c index a6d18bf09..fe28fae3b 100644 --- a/src/modules/module-protocol-pulse/collect.c +++ b/src/modules/module-protocol-pulse/collect.c @@ -74,7 +74,22 @@ struct pw_manager_object *select_object(struct pw_manager *m, struct selector *s uint32_t id_to_index(struct pw_manager *m, uint32_t id) { - return id; + struct pw_manager_object *o; + spa_list_for_each(o, &m->object_list, link) { + if (o->id == id) + return o->index; + } + return SPA_ID_INVALID; +} + +uint32_t index_to_id(struct pw_manager *m, uint32_t index) +{ + struct pw_manager_object *o; + spa_list_for_each(o, &m->object_list, link) { + if (o->index == index) + return o->id; + } + return SPA_ID_INVALID; } bool collect_is_linked(struct pw_manager *m, uint32_t id, enum pw_direction direction) diff --git a/src/modules/module-protocol-pulse/collect.h b/src/modules/module-protocol-pulse/collect.h index b576c7493..d6bf5f2d8 100644 --- a/src/modules/module-protocol-pulse/collect.h +++ b/src/modules/module-protocol-pulse/collect.h @@ -54,6 +54,7 @@ struct selector { struct pw_manager_object *select_object(struct pw_manager *m, struct selector *s); uint32_t id_to_index(struct pw_manager *m, uint32_t id); +uint32_t index_to_id(struct pw_manager *m, uint32_t index); void select_best(struct selector *s, struct pw_manager_object *o); /* ========================================================================== */ diff --git a/src/modules/module-protocol-pulse/manager.c b/src/modules/module-protocol-pulse/manager.c index 128260317..c783fc1de 100644 --- a/src/modules/module-protocol-pulse/manager.c +++ b/src/modules/module-protocol-pulse/manager.c @@ -586,6 +586,7 @@ static void registry_event_global(void *data, uint32_t id, struct manager *m = data; struct object *o; const struct object_info *info; + const char *str; struct pw_proxy *proxy; info = find_info(type, version); @@ -603,11 +604,13 @@ static void registry_event_global(void *data, uint32_t id, pw_proxy_destroy(proxy); return; } + str = props ? spa_dict_lookup(props, PW_KEY_OBJECT_SERIAL) : NULL; + spa_atou64(str, &o->this.serial, 0); o->this.id = id; o->this.permissions = permissions; o->this.type = info->type; o->this.version = version; - o->this.index = id; + o->this.index = o->this.serial < (1ULL<<32) ? o->this.serial : SPA_ID_INVALID; o->this.props = props ? pw_properties_new_dict(props) : NULL; o->this.proxy = proxy; o->this.creating = true; diff --git a/src/modules/module-protocol-pulse/manager.h b/src/modules/module-protocol-pulse/manager.h index d49065636..e8fe2443f 100644 --- a/src/modules/module-protocol-pulse/manager.h +++ b/src/modules/module-protocol-pulse/manager.h @@ -75,6 +75,7 @@ struct pw_manager_param { struct pw_manager_object { struct spa_list link; /**< link in manager object_list */ + uint64_t serial; uint32_t id; uint32_t permissions; const char *type; diff --git a/src/modules/module-protocol-pulse/pulse-server.c b/src/modules/module-protocol-pulse/pulse-server.c index 30195c144..82d105e6c 100644 --- a/src/modules/module-protocol-pulse/pulse-server.c +++ b/src/modules/module-protocol-pulse/pulse-server.c @@ -1376,6 +1376,7 @@ static void log_format_info(struct impl *impl, enum spa_log_level level, struct static int do_create_playback_stream(struct client *client, uint32_t command, uint32_t tag, struct message *m) { struct impl *impl = client->impl; + struct pw_manager *manager = client->manager; const char *name = NULL; int res; struct sample_spec ss; @@ -1585,7 +1586,8 @@ static int do_create_playback_stream(struct client *client, uint32_t command, ui PW_KEY_NODE_TARGET, sink_name); else if (sink_index != SPA_ID_INVALID && sink_index != 0) pw_properties_setf(props, - PW_KEY_NODE_TARGET, "%u", sink_index); + PW_KEY_NODE_TARGET, "%u", + index_to_id(manager, sink_index)); stream->stream = pw_stream_new(client->core, name, props); props = NULL; @@ -1632,6 +1634,7 @@ error: static int do_create_record_stream(struct client *client, uint32_t command, uint32_t tag, struct message *m) { struct impl *impl = client->impl; + struct pw_manager *manager = client->manager; const char *name = NULL; int res; struct sample_spec ss; @@ -1841,7 +1844,8 @@ static int do_create_record_stream(struct client *client, uint32_t command, uint } if (source_index != SPA_ID_INVALID && source_index != 0) { pw_properties_setf(props, - PW_KEY_NODE_TARGET, "%u", source_index); + PW_KEY_NODE_TARGET, "%u", + index_to_id(manager, source_index)); } else if (source_name != NULL) { if (spa_strendswith(source_name, ".monitor")) { pw_properties_setf(props,