diff --git a/src/intercept/intercept.h b/src/intercept/intercept.h new file mode 100644 index 0000000..29ef0ff --- /dev/null +++ b/src/intercept/intercept.h @@ -0,0 +1,41 @@ +/* + * This file is part of linux-steam-integration. + * + * Copyright © 2016-2017 Ikey Doherty + * + * linux-steam-integration is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + */ + +#pragma once + +#include + +/** + * Attempt to handle snapd specific paths and perform any necessary redirections + * for the solus-runtime-gaming based LSI snap package. + * + * @note This must run for all processes, as we handle libGL interception. + * + * @param name Original search name + * @param flag rtld-audit flags + * @param soname Pointer to store the final soname in + * + * @returns True if we performed any redirection, to stop further processing. + */ +bool lsi_override_snapd(const char *name, unsigned int flag, const char **soname); + +/* + * Editor modelines - https://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 8 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=8 tabstop=8 expandtab: + * :indentSize=8:tabSize=8:noTabs=true: + */ diff --git a/src/intercept/main.c b/src/intercept/main.c index 30558a2..577ccf7 100644 --- a/src/intercept/main.c +++ b/src/intercept/main.c @@ -22,6 +22,7 @@ #include "../common/files.h" #include "../common/log.h" #include "config.h" +#include "intercept.h" #include "nica/util.h" /** @@ -582,16 +583,12 @@ _nica_public_ char *la_objsearch(const char *name, __lsi_unused__ uintptr_t *coo unsigned int flag) { #ifdef HAVE_SNAPD_SUPPORT - /* - * Super special case. If we're a snap, and the file being requested is - * actually within the private snapd trees, we must unconditionally permit - * that file, as it is most likely a driver - */ - if (strstr(name, "/var/lib/snapd/gl") || strstr(name, "/var/lib/snapd/hostfs")) { - lsi_log_debug("skipping snapd file: %s", name); - return name; + const char *out_name = NULL; + + /* Only attempt snapd overrides if snapd support is enabled */ + if (lsi_override_snapd(name, flag, &out_name)) { + return (char *)out_name; } - lsi_log_debug("snapd debug: %s", name); #endif switch (work_mode) { case INTERCEPT_MODE_STEAM: diff --git a/src/intercept/meson.build b/src/intercept/meson.build index 8d131d3..2aaa2f5 100644 --- a/src/intercept/meson.build +++ b/src/intercept/meson.build @@ -6,6 +6,10 @@ if with_libintercept == true 'main.c', ] + if with_snap_support == true + intercept_sources += 'snapd.c' + endif + sym_map = join_paths(meson.current_source_dir(), 'sym.map') main_intercept = shared_library( diff --git a/src/intercept/snapd.c b/src/intercept/snapd.c new file mode 100644 index 0000000..2899ac2 --- /dev/null +++ b/src/intercept/snapd.c @@ -0,0 +1,121 @@ +/* + * This file is part of linux-steam-integration. + * + * Copyright © 2016-2017 Ikey Doherty + * + * linux-steam-integration is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + */ + +#define _GNU_SOURCE + +#include +#include +#include + +#include "../common/common.h" +#include "../common/files.h" +#include "../common/log.h" +#include "intercept.h" + +/** + * Contains the exact soname paths that the linker will request + */ +static const char *libgl_source_table[] = { +#if UINTPTR_MAX == 0xffffffffffffffff + "/usr/lib64/libGL.so.1", + "/usr/lib64/libEGL.so.1", + /* Duped due to lib vs lib64 differences between solus + snap */ + "/usr/lib/libGL.so.1", + "/usr/lib/libEGL.so.1", +#else + /* 32bit support */ + "/usr/lib32/libGL.so.1", + "/usr/lib32/libEGL.so.1", +#endif +}; + +/** + * Contains the exact soname paths that we'll return for biarch situations + * + * TODO: Also support Ubuntu/Debian multiarch overlay + */ +static const char *libgl_target_table[] = { +#if UINTPTR_MAX == 0xffffffffffffffff + "/var/lib/snapd/lib/gl/libGL.so.1", + "/var/lib/snapd/lib/gl/libEGL.so.1", + /* Duped due to lib vs lib64 differences between solus + snap */ + "/var/lib/snapd/lib/gl/libGL.so.1", + "/var/lib/snapd/lib/gl/libEGL.so.1", +#else + /* 32bit support */ + "/var/lib/snapd/lib/gl/32/libGL.so.1", + "/var/lib/snapd/lib/gl/32/libEGL.so.1", +#endif +}; + +/** + * If the hostfs provided links don't exist, then we didn't get any links from + * the snapd setup routine, so we'll just repoint back to mesa. + */ +static const char *libgl_mesa_table[] = { +#if UINTPTR_MAX == 0xffffffffffffffff + "/usr/lib64/glx-provider/default/libGL.so.1", + "/usr/lib64/glx-provider/default/libEGL.so.1", + /* Duped due to lib vs lib64 differences between solus + snap */ + "/usr/lib/glx-provider/default/libGL.so.1", + "/usr/lib/glx-provider/default/libEGL.so.1", +#else + /* 32bit support */ + "/usr/lib32/glx-provider/default/libGL.so.1", + "/usr/lib32/glx-provider/default/libEGL.so.1", +#endif +}; + +bool lsi_override_snapd(const char *name, __lsi_unused__ unsigned int flag, const char **soname) +{ + for (size_t i = 0; i < ARRAY_SIZE(libgl_source_table); i++) { + const char *source = libgl_source_table[i]; + const char *target = NULL; + + if (strcmp(name, source) != 0) { + continue; + } + + if (lsi_file_exists(libgl_target_table[i])) { + target = libgl_target_table[i]; + lsi_log_debug( + "Enforcing hostfs snapd driver links: \033[31;1m%s\033[0m -> " + "\033[34;1m%s\033[0m", + name, + target); + } else { + target = libgl_mesa_table[i]; + lsi_log_debug( + "Enforcing Mesa snapd driver links: \033[31;1m%s\033[0m -> " + "\033[34;1m%s\033[0m", + name, + target); + } + *soname = target; + return true; + } + + /* We didn't get a match. Allow to continue */ + return false; +} + +/* + * Editor modelines - https://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 8 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=8 tabstop=8 expandtab: + * :indentSize=8:tabSize=8:noTabs=true: + */