git: 4305fd126c77 - stable/13 - Kernel linkers: add emergency sysctl to restore old behavior

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Wed, 15 Dec 2021 01:55:17 UTC
The branch stable/13 has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=4305fd126c77143f3f3205e201ec413ae2012a0f

commit 4305fd126c77143f3f3205e201ec413ae2012a0f
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2021-11-07 09:26:26 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2021-12-15 01:41:29 +0000

    Kernel linkers: add emergency sysctl to restore old behavior
    
    PR:     207898
    
    (cherry picked from commit ecd8245e0d7784bcd78dafce233f303eee765068)
---
 sys/kern/link_elf.c     |  9 +++++++++
 sys/kern/link_elf_obj.c | 12 ++++++++++--
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/sys/kern/link_elf.c b/sys/kern/link_elf.c
index 445260246946..245c8697cf79 100644
--- a/sys/kern/link_elf.c
+++ b/sys/kern/link_elf.c
@@ -194,6 +194,11 @@ static struct linker_class link_elf_class = {
 	link_elf_methods, sizeof(struct elf_file)
 };
 
+static bool link_elf_leak_locals = true;
+SYSCTL_BOOL(_debug, OID_AUTO, link_elf_leak_locals,
+    CTLFLAG_RWTUN, &link_elf_leak_locals, 0,
+    "Allow local symbols to participate in global module symbol resolution");
+
 typedef int (*elf_reloc_fn)(linker_file_t lf, Elf_Addr relocbase,
     const void *data, int type, elf_lookup_fn lookup);
 
@@ -1552,6 +1557,8 @@ link_elf_lookup_symbol1(linker_file_t lf, const char *name, c_linker_sym_t *sym,
 static int
 link_elf_lookup_symbol(linker_file_t lf, const char *name, c_linker_sym_t *sym)
 {
+	if (link_elf_leak_locals)
+		return (link_elf_lookup_debug_symbol(lf, name, sym));
 	return (link_elf_lookup_symbol1(lf, name, sym, false));
 }
 
@@ -1612,6 +1619,8 @@ static int
 link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym,
     linker_symval_t *symval)
 {
+	if (link_elf_leak_locals)
+		return (link_elf_debug_symbol_values(lf, sym, symval));
 	return (link_elf_symbol_values1(lf, sym, symval, false));
 }
 
diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c
index 2c1b7713c346..689aeae86840 100644
--- a/sys/kern/link_elf_obj.c
+++ b/sys/kern/link_elf_obj.c
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/namei.h>
 #include <sys/proc.h>
 #include <sys/rwlock.h>
+#include <sys/sysctl.h>
 #include <sys/vnode.h>
 
 #include <machine/elf.h>
@@ -183,6 +184,11 @@ static struct linker_class link_elf_class = {
 	link_elf_methods, sizeof(struct elf_file)
 };
 
+static bool link_elf_obj_leak_locals = true;
+SYSCTL_BOOL(_debug, OID_AUTO, link_elf_obj_leak_locals,
+    CTLFLAG_RWTUN, &link_elf_obj_leak_locals, 0,
+    "Allow local symbols to participate in global module symbol resolution");
+
 static int	relocate_file(elf_file_t ef);
 static void	elf_obj_cleanup_globals_cache(elf_file_t);
 
@@ -1455,7 +1461,8 @@ link_elf_lookup_symbol1(linker_file_t lf, const char *name, c_linker_sym_t *sym,
 static int
 link_elf_lookup_symbol(linker_file_t lf, const char *name, c_linker_sym_t *sym)
 {
-	return (link_elf_lookup_symbol1(lf, name, sym, false));
+	return (link_elf_lookup_symbol1(lf, name, sym,
+	    link_elf_obj_leak_locals));
 }
 
 static int
@@ -1494,7 +1501,8 @@ static int
 link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym,
     linker_symval_t *symval)
 {
-	return (link_elf_symbol_values1(lf, sym, symval, false));
+	return (link_elf_symbol_values1(lf, sym, symval,
+	    link_elf_obj_leak_locals));
 }
 
 static int