From e75161b312641af326a897bdfbd627ffc18a594d Mon Sep 17 00:00:00 2001 From: aszlig Date: Tue, 15 Aug 2023 10:27:42 +0200 Subject: [PATCH] Revert "Use dlopen on libc instead of RTLD_NEXT" This reverts commit f47125c0513ecc484c8f537e9f496d601c3ec7b4. The commit in question directly used the C library instead of RTLD_NEXT whenever possible, based on some deadlock I didn't specify further in the commit message. I could not reproduce a deadlock like this and given that we don't have a test case that fails with RTLD_NEXT tells me that it doesn't matter. In addition to just reverting, I also added a small test case that I used in order to try reproducing the aforementioned issue. Even though I couldn't reproduce the issue, I'm adding the test anyway since we didn't have a test case where we use multiple LD_PRELOAD wrappers that operate on the same set of calls as ip2unix. Signed-off-by: aszlig --- CHANGELOG.md | 1 + flake.nix | 1 + meson.build | 8 ------ scripts/findlibc.py | 8 ------ src/realcalls.cc | 31 -------------------- src/realcalls.hh | 19 +------------ tests/programs/multiple-preload.nix | 44 +++++++++++++++++++++++++++++ 7 files changed, 47 insertions(+), 65 deletions(-) delete mode 100644 scripts/findlibc.py create mode 100644 tests/programs/multiple-preload.nix diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a0fdf0..a66d347 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ The format is based on [Keep a Changelog], and this project adheres to ### Removed - Badges (eg. LGTM and build status) in README and Hydra. +- No longer prefer C library path over `RTLD_NEXT`. ## [2.1.4] - 2021-07-10 diff --git a/flake.nix b/flake.nix index 9ed3f98..2eb86ef 100644 --- a/flake.nix +++ b/flake.nix @@ -360,6 +360,7 @@ in lib.mapAttrs (lib.const (lib.mapAttrs mkProgramTest)) { mariadb-php-abstract.x86_64-linux = tests/programs/mariadb-php-abstract.nix; + multiple-preload.x86_64-linux = tests/programs/multiple-preload.nix; rsession.x86_64-linux = tests/programs/rsession.nix; }; diff --git a/meson.build b/meson.build index bf28827..a1ae020 100644 --- a/meson.build +++ b/meson.build @@ -2,7 +2,6 @@ project('ip2unix', 'cpp', default_options: ['cpp_std=c++17', 'warning_level=3'], meson_version: '>=0.47.0', version: '2.1.4') -script_findlibc = files('scripts/findlibc.py') script_generrno = files('scripts/generrno.py') script_genoffsets = files('scripts/genoffsets.py') script_gensyms = files('scripts/gensyms.py') @@ -55,13 +54,6 @@ deps = [ cc.find_library('dl') ] -libcpath = run_command(python, script_findlibc, cc.cmd_array(), check: false) -if libcpath.returncode() == 0 - fullpath = libcpath.stdout() - message('Found C library at ' + fullpath) - lib_cflags += ['-DLIBC_PATH="' + fullpath + '"'] -endif - systemd_enabled = get_option('systemd-support') if systemd_enabled diff --git a/scripts/findlibc.py b/scripts/findlibc.py deleted file mode 100644 index 854d9bb..0000000 --- a/scripts/findlibc.py +++ /dev/null @@ -1,8 +0,0 @@ -import os -import sys -import subprocess - -cmd = sys.argv[1:] + ['--print-file-name=libc.so.6'] -path = subprocess.check_output(cmd).strip() -assert os.path.exists(path) -sys.stdout.buffer.write(path) diff --git a/src/realcalls.cc b/src/realcalls.cc index ba61478..3a9957b 100644 --- a/src/realcalls.cc +++ b/src/realcalls.cc @@ -2,35 +2,4 @@ #define IP2UNIX_REALCALL_EXTERN #include "realcalls.hh" -#include -#include -#include - std::mutex g_dlsym_mutex; - -DlsymHandle dlsym_handle; - -DlsymHandle::DlsymHandle() : handle(nullptr) -{ - std::scoped_lock lock(g_dlsym_mutex); - - for (const char *libname : { -#ifdef LIBC_PATH - LIBC_PATH, -#endif - "libc.so.6" - }) { - this->handle = dlopen(libname, RTLD_LAZY | RTLD_DEEPBIND); - if (this->handle != nullptr) return; - } - - this->handle = RTLD_NEXT; -} - -DlsymHandle::~DlsymHandle() -{ - std::scoped_lock lock(g_dlsym_mutex); - - if (this->handle != RTLD_NEXT) - dlclose(this->handle); -} diff --git a/src/realcalls.hh b/src/realcalls.hh index e4797d3..92d8dfd 100644 --- a/src/realcalls.hh +++ b/src/realcalls.hh @@ -24,24 +24,7 @@ #define IP2UNIX_REALCALL_EXTERN extern #endif -struct DlsymHandle -{ - DlsymHandle(); - ~DlsymHandle(); - - inline void *get(void) const { - return this->handle; - } - - private: - DlsymHandle(const DlsymHandle&) = delete; - DlsymHandle &operator=(const DlsymHandle&) = delete; - - void *handle; -}; - extern std::mutex g_dlsym_mutex; -extern DlsymHandle dlsym_handle; /* This namespace is here so that we can autogenerate and call wrappers for C * library functions in a convenient way. For example to call the wrapper for @@ -58,7 +41,7 @@ namespace real { { g_dlsym_mutex.lock(); if (this->fptr == nullptr) { - void *result = dlsym(dlsym_handle.get(), Self::fname); + void *result = dlsym(RTLD_NEXT, Self::fname); if (result == nullptr) { LOG(FATAL) << "Loading of symbol '" << Self::fname << "' failed: " << strerror(errno); diff --git a/tests/programs/multiple-preload.nix b/tests/programs/multiple-preload.nix new file mode 100644 index 0000000..883f4c1 --- /dev/null +++ b/tests/programs/multiple-preload.nix @@ -0,0 +1,44 @@ +{ pkgs, ip2unix, ... }: + +pkgs.runCommand "multiple-preload" { + TSOCKS_DEBUG = 10; + TSOCKS_CONF_FILE = pkgs.writeText "tsocks.conf" '' + server = 127.0.0.2 + ''; + + nativeBuildInputs = [ + ip2unix + pkgs.tsocks + pkgs.netcat-openbsd + + (pkgs.writeScriptBin "socksd" '' + #!${(pkgs.python3.withPackages (p: [ p.tiny-proxy ])).interpreter} + import anyio + from tiny_proxy import Socks4ProxyHandler + + async def main(): + handler = Socks4ProxyHandler() + listener = await anyio.create_tcp_listener() + await listener.serve(handler.handle) + + anyio.run(main) + '') + + (pkgs.writeScriptBin "testprog" '' + #!${pkgs.python3.interpreter} + import socket + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: + sock.connect(('1.2.3.4', 1234)) + assert sock.recv(3) == b'foo' + '') + ]; +} '' + echo foo | nc -N -lU foo.sock & + while [ ! -e foo.sock ]; do sleep 1; done + + ip2unix -r in,path=bar.sock -r out,path=foo.sock socksd & + while [ ! -e bar.sock ]; do sleep 1; done + + ip2unix -vvvvv -r out,addr=127.0.0.2,path=bar.sock tsocks testprog + touch "$out" +''