11 Commits
Author SHA1 Message Date
Ikey Doherty be3023263f Bump version to 0.5 for release
Signed-off-by: Ikey Doherty <ikey@solus-project.com>
2017-10-12 02:56:27 +01:00
Ikey Doherty 27e5cd0ae0 intercept: Ensure openAL isn't replaced with broken vendor libraries
We often see cases where the vendored openAL library is incapable of HRTF
due to some old or broken openAL version/build, so let's stop games doing
that with the vendor_offender mode.

Signed-off-by: Ikey Doherty <ikey@solus-project.com>
2017-10-12 02:53:50 +01:00
Ikey Doherty 79fece840c intercept: Actually really blacklist it. Like seriously
Signed-off-by: Ikey Doherty <ikey@solus-project.com>
2017-10-12 02:46:05 +01:00
Ikey Doherty 478a0f1810 intercept: Hit Black Mesa with a really, really big hammer.
Signed-off-by: Ikey Doherty <ikey@solus-project.com>
2017-10-12 02:27:34 +01:00
Ikey Doherty 2cf5db42b3 intercept: Use private file exists function to strip nica API from exposed ABI
Signed-off-by: Ikey Doherty <ikey@solus-project.com>
2017-10-12 02:20:38 +01:00
Ikey Doherty 191ea02946 intercept: Remove much in the way of symbol visibility issues
Signed-off-by: Ikey Doherty <ikey@solus-project.com>
2017-10-12 02:19:46 +01:00
Ikey Doherty 03dd537574 intercept: Prevent "Black Mesa" from using vendored libstdc++/libSDL
Signed-off-by: Ikey Doherty <ikey@solus-project.com>
2017-10-12 02:06:35 +01:00
Ikey Doherty 8ded405801 intercept: Decouple hardcoding from the Steam logic
This allows us to match process names to work modes, so that we'll take one
path for Steam, and allow another path completely for "vendor offenders".

Signed-off-by: Ikey Doherty <ikey@solus-project.com>
2017-10-12 01:57:45 +01:00
Ikey Doherty 35b3f132fd intercept: Use globally defined tables to make it easier to extend
Signed-off-by: Ikey Doherty <ikey@solus-project.com>
2017-10-12 01:47:54 +01:00
Ikey Doherty 4b718a4bc7 shim: Always respect steam-binary option
This resolves issue #13, but requires the packagers are explicit in setting
the steam path.

