only dlopen from the defined search paths

Don't accept absolute library paths and skip the ../ in paths to avoid
opening arbitrary libraries from unexpected places.
This commit is contained in:
Wim Taymans 2026-04-06 14:18:22 +02:00
parent ad0bab69a1
commit 8fd7982087
4 changed files with 51 additions and 50 deletions

View file

@ -236,40 +236,37 @@ static inline const char *split_walk(const char *str, const char *delimiter, siz
static int load_ladspa_plugin(struct plugin *impl, const char *path) static int load_ladspa_plugin(struct plugin *impl, const char *path)
{ {
int res = -ENOENT; int res = -ENOENT;
const char *search_dirs, *p, *state = NULL;
char filename[PATH_MAX];
size_t len;
if (path[0] != '/') { while ((p = strstr(path, "../")) != NULL)
const char *search_dirs, *p, *state = NULL; path = p + 3;
char filename[PATH_MAX];
size_t len;
search_dirs = getenv("LADSPA_PATH"); search_dirs = getenv("LADSPA_PATH");
if (!search_dirs) if (!search_dirs)
search_dirs = "/usr/lib64/ladspa:/usr/lib/ladspa:" LIBDIR; search_dirs = "/usr/lib64/ladspa:/usr/lib/ladspa:" LIBDIR;
/* /*
* set the errno for the case when `ladspa_handle_load_by_path()` * set the errno for the case when `ladspa_handle_load_by_path()`
* is never called, which can only happen if the supplied * is never called, which can only happen if the supplied
* LADSPA_PATH contains too long paths * LADSPA_PATH contains too long paths
*/ */
res = -ENAMETOOLONG; res = -ENAMETOOLONG;
while ((p = split_walk(search_dirs, ":", &len, &state))) { while ((p = split_walk(search_dirs, ":", &len, &state))) {
int namelen; int namelen;
if (len >= sizeof(filename)) if (len >= sizeof(filename))
continue; continue;
namelen = snprintf(filename, sizeof(filename), "%.*s/%s.so", (int) len, p, path); namelen = snprintf(filename, sizeof(filename), "%.*s/%s.so", (int) len, p, path);
if (namelen < 0 || (size_t) namelen >= sizeof(filename)) if (namelen < 0 || (size_t) namelen >= sizeof(filename))
continue; continue;
res = ladspa_handle_load_by_path(impl, filename); res = ladspa_handle_load_by_path(impl, filename);
if (res >= 0) if (res >= 0)
break; break;
}
}
else {
res = ladspa_handle_load_by_path(impl, path);
} }
return res; return res;
} }

View file

@ -158,34 +158,32 @@ static inline int weakjack_load_by_path(struct weakjack *jack, const char *path)
static inline int weakjack_load(struct weakjack *jack, const char *lib) static inline int weakjack_load(struct weakjack *jack, const char *lib)
{ {
int res = -ENOENT; int res = -ENOENT;
const char *search_dirs, *p, *state = NULL;
char path[PATH_MAX];
size_t len;
if (lib[0] != '/') { while ((p = strstr(lib, "../")) != NULL)
const char *search_dirs, *p, *state = NULL; lib = p + 3;
char path[PATH_MAX];
size_t len;
search_dirs = getenv("LIBJACK_PATH"); search_dirs = getenv("LIBJACK_PATH");
if (!search_dirs) if (!search_dirs)
search_dirs = PREFIX "/lib64/:" PREFIX "/lib/:" search_dirs = PREFIX "/lib64/:" PREFIX "/lib/:"
"/usr/lib64/:/usr/lib/:" LIBDIR; "/usr/lib64/:/usr/lib/:" LIBDIR;
while ((p = pw_split_walk(search_dirs, ":", &len, &state))) { while ((p = pw_split_walk(search_dirs, ":", &len, &state))) {
int pathlen; int pathlen;
if (len >= sizeof(path)) { if (len >= sizeof(path)) {
res = -ENAMETOOLONG; res = -ENAMETOOLONG;
continue; continue;
}
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 { pathlen = snprintf(path, sizeof(path), "%.*s/%s", (int) len, p, lib);
res = weakjack_load_by_path(jack, lib); if (pathlen < 0 || (size_t) pathlen >= sizeof(path)) {
res = -ENAMETOOLONG;
continue;
}
if ((res = weakjack_load_by_path(jack, path)) == 0)
break;
} }
return res; return res;
} }

View file

@ -154,6 +154,9 @@ pw_context_load_module(struct pw_context *context,
NULL NULL
}; };
while ((p = strstr(name, "../")) != NULL)
name = p + 3;
pw_log_info("%p: name:%s args:%s", context, name, args); pw_log_info("%p: name:%s args:%s", context, name, args);
module_dir = getenv("PIPEWIRE_MODULE_DIR"); module_dir = getenv("PIPEWIRE_MODULE_DIR");

View file

@ -232,6 +232,9 @@ static struct spa_handle *load_spa_handle(const char *lib,
if (lib == NULL) if (lib == NULL)
lib = sup->support_lib; lib = sup->support_lib;
while ((p = strstr(lib, "../")) != NULL)
lib = p + 3;
pw_log_debug("load lib:'%s' factory-name:'%s'", lib, factory_name); pw_log_debug("load lib:'%s' factory-name:'%s'", lib, factory_name);
plugin = NULL; plugin = NULL;