modules: get also instance id for flatpak apps

Add "pipewire.access.portal.instance_id" property for distinguishing
Flatpak application instances from each other.
This commit is contained in:
Pauli Virtanen 2025-05-11 13:45:34 +03:00 committed by Wim Taymans
parent 09a5b7ee35
commit 1445843ced
3 changed files with 21 additions and 10 deletions

View file

@ -16,8 +16,6 @@
#include <sys/vfs.h> #include <sys/vfs.h>
#endif #endif
#include "config.h"
#ifdef HAVE_GLIB2 #ifdef HAVE_GLIB2
#include <glib.h> #include <glib.h>
#endif #endif
@ -26,7 +24,7 @@
#include <spa/utils/result.h> #include <spa/utils/result.h>
#include <pipewire/log.h> #include <pipewire/log.h>
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 #ifdef HAVE_GLIB2
/* /*
@ -53,13 +51,19 @@ static int pw_check_flatpak_parse_metadata(const char *buf, size_t size, char **
g_free(s); 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; return 0;
#else #else
return -ENOTSUP; return -ENOTSUP;
#endif #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__) #if defined(__linux__)
char root_path[2048]; char root_path[2048];
@ -68,6 +72,8 @@ static int pw_check_flatpak(pid_t pid, char **app_id, char **devices)
if (app_id) if (app_id)
*app_id = NULL; *app_id = NULL;
if (instance_id)
*instance_id = NULL;
if (devices) if (devices)
*devices = NULL; *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)) { if (fstat (info_fd, &stat_buf) != 0 || !S_ISREG (stat_buf.st_mode)) {
/* Some weird fd => failure, assume sandboxed */ /* Some weird fd => failure, assume sandboxed */
pw_log_error("error fstat .flatpak-info: %m"); 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 */ /* Parse the application ID if needed */
const size_t size = stat_buf.st_size; const size_t size = stat_buf.st_size;
if (size > 0) { if (size > 0) {
void *buf = mmap(NULL, size, PROT_READ, MAP_PRIVATE, info_fd, 0); void *buf = mmap(NULL, size, PROT_READ, MAP_PRIVATE, info_fd, 0);
if (buf != MAP_FAILED) { 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); munmap(buf, size);
} else { } else {
res = -errno; res = -errno;

View file

@ -167,12 +167,13 @@ context_check_access(void *data, struct pw_impl_client *client)
{ {
struct impl *impl = data; struct impl *impl = data;
struct pw_permission permissions[1]; struct pw_permission permissions[1];
struct spa_dict_item items[3]; struct spa_dict_item items[4];
const struct pw_properties *props; const struct pw_properties *props;
const char *str; const char *str;
const char *access; const char *access;
const char *socket; const char *socket;
spa_autofree char *flatpak_app_id = NULL; spa_autofree char *flatpak_app_id = NULL;
spa_autofree char *flatpak_instance_id = NULL;
int nitems = 0; int nitems = 0;
bool sandbox_flatpak; bool sandbox_flatpak;
int pid, res; int pid, res;
@ -197,7 +198,7 @@ context_check_access(void *data, struct pw_impl_client *client)
} else { } else {
pw_log_info("client %p has trusted pid %d", client, pid); 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) {
if (res < 0) if (res < 0)
pw_log_warn("%p: client %p flatpak check failed: %s", 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) { if (sandbox_flatpak) {
items[nitems++] = SPA_DICT_ITEM_INIT("pipewire.access.portal.app_id", items[nitems++] = SPA_DICT_ITEM_INIT("pipewire.access.portal.app_id",
flatpak_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"); items[nitems++] = SPA_DICT_ITEM_INIT("pipewire.sec.flatpak", "true");
} }

View file

@ -430,7 +430,7 @@ on_connect(void *data, int fd, uint32_t mask)
client_access = server->client_access; client_access = server->client_access;
if (server->addr.ss_family == AF_UNIX) { 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 #ifdef HAVE_SNAP
pw_sandbox_access_t snap_access; pw_sandbox_access_t snap_access;
#endif #endif
@ -441,7 +441,7 @@ on_connect(void *data, int fd, uint32_t mask)
pw_log_warn("setsockopt(SO_PRIORITY) failed: %m"); pw_log_warn("setsockopt(SO_PRIORITY) failed: %m");
#endif #endif
pid = get_client_pid(client, client_fd); 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 * 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"; client_access = "flatpak";
pw_properties_set(client->props, "pipewire.access.portal.app_id", pw_properties_set(client->props, "pipewire.access.portal.app_id",
app_id); app_id);
pw_properties_set(client->props, "pipewire.access.portal.instance_id",
instance_id);
if (devices && (spa_streq(devices, "all") || if (devices && (spa_streq(devices, "all") ||
spa_strstartswith(devices, "all;") || spa_strstartswith(devices, "all;") ||