pulse-server: block arbitrary filter-graphs

Add a special 'blocked' spa-libs value that returns EPERM when trying to
load the factory.

Only allow loading the LADSPA filter.graph nodes for the LADSPA sink and
source. The most problematic part is the pipe filter, that allows it to
spawn arbirary programs as part of the filter.graph.

You can add a filter-graph to any stream with stream_props.
This commit is contained in:
Wim Taymans 2026-05-07 14:08:30 +02:00
parent e3f75314be
commit a4e2856d06
3 changed files with 11 additions and 2 deletions

View file

@ -358,6 +358,8 @@ factory-name and the plugin where the factory can be found.
Factory names can contain a wildcard to group several related factories into one
plugin. The plugin is loaded from the first matching factory-name.
A special `blocked` value for the plugin disables the factory-name.
## Example
```
@ -374,6 +376,7 @@ context.spa-libs = {
api.jack.* = jack/libspa-jack
support.* = support/libspa-support
video.convert.* = videoconvert/libspa-videoconvert
#filter.graph = blocked
}
```

View file

@ -22,6 +22,12 @@ context.properties = {
context.spa-libs = {
audio.convert.* = audioconvert/libspa-audioconvert
support.* = support/libspa-support
# because the pulse server allows dynamic loading of streams and modules
# inside the server, we must be careful with the filter-graph. Only allow
# LADSPA filters.
filter.graph.plugin.ladspa = filter-graph/libspa-filter-graph-plugin-ladspa
filter.graph.plugin.* = blocked
filter.graph = filter-graph/libspa-filter-graph
}
context.modules = [

View file

@ -1067,8 +1067,8 @@ struct spa_handle *pw_context_load_spa_handle(struct pw_context *context,
lib = pw_context_find_spa_lib(context, factory_name);
if (lib == NULL && info != NULL)
lib = spa_dict_lookup(info, SPA_KEY_LIBRARY_NAME);
if (lib == NULL) {
errno = ENOENT;
if (lib == NULL || spa_streq(lib, "blocked")) {
errno = lib ? EPERM : ENOENT;
pw_log_warn("%p: no library for %s: %m",
context, factory_name);
return NULL;