mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-03 09:01:54 -05:00
context: move registry generation checks to context methods
Add registry generation checks to pw_context methods that find globals, (pw_context_find_global, pw_context_for_each_global), so that they are made everywhere where a client acquires globals. In addition to previously covered registry bind/destroy, this also covers link creation (port/node ids) and metadata (subject ids).
This commit is contained in:
parent
a59a551202
commit
651cb7bd71
3 changed files with 44 additions and 26 deletions
|
|
@ -553,6 +553,19 @@ static bool global_can_read(struct pw_context *context, struct pw_global *global
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool global_is_stale(struct pw_context *context, struct pw_global *global)
|
||||
{
|
||||
struct pw_impl_client *client = context->current_client;
|
||||
|
||||
if (!client)
|
||||
return false;
|
||||
|
||||
if (client->recv_generation != 0 && global->generation > client->recv_generation)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
SPA_EXPORT
|
||||
int pw_context_for_each_global(struct pw_context *context,
|
||||
int (*callback) (void *data, struct pw_global *global),
|
||||
|
|
@ -562,7 +575,7 @@ int pw_context_for_each_global(struct pw_context *context,
|
|||
int res;
|
||||
|
||||
spa_list_for_each_safe(g, t, &context->global_list, link) {
|
||||
if (!global_can_read(context, g))
|
||||
if (!global_can_read(context, g) || global_is_stale(context, g))
|
||||
continue;
|
||||
if ((res = callback(data, g)) != 0)
|
||||
return res;
|
||||
|
|
@ -581,6 +594,11 @@ struct pw_global *pw_context_find_global(struct pw_context *context, uint32_t id
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (global_is_stale(context, global)) {
|
||||
errno = global_can_read(context, global) ? ESTALE : ENOENT;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!global_can_read(context, global)) {
|
||||
errno = EACCES;
|
||||
return NULL;
|
||||
|
|
|
|||
|
|
@ -117,15 +117,16 @@ static int client_error(void *object, uint32_t id, int res, const char *error)
|
|||
struct pw_impl_client *sender = resource->client;
|
||||
struct pw_impl_client *client = data->client;
|
||||
struct error_data d = { id, res, error };
|
||||
struct pw_global *global;
|
||||
|
||||
/* Check the global id provided by sender refers to a registered global
|
||||
* known to the sender.
|
||||
*/
|
||||
if ((global = pw_context_find_global(resource->context, id)) == NULL)
|
||||
goto error_no_id;
|
||||
if (sender->recv_generation != 0 && global->generation > sender->recv_generation)
|
||||
goto error_stale_id;
|
||||
if (pw_context_find_global(resource->context, id) == NULL) {
|
||||
if (errno == ESTALE)
|
||||
goto error_stale_id;
|
||||
else
|
||||
goto error_no_id;
|
||||
}
|
||||
|
||||
pw_log_debug("%p: sender %p: error for global %u", client, sender, id);
|
||||
pw_map_for_each(&client->objects, error_resource, &d);
|
||||
|
|
@ -136,8 +137,8 @@ error_no_id:
|
|||
pw_resource_errorf(resource, -ENOENT, "no global %u", id);
|
||||
return -ENOENT;
|
||||
error_stale_id:
|
||||
pw_log_debug("%p: sender %p: error for stale global %u generation:%"PRIu64" recv-generation:%"PRIu64,
|
||||
client, sender, id, global->generation, sender->recv_generation);
|
||||
pw_log_debug("%p: sender %p: error for stale global %u recv-generation:%"PRIu64,
|
||||
client, sender, id, sender->recv_generation);
|
||||
pw_resource_errorf(resource, -ESTALE, "no global %u any more", id);
|
||||
return -ESTALE;
|
||||
}
|
||||
|
|
@ -804,10 +805,7 @@ int pw_impl_client_check_permissions(struct pw_impl_client *client,
|
|||
uint32_t perms;
|
||||
|
||||
if ((global = pw_context_find_global(context, global_id)) == NULL)
|
||||
return -ENOENT;
|
||||
|
||||
if (client->recv_generation != 0 && global->generation > client->recv_generation)
|
||||
return -ESTALE;
|
||||
return (errno == ESTALE) ? -ESTALE : -ENOENT;
|
||||
|
||||
perms = pw_global_get_permissions(global, client);
|
||||
if ((perms & permissions) != permissions)
|
||||
|
|
|
|||
|
|
@ -33,17 +33,18 @@ static void * registry_bind(void *object, uint32_t id,
|
|||
struct pw_global *global;
|
||||
uint32_t permissions, new_id = user_data_size;
|
||||
|
||||
if ((global = pw_context_find_global(context, id)) == NULL)
|
||||
goto error_no_id;
|
||||
if ((global = pw_context_find_global(context, id)) == NULL) {
|
||||
if (errno == ESTALE)
|
||||
goto error_stale_id;
|
||||
else
|
||||
goto error_no_id;
|
||||
}
|
||||
|
||||
permissions = pw_global_get_permissions(global, client);
|
||||
|
||||
if (!PW_PERM_IS_R(permissions))
|
||||
goto error_no_id;
|
||||
|
||||
if (resource->client->recv_generation != 0 && global->generation > resource->client->recv_generation)
|
||||
goto error_stale_id;
|
||||
|
||||
if (!spa_streq(global->type, type))
|
||||
goto error_wrong_interface;
|
||||
|
||||
|
|
@ -57,8 +58,8 @@ static void * registry_bind(void *object, uint32_t id,
|
|||
|
||||
error_stale_id:
|
||||
pw_log_debug("registry %p: not binding stale global "
|
||||
"id %u to %u, generation:%"PRIu64" recv-generation:%"PRIu64,
|
||||
resource, id, new_id, global->generation, resource->client->recv_generation);
|
||||
"id %u to %u recv-generation:%"PRIu64,
|
||||
resource, id, new_id, resource->client->recv_generation);
|
||||
pw_resource_errorf_id(resource, new_id, -ESTALE, "no global %u any more", id);
|
||||
goto error_exit_clean;
|
||||
error_no_id:
|
||||
|
|
@ -88,17 +89,18 @@ static int registry_destroy(void *object, uint32_t id)
|
|||
uint32_t permissions;
|
||||
int res;
|
||||
|
||||
if ((global = pw_context_find_global(context, id)) == NULL)
|
||||
goto error_no_id;
|
||||
if ((global = pw_context_find_global(context, id)) == NULL) {
|
||||
if (errno == ESTALE)
|
||||
goto error_stale_id;
|
||||
else
|
||||
goto error_no_id;
|
||||
}
|
||||
|
||||
permissions = pw_global_get_permissions(global, client);
|
||||
|
||||
if (!PW_PERM_IS_R(permissions))
|
||||
goto error_no_id;
|
||||
|
||||
if (resource->client->recv_generation != 0 && global->generation > resource->client->recv_generation)
|
||||
goto error_stale_id;
|
||||
|
||||
if (id == PW_ID_CORE || !PW_PERM_IS_X(permissions))
|
||||
goto error_not_allowed;
|
||||
|
||||
|
|
@ -109,8 +111,8 @@ static int registry_destroy(void *object, uint32_t id)
|
|||
|
||||
error_stale_id:
|
||||
pw_log_debug("registry %p: not destroying stale global "
|
||||
"id %u, generation:%"PRIu64" recv-generation:%"PRIu64,
|
||||
resource, id, global->generation, resource->client->recv_generation);
|
||||
"id %u, recv-generation:%"PRIu64,
|
||||
resource, id, resource->client->recv_generation);
|
||||
pw_resource_errorf(resource, -ESTALE, "no global %u any more", id);
|
||||
res = -ESTALE;
|
||||
goto error_exit;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue