Skip to content

Commit 6bc07df

Browse files
committed
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.
1 parent 1689b44 commit 6bc07df

7 files changed

Lines changed: 72 additions & 58 deletions

File tree

‎spa/plugins/filter-graph/plugin_ladspa.c‎

Lines changed: 40 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -233,43 +233,49 @@ static inline const char *split_walk(const char *str, const char *delimiter, siz
233233
return s;
234234
}
235235

236-
static int load_ladspa_plugin(struct plugin *impl, const char *path)
236+
static void make_search_paths(const char **path, const char **search_dirs)
237237
{
238-
int res = -ENOENT;
238+
const char *p;
239+
240+
while ((p = strstr(*path, "../")) != NULL)
241+
*path = p + 3;
239242

240-
if (path[0] != '/') {
241-
const char *search_dirs, *p, *state = NULL;
242-
char filename[PATH_MAX];
243-
size_t len;
243+
*search_dirs = getenv("LADSPA_PATH");
244+
if (!*search_dirs)
245+
*search_dirs = "/usr/lib64/ladspa:/usr/lib/ladspa:" LIBDIR;
246+
}
244247

245-
search_dirs = getenv("LADSPA_PATH");
246-
if (!search_dirs)
247-
search_dirs = "/usr/lib64/ladspa:/usr/lib/ladspa:" LIBDIR;
248+
static int load_ladspa_plugin(struct plugin *impl, const char *path, const char *search_dirs)
249+
{
250+
int res = -ENOENT;
251+
const char *p, *state = NULL;
252+
char filename[PATH_MAX];
253+
size_t len;
248254

249-
/*
250-
* set the errno for the case when `ladspa_handle_load_by_path()`
251-
* is never called, which can only happen if the supplied
252-
* LADSPA_PATH contains too long paths
253-
*/
254-
res = -ENAMETOOLONG;
255+
/*
256+
* set the errno for the case when `ladspa_handle_load_by_path()`
257+
* is never called, which can only happen if the supplied
258+
* LADSPA_PATH contains too long paths
259+
*/
260+
res = -ENAMETOOLONG;
255261

256-
while ((p = split_walk(search_dirs, ":", &len, &state))) {
257-
int namelen;
262+
while ((p = split_walk(search_dirs, ":", &len, &state))) {
263+
int namelen;
258264

259-
if (len >= sizeof(filename))
260-
continue;
265+
if (len >= sizeof(filename))
266+
continue;
261267

268+
if (strncmp(path, p, len) == 0)
269+
namelen = snprintf(filename, sizeof(filename), "%s", path);
270+
else
262271
namelen = snprintf(filename, sizeof(filename), "%.*s/%s.so", (int) len, p, path);
263-
if (namelen < 0 || (size_t) namelen >= sizeof(filename))
264-
continue;
265272

266-
res = ladspa_handle_load_by_path(impl, filename);
267-
if (res >= 0)
268-
break;
269-
}
270-
}
271-
else {
272-
res = ladspa_handle_load_by_path(impl, path);
273+
if (namelen < 0 || (size_t) namelen >= sizeof(filename))
274+
continue;
275+
276+
res = ladspa_handle_load_by_path(impl, filename);
277+
if (res >= 0)
278+
break;
273279
}
274280
return res;
275281
}
@@ -317,7 +323,7 @@ impl_init(const struct spa_handle_factory *factory,
317323
struct plugin *impl;
318324
uint32_t i;
319325
int res;
320-
const char *path = NULL;
326+
const char *path = NULL, *search_dirs;
321327

322328
handle->get_interface = impl_get_interface;
323329
handle->clear = impl_clear;
@@ -335,9 +341,11 @@ impl_init(const struct spa_handle_factory *factory,
335341
if (path == NULL)
336342
return -EINVAL;
337343

338-
if ((res = load_ladspa_plugin(impl, path)) < 0) {
339-
spa_log_error(impl->log, "failed to load plugin '%s': %s",
340-
path, spa_strerror(res));
344+
make_search_paths(&path, &search_dirs);
345+
346+
if ((res = load_ladspa_plugin(impl, path, search_dirs)) < 0) {
347+
spa_log_error(impl->log, "failed to load plugin '%s' in '%s': %s",
348+
path, search_dirs, spa_strerror(res));
341349
return res;
342350
}
343351

‎src/daemon/filter-chain/source-rnnoise.conf‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ context.modules = [
2121
# listed in the environment variable LADSPA_PATH or
2222
# /usr/lib64/ladspa, /usr/lib/ladspa or the system library directory
2323
# as a fallback.
24-
# You might want to use an absolute path here to avoid problems.
2524
plugin = "librnnoise_ladspa"
2625
label = noise_suppressor_stereo
2726
control = {

‎src/modules/module-filter-chain.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ extern struct spa_handle_factory spa_filter_graph_factory;
128128
* # an example ladspa plugin
129129
* type = ladspa
130130
* name = pitch
131-
* plugin = "/usr/lib64/ladspa/ladspa-rubberband.so"
131+
* plugin = "ladspa-rubberband"
132132
* label = "rubberband-r3-pitchshifter-mono"
133133
* control = {
134134
* # controls are using the ladspa port names as seen in analyseplugin

‎src/modules/module-jack-tunnel.c‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@
5050
*
5151
* - `jack.library`: the libjack to load, by default libjack.so.0 is searched in
5252
* LIBJACK_PATH directories and then some standard library paths.
53-
* Can be an absolute path.
5453
* - `jack.server`: the name of the JACK server to tunnel to.
5554
* - `jack.client-name`: the name of the JACK client.
5655
* - `jack.connect`: if jack ports should be connected automatically. Can also be

‎src/modules/module-jack-tunnel/weakjack.h‎

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -158,34 +158,36 @@ static inline int weakjack_load_by_path(struct weakjack *jack, const char *path)
158158
static inline int weakjack_load(struct weakjack *jack, const char *lib)
159159
{
160160
int res = -ENOENT;
161+
const char *search_dirs, *p, *state = NULL;
162+
char path[PATH_MAX];
163+
size_t len;
161164

162-
if (lib[0] != '/') {
163-
const char *search_dirs, *p, *state = NULL;
164-
char path[PATH_MAX];
165-
size_t len;
165+
while ((p = strstr(lib, "../")) != NULL)
166+
lib = p + 3;
166167

167-
search_dirs = getenv("LIBJACK_PATH");
168-
if (!search_dirs)
169-
search_dirs = PREFIX "/lib64/:" PREFIX "/lib/:"
170-
"/usr/lib64/:/usr/lib/:" LIBDIR;
168+
search_dirs = getenv("LIBJACK_PATH");
169+
if (!search_dirs)
170+
search_dirs = PREFIX "/lib64/:" PREFIX "/lib/:"
171+
"/usr/lib64/:/usr/lib/:" LIBDIR;
171172

172-
while ((p = pw_split_walk(search_dirs, ":", &len, &state))) {
173-
int pathlen;
173+
res = -ENAMETOOLONG;
174174

175-
if (len >= sizeof(path)) {
176-
res = -ENAMETOOLONG;
177-
continue;
178-
}
175+
while ((p = pw_split_walk(search_dirs, ":", &len, &state))) {
176+
int pathlen;
177+
178+
if (len >= sizeof(path))
179+
continue;
180+
181+
if (strncmp(lib, p, len) == 0)
182+
pathlen = snprintf(path, sizeof(path), "%s", lib);
183+
else
179184
pathlen = snprintf(path, sizeof(path), "%.*s/%s", (int) len, p, lib);
180-
if (pathlen < 0 || (size_t) pathlen >= sizeof(path)) {
181-
res = -ENAMETOOLONG;
182-
continue;
183-
}
184-
if ((res = weakjack_load_by_path(jack, path)) == 0)
185-
break;
186-
}
187-
} else {
188-
res = weakjack_load_by_path(jack, lib);
185+
186+
if (pathlen < 0 || (size_t) pathlen >= sizeof(path))
187+
continue;
188+
189+
if ((res = weakjack_load_by_path(jack, path)) == 0)
190+
break;
189191
}
190192
return res;
191193
}

‎src/pipewire/impl-module.c‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,9 @@ pw_context_load_module(struct pw_context *context,
154154
NULL
155155
};
156156

157+
while ((p = strstr(name, "../")) != NULL)
158+
name = p + 3;
159+
157160
pw_log_info("%p: name:%s args:%s", context, name, args);
158161

159162
module_dir = getenv("PIPEWIRE_MODULE_DIR");

‎src/pipewire/pipewire.c‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,9 @@ static struct spa_handle *load_spa_handle(const char *lib,
232232
if (lib == NULL)
233233
lib = sup->support_lib;
234234

235+
while ((p = strstr(lib, "../")) != NULL)
236+
lib = p + 3;
237+
235238
pw_log_debug("load lib:'%s' factory-name:'%s'", lib, factory_name);
236239

237240
plugin = NULL;

0 commit comments

Comments
 (0)