intercept: Blacklist vendoring libmpg123/libz/libfreetype

Discovered while validating 'Overlord II', these libraries should be
provided by the LSI integrator, especially at such a low level in the
stack (and mpg123 being security sensitive.)

Additionally these files are relative to the CWD so got missed by the
previous "./" grouping, thus we'll conditionally replace these guys
with the host libraries per the blacklist only.

Signed-off-by: Ikey Doherty <ikey@solus-project.com>
This commit is contained in:
Ikey Doherty
2017-11-08 01:40:46 +00:00
parent ce3cab3270
commit 3eeb731224
+85 -24
View File
@@ -108,6 +108,11 @@ static const char *vendor_blacklist[] = {
"libstdc++",
"libSDL",
/* vendor-owned */
"libz.so.1",
"libfreetype.so.6",
"libmpg123.so.0",
/* general problem causer. */
"libopenal.so.",
@@ -133,6 +138,8 @@ static const char *vendor_blacklist[] = {
"libcrypto.so.1.0.0",
"libssl.so.1.0.0",
#endif
/* TODO/FUTURE:
"libaudiofile.so.1", */
};
/**
@@ -357,15 +364,10 @@ static bool lsi_override_x86_derp(__lsi_unused__ const char *orig_name,
}
/**
* lsi_override_dlopen is used to override simple dlopen() requests typically
* used by Mono games, i.e.:
*
* <dllmap dll="SDL2.dll" os="linux" cpu="x86-64" target="./lib64/libSDL2-2.0.so.0"/>
*
* We'll attempt to do a trivial lookup for "/usr/./lib64/libSDL2-2.0.so.0 in this
* case.
* Internal helper for path replacement to host lib
*/
static bool lsi_override_dlopen(const char *orig_name, const char **soname)
static bool lsi_override_replace_with_host(const char *orig_name, const char **soname,
const char *msg)
{
static char path_lookup[PATH_MAX];
static char path_copy[PATH_MAX];
@@ -382,18 +384,6 @@ static bool lsi_override_dlopen(const char *orig_name, const char **soname)
#endif
};
if (lsi_override_dll_fail(orig_name, soname)) {
return true;
}
if (!lsi_file_exists(orig_name)) {
return false;
}
if (lsi_override_x86_derp(orig_name, soname)) {
return true;
}
if (!strcpy(path_copy, orig_name)) {
return false;
}
@@ -422,16 +412,42 @@ static bool lsi_override_dlopen(const char *orig_name, const char **soname)
}
*soname = path_lookup;
lsi_log_debug(
"intercepting vendor dlopen() \033[31;1m%s\033[0m -> \033[34;1m%s\033[0m",
orig_name,
path_lookup);
lsi_log_debug("%s \033[31;1m%s\033[0m -> \033[34;1m%s\033[0m",
msg,
orig_name,
path_lookup);
return true;
}
return false;
}
/**
* lsi_override_dlopen is used to override simple dlopen() requests typically
* used by Mono games, i.e.:
*
* <dllmap dll="SDL2.dll" os="linux" cpu="x86-64" target="./lib64/libSDL2-2.0.so.0"/>
*
* We'll attempt to do a trivial lookup for "/usr/./lib64/libSDL2-2.0.so.0 in this
* case.
*/
static bool lsi_override_dlopen(const char *orig_name, const char **soname)
{
if (lsi_override_dll_fail(orig_name, soname)) {
return true;
}
if (!lsi_file_exists(orig_name)) {
return false;
}
if (lsi_override_x86_derp(orig_name, soname)) {
return true;
}
return lsi_override_replace_with_host(orig_name, soname, "intercepting vendor dlopen()");
}
/**
* lsi_override_soname will deal with LA_SER_ORIG entries, i.e. the original
* soname request when the linker tries to load a library.
@@ -480,6 +496,46 @@ static bool lsi_override_soname(unsigned int flag, const char *orig_name, const
return false;
}
/**
* If the library exists locally, and we're attempting to load this from a
* relative location, strongly attempt to actually use the system-version instead.
*
* Thus, if our CWD is our LD_LIBRARY_PATH and contains "libfreetype.so.6", we'll
* try to use the host version of the library if that exists, instead of relying
* on the locally vendored, potentially insecure/buggy version.
*/
static bool lsi_override_local(unsigned int flag, const char *orig_name, const char **soname)
{
*soname = NULL;
/* We only need to deal with LA_SER_ORIG */
if ((flag & LA_SER_ORIG) != LA_SER_ORIG) {
return false;
}
/* We only care about relative paths */
if (strstr(orig_name, "/")) {
return false;
}
/* We also only care about relative paths */
if (!lsi_file_exists(orig_name)) {
return false;
}
/* Resolve all paths back to the real library path version if they exist */
for (size_t i = 0; i < ARRAY_SIZE(vendor_blacklist); i++) {
if (!strstr(orig_name, vendor_blacklist[i])) {
continue;
}
return lsi_override_replace_with_host(orig_name,
soname,
"forcing use of host library");
}
return false;
}
char *lsi_blacklist_vendor(unsigned int flag, const char *name)
{
/* Find out if it exists */
@@ -491,6 +547,11 @@ char *lsi_blacklist_vendor(unsigned int flag, const char *name)
return (char *)override_soname;
}
/* Locally exists due to directory foobar */
if (lsi_override_local(flag, name, &override_soname)) {
return (char *)override_soname;
}
/* Find out if its a Steam private lib.. These are relative "./" files too! */
if (name && (strstr(name, "/Steam/") || strncmp(name, "./", 2) == 0)) {
for (size_t i = 0; i < ARRAY_SIZE(vendor_blacklist); i++) {