From owner-svn-src-all@freebsd.org Thu Feb 20 01:27:38 2020 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id A8D6B24B708; Thu, 20 Feb 2020 01:27:38 +0000 (UTC) (envelope-from kib@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) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 48NH5Q0qf5z3Cmn; Thu, 20 Feb 2020 01:27:37 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id CD33219E06; Thu, 20 Feb 2020 01:27:37 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 01K1RbF1086222; Thu, 20 Feb 2020 01:27:37 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 01K1RZ9w086209; Thu, 20 Feb 2020 01:27:35 GMT (envelope-from kib@FreeBSD.org) Message-Id: <202002200127.01K1RZ9w086209@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Thu, 20 Feb 2020 01:27:35 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r358142 - in stable/12/libexec/rtld-elf: . aarch64 amd64 arm i386 mips powerpc powerpc64 riscv sparc64 X-SVN-Group: stable-12 X-SVN-Commit-Author: kib X-SVN-Commit-Paths: in stable/12/libexec/rtld-elf: . aarch64 amd64 arm i386 mips powerpc powerpc64 riscv sparc64 X-SVN-Commit-Revision: 358142 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 20 Feb 2020 01:27:38 -0000 Author: kib Date: Thu Feb 20 01:27:35 2020 New Revision: 358142 URL: https://svnweb.freebsd.org/changeset/base/358142 Log: MFC r357895, r357910: Handle non-plt IRELATIVE relocations, at least for x86. Modified: stable/12/libexec/rtld-elf/aarch64/reloc.c stable/12/libexec/rtld-elf/amd64/reloc.c stable/12/libexec/rtld-elf/arm/reloc.c stable/12/libexec/rtld-elf/i386/reloc.c stable/12/libexec/rtld-elf/mips/reloc.c stable/12/libexec/rtld-elf/powerpc/reloc.c stable/12/libexec/rtld-elf/powerpc64/reloc.c stable/12/libexec/rtld-elf/riscv/reloc.c stable/12/libexec/rtld-elf/rtld.c stable/12/libexec/rtld-elf/rtld.h stable/12/libexec/rtld-elf/sparc64/reloc.c Directory Properties: stable/12/ (props changed) Modified: stable/12/libexec/rtld-elf/aarch64/reloc.c ============================================================================== --- stable/12/libexec/rtld-elf/aarch64/reloc.c Thu Feb 20 01:24:45 2020 (r358141) +++ stable/12/libexec/rtld-elf/aarch64/reloc.c Thu Feb 20 01:27:35 2020 (r358142) @@ -258,31 +258,56 @@ reloc_jmpslots(Obj_Entry *obj, int flags, RtldLockStat return (0); } +static void +reloc_iresolve_one(Obj_Entry *obj, const Elf_Rela *rela, + RtldLockState *lockstate) +{ + Elf_Addr *where, target, *ptr; + + ptr = (Elf_Addr *)(obj->relocbase + rela->r_addend); + where = (Elf_Addr *)(obj->relocbase + rela->r_offset); + lock_release(rtld_bind_lock, lockstate); + target = call_ifunc_resolver(ptr); + wlock_acquire(rtld_bind_lock, lockstate); + *where = target; +} + int reloc_iresolve(Obj_Entry *obj, struct Struct_RtldLockState *lockstate) { const Elf_Rela *relalim; const Elf_Rela *rela; - Elf_Addr *where, target, *ptr; if (!obj->irelative) return (0); - relalim = (const Elf_Rela *)((const char *)obj->pltrela + obj->pltrelasize); + obj->irelative = false; + relalim = (const Elf_Rela *)((const char *)obj->pltrela + + obj->pltrelasize); for (rela = obj->pltrela; rela < relalim; rela++) { - if (ELF_R_TYPE(rela->r_info) == R_AARCH64_IRELATIVE) { - ptr = (Elf_Addr *)(obj->relocbase + rela->r_addend); - where = (Elf_Addr *)(obj->relocbase + rela->r_offset); - lock_release(rtld_bind_lock, lockstate); - target = call_ifunc_resolver(ptr); - wlock_acquire(rtld_bind_lock, lockstate); - *where = target; - } + if (ELF_R_TYPE(rela->r_info) == R_AARCH64_IRELATIVE) + reloc_iresolve_one(obj, rela, lockstate); } - obj->irelative = false; return (0); } int +reloc_iresolve_nonplt(Obj_Entry *obj, struct Struct_RtldLockState *lockstate) +{ + const Elf_Rela *relalim; + const Elf_Rela *rela; + + if (!obj->irelative_nonplt) + return (0); + obj->irelative_nonplt = false; + relalim = (const Elf_Rela *)((const char *)obj->rela + obj->relasize); + for (rela = obj->rela; rela < relalim; rela++) { + if (ELF_R_TYPE(rela->r_info) == R_AARCH64_IRELATIVE) + reloc_iresolve_one(obj, rela, lockstate); + } + return (0); +} + +int reloc_gnu_ifunc(Obj_Entry *obj, int flags, struct Struct_RtldLockState *lockstate) { @@ -497,6 +522,9 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int *where = (Elf_Addr)(obj->relocbase + rela->r_addend); break; case R_AARCH64_NONE: + break; + case R_AARCH64_IRELATIVE: + obj->irelative_nonplt = true; break; default: rtld_printf("%s: Unhandled relocation %lu\n", Modified: stable/12/libexec/rtld-elf/amd64/reloc.c ============================================================================== --- stable/12/libexec/rtld-elf/amd64/reloc.c Thu Feb 20 01:24:45 2020 (r358141) +++ stable/12/libexec/rtld-elf/amd64/reloc.c Thu Feb 20 01:27:35 2020 (r358142) @@ -303,6 +303,10 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int case R_X86_64_RELATIVE: *where = (Elf_Addr)(obj->relocbase + rela->r_addend); break; + case R_X86_64_IRELATIVE: + obj->irelative_nonplt = true; + break; + /* * missing: * R_X86_64_GOTPCREL, R_X86_64_32, R_X86_64_32S, R_X86_64_16, @@ -410,34 +414,53 @@ reloc_jmpslot(Elf_Addr *where, Elf_Addr target, return (target); } +static void +reloc_iresolve_one(Obj_Entry *obj, const Elf_Rela *rela, + RtldLockState *lockstate) +{ + Elf_Addr *where, target, *ptr; + + ptr = (Elf_Addr *)(obj->relocbase + rela->r_addend); + where = (Elf_Addr *)(obj->relocbase + rela->r_offset); + lock_release(rtld_bind_lock, lockstate); + target = call_ifunc_resolver(ptr); + wlock_acquire(rtld_bind_lock, lockstate); + *where = target; +} + int reloc_iresolve(Obj_Entry *obj, RtldLockState *lockstate) { - const Elf_Rela *relalim; - const Elf_Rela *rela; + const Elf_Rela *relalim; + const Elf_Rela *rela; - if (!obj->irelative) + if (!obj->irelative) + return (0); + obj->irelative = false; + relalim = (const Elf_Rela *)((const char *)obj->pltrela + + obj->pltrelasize); + for (rela = obj->pltrela; rela < relalim; rela++) { + if (ELF_R_TYPE(rela->r_info) == R_X86_64_IRELATIVE) + reloc_iresolve_one(obj, rela, lockstate); + } return (0); - relalim = (const Elf_Rela *)((const char *)obj->pltrela + obj->pltrelasize); - for (rela = obj->pltrela; rela < relalim; rela++) { - Elf_Addr *where, target, *ptr; +} - switch (ELF_R_TYPE(rela->r_info)) { - case R_X86_64_JMP_SLOT: - break; +int +reloc_iresolve_nonplt(Obj_Entry *obj, RtldLockState *lockstate) +{ + const Elf_Rela *relalim; + const Elf_Rela *rela; - case R_X86_64_IRELATIVE: - ptr = (Elf_Addr *)(obj->relocbase + rela->r_addend); - where = (Elf_Addr *)(obj->relocbase + rela->r_offset); - lock_release(rtld_bind_lock, lockstate); - target = call_ifunc_resolver(ptr); - wlock_acquire(rtld_bind_lock, lockstate); - *where = target; - break; + if (!obj->irelative_nonplt) + return (0); + obj->irelative_nonplt = false; + relalim = (const Elf_Rela *)((const char *)obj->rela + obj->relasize); + for (rela = obj->rela; rela < relalim; rela++) { + if (ELF_R_TYPE(rela->r_info) == R_X86_64_IRELATIVE) + reloc_iresolve_one(obj, rela, lockstate); } - } - obj->irelative = false; - return (0); + return (0); } int Modified: stable/12/libexec/rtld-elf/arm/reloc.c ============================================================================== --- stable/12/libexec/rtld-elf/arm/reloc.c Thu Feb 20 01:24:45 2020 (r358141) +++ stable/12/libexec/rtld-elf/arm/reloc.c Thu Feb 20 01:27:35 2020 (r358142) @@ -452,6 +452,15 @@ reloc_iresolve(Obj_Entry *obj __unused, } int +reloc_iresolve_nonplt(Obj_Entry *obj __unused, + struct Struct_RtldLockState *lockstate __unused) +{ + + /* XXX not implemented */ + return (0); +} + +int reloc_gnu_ifunc(Obj_Entry *obj __unused, int flags __unused, struct Struct_RtldLockState *lockstate __unused) { Modified: stable/12/libexec/rtld-elf/i386/reloc.c ============================================================================== --- stable/12/libexec/rtld-elf/i386/reloc.c Thu Feb 20 01:24:45 2020 (r358141) +++ stable/12/libexec/rtld-elf/i386/reloc.c Thu Feb 20 01:27:35 2020 (r358142) @@ -259,6 +259,9 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int case R_386_TLS_DTPOFF32: *where += (Elf_Addr) def->st_value; break; + case R_386_IRELATIVE: + obj->irelative_nonplt = true; + break; default: _rtld_error("%s: Unsupported relocation type %d" " in non-PLT relocations\n", obj->path, @@ -361,29 +364,51 @@ reloc_jmpslot(Elf_Addr *where, Elf_Addr target, return (target); } +static void +reloc_iresolve_one(Obj_Entry *obj, const Elf_Rel *rel, + RtldLockState *lockstate) +{ + Elf_Addr *where, target; + + where = (Elf_Addr *)(obj->relocbase + rel->r_offset); + lock_release(rtld_bind_lock, lockstate); + target = call_ifunc_resolver(obj->relocbase + *where); + wlock_acquire(rtld_bind_lock, lockstate); + *where = target; +} + int reloc_iresolve(Obj_Entry *obj, RtldLockState *lockstate) { - const Elf_Rel *rellim; - const Elf_Rel *rel; - Elf_Addr *where, target; + const Elf_Rel *rellim; + const Elf_Rel *rel; - if (!obj->irelative) + if (!obj->irelative) + return (0); + obj->irelative = false; + rellim = (const Elf_Rel *)((const char *)obj->pltrel + obj->pltrelsize); + for (rel = obj->pltrel; rel < rellim; rel++) { + if (ELF_R_TYPE(rel->r_info) == R_386_IRELATIVE) + reloc_iresolve_one(obj, rel, lockstate); + } return (0); - rellim = (const Elf_Rel *)((const char *)obj->pltrel + obj->pltrelsize); - for (rel = obj->pltrel; rel < rellim; rel++) { - switch (ELF_R_TYPE(rel->r_info)) { - case R_386_IRELATIVE: - where = (Elf_Addr *)(obj->relocbase + rel->r_offset); - lock_release(rtld_bind_lock, lockstate); - target = call_ifunc_resolver(obj->relocbase + *where); - wlock_acquire(rtld_bind_lock, lockstate); - *where = target; - break; +} + +int +reloc_iresolve_nonplt(Obj_Entry *obj, RtldLockState *lockstate) +{ + const Elf_Rel *rellim; + const Elf_Rel *rel; + + if (!obj->irelative_nonplt) + return (0); + obj->irelative_nonplt = false; + rellim = (const Elf_Rel *)((const char *)obj->rel + obj->relsize); + for (rel = obj->rel; rel < rellim; rel++) { + if (ELF_R_TYPE(rel->r_info) == R_386_IRELATIVE) + reloc_iresolve_one(obj, rel, lockstate); } - } - obj->irelative = false; - return (0); + return (0); } int Modified: stable/12/libexec/rtld-elf/mips/reloc.c ============================================================================== --- stable/12/libexec/rtld-elf/mips/reloc.c Thu Feb 20 01:24:45 2020 (r358141) +++ stable/12/libexec/rtld-elf/mips/reloc.c Thu Feb 20 01:27:35 2020 (r358142) @@ -723,6 +723,15 @@ reloc_iresolve(Obj_Entry *obj __unused, } int +reloc_iresolve_nonplt(Obj_Entry *obj __unused, + struct Struct_RtldLockState *lockstate __unused) +{ + + /* XXX not implemented */ + return (0); +} + +int reloc_gnu_ifunc(Obj_Entry *obj __unused, int flags __unused, struct Struct_RtldLockState *lockstate __unused) { Modified: stable/12/libexec/rtld-elf/powerpc/reloc.c ============================================================================== --- stable/12/libexec/rtld-elf/powerpc/reloc.c Thu Feb 20 01:24:45 2020 (r358141) +++ stable/12/libexec/rtld-elf/powerpc/reloc.c Thu Feb 20 01:27:35 2020 (r358142) @@ -540,6 +540,13 @@ reloc_iresolve(Obj_Entry *obj __unused, } int +reloc_iresolve_nonplt(Obj_Entry *obj __unused, + struct Struct_RtldLockState *lockstate __unused) +{ + return (0); +} + +int reloc_gnu_ifunc(Obj_Entry *obj __unused, int flags __unused, struct Struct_RtldLockState *lockstate __unused) { Modified: stable/12/libexec/rtld-elf/powerpc64/reloc.c ============================================================================== --- stable/12/libexec/rtld-elf/powerpc64/reloc.c Thu Feb 20 01:24:45 2020 (r358141) +++ stable/12/libexec/rtld-elf/powerpc64/reloc.c Thu Feb 20 01:27:35 2020 (r358142) @@ -513,6 +513,13 @@ reloc_gnu_ifunc(Obj_Entry *obj __unused, int flags __u return (0); } +int +reloc_iresolve_nonplt(Obj_Entry *obj __unused, + struct Struct_RtldLockState *lockstate __unused) +{ + return (0); +} + void init_pltgot(Obj_Entry *obj) { Modified: stable/12/libexec/rtld-elf/riscv/reloc.c ============================================================================== --- stable/12/libexec/rtld-elf/riscv/reloc.c Thu Feb 20 01:24:45 2020 (r358141) +++ stable/12/libexec/rtld-elf/riscv/reloc.c Thu Feb 20 01:27:35 2020 (r358142) @@ -212,6 +212,15 @@ reloc_iresolve(Obj_Entry *obj __unused, } int +reloc_iresolve_nonplt(Obj_Entry *obj __unused, + struct Struct_RtldLockState *lockstate __unused) +{ + + /* XXX not implemented */ + return (0); +} + +int reloc_gnu_ifunc(Obj_Entry *obj __unused, int flags __unused, struct Struct_RtldLockState *lockstate __unused) { Modified: stable/12/libexec/rtld-elf/rtld.c ============================================================================== --- stable/12/libexec/rtld-elf/rtld.c Thu Feb 20 01:24:45 2020 (r358141) +++ stable/12/libexec/rtld-elf/rtld.c Thu Feb 20 01:27:35 2020 (r358142) @@ -2987,10 +2987,13 @@ resolve_object_ifunc(Obj_Entry *obj, bool bind_now, in if (obj->ifuncs_resolved) return (0); obj->ifuncs_resolved = true; - if (!obj->irelative && !((obj->bind_now || bind_now) && obj->gnu_ifunc)) + if (!obj->irelative && !obj->irelative_nonplt && + !((obj->bind_now || bind_now) && obj->gnu_ifunc)) return (0); if (obj_disable_relro(obj) == -1 || (obj->irelative && reloc_iresolve(obj, lockstate) == -1) || + (obj->irelative_nonplt && reloc_iresolve_nonplt(obj, + lockstate) == -1) || ((obj->bind_now || bind_now) && obj->gnu_ifunc && reloc_gnu_ifunc(obj, flags, lockstate) == -1) || obj_enforce_relro(obj) == -1) Modified: stable/12/libexec/rtld-elf/rtld.h ============================================================================== --- stable/12/libexec/rtld-elf/rtld.h Thu Feb 20 01:24:45 2020 (r358141) +++ stable/12/libexec/rtld-elf/rtld.h Thu Feb 20 01:27:35 2020 (r358142) @@ -265,6 +265,7 @@ typedef struct Struct_Obj_Entry { bool dag_inited : 1; /* Object has its DAG initialized. */ bool filtees_loaded : 1; /* Filtees loaded */ bool irelative : 1; /* Object has R_MACHDEP_IRELATIVE relocs */ + bool irelative_nonplt : 1; /* Object has R_MACHDEP_IRELATIVE non-plt relocs */ bool gnu_ifunc : 1; /* Object has references to STT_GNU_IFUNC */ bool non_plt_gnu_ifunc : 1; /* Object has non-plt IFUNC references */ bool ifuncs_resolved : 1; /* Object ifuncs were already resolved */ @@ -406,6 +407,7 @@ int reloc_non_plt(Obj_Entry *, Obj_Entry *, int flags, int reloc_plt(Obj_Entry *, int flags, struct Struct_RtldLockState *); int reloc_jmpslots(Obj_Entry *, int flags, struct Struct_RtldLockState *); int reloc_iresolve(Obj_Entry *, struct Struct_RtldLockState *); +int reloc_iresolve_nonplt(Obj_Entry *, struct Struct_RtldLockState *); int reloc_gnu_ifunc(Obj_Entry *, int flags, struct Struct_RtldLockState *); void ifunc_init(Elf_Auxinfo[__min_size(AT_COUNT)]); void pre_init(void); Modified: stable/12/libexec/rtld-elf/sparc64/reloc.c ============================================================================== --- stable/12/libexec/rtld-elf/sparc64/reloc.c Thu Feb 20 01:24:45 2020 (r358141) +++ stable/12/libexec/rtld-elf/sparc64/reloc.c Thu Feb 20 01:27:35 2020 (r358142) @@ -570,6 +570,15 @@ reloc_iresolve(Obj_Entry *obj __unused, } int +reloc_iresolve_nonplt(Obj_Entry *obj __unused, + struct Struct_RtldLockState *lockstate __unused) +{ + + /* XXX not implemented */ + return (0); +} + +int reloc_gnu_ifunc(Obj_Entry *obj __unused, int flags __unused, struct Struct_RtldLockState *lockstate __unused) {