From 52943ce6dcaa19e2924846d2225176375f49b2c8 Mon Sep 17 00:00:00 2001 From: =?utf8?q?R=C3=A9mi=20Denis-Courmont?= Date: Sun, 10 Jan 2010 12:36:55 +0200 Subject: [PATCH] Check plugins directory names for unsupported capability --- src/libvlc.h | 1 + src/misc/cpu.c | 42 ++++++++++++++++++++++++++++++++++++++++++ src/modules/modules.c | 4 +++- 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/libvlc.h b/src/libvlc.h index e60f711940..ced230e343 100644 --- a/src/libvlc.h +++ b/src/libvlc.h @@ -79,6 +79,7 @@ void vlc_assert_locked (vlc_mutex_t *); */ extern uint32_t cpu_flags; uint32_t CPUCapabilities( void ); +bool vlc_CPU_CheckPluginDir (const char *name); /* * Message/logging stuff diff --git a/src/misc/cpu.c b/src/misc/cpu.c index 6c979fd242..d1b9324902 100644 --- a/src/misc/cpu.c +++ b/src/misc/cpu.c @@ -296,6 +296,48 @@ unsigned vlc_CPU (void) return cpu_flags; } +const struct +{ + uint32_t value; + char name[12]; +} cap_dirs[] = { +#if defined ( __i386__ ) || defined ( __x86_64__ ) + { CPU_CAPABILITY_MMX, "mmx" }, + { CPU_CAPABILITY_MMXEXT, "mmxext" }, + { CPU_CAPABILITY_3DNOW, "3dnow" }, + { CPU_CAPABILITY_SSE, "sse" }, +#endif +#if defined (__ppc__) || defined (__ppc64__) || defined (__powerpc__) + { CPU_CAPABILITY_ALTIVEC, "altivec" }, +#endif +#if defined (__arm__) + { CPU_CAPABILITY_NEON, "arm_neon" }, +#endif +}; + +/** + * Check if a directory name contains usable plugins w.r.t. the hardware + * capabilities. Loading a plugin when the hardware has insufficient + * capabilities may lead to illegal instructions (SIGILL) and must be avoided. + * + * @param name the name of the directory (not the path) + * + * @return true if the hardware has sufficient capabilities or the directory + * does not require any special capability; false if the running hardware has + * insufficient capabilities. + */ +bool vlc_CPU_CheckPluginDir (const char *name) +{ + const unsigned flags = vlc_CPU (); + for (size_t i = 0; i < sizeof (cap_dirs) / sizeof (cap_dirs[0]); i++) + { + if (strcmp (name, cap_dirs[i].name)) + continue; + return (flags & cap_dirs[i].value) != 0; + } + return true; +} + static vlc_memcpy_t pf_vlc_memcpy = memcpy; static vlc_memset_t pf_vlc_memset = memset; diff --git a/src/modules/modules.c b/src/modules/modules.c index cdd26307aa..ec4fa311cd 100644 --- a/src/modules/modules.c +++ b/src/modules/modules.c @@ -906,7 +906,9 @@ static void AllocatePluginDir( vlc_object_t *p_this, module_bank_t *p_bank, break; /* Skip ".", ".." */ - if (!strcmp (file, ".") || !strcmp (file, "..")) + if (!strcmp (file, ".") || !strcmp (file, "..") + /* Skip directories for unsupported optimizations */ + || !vlc_CPU_CheckPluginDir (file)) { free (file); continue; -- 2.39.2