From b1fff0fa9f16f14780d3ec8fc46cce94c39adef3 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 15 May 2026 10:59:25 +0200 Subject: [PATCH] Rebase to 1.4.11 Add fixes for CVE-2026-5674 Resolves: RHEL-164830 --- ...dlopen-from-the-defined-search-paths.patch | 244 ++++++++++++++++++ ...lopen-improve-prefix-check-some-more.patch | 50 ++++ ...dlopen-support-search-path-ending-in.patch | 42 +++ ...-error-when-there-are-no-valid-nodes.patch | 51 ++++ ...er-graph-relax-LADSPA-plugin-loading.patch | 164 ++++++++++++ pipewire.spec | 12 +- sources | 2 +- 7 files changed, 563 insertions(+), 2 deletions(-) create mode 100644 0001-only-dlopen-from-the-defined-search-paths.patch create mode 100644 0002-dlopen-improve-prefix-check-some-more.patch create mode 100644 0003-dlopen-support-search-path-ending-in.patch create mode 100644 0004-filter-graph-error-when-there-are-no-valid-nodes.patch create mode 100644 0005-filter-graph-relax-LADSPA-plugin-loading.patch diff --git a/0001-only-dlopen-from-the-defined-search-paths.patch b/0001-only-dlopen-from-the-defined-search-paths.patch new file mode 100644 index 0000000..53580d2 --- /dev/null +++ b/0001-only-dlopen-from-the-defined-search-paths.patch @@ -0,0 +1,244 @@ +From 0d7801240eca8c7e7ccbdb3530dd14d2797b43bc Mon Sep 17 00:00:00 2001 +From: Wim Taymans +Date: Mon, 6 Apr 2026 14:18:22 +0200 +Subject: [PATCH 1/5] only dlopen from the defined search paths + +Don't accept absolute library paths that are not in the search path, +skip the ../ in paths to avoid opening arbitrary libraries from +unexpected places. +--- + spa/plugins/filter-graph/ladspa_plugin.c | 72 ++++++++++++--------- + src/daemon/filter-chain/source-rnnoise.conf | 1 - + src/modules/module-jack-tunnel.c | 3 +- + src/modules/module-jack-tunnel/weakjack.h | 48 +++++++------- + src/pipewire/impl-module.c | 3 + + src/pipewire/pipewire.c | 3 + + 6 files changed, 72 insertions(+), 58 deletions(-) + +diff --git a/spa/plugins/filter-graph/ladspa_plugin.c b/spa/plugins/filter-graph/ladspa_plugin.c +index 45026c8e7..354e779b9 100644 +--- a/spa/plugins/filter-graph/ladspa_plugin.c ++++ b/spa/plugins/filter-graph/ladspa_plugin.c +@@ -218,43 +218,49 @@ static inline const char *split_walk(const char *str, const char *delimiter, siz + return s; + } + +-static int load_ladspa_plugin(struct plugin *impl, const char *path) ++static void make_search_paths(const char **path, const char **search_dirs) + { +- int res = -ENOENT; ++ const char *p; ++ ++ while ((p = strstr(*path, "../")) != NULL) ++ *path = p + 3; + +- if (path[0] != '/') { +- const char *search_dirs, *p, *state = NULL; +- char filename[PATH_MAX]; +- size_t len; ++ *search_dirs = getenv("LADSPA_PATH"); ++ if (!*search_dirs) ++ *search_dirs = "/usr/lib64/ladspa:/usr/lib/ladspa:" LIBDIR; ++} + +- search_dirs = getenv("LADSPA_PATH"); +- if (!search_dirs) +- search_dirs = "/usr/lib64/ladspa:/usr/lib/ladspa:" LIBDIR; ++static int load_ladspa_plugin(struct plugin *impl, const char *path, const char *search_dirs) ++{ ++ int res = -ENOENT; ++ const char *p, *state = NULL; ++ char filename[PATH_MAX]; ++ size_t len; + +- /* +- * set the errno for the case when `ladspa_handle_load_by_path()` +- * is never called, which can only happen if the supplied +- * LADSPA_PATH contains too long paths +- */ +- res = -ENAMETOOLONG; ++ /* ++ * set the errno for the case when `ladspa_handle_load_by_path()` ++ * is never called, which can only happen if the supplied ++ * LADSPA_PATH contains too long paths ++ */ ++ res = -ENAMETOOLONG; + +- while ((p = split_walk(search_dirs, ":", &len, &state))) { +- int namelen; ++ while ((p = split_walk(search_dirs, ":", &len, &state))) { ++ int namelen; + +- if (len >= sizeof(filename)) +- continue; ++ if (len >= sizeof(filename)) ++ continue; + ++ if (strncmp(path, p, len) == 0) ++ namelen = snprintf(filename, sizeof(filename), "%s", path); ++ else + namelen = snprintf(filename, sizeof(filename), "%.*s/%s.so", (int) len, p, path); +- if (namelen < 0 || (size_t) namelen >= sizeof(filename)) +- continue; + +- res = ladspa_handle_load_by_path(impl, filename); +- if (res >= 0) +- break; +- } +- } +- else { +- res = ladspa_handle_load_by_path(impl, path); ++ if (namelen < 0 || (size_t) namelen >= sizeof(filename)) ++ continue; ++ ++ res = ladspa_handle_load_by_path(impl, filename); ++ if (res >= 0) ++ break; + } + return res; + } +@@ -302,7 +308,7 @@ impl_init(const struct spa_handle_factory *factory, + struct plugin *impl; + uint32_t i; + int res; +- const char *path = NULL; ++ const char *path = NULL, *search_dirs; + + handle->get_interface = impl_get_interface; + handle->clear = impl_clear; +@@ -320,9 +326,11 @@ impl_init(const struct spa_handle_factory *factory, + if (path == NULL) + return -EINVAL; + +- if ((res = load_ladspa_plugin(impl, path)) < 0) { +- spa_log_error(impl->log, "failed to load plugin '%s': %s", +- path, spa_strerror(res)); ++ make_search_paths(&path, &search_dirs); ++ ++ if ((res = load_ladspa_plugin(impl, path, search_dirs)) < 0) { ++ spa_log_error(impl->log, "failed to load plugin '%s' in '%s': %s", ++ path, search_dirs, spa_strerror(res)); + return res; + } + +diff --git a/src/daemon/filter-chain/source-rnnoise.conf b/src/daemon/filter-chain/source-rnnoise.conf +index f3c2c71be..83142dd29 100644 +--- a/src/daemon/filter-chain/source-rnnoise.conf ++++ b/src/daemon/filter-chain/source-rnnoise.conf +@@ -21,7 +21,6 @@ context.modules = [ + # listed in the environment variable LADSPA_PATH or + # /usr/lib64/ladspa, /usr/lib/ladspa or the system library directory + # as a fallback. +- # You might want to use an absolute path here to avoid problems. + plugin = "librnnoise_ladspa" + label = noise_suppressor_stereo + control = { +diff --git a/src/modules/module-jack-tunnel.c b/src/modules/module-jack-tunnel.c +index b55dd5ee8..55fac1a10 100644 +--- a/src/modules/module-jack-tunnel.c ++++ b/src/modules/module-jack-tunnel.c +@@ -49,8 +49,7 @@ + * ## Module Options + * + * - `jack.library`: the libjack to load, by default libjack.so.0 is searched in +- * JACK_PATH directories and then some standard library paths. +- * Can be an absolute path. ++ * LIBJACK_PATH directories and then some standard library paths. + * - `jack.server`: the name of the JACK server to tunnel to. + * - `jack.client-name`: the name of the JACK client. + * - `jack.connect`: if jack ports should be connected automatically. Can also be +diff --git a/src/modules/module-jack-tunnel/weakjack.h b/src/modules/module-jack-tunnel/weakjack.h +index 1b057b0ba..19537dbff 100644 +--- a/src/modules/module-jack-tunnel/weakjack.h ++++ b/src/modules/module-jack-tunnel/weakjack.h +@@ -158,34 +158,36 @@ static inline int weakjack_load_by_path(struct weakjack *jack, const char *path) + static inline int weakjack_load(struct weakjack *jack, const char *lib) + { + int res = -ENOENT; ++ const char *search_dirs, *p, *state = NULL; ++ char path[PATH_MAX]; ++ size_t len; + +- if (lib[0] != '/') { +- const char *search_dirs, *p, *state = NULL; +- char path[PATH_MAX]; +- size_t len; ++ while ((p = strstr(lib, "../")) != NULL) ++ lib = p + 3; + +- search_dirs = getenv("LIBJACK_PATH"); +- if (!search_dirs) +- search_dirs = PREFIX "/lib64/:" PREFIX "/lib/:" +- "/usr/lib64/:/usr/lib/:" LIBDIR; ++ search_dirs = getenv("LIBJACK_PATH"); ++ if (!search_dirs) ++ search_dirs = PREFIX "/lib64/:" PREFIX "/lib/:" ++ "/usr/lib64/:/usr/lib/:" LIBDIR; + +- while ((p = pw_split_walk(search_dirs, ":", &len, &state))) { +- int pathlen; ++ res = -ENAMETOOLONG; + +- if (len >= sizeof(path)) { +- res = -ENAMETOOLONG; +- continue; +- } ++ while ((p = pw_split_walk(search_dirs, ":", &len, &state))) { ++ int pathlen; ++ ++ if (len >= sizeof(path)) ++ continue; ++ ++ if (strncmp(lib, p, len) == 0) ++ pathlen = snprintf(path, sizeof(path), "%s", lib); ++ else + pathlen = snprintf(path, sizeof(path), "%.*s/%s", (int) len, p, lib); +- if (pathlen < 0 || (size_t) pathlen >= sizeof(path)) { +- res = -ENAMETOOLONG; +- continue; +- } +- if ((res = weakjack_load_by_path(jack, path)) == 0) +- break; +- } +- } else { +- res = weakjack_load_by_path(jack, lib); ++ ++ if (pathlen < 0 || (size_t) pathlen >= sizeof(path)) ++ continue; ++ ++ if ((res = weakjack_load_by_path(jack, path)) == 0) ++ break; + } + return res; + } +diff --git a/src/pipewire/impl-module.c b/src/pipewire/impl-module.c +index 10aa432fe..1921c87cd 100644 +--- a/src/pipewire/impl-module.c ++++ b/src/pipewire/impl-module.c +@@ -154,6 +154,9 @@ pw_context_load_module(struct pw_context *context, + NULL + }; + ++ while ((p = strstr(name, "../")) != NULL) ++ name = p + 3; ++ + pw_log_info("%p: name:%s args:%s", context, name, args); + + module_dir = getenv("PIPEWIRE_MODULE_DIR"); +diff --git a/src/pipewire/pipewire.c b/src/pipewire/pipewire.c +index 4451fa525..bccd48f35 100644 +--- a/src/pipewire/pipewire.c ++++ b/src/pipewire/pipewire.c +@@ -232,6 +232,9 @@ static struct spa_handle *load_spa_handle(const char *lib, + if (lib == NULL) + lib = sup->support_lib; + ++ while ((p = strstr(lib, "../")) != NULL) ++ lib = p + 3; ++ + pw_log_debug("load lib:'%s' factory-name:'%s'", lib, factory_name); + + plugin = NULL; +-- +2.54.0 + diff --git a/0002-dlopen-improve-prefix-check-some-more.patch b/0002-dlopen-improve-prefix-check-some-more.patch new file mode 100644 index 0000000..69a8fc6 --- /dev/null +++ b/0002-dlopen-improve-prefix-check-some-more.patch @@ -0,0 +1,50 @@ +From 726f9d31440b5e28ca72b7a69a6ae6e8966986b3 Mon Sep 17 00:00:00 2001 +From: Wim Taymans +Date: Wed, 8 Apr 2026 12:00:04 +0200 +Subject: [PATCH 2/5] dlopen: improve prefix check some more + +If we pass a path /usr/libevil/mycode.so, it might have a prefix of +/usr/lib but we should still reject it. Do thi by checking that after +the prefix match, we start a new directory. +--- + spa/plugins/filter-graph/ladspa_plugin.c | 4 ++-- + src/modules/module-jack-tunnel/weakjack.h | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/spa/plugins/filter-graph/ladspa_plugin.c b/spa/plugins/filter-graph/ladspa_plugin.c +index 354e779b9..32e57c90a 100644 +--- a/spa/plugins/filter-graph/ladspa_plugin.c ++++ b/spa/plugins/filter-graph/ladspa_plugin.c +@@ -247,10 +247,10 @@ static int load_ladspa_plugin(struct plugin *impl, const char *path, const char + while ((p = split_walk(search_dirs, ":", &len, &state))) { + int namelen; + +- if (len >= sizeof(filename)) ++ if (len == 0 || len >= sizeof(filename)) + continue; + +- if (strncmp(path, p, len) == 0) ++ if (strncmp(path, p, len) == 0 && path[len] == '/') + namelen = snprintf(filename, sizeof(filename), "%s", path); + else + namelen = snprintf(filename, sizeof(filename), "%.*s/%s.so", (int) len, p, path); +diff --git a/src/modules/module-jack-tunnel/weakjack.h b/src/modules/module-jack-tunnel/weakjack.h +index 19537dbff..7e621bffb 100644 +--- a/src/modules/module-jack-tunnel/weakjack.h ++++ b/src/modules/module-jack-tunnel/weakjack.h +@@ -175,10 +175,10 @@ static inline int weakjack_load(struct weakjack *jack, const char *lib) + while ((p = pw_split_walk(search_dirs, ":", &len, &state))) { + int pathlen; + +- if (len >= sizeof(path)) ++ if (len == 0 || len >= sizeof(path)) + continue; + +- if (strncmp(lib, p, len) == 0) ++ if (strncmp(lib, p, len) == 0 && lib[len] == '/') + pathlen = snprintf(path, sizeof(path), "%s", lib); + else + pathlen = snprintf(path, sizeof(path), "%.*s/%s", (int) len, p, lib); +-- +2.54.0 + diff --git a/0003-dlopen-support-search-path-ending-in.patch b/0003-dlopen-support-search-path-ending-in.patch new file mode 100644 index 0000000..a45fa08 --- /dev/null +++ b/0003-dlopen-support-search-path-ending-in.patch @@ -0,0 +1,42 @@ +From 142d3d7896a28f6426a887f5e2b569f0151bac40 Mon Sep 17 00:00:00 2001 +From: Wim Taymans +Date: Mon, 13 Apr 2026 10:26:33 +0200 +Subject: [PATCH 3/5] dlopen: support search path ending in / + +When the search path is /usr/lib/, /usr/lib/foo.so fails to load because +there is no / after the search path. Fix this by requiring that either +the search path end with / or the following char is a /. +--- + spa/plugins/filter-graph/ladspa_plugin.c | 2 +- + src/modules/module-jack-tunnel/weakjack.h | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/spa/plugins/filter-graph/ladspa_plugin.c b/spa/plugins/filter-graph/ladspa_plugin.c +index 32e57c90a..9274e69c4 100644 +--- a/spa/plugins/filter-graph/ladspa_plugin.c ++++ b/spa/plugins/filter-graph/ladspa_plugin.c +@@ -250,7 +250,7 @@ static int load_ladspa_plugin(struct plugin *impl, const char *path, const char + if (len == 0 || len >= sizeof(filename)) + continue; + +- if (strncmp(path, p, len) == 0 && path[len] == '/') ++ if (strncmp(path, p, len) == 0 && (path[len-1] == '/' || path[len] == '/')) + namelen = snprintf(filename, sizeof(filename), "%s", path); + else + namelen = snprintf(filename, sizeof(filename), "%.*s/%s.so", (int) len, p, path); +diff --git a/src/modules/module-jack-tunnel/weakjack.h b/src/modules/module-jack-tunnel/weakjack.h +index 7e621bffb..3bb0dd17e 100644 +--- a/src/modules/module-jack-tunnel/weakjack.h ++++ b/src/modules/module-jack-tunnel/weakjack.h +@@ -178,7 +178,7 @@ static inline int weakjack_load(struct weakjack *jack, const char *lib) + if (len == 0 || len >= sizeof(path)) + continue; + +- if (strncmp(lib, p, len) == 0 && lib[len] == '/') ++ if (strncmp(lib, p, len) == 0 && (lib[len-1] == '/' || lib[len] == '/')) + pathlen = snprintf(path, sizeof(path), "%s", lib); + else + pathlen = snprintf(path, sizeof(path), "%.*s/%s", (int) len, p, lib); +-- +2.54.0 + diff --git a/0004-filter-graph-error-when-there-are-no-valid-nodes.patch b/0004-filter-graph-error-when-there-are-no-valid-nodes.patch new file mode 100644 index 0000000..e9c4546 --- /dev/null +++ b/0004-filter-graph-error-when-there-are-no-valid-nodes.patch @@ -0,0 +1,51 @@ +From 925e071a260b28e79645d65393d7cdd8b883d8fa Mon Sep 17 00:00:00 2001 +From: Wim Taymans +Date: Thu, 7 May 2026 13:30:41 +0200 +Subject: [PATCH 4/5] filter-graph: error when there are no valid nodes + +The nodes might have failed to load or there was an empty array or the +array did not contain objects. +--- + spa/plugins/filter-graph/filter-graph.c | 5 ++++- + src/modules/module-filter-chain.c | 2 +- + 2 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/spa/plugins/filter-graph/filter-graph.c b/spa/plugins/filter-graph/filter-graph.c +index eaaebe3f2..b83a6b1da 100644 +--- a/spa/plugins/filter-graph/filter-graph.c ++++ b/spa/plugins/filter-graph/filter-graph.c +@@ -2092,6 +2092,10 @@ static int load_graph(struct graph *graph, const struct spa_dict *props) + if ((res = load_node(graph, &it[1])) < 0) + return res; + } ++ if (spa_list_is_empty(&graph->node_list)) { ++ spa_log_error(impl->log, "filter.graph has no nodes"); ++ return -EINVAL; ++ } + if (plinks != NULL) { + while (spa_json_enter_object(plinks, &it[1]) > 0) { + if ((res = parse_link(graph, &it[1])) < 0) +@@ -2144,7 +2148,6 @@ static int load_graph(struct graph *graph, const struct spa_dict *props) + else + graph->default_outputs = last->desc->n_output; + +- + return 0; + } + +diff --git a/src/modules/module-filter-chain.c b/src/modules/module-filter-chain.c +index 764cd481a..cedeb675e 100644 +--- a/src/modules/module-filter-chain.c ++++ b/src/modules/module-filter-chain.c +@@ -1191,7 +1191,7 @@ static const struct pw_stream_events out_stream_events = { + + static int setup_streams(struct impl *impl) + { +- int res; ++ int res = 0; + uint32_t i, n_params, *offs; + struct pw_array offsets; + const struct spa_pod **params = NULL; +-- +2.54.0 + diff --git a/0005-filter-graph-relax-LADSPA-plugin-loading.patch b/0005-filter-graph-relax-LADSPA-plugin-loading.patch new file mode 100644 index 0000000..fd32c3d --- /dev/null +++ b/0005-filter-graph-relax-LADSPA-plugin-loading.patch @@ -0,0 +1,164 @@ +From 61726f41d533199cbb5399436e0222dbbb21d74b Mon Sep 17 00:00:00 2001 +From: Wim Taymans +Date: Thu, 14 May 2026 13:23:19 +0200 +Subject: [PATCH 5/5] filter-graph: relax LADSPA plugin loading + +Make a new library.filter-path for the filter-graph that will filter and +restrict the dlopen filenames (used for the LADSPA plugin only). + +By default this is false and so filter-chain can load from absolute +paths without extra checks. + +Enable the extra checks for the pulse LADSPA modules and the +audioconvert filter graphs because these allow loading LADSPA plugins +into other processes. + +Fixes #5222 +--- + spa/plugins/audioconvert/audioconvert.c | 1 + + spa/plugins/filter-graph/filter-graph.c | 8 +++++++- + spa/plugins/filter-graph/ladspa_plugin.c | 19 ++++++++++++------- + .../modules/module-ladspa-sink.c | 1 + + .../modules/module-ladspa-source.c | 1 + + 5 files changed, 22 insertions(+), 8 deletions(-) + +diff --git a/spa/plugins/audioconvert/audioconvert.c b/spa/plugins/audioconvert/audioconvert.c +index 946e1934c..cfdda59ec 100644 +--- a/spa/plugins/audioconvert/audioconvert.c ++++ b/spa/plugins/audioconvert/audioconvert.c +@@ -1258,6 +1258,7 @@ static int load_filter_graph(struct impl *impl, const char *graph, int order) + &SPA_DICT_ITEMS( + SPA_DICT_ITEM(SPA_KEY_LIBRARY_NAME, "filter-graph/libspa-filter-graph"), + SPA_DICT_ITEM("clock.quantum-limit", qlimit), ++ SPA_DICT_ITEM("library.filter-path", "true"), + SPA_DICT_ITEM("filter.graph", graph))); + if (new_handle == NULL) + goto error; +diff --git a/spa/plugins/filter-graph/filter-graph.c b/spa/plugins/filter-graph/filter-graph.c +index b83a6b1da..69a5a9069 100644 +--- a/spa/plugins/filter-graph/filter-graph.c ++++ b/spa/plugins/filter-graph/filter-graph.c +@@ -219,6 +219,7 @@ struct impl { + uint32_t quantum_limit; + uint32_t max_align; + long unsigned rate; ++ bool filter_path; + + struct spa_list plugin_list; + +@@ -830,7 +831,7 @@ static struct plugin *plugin_load(struct impl *impl, const char *type, const cha + struct spa_handle *hndl = NULL; + struct plugin *plugin; + char module[PATH_MAX]; +- char factory_name[256], dsp_ptr[256]; ++ char factory_name[256], dsp_ptr[256], filter[16]; + void *iface; + int res; + +@@ -848,11 +849,14 @@ static struct plugin *plugin_load(struct impl *impl, const char *type, const cha + "filter.graph.plugin.%s", type); + spa_scnprintf(dsp_ptr, sizeof(dsp_ptr), + "pointer:%p", impl->dsp); ++ spa_scnprintf(filter, sizeof(filter), ++ "%s", impl->filter_path ? "true" : "false"); + + hndl = spa_plugin_loader_load(impl->loader, factory_name, + &SPA_DICT_ITEMS( + SPA_DICT_ITEM(SPA_KEY_LIBRARY_NAME, module), + SPA_DICT_ITEM("filter.graph.path", path), ++ SPA_DICT_ITEM("library.filter-path", filter), + SPA_DICT_ITEM("filter.graph.audio.dsp", dsp_ptr))); + + if (hndl == NULL) { +@@ -2261,6 +2265,8 @@ impl_init(const struct spa_handle_factory *factory, + spa_atou32(s, &impl->info.n_inputs, 0); + if (spa_streq(k, "filter-graph.n_outputs")) + spa_atou32(s, &impl->info.n_outputs, 0); ++ if (spa_streq(k, "library.filter-path")) ++ impl->filter_path = spa_atob(s); + } + if (impl->quantum_limit == 0) + return -EINVAL; +diff --git a/spa/plugins/filter-graph/ladspa_plugin.c b/spa/plugins/filter-graph/ladspa_plugin.c +index 9274e69c4..1f7cb6ae5 100644 +--- a/spa/plugins/filter-graph/ladspa_plugin.c ++++ b/spa/plugins/filter-graph/ladspa_plugin.c +@@ -20,6 +20,7 @@ + struct plugin { + struct spa_handle handle; + struct spa_fga_plugin plugin; ++ bool filter_path; + + struct spa_log *log; + +@@ -218,13 +219,13 @@ static inline const char *split_walk(const char *str, const char *delimiter, siz + return s; + } + +-static void make_search_paths(const char **path, const char **search_dirs) ++static void make_search_paths(const char **path, const char **search_dirs, bool filter) + { +- const char *p; +- +- while ((p = strstr(*path, "../")) != NULL) +- *path = p + 3; +- ++ if (filter) { ++ const char *p; ++ while ((p = strstr(*path, "../")) != NULL) ++ *path = p + 3; ++ } + *search_dirs = getenv("LADSPA_PATH"); + if (!*search_dirs) + *search_dirs = "/usr/lib64/ladspa:/usr/lib/ladspa:" LIBDIR; +@@ -237,6 +238,8 @@ static int load_ladspa_plugin(struct plugin *impl, const char *path, const char + char filename[PATH_MAX]; + size_t len; + ++ if (!impl->filter_path && path[0] == '/') ++ return ladspa_handle_load_by_path(impl, path); + /* + * set the errno for the case when `ladspa_handle_load_by_path()` + * is never called, which can only happen if the supplied +@@ -322,11 +325,13 @@ impl_init(const struct spa_handle_factory *factory, + const char *s = info->items[i].value; + if (spa_streq(k, "filter.graph.path")) + path = s; ++ else if (spa_streq(k, "library.filter-path")) ++ impl->filter_path = spa_atob(s); + } + if (path == NULL) + return -EINVAL; + +- make_search_paths(&path, &search_dirs); ++ make_search_paths(&path, &search_dirs, impl->filter_path); + + if ((res = load_ladspa_plugin(impl, path, search_dirs)) < 0) { + spa_log_error(impl->log, "failed to load plugin '%s' in '%s': %s", +diff --git a/src/modules/module-protocol-pulse/modules/module-ladspa-sink.c b/src/modules/module-protocol-pulse/modules/module-ladspa-sink.c +index 50c368398..d19239d36 100644 +--- a/src/modules/module-protocol-pulse/modules/module-ladspa-sink.c ++++ b/src/modules/module-protocol-pulse/modules/module-ladspa-sink.c +@@ -200,6 +200,7 @@ static int module_ladspa_sink_prepare(struct module * const module) + } else { + pw_properties_set(props, PW_KEY_NODE_DESCRIPTION, str); + } ++ pw_properties_set(props, "library.filter-path", "true"); + + if ((str = pw_properties_get(props, "master")) != NULL || + (str = pw_properties_get(props, "sink_master")) != NULL) { +diff --git a/src/modules/module-protocol-pulse/modules/module-ladspa-source.c b/src/modules/module-protocol-pulse/modules/module-ladspa-source.c +index 09eb11ce4..2f3521d12 100644 +--- a/src/modules/module-protocol-pulse/modules/module-ladspa-source.c ++++ b/src/modules/module-protocol-pulse/modules/module-ladspa-source.c +@@ -200,6 +200,7 @@ static int module_ladspa_source_prepare(struct module * const module) + } else { + pw_properties_set(props, PW_KEY_NODE_DESCRIPTION, str); + } ++ pw_properties_set(props, "library.filter-path", "true"); + + if ((str = pw_properties_get(props, "master")) != NULL || + (str = pw_properties_get(props, "source_master")) != NULL) { +-- +2.54.0 + diff --git a/pipewire.spec b/pipewire.spec index b20025b..f49a113 100644 --- a/pipewire.spec +++ b/pipewire.spec @@ -1,6 +1,6 @@ %global majorversion 1 %global minorversion 4 -%global microversion 9 +%global microversion 11 %global apiversion 0.3 %global spaversion 0.2 @@ -80,6 +80,11 @@ Source0: https://gitlab.freedesktop.org/pipewire/pipewire/-/archive/%{ver Source1: pipewire.sysusers ## upstream patches +Patch0001: 0001-only-dlopen-from-the-defined-search-paths.patch +Patch0002: 0002-dlopen-improve-prefix-check-some-more.patch +Patch0003: 0003-dlopen-support-search-path-ending-in.patch +Patch0004: 0004-filter-graph-error-when-there-are-no-valid-nodes.patch +Patch0005: 0005-filter-graph-relax-LADSPA-plugin-loading.patch ## upstreamable patches @@ -913,6 +918,11 @@ systemctl --no-reload preset --global pipewire.socket >/dev/null 2>&1 || : %{_datadir}/pipewire/pipewire.conf.d/50-raop.conf %changelog +* Fri May 15 2026 Wim Taymans - 1.4.11-1 +- Rebase to 1.4.11 +- Add fixes for CVE-2026-5674 + Resolves: RHEL-164830 + * Fri Nov 21 2025 Wim Taymans - 1.4.9-1 - Rebase to 1.4.9 Resolves: RHEL-123614 diff --git a/sources b/sources index afb7060..fb8d8f2 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (pipewire-1.4.9.tar.gz) = 15d5383b307c6a33e221a1f3b13e1a6b182e1826f419420654e25c5db2daf3793b094f816604bda9fa03abe6dff66c12dad98637edab67ca5966bbb8c57ea4ad +SHA512 (pipewire-1.4.11.tar.gz) = 917d599914dcc535a5aa2478c54de306e620c06e9d1a02220e9681e13e05566fe997eb25b59930d95ea9e9a8dc8fe6da86d41652d707cec0a2ee970b00e18a13