summaryrefslogtreecommitdiff
path: root/dlfcn-Do-not-use-rtld_active-to-determine-ld.so-stat.patch
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2024-08-03 06:28:41 +0000
committerCoprDistGit <infra@openeuler.org>2024-08-03 06:28:41 +0000
commitd20db0561a6a36f914fde030512503b114ef9a0c (patch)
treed4e5e3494d95c269a1cee6195f11bf3201bcadbf /dlfcn-Do-not-use-rtld_active-to-determine-ld.so-stat.patch
parent016343d99b1b269d7246ef1e143d4b54914433d4 (diff)
Diffstat (limited to 'dlfcn-Do-not-use-rtld_active-to-determine-ld.so-stat.patch')
-rw-r--r--dlfcn-Do-not-use-rtld_active-to-determine-ld.so-stat.patch400
1 files changed, 400 insertions, 0 deletions
diff --git a/dlfcn-Do-not-use-rtld_active-to-determine-ld.so-stat.patch b/dlfcn-Do-not-use-rtld_active-to-determine-ld.so-stat.patch
new file mode 100644
index 0000000..2a4e89b
--- /dev/null
+++ b/dlfcn-Do-not-use-rtld_active-to-determine-ld.so-stat.patch
@@ -0,0 +1,400 @@
+From 8dcb6d0af07fda3607b541857e4f3970a74ed55b Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Tue, 26 Apr 2022 14:23:02 +0200
+Subject: [PATCH] dlfcn: Do not use rtld_active () to determine ld.so state
+ (bug 29078)
+
+Conflict:adapt Makefile context
+Reference:https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=8dcb6d0af07fda3607b541857e4f3970a74ed55b
+
+When audit modules are loaded, ld.so initialization is not yet
+complete, and rtld_active () returns false even though ld.so is
+mostly working. Instead, the static dlopen hook is used, but that
+does not work at all because this is not a static dlopen situation.
+
+Commit 466c1ea15f461edb8e3ffaf5d86d708876343bbf ("dlfcn: Rework
+static dlopen hooks") moved the hook pointer into _rtld_global_ro,
+which means that separate protection is not needed anymore and the
+hook pointer can be checked directly.
+
+The guard for disabling libio vtable hardening in _IO_vtable_check
+should stay for now.
+
+Fixes commit 8e1472d2c1e25e6eabc2059170731365f6d5b3d1 ("ld.so:
+Examine GLRO to detect inactive loader [BZ #20204]").
+
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+---
+ dlfcn/dladdr.c | 2 +-
+ dlfcn/dladdr1.c | 2 +-
+ dlfcn/dlclose.c | 2 +-
+ dlfcn/dlerror.c | 2 +-
+ dlfcn/dlinfo.c | 2 +-
+ dlfcn/dlmopen.c | 2 +-
+ dlfcn/dlopen.c | 2 +-
+ dlfcn/dlopenold.c | 2 +-
+ dlfcn/dlsym.c | 2 +-
+ dlfcn/dlvsym.c | 2 +-
+ elf/Makefile | 6 +++
+ elf/dl-libc.c | 8 ++--
+ elf/tst-audit26.c | 35 +++++++++++++++
+ elf/tst-auditmod26.c | 104 +++++++++++++++++++++++++++++++++++++++++++
+ 14 files changed, 159 insertions(+), 14 deletions(-)
+ create mode 100644 elf/tst-audit26.c
+ create mode 100644 elf/tst-auditmod26.c
+
+diff --git a/dlfcn/dladdr.c b/dlfcn/dladdr.c
+index ead117326f..d188d0e289 100644
+--- a/dlfcn/dladdr.c
++++ b/dlfcn/dladdr.c
+@@ -24,7 +24,7 @@ int
+ __dladdr (const void *address, Dl_info *info)
+ {
+ #ifdef SHARED
+- if (!rtld_active ())
++ if (GLRO (dl_dlfcn_hook) != NULL)
+ return GLRO (dl_dlfcn_hook)->dladdr (address, info);
+ #endif
+ return _dl_addr (address, info, NULL, NULL);
+diff --git a/dlfcn/dladdr1.c b/dlfcn/dladdr1.c
+index 5dadfd1220..e0c9526c90 100644
+--- a/dlfcn/dladdr1.c
++++ b/dlfcn/dladdr1.c
+@@ -24,7 +24,7 @@ int
+ __dladdr1 (const void *address, Dl_info *info, void **extra, int flags)
+ {
+ #ifdef SHARED
+- if (!rtld_active ())
++ if (GLRO (dl_dlfcn_hook) != NULL)
+ return GLRO (dl_dlfcn_hook)->dladdr1 (address, info, extra, flags);
+ #endif
+
+diff --git a/dlfcn/dlclose.c b/dlfcn/dlclose.c
+index a9921c3169..aab88c47fc 100644
+--- a/dlfcn/dlclose.c
++++ b/dlfcn/dlclose.c
+@@ -24,7 +24,7 @@ int
+ __dlclose (void *handle)
+ {
+ #ifdef SHARED
+- if (!rtld_active ())
++ if (GLRO (dl_dlfcn_hook) != NULL)
+ return GLRO (dl_dlfcn_hook)->dlclose (handle);
+ #endif
+
+diff --git a/dlfcn/dlerror.c b/dlfcn/dlerror.c
+index 3bf6049e3c..b899d252a1 100644
+--- a/dlfcn/dlerror.c
++++ b/dlfcn/dlerror.c
+@@ -32,7 +32,7 @@ char *
+ __dlerror (void)
+ {
+ # ifdef SHARED
+- if (!rtld_active ())
++ if (GLRO (dl_dlfcn_hook) != NULL)
+ return GLRO (dl_dlfcn_hook)->dlerror ();
+ # endif
+
+diff --git a/dlfcn/dlinfo.c b/dlfcn/dlinfo.c
+index fc63c02681..068db5260c 100644
+--- a/dlfcn/dlinfo.c
++++ b/dlfcn/dlinfo.c
+@@ -89,7 +89,7 @@ dlinfo_implementation (void *handle, int request, void *arg)
+ int
+ ___dlinfo (void *handle, int request, void *arg)
+ {
+- if (!rtld_active ())
++ if (GLRO (dl_dlfcn_hook) != NULL)
+ return GLRO (dl_dlfcn_hook)->dlinfo (handle, request, arg);
+ else
+ return dlinfo_implementation (handle, request, arg);
+diff --git a/dlfcn/dlmopen.c b/dlfcn/dlmopen.c
+index 2437f5ce22..b41778f16c 100644
+--- a/dlfcn/dlmopen.c
++++ b/dlfcn/dlmopen.c
+@@ -80,7 +80,7 @@ dlmopen_implementation (Lmid_t nsid, const char *file, int mode,
+ void *
+ ___dlmopen (Lmid_t nsid, const char *file, int mode)
+ {
+- if (!rtld_active ())
++ if (GLRO (dl_dlfcn_hook) != NULL)
+ return GLRO (dl_dlfcn_hook)->dlmopen (nsid, file, mode, RETURN_ADDRESS (0));
+ else
+ return dlmopen_implementation (nsid, file, mode, RETURN_ADDRESS (0));
+diff --git a/dlfcn/dlopen.c b/dlfcn/dlopen.c
+index 846ca38338..2696dde4b1 100644
+--- a/dlfcn/dlopen.c
++++ b/dlfcn/dlopen.c
+@@ -75,7 +75,7 @@ dlopen_implementation (const char *file, int mode, void *dl_caller)
+ void *
+ ___dlopen (const char *file, int mode)
+ {
+- if (!rtld_active ())
++ if (GLRO (dl_dlfcn_hook) != NULL)
+ return GLRO (dl_dlfcn_hook)->dlopen (file, mode, RETURN_ADDRESS (0));
+ else
+ return dlopen_implementation (file, mode, RETURN_ADDRESS (0));
+diff --git a/dlfcn/dlopenold.c b/dlfcn/dlopenold.c
+index 67601434df..5c21a00496 100644
+--- a/dlfcn/dlopenold.c
++++ b/dlfcn/dlopenold.c
+@@ -70,7 +70,7 @@ __dlopen_nocheck (const char *file, int mode)
+ mode |= RTLD_LAZY;
+ args.mode = mode;
+
+- if (!rtld_active ())
++ if (GLRO (dl_dlfcn_hook) != NULL)
+ return GLRO (dl_dlfcn_hook)->dlopen (file, mode, RETURN_ADDRESS (0));
+
+ return _dlerror_run (dlopen_doit, &args) ? NULL : args.new;
+diff --git a/dlfcn/dlsym.c b/dlfcn/dlsym.c
+index a71f8ae247..2e9ff98e79 100644
+--- a/dlfcn/dlsym.c
++++ b/dlfcn/dlsym.c
+@@ -62,7 +62,7 @@ dlsym_implementation (void *handle, const char *name, void *dl_caller)
+ void *
+ ___dlsym (void *handle, const char *name)
+ {
+- if (!rtld_active ())
++ if (GLRO (dl_dlfcn_hook) != NULL)
+ return GLRO (dl_dlfcn_hook)->dlsym (handle, name, RETURN_ADDRESS (0));
+ else
+ return dlsym_implementation (handle, name, RETURN_ADDRESS (0));
+diff --git a/dlfcn/dlvsym.c b/dlfcn/dlvsym.c
+index 72219d6da6..caa46ba1e0 100644
+--- a/dlfcn/dlvsym.c
++++ b/dlfcn/dlvsym.c
+@@ -65,7 +65,7 @@ dlvsym_implementation (void *handle, const char *name, const char *version,
+ void *
+ ___dlvsym (void *handle, const char *name, const char *version)
+ {
+- if (!rtld_active ())
++ if (GLRO (dl_dlfcn_hook) != NULL)
+ return GLRO (dl_dlfcn_hook)->dlvsym (handle, name, version,
+ RETURN_ADDRESS (0));
+ else
+diff --git a/elf/Makefile b/elf/Makefile
+index 8ed6c3b0b1..e4907d5de9 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -390,6 +390,7 @@ tests += \
+ tst-audit16 \
+ tst-audit17 \
+ tst-audit21 \
++ tst-audit26 \
+ tst-auditmany \
+ tst-auxobj \
+ tst-auxobj-dlopen \
+@@ -767,6 +768,7 @@ modules-names = \
+ tst-auditmod12 \
+ tst-auditmod21a \
+ tst-auditmod21b \
++ tst-auditmod26 \
+ tst-auxvalmod \
+ tst-big-note-lib \
+ tst-deep1mod1 \
+@@ -2286,6 +2288,10 @@ $(objpfx)tst-audit25b: $(objpfx)tst-audit25mod1.so \
+ $(objpfx)tst-auditmod21a.so: $(objpfx)tst-auditmod21b.so
+ tst-audit21-ENV = LD_AUDIT=$(objpfx)tst-auditmod21a.so
+
++$(objpfx)tst-audit26.out: $(objpfx)tst-auditmod26.so
++$(objpfx)tst-auditmod26.so: $(libsupport)
++tst-audit26-ENV = LD_AUDIT=$(objpfx)tst-auditmod26.so
++
+ # tst-sonamemove links against an older implementation of the library.
+ LDFLAGS-tst-sonamemove-linkmod1.so = \
+ -Wl,--version-script=tst-sonamemove-linkmod1.map \
+diff --git a/elf/dl-libc.c b/elf/dl-libc.c
+index a7180d0af8..266e068da6 100644
+--- a/elf/dl-libc.c
++++ b/elf/dl-libc.c
+@@ -156,7 +156,7 @@ __libc_dlopen_mode (const char *name, int mode)
+ args.caller_dlopen = RETURN_ADDRESS (0);
+
+ #ifdef SHARED
+- if (!rtld_active ())
++ if (GLRO (dl_dlfcn_hook) != NULL)
+ return GLRO (dl_dlfcn_hook)->libc_dlopen_mode (name, mode);
+ #endif
+ return dlerror_run (do_dlopen, &args) ? NULL : (void *) args.map;
+@@ -184,7 +184,7 @@ __libc_dlsym (void *map, const char *name)
+ args.name = name;
+
+ #ifdef SHARED
+- if (!rtld_active ())
++ if (GLRO (dl_dlfcn_hook) != NULL)
+ return GLRO (dl_dlfcn_hook)->libc_dlsym (map, name);
+ #endif
+ return (dlerror_run (do_dlsym, &args) ? NULL
+@@ -198,7 +198,7 @@ void *
+ __libc_dlvsym (void *map, const char *name, const char *version)
+ {
+ #ifdef SHARED
+- if (!rtld_active ())
++ if (GLRO (dl_dlfcn_hook) != NULL)
+ return GLRO (dl_dlfcn_hook)->libc_dlvsym (map, name, version);
+ #endif
+
+@@ -221,7 +221,7 @@ int
+ __libc_dlclose (void *map)
+ {
+ #ifdef SHARED
+- if (!rtld_active ())
++ if (GLRO (dl_dlfcn_hook) != NULL)
+ return GLRO (dl_dlfcn_hook)->libc_dlclose (map);
+ #endif
+ return dlerror_run (do_dlclose, map);
+diff --git a/elf/tst-audit26.c b/elf/tst-audit26.c
+new file mode 100644
+index 0000000000..3f920e83ba
+--- /dev/null
++++ b/elf/tst-audit26.c
+@@ -0,0 +1,35 @@
++/* Check the usability of <dlfcn.h> functions in audit modules.
++ Copyright (C) 2022 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library 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.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#include <gnu/lib-names.h>
++
++#include <support/check.h>
++#include <support/xdlfcn.h>
++
++static int
++do_test (void)
++{
++ /* Check that the audit module has been loaded. */
++ void *handle = xdlopen ("mapped to libc", RTLD_LOCAL | RTLD_NOW);
++ TEST_VERIFY (handle
++ == xdlopen (LIBC_SO, RTLD_LOCAL | RTLD_NOW | RTLD_NOLOAD));
++
++ return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/elf/tst-auditmod26.c b/elf/tst-auditmod26.c
+new file mode 100644
+index 0000000000..db7ba95abe
+--- /dev/null
++++ b/elf/tst-auditmod26.c
+@@ -0,0 +1,104 @@
++/* Check the usability of <dlfcn.h> functions in audit modules. Audit module.
++ Copyright (C) 2022 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library 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.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#include <dlfcn.h>
++#include <first-versions.h>
++#include <gnu/lib-names.h>
++#include <link.h>
++#include <stdio.h>
++#include <string.h>
++#include <unistd.h>
++
++#include <support/check.h>
++#include <support/xdlfcn.h>
++
++unsigned int
++la_version (unsigned int current)
++{
++ /* Exercise various <dlfcn.h> functions. */
++
++ /* Check dlopen, dlsym, dlclose. */
++ void *handle = xdlopen (LIBM_SO, RTLD_LOCAL | RTLD_NOW);
++ void *ptr = xdlsym (handle, "sincos");
++ TEST_VERIFY (ptr != NULL);
++ ptr = dlsym (handle, "SINCOS");
++ TEST_VERIFY (ptr == NULL);
++ const char *message = dlerror ();
++ TEST_VERIFY (strstr (message, ": undefined symbol: SINCOS") != NULL);
++ ptr = dlsym (handle, "SINCOS");
++ TEST_VERIFY (ptr == NULL);
++ xdlclose (handle);
++ TEST_COMPARE_STRING (dlerror (), NULL);
++
++ handle = xdlopen (LIBC_SO, RTLD_LOCAL | RTLD_NOW | RTLD_NOLOAD);
++
++ /* Check dlvsym. _exit is unlikely to gain another symbol
++ version. */
++ TEST_VERIFY (xdlsym (handle, "_exit")
++ == xdlvsym (handle, "_exit", FIRST_VERSION_libc__exit_STRING));
++
++ /* Check dlinfo. */
++ {
++ void *handle2 = NULL;
++ TEST_COMPARE (dlinfo (handle, RTLD_DI_LINKMAP, &handle2), 0);
++ TEST_VERIFY (handle2 == handle);
++ }
++
++ /* Check dladdr and dladdr1. */
++ Dl_info info = { };
++ TEST_VERIFY (dladdr (&_exit, &info) != 0);
++ if (strcmp (info.dli_sname, "_Exit") != 0) /* _Exit is an alias. */
++ TEST_COMPARE_STRING (info.dli_sname, "_exit");
++ TEST_VERIFY (info.dli_saddr == &_exit);
++ TEST_VERIFY (strstr (info.dli_fname, LIBC_SO));
++ void *extra_info;
++ memset (&info, 0, sizeof (info));
++ TEST_VERIFY (dladdr1 (&_exit, &info, &extra_info, RTLD_DL_LINKMAP) != 0);
++ TEST_VERIFY (extra_info == handle);
++
++ /* Verify that dlmopen creates a new namespace. */
++ void *dlmopen_handle = xdlmopen (LM_ID_NEWLM, LIBC_SO, RTLD_NOW);
++ TEST_VERIFY (dlmopen_handle != handle);
++ memset (&info, 0, sizeof (info));
++ extra_info = NULL;
++ ptr = xdlsym (dlmopen_handle, "_exit");
++ TEST_VERIFY (dladdr1 (ptr, &info, &extra_info, RTLD_DL_LINKMAP) != 0);
++ TEST_VERIFY (extra_info == dlmopen_handle);
++ xdlclose (dlmopen_handle);
++
++ /* Terminate the process with an error state. This does not happen
++ automatically because the audit module state is not shared with
++ the main program. */
++ if (support_record_failure_is_failed ())
++ {
++ fflush (stdout);
++ fflush (stderr);
++ _exit (1);
++ }
++
++ return LAV_CURRENT;
++}
++
++char *
++la_objsearch (const char *name, uintptr_t *cookie, unsigned int flag)
++{
++ if (strcmp (name, "mapped to libc") == 0)
++ return (char *) LIBC_SO;
++ else
++ return (char *) name;
++}
+--
+2.27.0
+