From owner-svn-src-all@freebsd.org Tue Dec 24 15:56:26 2019 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 8BC5E1EB963; Tue, 24 Dec 2019 15:56:26 +0000 (UTC) (envelope-from bdragon@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 47j16f39dtz3ySP; Tue, 24 Dec 2019 15:56:26 +0000 (UTC) (envelope-from bdragon@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 682E32745; Tue, 24 Dec 2019 15:56:26 +0000 (UTC) (envelope-from bdragon@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id xBOFuQ1K020529; Tue, 24 Dec 2019 15:56:26 GMT (envelope-from bdragon@FreeBSD.org) Received: (from bdragon@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id xBOFuO6l020520; Tue, 24 Dec 2019 15:56:24 GMT (envelope-from bdragon@FreeBSD.org) Message-Id: <201912241556.xBOFuO6l020520@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: bdragon set sender to bdragon@FreeBSD.org using -f From: Brandon Bergren Date: Tue, 24 Dec 2019 15:56:24 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r356053 - in head/sys: arm/arm arm64/arm64 i386/i386 kern powerpc/powerpc riscv/riscv sparc64/sparc64 sys X-SVN-Group: head X-SVN-Commit-Author: bdragon X-SVN-Commit-Paths: in head/sys: arm/arm arm64/arm64 i386/i386 kern powerpc/powerpc riscv/riscv sparc64/sparc64 sys X-SVN-Commit-Revision: 356053 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: Tue, 24 Dec 2019 15:56:26 -0000 Author: bdragon Date: Tue Dec 24 15:56:24 2019 New Revision: 356053 URL: https://svnweb.freebsd.org/changeset/base/356053 Log: [PowerPC] Implement Secure-PLT jump table processing for ppc32. Due to clang and LLD's tendency to use a PLT for builtins, and as they don't have full support for EABI, we sometimes have to deal with a PLT in .ko files in a clang-built kernel. As such, augment the in-kernel linker to support jump table processing. As there is no particular reason to support lazy binding in kernel modules, only implement Secure-PLT immediate binding. As part of these changes, add elf_cpu_parse_dynamic() to the MD API of the in-kernel linker (except on platforms that use raw object files.) The new function will allow MD code to act on MD tags in _DYNAMIC. Use this new function in the PowerPC MD code to ensure BSS-PLT modules using PLT will be rejected during insertion, and to poison the runtime resolver to ensure we get a clear panic reason if a call is made to the resolver. Reviewed by: jhibbits Differential Revision: https://reviews.freebsd.org/D22608 Modified: head/sys/arm/arm/elf_machdep.c head/sys/arm64/arm64/elf_machdep.c head/sys/i386/i386/elf_machdep.c head/sys/kern/link_elf.c head/sys/powerpc/powerpc/elf32_machdep.c head/sys/powerpc/powerpc/elf64_machdep.c head/sys/riscv/riscv/elf_machdep.c head/sys/sparc64/sparc64/elf_machdep.c head/sys/sys/linker.h Modified: head/sys/arm/arm/elf_machdep.c ============================================================================== --- head/sys/arm/arm/elf_machdep.c Tue Dec 24 14:50:17 2019 (r356052) +++ head/sys/arm/arm/elf_machdep.c Tue Dec 24 15:56:24 2019 (r356053) @@ -321,6 +321,13 @@ elf_cpu_load_file(linker_file_t lf) } int +elf_cpu_parse_dynamic(linker_file_t lf __unused, Elf_Dyn *dynamic __unused) +{ + + return (0); +} + +int elf_cpu_unload_file(linker_file_t lf) { Modified: head/sys/arm64/arm64/elf_machdep.c ============================================================================== --- head/sys/arm64/arm64/elf_machdep.c Tue Dec 24 14:50:17 2019 (r356052) +++ head/sys/arm64/arm64/elf_machdep.c Tue Dec 24 15:56:24 2019 (r356053) @@ -216,3 +216,10 @@ elf_cpu_unload_file(linker_file_t lf __unused) return (0); } + +int +elf_cpu_parse_dynamic(linker_file_t lf __unused, Elf_Dyn *dynamic __unused) +{ + + return (0); +} Modified: head/sys/i386/i386/elf_machdep.c ============================================================================== --- head/sys/i386/i386/elf_machdep.c Tue Dec 24 14:50:17 2019 (r356052) +++ head/sys/i386/i386/elf_machdep.c Tue Dec 24 15:56:24 2019 (r356053) @@ -295,3 +295,10 @@ elf_cpu_unload_file(linker_file_t lf __unused) return (0); } + +int +elf_cpu_parse_dynamic(linker_file_t lf __unused, Elf_Dyn *dynamic __unused) +{ + + return (0); +} Modified: head/sys/kern/link_elf.c ============================================================================== --- head/sys/kern/link_elf.c Tue Dec 24 14:50:17 2019 (r356052) +++ head/sys/kern/link_elf.c Tue Dec 24 15:56:24 2019 (r356053) @@ -611,7 +611,7 @@ parse_dynamic(elf_file_t ef) ef->ddbstrtab = ef->strtab; ef->ddbstrcnt = ef->strsz; - return (0); + return elf_cpu_parse_dynamic(&ef->lf, ef->dynamic); } #define LS_PADDING 0x90909090 Modified: head/sys/powerpc/powerpc/elf32_machdep.c ============================================================================== --- head/sys/powerpc/powerpc/elf32_machdep.c Tue Dec 24 14:50:17 2019 (r356052) +++ head/sys/powerpc/powerpc/elf32_machdep.c Tue Dec 24 15:56:24 2019 (r356053) @@ -63,6 +63,7 @@ extern const char *freebsd32_syscallnames[]; static void ppc32_fixlimit(struct rlimit *rl, int which); +static void ppc32_runtime_resolve(void); static SYSCTL_NODE(_compat, OID_AUTO, ppc32, CTLFLAG_RW, 0, "32-bit mode"); @@ -296,6 +297,20 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbas *where = elf_relocaddr(lf, relocbase + addend); break; + case R_PPC_JMP_SLOT: /* PLT jump slot entry */ + /* + * We currently only support Secure-PLT jump slots. + * Given that we reject BSS-PLT modules during load, we + * don't need to check again. + * The method we are using here is equivilent to + * LD_BIND_NOW. + */ + error = lookup(lf, symidx, 1, &addr); + if (error != 0) + return -1; + *where = elf_relocaddr(lf, addr + addend); + break; + default: printf("kldload: unexpected relocation type %d\n", (int) rtype); @@ -356,6 +371,7 @@ elf_reloc_local(linker_file_t lf, Elf_Addr relocbase, int elf_cpu_load_file(linker_file_t lf) { + /* Only sync the cache for non-kernel modules */ if (lf->id != 1) __syncicache(lf->address, lf->size); @@ -366,6 +382,47 @@ int elf_cpu_unload_file(linker_file_t lf __unused) { + return (0); +} + +static void +ppc32_runtime_resolve() +{ + + /* + * Since we don't support lazy binding, panic immediately if anyone + * manages to call the runtime resolver. + */ + panic("kldload: Runtime resolver was called unexpectedly!"); +} + +int +elf_cpu_parse_dynamic(linker_file_t lf, Elf_Dyn *dynamic) +{ + Elf_Dyn *dp; + bool has_plt = false; + bool secure_plt = false; + Elf_Addr *got; + + for (dp = dynamic; dp->d_tag != DT_NULL; dp++) { + switch (dp->d_tag) { + case DT_PPC_GOT: + secure_plt = true; + got = (Elf_Addr *)(lf->address + dp->d_un.d_ptr); + /* Install runtime resolver canary. */ + got[1] = (Elf_Addr)ppc32_runtime_resolve; + got[2] = (Elf_Addr)0; + break; + case DT_PLTGOT: + has_plt = true; + break; + } + } + + if (has_plt && !secure_plt) { + printf("kldload: BSS-PLT modules are not supported.\n"); + return (-1); + } return (0); } #endif Modified: head/sys/powerpc/powerpc/elf64_machdep.c ============================================================================== --- head/sys/powerpc/powerpc/elf64_machdep.c Tue Dec 24 14:50:17 2019 (r356052) +++ head/sys/powerpc/powerpc/elf64_machdep.c Tue Dec 24 15:56:24 2019 (r356053) @@ -410,3 +410,10 @@ elf_cpu_unload_file(linker_file_t lf __unused) return (0); } + +int +elf_cpu_parse_dynamic(linker_file_t lf __unused, Elf_Dyn *dynamic __unused) +{ + + return (0); +} Modified: head/sys/riscv/riscv/elf_machdep.c ============================================================================== --- head/sys/riscv/riscv/elf_machdep.c Tue Dec 24 14:50:17 2019 (r356052) +++ head/sys/riscv/riscv/elf_machdep.c Tue Dec 24 15:56:24 2019 (r356053) @@ -504,3 +504,10 @@ elf_cpu_unload_file(linker_file_t lf __unused) return (0); } + +int +elf_cpu_parse_dynamic(linker_file_t lf __unused, Elf_Dyn *dynamic __unused) +{ + + return (0); +} Modified: head/sys/sparc64/sparc64/elf_machdep.c ============================================================================== --- head/sys/sparc64/sparc64/elf_machdep.c Tue Dec 24 14:50:17 2019 (r356052) +++ head/sys/sparc64/sparc64/elf_machdep.c Tue Dec 24 15:56:24 2019 (r356053) @@ -429,3 +429,10 @@ elf_cpu_unload_file(linker_file_t lf __unused) return (0); } + +int +elf_cpu_parse_dynamic(linker_file_t lf __unused, Elf_Dyn *dynamic __unused) +{ + + return (0); +} Modified: head/sys/sys/linker.h ============================================================================== --- head/sys/sys/linker.h Tue Dec 24 14:50:17 2019 (r356052) +++ head/sys/sys/linker.h Tue Dec 24 15:56:24 2019 (r356053) @@ -305,6 +305,10 @@ int linker_ctf_get(linker_file_t, linker_ctf_t *); int elf_cpu_load_file(linker_file_t); int elf_cpu_unload_file(linker_file_t); +/* amd64 and mips use objects instead of shared libraries */ +#if !defined(__amd64__) && !defined(__mips__) +int elf_cpu_parse_dynamic(linker_file_t, Elf_Dyn *); +#endif /* values for type */ #define ELF_RELOC_REL 1