The documentation seemed to imply that SecurityContext provided security similar to Wayland security-context-v1, with a similar interface and plenty of references to Wayland documentation. Testing shows that while access through pipewire-pulse is indeed restricted, protocol native is entirely unaffected and behaves as if no SecurityContext was attached at all. It was, in fact, even possible to destroy the SecurityContext object on the PipeWire server by targeting its global id in a Registry::Destroy message.
If this is confirmed, and nothing can be done, Hakurei will need to expose only the pipewire-pulse socket via the host filesystem, analyse its behaviour to consider whether it is vulnerable to a confused deputy attack (protocol native has full access), and potentially also apply hardening via Landlock or similar to reduce access to the filesystem.
The [documentation](https://docs.pipewire.org/group__pw__security__context.html) seemed to imply that `SecurityContext` provided security similar to Wayland `security-context-v1`, with a similar interface and plenty of references to Wayland documentation. Testing shows that while access through `pipewire-pulse` is indeed restricted, protocol native is entirely unaffected and behaves as if no `SecurityContext` was attached at all. It was, in fact, even possible to [destroy the `SecurityContext` object on the PipeWire server](https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/5023) by targeting its global id in a `Registry::Destroy` message.
If this is confirmed, and nothing can be done, Hakurei will need to expose only the `pipewire-pulse` socket via the host filesystem, analyse its behaviour to consider whether it is vulnerable to a confused deputy attack (protocol native has full access), and potentially also apply hardening via Landlock or similar to reduce access to the filesystem.
Permissions are set up by code in an entirely separate repository, where read and execute permissions are blindly set on everything for clients with PW_KEY_ACCESS set to "restricted":
if(client->obj->info==NULL||client->obj->info->props==NULL||(str=spa_dict_lookup(client->obj->info->props,PW_KEY_ACCESS))==NULL)return;if(spa_streq(str,"flatpak")){if((str=spa_dict_lookup(client->obj->info->props,PW_KEY_MEDIA_CATEGORY))!=NULL&&(spa_streq(str,"Manager"))){/* FIXME, use permission store to check if this app is allowed to
* be a manager app */perms=PW_PERM_ALL;}else{/* limited access for everything else */perms=PW_PERM_R|PW_PERM_X;}}elseif(spa_streq(str,"restricted")){perms=PW_PERM_R|PW_PERM_X;}elsereturn;pw_log_info("%p: flatpak client %d granted 0x%08x permissions",impl,client->id,perms);permissions[0]=PW_PERMISSION_INIT(PW_ID_ANY,perms);pw_client_update_permissions((structpw_client*)client->obj->obj.proxy,1,permissions);client->active=true;
permissions=pw_global_get_permissions(global,client);if(!PW_PERM_IS_R(permissions))gotoerror_no_id;if(id==PW_ID_CORE||!PW_PERM_IS_X(permissions))gotoerror_not_allowed;pw_log_debug("global %p: destroy global id %d",global,id);pw_global_destroy(global);
This means that, with the exception of PW_ID_CORE, the client is allowed to destroy any other object, even from behind SecurityContext.
Permissions are set up by code in an [entirely separate repository](https://gitlab.freedesktop.org/pipewire/media-session/-/blob/7376c167f1ad20b3968d7a5d6c395a8b698d31d8/src/access-flatpak.c#L82-121), where read and execute permissions are blindly set on everything for clients with `PW_KEY_ACCESS` set to `"restricted"`:
```c
if (client->obj->info == NULL || client->obj->info->props == NULL ||
(str = spa_dict_lookup(client->obj->info->props, PW_KEY_ACCESS)) == NULL)
return;
if (spa_streq(str, "flatpak")) {
if ((str = spa_dict_lookup(client->obj->info->props, PW_KEY_MEDIA_CATEGORY)) != NULL &&
(spa_streq(str, "Manager"))) {
/* FIXME, use permission store to check if this app is allowed to
* be a manager app */
perms = PW_PERM_ALL;
} else {
/* limited access for everything else */
perms = PW_PERM_R | PW_PERM_X;
}
} else if (spa_streq(str, "restricted")) {
perms = PW_PERM_R | PW_PERM_X;
} else
return;
pw_log_info("%p: flatpak client %d granted 0x%08x permissions"
, impl, client->id, perms);
permissions[0] = PW_PERMISSION_INIT(PW_ID_ANY, perms);
pw_client_update_permissions((struct pw_client*)client->obj->obj.proxy,
1, permissions);
client->active = true;
```
`Registry::Destroy` is implemented in [src/pipewire/impl-core.c](https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/d329dac6ba7d32dacb13fd358b5360a59f7aac27/src/pipewire/impl-core.c#L82-131):
```c
permissions = pw_global_get_permissions(global, client);
if (!PW_PERM_IS_R(permissions))
goto error_no_id;
if (id == PW_ID_CORE || !PW_PERM_IS_X(permissions))
goto error_not_allowed;
pw_log_debug("global %p: destroy global id %d", global, id);
pw_global_destroy(global);
```
This means that, with the exception of `PW_ID_CORE`, the client is allowed to destroy any other object, even from behind `SecurityContext`.
The PipeWire socket is no longer directly exposed due to fundamental and unfixable flaws in the SecurityContext machinery. The current implementation now maintains a pipewire-pulse container for each instance via the shim. A security update will be tagged after all automated tests pass and manual testing is completed.
The PipeWire socket is no longer directly exposed due to fundamental and unfixable flaws in the `SecurityContext` machinery. The current implementation now maintains a `pipewire-pulse` container for each instance via the shim. A security update will be tagged after all automated tests pass and manual testing is completed.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
The documentation seemed to imply that
SecurityContextprovided security similar to Waylandsecurity-context-v1, with a similar interface and plenty of references to Wayland documentation. Testing shows that while access throughpipewire-pulseis indeed restricted, protocol native is entirely unaffected and behaves as if noSecurityContextwas attached at all. It was, in fact, even possible to destroy theSecurityContextobject on the PipeWire server by targeting its global id in aRegistry::Destroymessage.If this is confirmed, and nothing can be done, Hakurei will need to expose only the
pipewire-pulsesocket via the host filesystem, analyse its behaviour to consider whether it is vulnerable to a confused deputy attack (protocol native has full access), and potentially also apply hardening via Landlock or similar to reduce access to the filesystem.Permissions are set up by code in an entirely separate repository, where read and execute permissions are blindly set on everything for clients with
PW_KEY_ACCESSset to"restricted":Registry::Destroyis implemented in src/pipewire/impl-core.c:This means that, with the exception of
PW_ID_CORE, the client is allowed to destroy any other object, even from behindSecurityContext.The PipeWire socket is no longer directly exposed due to fundamental and unfixable flaws in the
SecurityContextmachinery. The current implementation now maintains apipewire-pulsecontainer for each instance via the shim. A security update will be tagged after all automated tests pass and manual testing is completed.