Signed-off-by: Ikey Doherty <ikey@solus-project.com>
2017-10-11 21:01:01 +01:00
Ikey Doherty 5ceacb27fb Post-update mkrelease script
Signed-off-by: Ikey Doherty <ikey@solus-project.com>
2017-10-11 16:26:55 +01:00
5 changed files with 185 additions and 84 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
project(
'linux-steam-integration',
['c'],
version: '0.4.1',
version: '0.5',
license: [
'LGPL-2.1',
],
+1 -1
View File
@@ -5,7 +5,7 @@ git submodule init
git submodule update
# Script for ikey because he went with meson. *shrug*
VERSION="0.4"
VERSION="0.5"
NAME="linux-steam-integration"
git-archive-all.sh --format tar --prefix ${NAME}-${VERSION}/ --verbose -t HEAD ${NAME}-${VERSION}.tar
xz -9 "${NAME}-${VERSION}.tar"
+165 -77
View File
@@ -14,16 +14,101 @@
#include <link.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include "../common.h"
#include "nica/nica.h"
#include "nica/util.h"
static inline bool lsi_file_exists(const char *path)
{
struct stat st = { .st_ino = 0 };
return (lstat(path, &st) == 0);
}
/**
* Is this a process we're actually interested in?
* What's the known process name?
*/
static bool process_supported = false;
static const char *matched_process = NULL;
/**
* We support a number of modes, but we mostly exist to make Steam behave
*/
typedef enum {
INTERCEPT_MODE_NONE = 0,
INTERCEPT_MODE_STEAM,
INTERCEPT_MODE_VENDOR_OFFENDER,
} InterceptMode;
/**
* by default, we're not "on"
*/
static InterceptMode work_mode = INTERCEPT_MODE_NONE;
/* Patterns we'll permit Steam to privately load */
static const char *steam_allowed[] = {
/* general */
"libicui18n.so",
"libicuuc.so",
"libavcodec.so.",
"libavformat.so.",
"libavresample.so.",
"libavutil.so.",
"libswscale.so.",
/* core plugins */
"chromehtml.so",
"crashhandler.so",
"filesystem_stdio.so",
"friendsui.so",
"gameoverlayrenderer.so",
"gameoverlayui.so",
"libaudio.so",
"libmiles.so",
"libopenvr_api.so",
"liboverride.so",
"libsteam.so",
"libtier0_s.so",
"libv8.so",
"libvideo.so",
"libvstdlib_s.so",
"serverbrowser.so",
"steamclient.so",
"steamoverlayvulkanlayer.so",
"steamservice.so",
"steamui.so",
"vgui2_s.so",
/* big picture mode */
"panorama",
"libpangoft2-1.0.so",
"libpango-1.0.so",
/* steamwebhelper */
"libcef.so",
};
static const char *wanted_steam_processes[] = {
"html5app_steam",
"opengl-program",
"steam",
"steamwebhelper",
};
/**
* Vendor offendors should not be allowed to load replacements for libraries
* that are KNOWN to cause issues, i.e. SDL + libstdc++
*/
static const char *vendor_blacklist[] = {
/* base libraries being replaced will cause a C++ ABI issue when
* loading the mesalib drivers. */
"libgcc_",
"libstdc++",
"libSDL",
/* general problem causer. */
"libopenal.so.",
};
/**
* Determine the basename'd process
*/
@@ -42,27 +127,16 @@ static inline char *get_process_name(void)
}
/**
* Find out if we're being executed by a process we actually need to override,
* otherwise we'd not be loaded by rtld-audit
* Determine if we're in a given process set, i.e. the process name matches
* the given table
*/
static bool is_intercept_candidate(void)
static bool is_in_process_set(char *process_name, const char **processes, size_t n_processes)
{
static const char *wanted_processes[] = {
"html5app_steam",
"opengl-program",
"steam",
"steamwebhelper",
};
autofree(char) *nom = NULL;
nom = get_process_name();
if (!nom) {
return false;
}
for (size_t i = 0; i < ARRAY_SIZE(wanted_processes); i++) {
if (streq(wanted_processes[i], nom)) {
matched_process = wanted_processes[i];
/* Are we some portion of the process set? */
for (size_t i = 0; i < n_processes; i++) {
if (streq(processes[i], process_name)) {
work_mode = INTERCEPT_MODE_STEAM;
matched_process = processes[i];
if (!getenv("LSI_DEBUG")) {
return true;
}
@@ -75,6 +149,27 @@ static bool is_intercept_candidate(void)
return false;
}
/**
* Find out if we're being executed by a process we actually need to override,
* otherwise we'd not be loaded by rtld-audit
*/
static void check_is_intercept_candidate(void)
{
autofree(char) *nom = NULL;
nom = get_process_name();
if (!nom) {
return;
}
if (is_in_process_set(nom, wanted_steam_processes, ARRAY_SIZE(wanted_steam_processes))) {
work_mode = INTERCEPT_MODE_STEAM;
} else {
work_mode = INTERCEPT_MODE_VENDOR_OFFENDER;
matched_process = "vendor_offender";
}
}
/**
* la_version is our main entry point and will only continue if our
* process is explicitly Steam
@@ -82,7 +177,7 @@ static bool is_intercept_candidate(void)
_nica_public_ unsigned int la_version(unsigned int supported_version)
{
/* Unfortunately glibc will die if we tell it to skip us .. */
process_supported = is_intercept_candidate();
check_is_intercept_candidate();
return supported_version;
}
@@ -100,63 +195,12 @@ static void emit_overriden_lib(const char *lib_name)
}
/**
* la_objsearch will allow us to blacklist certain LD_LIBRARY_PATH duplicate
* libraries being loaded by the Steam client, such as the broken libSDL shipped
* as a private vendored lib
* lsi_search_steam handles whitelisting for the main Steam processes
*/
_nica_public_ char *la_objsearch(const char *name, __lsi_unused__ uintptr_t *cookie,
__lsi_unused__ unsigned int flag)
char *lsi_search_steam(const char *name)
{
/* We don't know about this process, so have glibc do its thing as normal */
if (!process_supported) {
return (char *)name;
}
/* Patterns we'll permit Steam to privately load */
static const char *steam_allowed[] = {
/* general */
"libicui18n.so",
"libicuuc.so",
"libavcodec.so.",
"libavformat.so.",
"libavresample.so.",
"libavutil.so.",
"libswscale.so.",
/* core plugins */
"chromehtml.so",
"crashhandler.so",
"filesystem_stdio.so",
"friendsui.so",
"gameoverlayrenderer.so",
"gameoverlayui.so",
"libaudio.so",
"libmiles.so",
"libopenvr_api.so",
"liboverride.so",
"libsteam.so",
"libtier0_s.so",
"libv8.so",
"libvideo.so",
"libvstdlib_s.so",
"serverbrowser.so",
"steamclient.so",
"steamoverlayvulkanlayer.so",
"steamservice.so",
"steamui.so",
"vgui2_s.so",
/* big picture mode */
"panorama",
"libpangoft2-1.0.so",
"libpango-1.0.so",
/* steamwebhelper */
"libcef.so",
};
/* Find out if it exists */
bool file_exists = nc_file_exists(name);
bool file_exists = lsi_file_exists(name);
/* Find out if its a Steam private lib.. These are relative "./" files too! */
if (name && (strstr(name, "/Steam/") || strncmp(name, "./", 2) == 0)) {
@@ -176,6 +220,50 @@ _nica_public_ char *la_objsearch(const char *name, __lsi_unused__ uintptr_t *coo
return (char *)name;
}
char *lsi_blacklist_vendor(const char *name)
{
/* Find out if it exists */
bool file_exists = lsi_file_exists(name);
/* 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++) {
if (!strstr(name, vendor_blacklist[i])) {
continue;
}
/* If LSI_DEBUG is set, spam it. */
if (getenv("LSI_DEBUG") && file_exists) {
emit_overriden_lib(name);
}
return NULL;
}
/* Allowed to exist */
return (char *)name;
}
return (char *)name;
}
/**
* la_objsearch will allow us to blacklist certain LD_LIBRARY_PATH duplicate
* libraries being loaded by the Steam client, such as the broken libSDL shipped
* as a private vendored lib
*/
_nica_public_ char *la_objsearch(const char *name, __lsi_unused__ uintptr_t *cookie,
__lsi_unused__ unsigned int flag)
{
switch (work_mode) {
case INTERCEPT_MODE_STEAM:
return lsi_search_steam(name);
case INTERCEPT_MODE_VENDOR_OFFENDER:
return lsi_blacklist_vendor(name);
case INTERCEPT_MODE_NONE:
default:
return (char *)name;
}
}
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*
+17 -1
View File
@@ -6,10 +6,26 @@ if with_libintercept == true
'main.c',
]
nica_build = static_library(
'nica',
sources: nica_sources,
include_directories: nica_includes,
)
link_nica = declare_dependency(
link_with: nica_build,
include_directories: nica_includes,
)
main_intercept = shared_library(
'lsi-intercept',
sources: intercept_sources + nica_sources,
sources: intercept_sources,
c_args: ['-fvisibility=hidden'],
include_directories: nica_includes,
dependencies: [
link_nica,
],
install: true,
)
endif
+1 -4
View File
@@ -44,11 +44,8 @@ int main(int argc, char **argv)
int8_t off = 0;
int (*vfunc)(const char *, char *const argv[]) = NULL;
#ifdef REPLACE_STEAM
lsi_exec_bin = STEAM_BINARY;
#else
lsi_exec_bin = "/usr/bin/steam";
#endif
/* Initialise config */
if (!lsi_config_load(&config)) {
lsi_config_load_defaults(&config);