From 1445843cedcf11e22b38391f3741e7cdb5a0e3e6 Mon Sep 17 00:00:00 2001 From: Pauli Virtanen Date: Sun, 11 May 2025 13:45:34 +0300 Subject: [PATCH] modules: get also instance id for flatpak apps Add "pipewire.access.portal.instance_id" property for distinguishing Flatpak application instances from each other. --- src/modules/flatpak-utils.h | 18 ++++++++++++------ src/modules/module-access.c | 7 +++++-- src/modules/module-protocol-pulse/server.c | 6 ++++-- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/modules/flatpak-utils.h b/src/modules/flatpak-utils.h index 9b839e210..76b14491c 100644 --- a/src/modules/flatpak-utils.h +++ b/src/modules/flatpak-utils.h @@ -16,8 +16,6 @@ #include #endif -#include "config.h" - #ifdef HAVE_GLIB2 #include #endif @@ -26,7 +24,7 @@ #include #include -static int pw_check_flatpak_parse_metadata(const char *buf, size_t size, char **app_id, char **devices) +static int pw_check_flatpak_parse_metadata(const char *buf, size_t size, char **app_id, char **instance_id, char **devices) { #ifdef HAVE_GLIB2 /* @@ -53,13 +51,19 @@ static int pw_check_flatpak_parse_metadata(const char *buf, size_t size, char ** g_free(s); } + if (instance_id) { + s = g_key_file_get_value(metadata, "Instance", "instance-id", NULL); + *instance_id = s ? strdup(s) : NULL; + g_free(s); + } + return 0; #else return -ENOTSUP; #endif } -static int pw_check_flatpak(pid_t pid, char **app_id, char **devices) +static int pw_check_flatpak(pid_t pid, char **app_id, char **instance_id, char **devices) { #if defined(__linux__) char root_path[2048]; @@ -68,6 +72,8 @@ static int pw_check_flatpak(pid_t pid, char **app_id, char **devices) if (app_id) *app_id = NULL; + if (instance_id) + *instance_id = NULL; if (devices) *devices = NULL; @@ -107,14 +113,14 @@ static int pw_check_flatpak(pid_t pid, char **app_id, char **devices) if (fstat (info_fd, &stat_buf) != 0 || !S_ISREG (stat_buf.st_mode)) { /* Some weird fd => failure, assume sandboxed */ pw_log_error("error fstat .flatpak-info: %m"); - } else if (app_id || devices) { + } else if (app_id || instance_id || devices) { /* Parse the application ID if needed */ const size_t size = stat_buf.st_size; if (size > 0) { void *buf = mmap(NULL, size, PROT_READ, MAP_PRIVATE, info_fd, 0); if (buf != MAP_FAILED) { - res = pw_check_flatpak_parse_metadata(buf, size, app_id, devices); + res = pw_check_flatpak_parse_metadata(buf, size, app_id, instance_id, devices); munmap(buf, size); } else { res = -errno; diff --git a/src/modules/module-access.c b/src/modules/module-access.c index 2e246ae91..05bc14483 100644 --- a/src/modules/module-access.c +++ b/src/modules/module-access.c @@ -167,12 +167,13 @@ context_check_access(void *data, struct pw_impl_client *client) { struct impl *impl = data; struct pw_permission permissions[1]; - struct spa_dict_item items[3]; + struct spa_dict_item items[4]; const struct pw_properties *props; const char *str; const char *access; const char *socket; spa_autofree char *flatpak_app_id = NULL; + spa_autofree char *flatpak_instance_id = NULL; int nitems = 0; bool sandbox_flatpak; int pid, res; @@ -197,7 +198,7 @@ context_check_access(void *data, struct pw_impl_client *client) } else { pw_log_info("client %p has trusted pid %d", client, pid); - res = pw_check_flatpak(pid, &flatpak_app_id, NULL); + res = pw_check_flatpak(pid, &flatpak_app_id, &flatpak_instance_id, NULL); if (res != 0) { if (res < 0) pw_log_warn("%p: client %p flatpak check failed: %s", @@ -233,6 +234,8 @@ context_check_access(void *data, struct pw_impl_client *client) if (sandbox_flatpak) { items[nitems++] = SPA_DICT_ITEM_INIT("pipewire.access.portal.app_id", flatpak_app_id); + items[nitems++] = SPA_DICT_ITEM_INIT("pipewire.access.portal.instance_id", + flatpak_instance_id); items[nitems++] = SPA_DICT_ITEM_INIT("pipewire.sec.flatpak", "true"); } diff --git a/src/modules/module-protocol-pulse/server.c b/src/modules/module-protocol-pulse/server.c index fe7d47ab0..e1ffafffa 100644 --- a/src/modules/module-protocol-pulse/server.c +++ b/src/modules/module-protocol-pulse/server.c @@ -430,7 +430,7 @@ on_connect(void *data, int fd, uint32_t mask) client_access = server->client_access; if (server->addr.ss_family == AF_UNIX) { - spa_autofree char *app_id = NULL, *snap_app_id = NULL, *devices = NULL; + spa_autofree char *app_id = NULL, *snap_app_id = NULL, *devices = NULL, *instance_id = NULL; #ifdef HAVE_SNAP pw_sandbox_access_t snap_access; #endif @@ -441,7 +441,7 @@ on_connect(void *data, int fd, uint32_t mask) pw_log_warn("setsockopt(SO_PRIORITY) failed: %m"); #endif pid = get_client_pid(client, client_fd); - if (pid != 0 && pw_check_flatpak(pid, &app_id, &devices) == 1) { + if (pid != 0 && pw_check_flatpak(pid, &app_id, &instance_id, &devices) == 1) { /* * XXX: we should really use Portal client access here * @@ -464,6 +464,8 @@ on_connect(void *data, int fd, uint32_t mask) client_access = "flatpak"; pw_properties_set(client->props, "pipewire.access.portal.app_id", app_id); + pw_properties_set(client->props, "pipewire.access.portal.instance_id", + instance_id); if (devices && (spa_streq(devices, "all") || spa_strstartswith(devices, "all;") ||