flatpak: fix resource override

Make sure we chain up to the same resource that we override, for this
keep a per resource info that we pass around.
This commit is contained in:
Wim Taymans 2017-09-15 14:52:17 +02:00
parent 8a45fd4f31
commit d26d7a8040

View file

@ -51,23 +51,31 @@ struct impl {
struct spa_source *dispatch_event; struct spa_source *dispatch_event;
}; };
struct resource;
struct client_info { struct client_info {
struct impl *impl;
struct spa_list link; struct spa_list link;
struct impl *impl;
struct pw_client *client; struct pw_client *client;
bool is_sandboxed;
struct pw_resource *core_resource;
struct spa_hook core_override;
struct spa_list async_pending;
struct spa_hook client_listener; struct spa_hook client_listener;
bool is_sandboxed;
struct spa_list resources;
struct resource *core_resource;
struct spa_list async_pending;
};
struct resource {
struct spa_list link;
struct client_info *cinfo;
struct pw_resource *resource;
struct spa_hook override;
}; };
struct async_pending { struct async_pending {
struct spa_list link; struct spa_list link;
struct client_info *info; struct resource *resource;
bool handled; bool handled;
char *handle; char *handle;
struct pw_resource *resource;
char *factory_name; char *factory_name;
char *name; char *name;
uint32_t type; uint32_t type;
@ -90,7 +98,7 @@ static struct client_info *find_client_info(struct impl *impl, struct pw_client
static void close_request(struct async_pending *p) static void close_request(struct async_pending *p)
{ {
DBusMessage *m = NULL; DBusMessage *m = NULL;
struct impl *impl = p->info->impl; struct impl *impl = p->resource->cinfo->impl;
pw_log_debug("pending %p: handle %s", p, p->handle); pw_log_debug("pending %p: handle %s", p, p->handle);
@ -133,12 +141,21 @@ static void free_pending(struct async_pending *p)
free(p); free(p);
} }
static void free_resource(struct resource *r)
{
spa_list_remove(&r->link);
free(r);
}
static void client_info_free(struct client_info *cinfo) static void client_info_free(struct client_info *cinfo)
{ {
struct async_pending *p, *tmp; struct async_pending *p, *tp;
struct resource *r, *tr;
spa_list_for_each_safe(p, tmp, &cinfo->async_pending, link) spa_list_for_each_safe(p, tp, &cinfo->async_pending, link)
free_pending(p); free_pending(p);
spa_list_for_each_safe(r, tr, &cinfo->resources, link)
free_resource(r);
spa_hook_remove(&cinfo->client_listener); spa_hook_remove(&cinfo->client_listener);
spa_list_remove(&cinfo->link); spa_list_remove(&cinfo->link);
@ -285,8 +302,8 @@ portal_response(DBusConnection *connection, DBusMessage *msg, void *user_data)
pw_log_debug("portal check result: %d", response); pw_log_debug("portal check result: %d", response);
if (response == 0) { if (response == 0) {
pw_resource_do_parent(cinfo->core_resource, pw_resource_do_parent(p->resource->resource,
&cinfo->core_override, &p->resource->override,
struct pw_core_proxy_methods, struct pw_core_proxy_methods,
create_node, create_node,
p->factory_name, p->factory_name,
@ -296,7 +313,7 @@ portal_response(DBusConnection *connection, DBusMessage *msg, void *user_data)
&p->properties->dict, &p->properties->dict,
p->new_id); p->new_id);
} else { } else {
pw_resource_error(p->resource, SPA_RESULT_NO_PERMISSION, "not allowed"); pw_resource_error(p->resource->resource, SPA_RESULT_NO_PERMISSION, "not allowed");
} }
free_pending(p); free_pending(p);
@ -316,7 +333,8 @@ static void do_create_node(void *data,
const struct spa_dict *props, const struct spa_dict *props,
uint32_t new_id) uint32_t new_id)
{ {
struct client_info *cinfo = data; struct resource *resource = data;
struct client_info *cinfo = resource->cinfo;
struct impl *impl = cinfo->impl; struct impl *impl = cinfo->impl;
struct pw_client *client = cinfo->client; struct pw_client *client = cinfo->client;
DBusMessage *m = NULL, *r = NULL; DBusMessage *m = NULL, *r = NULL;
@ -329,8 +347,8 @@ static void do_create_node(void *data,
struct async_pending *p; struct async_pending *p;
if (!cinfo->is_sandboxed) { if (!cinfo->is_sandboxed) {
pw_resource_do_parent(cinfo->core_resource, pw_resource_do_parent(resource->resource,
&cinfo->core_override, &resource->override,
struct pw_core_proxy_methods, struct pw_core_proxy_methods,
create_node, create_node,
factory_name, factory_name,
@ -389,10 +407,9 @@ static void do_create_node(void *data,
dbus_connection_add_filter(impl->bus, portal_response, cinfo, NULL); dbus_connection_add_filter(impl->bus, portal_response, cinfo, NULL);
p = calloc(1, sizeof(struct async_pending)); p = calloc(1, sizeof(struct async_pending));
p->info = cinfo; p->resource = resource;
p->handle = strdup(handle); p->handle = strdup(handle);
p->handled = false; p->handled = false;
p->resource = cinfo->core_resource;
p->factory_name = strdup(factory_name); p->factory_name = strdup(factory_name);
p->name = strdup(name); p->name = strdup(name);
p->type = type; p->type = type;
@ -401,7 +418,7 @@ static void do_create_node(void *data,
p->new_id = new_id; p->new_id = new_id;
pw_log_debug("pending %p: handle %s", p, handle); pw_log_debug("pending %p: handle %s", p, handle);
spa_list_insert(cinfo->async_pending.prev, &p->link); spa_list_append(&cinfo->async_pending, &p->link);
return; return;
@ -426,7 +443,7 @@ static void do_create_node(void *data,
dbus_error_free(&error); dbus_error_free(&error);
goto not_allowed; goto not_allowed;
not_allowed: not_allowed:
pw_resource_error(cinfo->core_resource, SPA_RESULT_NO_PERMISSION, "not allowed"); pw_resource_error(cinfo->core_resource->resource, SPA_RESULT_NO_PERMISSION, "not allowed");
return; return;
} }
@ -440,14 +457,15 @@ do_create_link(void *data,
const struct spa_dict *props, const struct spa_dict *props,
uint32_t new_id) uint32_t new_id)
{ {
struct client_info *cinfo = data; struct resource *resource = data;
struct client_info *cinfo = resource->cinfo;
if (cinfo->is_sandboxed) { if (cinfo->is_sandboxed) {
pw_resource_error(cinfo->core_resource, SPA_RESULT_NO_PERMISSION, "not allowed"); pw_resource_error(resource->resource, SPA_RESULT_NO_PERMISSION, "not allowed");
return; return;
} }
pw_resource_do_parent(cinfo->core_resource, pw_resource_do_parent(resource->resource,
&cinfo->core_override, &resource->override,
struct pw_core_proxy_methods, struct pw_core_proxy_methods,
create_link, create_link,
output_node_id, output_node_id,
@ -471,12 +489,21 @@ static void client_resource_impl(void *data, struct pw_resource *resource)
struct impl *impl = cinfo->impl; struct impl *impl = cinfo->impl;
if (pw_resource_get_type(resource) == impl->type->core) { if (pw_resource_get_type(resource) == impl->type->core) {
cinfo->core_resource = resource; struct resource *r;
r = calloc(1, sizeof(struct resource));
r->cinfo = cinfo;
r->resource = resource;
spa_list_append(&cinfo->resources, &r->link);
if (pw_resource_get_id(resource) == 0)
cinfo->core_resource = r;
pw_log_debug("module %p: add core override", impl); pw_log_debug("module %p: add core override", impl);
pw_resource_add_override(resource, pw_resource_add_override(resource,
&cinfo->core_override, &r->override,
&core_override, &core_override,
cinfo); r);
} }
} }
@ -499,6 +526,7 @@ core_global_added(void *data, struct pw_global *global)
cinfo->client = client; cinfo->client = client;
cinfo->is_sandboxed = client_is_sandboxed(client); cinfo->is_sandboxed = client_is_sandboxed(client);
spa_list_init(&cinfo->async_pending); spa_list_init(&cinfo->async_pending);
spa_list_init(&cinfo->resources);
pw_client_add_listener(client, &cinfo->client_listener, &client_events, cinfo); pw_client_add_listener(client, &cinfo->client_listener, &client_events, cinfo);