From nobody Wed Dec 08 21:59:28 2021 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 9E94318C3B62; Wed, 8 Dec 2021 21:59:29 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4J8WKX5Drlz4RF4; Wed, 8 Dec 2021 21:59:28 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 661A61AECC; Wed, 8 Dec 2021 21:59:28 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 1B8LxSgB064113; Wed, 8 Dec 2021 21:59:28 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 1B8LxSNu064112; Wed, 8 Dec 2021 21:59:28 GMT (envelope-from git) Date: Wed, 8 Dec 2021 21:59:28 GMT Message-Id: <202112082159.1B8LxSNu064112@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Konstantin Belousov Subject: git: 95c20faf11a1 - main - kernel linker: do not read debug symbol tables for non-debug symbols List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 95c20faf11a1af6924f97ec4aafc32d899fea8b0 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1639000769; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=5/PF6x3nwelDm+SZc/GpL0rayVmamxuooDKm3p2Nh1o=; b=laxGQtG9l7CdlTbWaRCcJDlbc6GpXOMVyFngr9bgA75EREALqudKpJjz8RigSaXMscZtAc 2ZzUQIvt9FRGPRC3C7i55EcKuP9MYSuYzKwvYXQzvhPssvknROYXOf4JLqkEdRyEi1STNL 6w8aM/BYLty0Cdr1stoLu1fDy/IsxVeC3Hrh1Xi6k1ZPDBMHFntIe6kvMzbIfwZXhea/9p 6bTiIZxaa2xNRF2r5lbfIMYEqTdGTdUMvFP+xlODpAlszVce1kmQveFp8VS0cg/ZFZa4Zq VH4ZQkygPgi1jja+uSwMpkiQBsY0hitMJhgBdm35E5dyg63ZPsV1HCF0gEyohQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1639000769; a=rsa-sha256; cv=none; b=m3ZiBZxoZ87BnXlCulkrJuubMoh02ZuND0uB7yUd9pO71IrfCIAvNcuqx7+Io0pT4xUgid JSQEV8Qaie3E4hZmLfWiL/4vd917Eq4lJj7qC5tMFmTH9s1UBdkYquingr4OplYU2rZzQa OdKUG/4NaXC/dlxE3i0Tab3OpqJOMhCMB08/W6rV1TFmTD2y1j4G/6xDkJJFDIImPCWo3a Dfo11+TfF2FDeTecOzBPODiaNZazj3B2YppCyvGDX1HLTdA8u6jrQIfC9e0L5jysd19vO3 QmTlIn8+Xg7z0cNqyUFdLSBWHSG7eZOo7l3nShZlEgBS6Lpr1Gr29rXbHYsUkA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=95c20faf11a1af6924f97ec4aafc32d899fea8b0 commit 95c20faf11a1af6924f97ec4aafc32d899fea8b0 Author: Konstantin Belousov AuthorDate: 2021-11-07 08:37:48 +0000 Commit: Konstantin Belousov CommitDate: 2021-12-08 21:32:29 +0000 kernel linker: do not read debug symbol tables for non-debug symbols In particular, this prevents resolving locals from other files. To access debug symbol tables, add LINKER_LOOKUP_DEBUG_SYMBOL and LINKER_DEBUG_SYMBOL_VALUES kobj methods, which are allowed to use any types of present symbols in all tables. PR: 207898 Reviewed by: emaste, markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D32878 --- sys/kern/kern_linker.c | 2 +- sys/kern/link_elf.c | 79 +++++++++++++++++++++++++++++++++++++++---------- sys/kern/link_elf_obj.c | 61 +++++++++++++++++++++++++++++++------- sys/kern/linker_if.m | 12 ++++++++ 4 files changed, 126 insertions(+), 28 deletions(-) diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c index b34131604fef..2e4c95f16c8f 100644 --- a/sys/kern/kern_linker.c +++ b/sys/kern/kern_linker.c @@ -912,7 +912,7 @@ linker_debug_lookup(const char *symstr, c_linker_sym_t *sym) linker_file_t lf; TAILQ_FOREACH(lf, &linker_files, link) { - if (LINKER_LOOKUP_SYMBOL(lf, symstr, sym) == 0) + if (LINKER_LOOKUP_DEBUG_SYMBOL(lf, symstr, sym) == 0) return (0); } return (ENOENT); diff --git a/sys/kern/link_elf.c b/sys/kern/link_elf.c index 075238b91d95..dc8002be0e89 100644 --- a/sys/kern/link_elf.c +++ b/sys/kern/link_elf.c @@ -144,8 +144,12 @@ static int link_elf_load_file(linker_class_t, const char *, linker_file_t *); static int link_elf_lookup_symbol(linker_file_t, const char *, c_linker_sym_t *); +static int link_elf_lookup_debug_symbol(linker_file_t, const char *, + c_linker_sym_t *); static int link_elf_symbol_values(linker_file_t, c_linker_sym_t, linker_symval_t *); +static int link_elf_debug_symbol_values(linker_file_t, c_linker_sym_t, + linker_symval_t*); static int link_elf_search_symbol(linker_file_t, caddr_t, c_linker_sym_t *, long *); @@ -164,7 +168,9 @@ static int elf_lookup(linker_file_t, Elf_Size, int, Elf_Addr *); static kobj_method_t link_elf_methods[] = { KOBJMETHOD(linker_lookup_symbol, link_elf_lookup_symbol), + KOBJMETHOD(linker_lookup_debug_symbol, link_elf_lookup_debug_symbol), KOBJMETHOD(linker_symbol_values, link_elf_symbol_values), + KOBJMETHOD(linker_debug_symbol_values, link_elf_debug_symbol_values), KOBJMETHOD(linker_search_symbol, link_elf_search_symbol), KOBJMETHOD(linker_unload, link_elf_unload_file), KOBJMETHOD(linker_load_file, link_elf_load_file), @@ -1490,14 +1496,14 @@ elf_hash(const char *name) } static int -link_elf_lookup_symbol(linker_file_t lf, const char *name, c_linker_sym_t *sym) +link_elf_lookup_symbol1(linker_file_t lf, const char *name, c_linker_sym_t *sym, + bool see_local) { elf_file_t ef = (elf_file_t) lf; unsigned long symnum; const Elf_Sym* symp; const char *strp; unsigned long hash; - int i; /* If we don't have a hash, bail. */ if (ef->buckets == NULL || ef->nbuckets == 0) { @@ -1528,8 +1534,11 @@ link_elf_lookup_symbol(linker_file_t lf, const char *name, c_linker_sym_t *sym) (symp->st_value != 0 && (ELF_ST_TYPE(symp->st_info) == STT_FUNC || ELF_ST_TYPE(symp->st_info) == STT_GNU_IFUNC))) { - *sym = (c_linker_sym_t) symp; - return (0); + if (see_local || + ELF_ST_BIND(symp->st_info) != STB_LOCAL) { + *sym = (c_linker_sym_t) symp; + return (0); + } } return (ENOENT); } @@ -1537,11 +1546,27 @@ link_elf_lookup_symbol(linker_file_t lf, const char *name, c_linker_sym_t *sym) symnum = ef->chains[symnum]; } - /* If we have not found it, look at the full table (if loaded) */ - if (ef->symtab == ef->ddbsymtab) - return (ENOENT); + return (ENOENT); +} + +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)); +} + +static int +link_elf_lookup_debug_symbol(linker_file_t lf, const char *name, + c_linker_sym_t *sym) +{ + elf_file_t ef = (elf_file_t)lf; + const Elf_Sym* symp; + const char *strp; + int i; + + if (link_elf_lookup_symbol1(lf, name, sym, true) == 0) + return (0); - /* Exhaustive search */ for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) { strp = ef->ddbstrtab + symp->st_name; if (strcmp(name, strp) == 0) { @@ -1560,8 +1585,8 @@ link_elf_lookup_symbol(linker_file_t lf, const char *name, c_linker_sym_t *sym) } static int -link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym, - linker_symval_t *symval) +link_elf_symbol_values1(linker_file_t lf, c_linker_sym_t sym, + linker_symval_t *symval, bool see_local) { elf_file_t ef; const Elf_Sym *es; @@ -1569,7 +1594,9 @@ link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym, ef = (elf_file_t)lf; es = (const Elf_Sym *)sym; - if (es >= ef->symtab && es < (ef->symtab + ef->nchains)) { + if (es >= ef->symtab && es < ef->symtab + ef->nchains) { + if (!see_local && ELF_ST_BIND(es->st_info) == STB_LOCAL) + return (ENOENT); symval->name = ef->strtab + es->st_name; val = (caddr_t)ef->address + es->st_value; if (ELF_ST_TYPE(es->st_info) == STT_GNU_IFUNC) @@ -1578,8 +1605,29 @@ link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym, symval->size = es->st_size; return (0); } + return (ENOENT); +} + +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)); +} + +static int +link_elf_debug_symbol_values(linker_file_t lf, c_linker_sym_t sym, + linker_symval_t *symval) +{ + elf_file_t ef = (elf_file_t)lf; + const Elf_Sym *es = (const Elf_Sym *)sym; + caddr_t val; + + if (link_elf_symbol_values1(lf, sym, symval, true) == 0) + return (0); if (ef->symtab == ef->ddbsymtab) return (ENOENT); + if (es >= ef->ddbsymtab && es < (ef->ddbsymtab + ef->ddbsymcnt)) { symval->name = ef->ddbstrtab + es->st_name; val = (caddr_t)ef->address + es->st_value; @@ -1597,7 +1645,7 @@ link_elf_search_symbol(linker_file_t lf, caddr_t value, c_linker_sym_t *sym, long *diffp) { elf_file_t ef = (elf_file_t)lf; - u_long off = (uintptr_t) (void *)value; + u_long off = (uintptr_t)(void *)value; u_long diff = off; u_long st_value; const Elf_Sym *es; @@ -1719,11 +1767,10 @@ link_elf_each_function_nameval(linker_file_t file, if (symp->st_value != 0 && (ELF_ST_TYPE(symp->st_info) == STT_FUNC || ELF_ST_TYPE(symp->st_info) == STT_GNU_IFUNC)) { - error = link_elf_symbol_values(file, + error = link_elf_debug_symbol_values(file, (c_linker_sym_t) symp, &symval); - if (error != 0) - return (error); - error = callback(file, i, &symval, opaque); + if (error == 0) + error = callback(file, i, &symval, opaque); if (error != 0) return (error); } diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c index fbefd0f8d7ca..ec2319ffad47 100644 --- a/sys/kern/link_elf_obj.c +++ b/sys/kern/link_elf_obj.c @@ -131,8 +131,12 @@ static int link_elf_link_preload_finish(linker_file_t); static int link_elf_load_file(linker_class_t, const char *, linker_file_t *); static int link_elf_lookup_symbol(linker_file_t, const char *, c_linker_sym_t *); +static int link_elf_lookup_debug_symbol(linker_file_t, const char *, + c_linker_sym_t *); static int link_elf_symbol_values(linker_file_t, c_linker_sym_t, linker_symval_t *); +static int link_elf_debug_symbol_values(linker_file_t, c_linker_sym_t, + linker_symval_t *); static int link_elf_search_symbol(linker_file_t, caddr_t value, c_linker_sym_t *sym, long *diffp); @@ -153,7 +157,9 @@ static int elf_obj_lookup(linker_file_t lf, Elf_Size symidx, int deps, static kobj_method_t link_elf_methods[] = { KOBJMETHOD(linker_lookup_symbol, link_elf_lookup_symbol), + KOBJMETHOD(linker_lookup_debug_symbol, link_elf_lookup_debug_symbol), KOBJMETHOD(linker_symbol_values, link_elf_symbol_values), + KOBJMETHOD(linker_debug_symbol_values, link_elf_debug_symbol_values), KOBJMETHOD(linker_search_symbol, link_elf_search_symbol), KOBJMETHOD(linker_unload, link_elf_unload_file), KOBJMETHOD(linker_load_file, link_elf_load_file), @@ -1424,9 +1430,10 @@ relocate_file(elf_file_t ef) } static int -link_elf_lookup_symbol(linker_file_t lf, const char *name, c_linker_sym_t *sym) +link_elf_lookup_symbol1(linker_file_t lf, const char *name, c_linker_sym_t *sym, + bool see_local) { - elf_file_t ef = (elf_file_t) lf; + elf_file_t ef = (elf_file_t)lf; const Elf_Sym *symp; const char *strp; int i; @@ -1434,16 +1441,33 @@ link_elf_lookup_symbol(linker_file_t lf, const char *name, c_linker_sym_t *sym) for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) { strp = ef->ddbstrtab + symp->st_name; if (symp->st_shndx != SHN_UNDEF && strcmp(name, strp) == 0) { - *sym = (c_linker_sym_t) symp; - return 0; + if (see_local || + ELF_ST_BIND(symp->st_info) == STB_GLOBAL) { + *sym = (c_linker_sym_t) symp; + return (0); + } + return (ENOENT); } } return (ENOENT); } static int -link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym, - linker_symval_t *symval) +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)); +} + +static int +link_elf_lookup_debug_symbol(linker_file_t lf, const char *name, + c_linker_sym_t *sym) +{ + return (link_elf_lookup_symbol1(lf, name, sym, true)); +} + +static int +link_elf_symbol_values1(linker_file_t lf, c_linker_sym_t sym, + linker_symval_t *symval, bool see_local) { elf_file_t ef; const Elf_Sym *es; @@ -1453,6 +1477,8 @@ link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym, es = (const Elf_Sym*) sym; val = (caddr_t)es->st_value; if (es >= ef->ddbsymtab && es < (ef->ddbsymtab + ef->ddbsymcnt)) { + if (!see_local && ELF_ST_BIND(es->st_info) == STB_LOCAL) + return (ENOENT); symval->name = ef->ddbstrtab + es->st_name; val = (caddr_t)es->st_value; if (ELF_ST_TYPE(es->st_info) == STT_GNU_IFUNC) @@ -1464,6 +1490,20 @@ link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym, return (ENOENT); } +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)); +} + +static int +link_elf_debug_symbol_values(linker_file_t lf, c_linker_sym_t sym, + linker_symval_t *symval) +{ + return (link_elf_symbol_values1(lf, sym, symval, true)); +} + static int link_elf_search_symbol(linker_file_t lf, caddr_t value, c_linker_sym_t *sym, long *diffp) @@ -1566,12 +1606,11 @@ link_elf_each_function_nameval(linker_file_t file, if (symp->st_value != 0 && (ELF_ST_TYPE(symp->st_info) == STT_FUNC || ELF_ST_TYPE(symp->st_info) == STT_GNU_IFUNC)) { - error = link_elf_symbol_values(file, + error = link_elf_debug_symbol_values(file, (c_linker_sym_t)symp, &symval); - if (error) - return (error); - error = callback(file, i, &symval, opaque); - if (error) + if (error == 0) + error = callback(file, i, &symval, opaque); + if (error != 0) return (error); } } diff --git a/sys/kern/linker_if.m b/sys/kern/linker_if.m index a583a0369ebc..524f786ccac8 100644 --- a/sys/kern/linker_if.m +++ b/sys/kern/linker_if.m @@ -40,12 +40,24 @@ METHOD int lookup_symbol { c_linker_sym_t* symp; }; +METHOD int lookup_debug_symbol { + linker_file_t file; + const char* name; + c_linker_sym_t* symp; +}; + METHOD int symbol_values { linker_file_t file; c_linker_sym_t sym; linker_symval_t* valp; }; +METHOD int debug_symbol_values { + linker_file_t file; + c_linker_sym_t sym; + linker_symval_t* valp; +}; + METHOD int search_symbol { linker_file_t file; caddr_t value;