mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-11-03 09:01:52 -05:00
dlsym: fix the race when snd_libdir_origin is freed
snd_dlobj_cache_cleanup() function frees snd_libdir_origin, but the pointer may be used again in snd_dlpath(). BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1847508 Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
parent
58682bedb6
commit
20e003a63d
1 changed files with 25 additions and 12 deletions
37
src/dlmisc.c
37
src/dlmisc.c
|
|
@ -34,14 +34,21 @@
|
||||||
#endif
|
#endif
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
|
#if defined(HAVE_LIBDL) && defined(__GLIBC__) && !defined(__UCLIBC__)
|
||||||
|
#define DL_ORIGIN_AVAILABLE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef DOC_HIDDEN
|
#ifndef DOC_HIDDEN
|
||||||
#ifndef PIC
|
#ifndef PIC
|
||||||
struct snd_dlsym_link *snd_dlsym_start = NULL;
|
struct snd_dlsym_link *snd_dlsym_start = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef DL_ORIGIN_AVAILABLE
|
||||||
|
static int snd_libdir_plugin_dir_set = 0;
|
||||||
static char *snd_libdir_origin = NULL;
|
static char *snd_libdir_origin = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_LIBPTHREAD
|
#if defined(DL_ORIGIN_AVAILABLE) && defined(HAVE_LIBPTHREAD)
|
||||||
static pthread_mutex_t snd_dlpath_mutex = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t snd_dlpath_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
static inline void snd_dlpath_lock(void)
|
static inline void snd_dlpath_lock(void)
|
||||||
|
|
@ -68,11 +75,9 @@ static inline void snd_dlpath_unlock(void) {}
|
||||||
*/
|
*/
|
||||||
int snd_dlpath(char *path, size_t path_len, const char *name)
|
int snd_dlpath(char *path, size_t path_len, const char *name)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_LIBDL
|
#ifdef DL_ORIGIN_AVAILABLE
|
||||||
#if defined(__GLIBC__) && !defined(__UCLIBC__)
|
|
||||||
static int plugin_dir_set = 0;
|
|
||||||
snd_dlpath_lock();
|
snd_dlpath_lock();
|
||||||
if (!plugin_dir_set) {
|
if (!snd_libdir_plugin_dir_set) {
|
||||||
struct link_map *links;
|
struct link_map *links;
|
||||||
Dl_info info;
|
Dl_info info;
|
||||||
char origin[PATH_MAX];
|
char origin[PATH_MAX];
|
||||||
|
|
@ -83,15 +88,17 @@ int snd_dlpath(char *path, size_t path_len, const char *name)
|
||||||
if (access(path, X_OK) == 0)
|
if (access(path, X_OK) == 0)
|
||||||
snd_libdir_origin = strdup(origin);
|
snd_libdir_origin = strdup(origin);
|
||||||
}
|
}
|
||||||
plugin_dir_set = 1;
|
snd_libdir_plugin_dir_set = 1;
|
||||||
|
}
|
||||||
|
if (snd_libdir_origin) {
|
||||||
|
snprintf(path, path_len, "%s/alsa-lib/%s", snd_libdir_origin, name);
|
||||||
|
} else {
|
||||||
|
snprintf(path, path_len, "%s/%s", ALSA_PLUGIN_DIR, name);
|
||||||
}
|
}
|
||||||
snd_dlpath_unlock();
|
snd_dlpath_unlock();
|
||||||
|
#else
|
||||||
|
snprintf(path, path_len, "%s/%s", ALSA_PLUGIN_DIR, name);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
if (snd_libdir_origin)
|
|
||||||
snprintf(path, path_len, "%s/alsa-lib/%s", snd_libdir_origin, name);
|
|
||||||
else
|
|
||||||
snprintf(path, path_len, "%s/%s", ALSA_PLUGIN_DIR, name);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -440,7 +447,13 @@ void snd_dlobj_cache_cleanup(void)
|
||||||
free((void *)c->lib); /* shut up gcc warning */
|
free((void *)c->lib); /* shut up gcc warning */
|
||||||
free(c);
|
free(c);
|
||||||
}
|
}
|
||||||
free(snd_libdir_origin);
|
|
||||||
snd_dlobj_unlock();
|
snd_dlobj_unlock();
|
||||||
|
#ifdef DL_ORIGIN_AVAILABLE
|
||||||
|
snd_dlpath_lock();
|
||||||
|
snd_libdir_plugin_dir_set = 0;
|
||||||
|
free(snd_libdir_origin);
|
||||||
|
snd_libdir_origin = NULL;
|
||||||
|
snd_dlpath_unlock();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue