From a3692f66a0fcceafac6d167c91883ecffc5ad13c Mon Sep 17 00:00:00 2001 From: Ryan O'Hara Date: Thu, 17 Sep 2020 10:39:30 -0500 Subject: [PATCH] Fix build for late loading of libgcc_s --- ...karound-for-late-loading-of-libgcc_s.patch | 98 +++++++++++++++++++ haproxy.spec | 8 +- 2 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 0001-BUILD-threads-workaround-for-late-loading-of-libgcc_s.patch diff --git a/0001-BUILD-threads-workaround-for-late-loading-of-libgcc_s.patch b/0001-BUILD-threads-workaround-for-late-loading-of-libgcc_s.patch new file mode 100644 index 0000000..ad04b2f --- /dev/null +++ b/0001-BUILD-threads-workaround-for-late-loading-of-libgcc_s.patch @@ -0,0 +1,98 @@ +From 10c627ab2ebeb0a38ae8df477a5f2d870ad77f7c Mon Sep 17 00:00:00 2001 +From: Willy Tarreau +Date: Wed, 9 Sep 2020 17:07:54 +0200 +Subject: [PATCH 1/2] BUILD: threads: better workaround for late loading of + libgcc_s + +Commit 77b98220e ("BUG/MINOR: threads: work around a libgcc_s issue with +chrooting") tried to address an issue with libgcc_s being loaded too late. +But it turns out that the symbol used there isn't present on armhf, thus +it breaks the build. + +Given that the issue manifests itself during pthread_exit(), the safest +and most portable way to test this is to call pthread_exit(). For this +we create a dummy thread which exits, during the early boot. This results +in the relevant library to be loaded if needed, making sure that a later +call to pthread_exit() will still work. It was tested to work fine under +linux on the following platforms: + + glibc: + - armhf + - aarch64 + - x86_64 + - sparc64 + - ppc64le + + musl: + - mipsel + +Just running the code under strace easily shows the call in the dummy +thread, for example here on armhf: + + $ strace -fe trace=file ./haproxy -v 2>&1 | grep gcc_s + [pid 23055] open("/lib/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 3 + +The code was isolated so that it's easy to #ifdef it out if needed. +This should be backported where the patch above is backported (likely +2.0). + +(cherry picked from commit f734ebfac4c406f245347527bd0e5831a251cc61) +Signed-off-by: Willy Tarreau +--- + src/thread.c | 33 ++++++++++++++++++++++----------- + 1 file changed, 22 insertions(+), 11 deletions(-) + +diff --git a/src/thread.c b/src/thread.c +index 5eb68e33a..eeb0e04f4 100644 +--- a/src/thread.c ++++ b/src/thread.c +@@ -189,6 +189,27 @@ static int thread_cpus_enabled() + return ret; + } + ++/* Depending on the platform and how libpthread was built, pthread_exit() may ++ * involve some code in libgcc_s that would be loaded on exit for the first ++ * time, causing aborts if the process is chrooted. It's harmless bit very ++ * dirty. There isn't much we can do to make sure libgcc_s is loaded only if ++ * needed, so what we do here is that during early boot we create a dummy ++ * thread that immediately exits. This will lead to libgcc_s being loaded ++ * during boot on the platforms where it's required. ++ */ ++static void *dummy_thread_function(void *data) ++{ ++ pthread_exit(NULL); ++ return NULL; ++} ++ ++static inline void preload_libgcc_s(void) ++{ ++ pthread_t dummy_thread; ++ pthread_create(&dummy_thread, NULL, dummy_thread_function, NULL); ++ pthread_join(dummy_thread, NULL); ++} ++ + __attribute__((constructor)) + static void __thread_init(void) + { +@@ -201,17 +222,7 @@ static void __thread_init(void) + exit(1); + } + +-#if defined(__GNUC__) && (__GNUC__ >= 3) && defined(__GNU_LIBRARY__) && !defined(__clang__) +- /* make sure libgcc_s is already loaded, because pthread_exit() may +- * may need it on exit after the chroot! _Unwind_Find_FDE() is defined +- * there since gcc 3.0, has no side effect, doesn't take any argument +- * and seems to be present on all supported platforms. +- */ +- { +- extern void _Unwind_Find_FDE(void); +- _Unwind_Find_FDE(); +- } +-#endif ++ preload_libgcc_s(); + + thread_cpus_enabled_at_boot = thread_cpus_enabled(); + +-- +2.26.2 + diff --git a/haproxy.spec b/haproxy.spec index 228f5df..430cef9 100644 --- a/haproxy.spec +++ b/haproxy.spec @@ -8,7 +8,7 @@ Name: haproxy Version: 2.2.3 -Release: 1%{?dist} +Release: 2%{?dist} Summary: HAProxy reverse proxy for high availability environments License: GPLv2+ @@ -21,6 +21,8 @@ Source3: %{name}.logrotate Source4: %{name}.sysconfig Source5: halog.1 +Patch0: 0001-BUILD-threads-workaround-for-late-loading-of-libgcc_s.patch + BuildRequires: gcc BuildRequires: lua-devel BuildRequires: pcre2-devel @@ -48,6 +50,7 @@ availability environments. Indeed, it can: %prep %setup -q +%patch0 -p1 %build regparm_opts= @@ -132,6 +135,9 @@ exit 0 %{_mandir}/man1/* %changelog +* Thu Sep 16 2020 Ryan O'Hara - 2.2.3-2 +- Fix build for late loading of libgcc_s + * Mon Sep 14 2020 Ryan O'Hara - 2.2.3-1 - Update to 2.2.3 (#1876932)