Date: Tue, 24 Dec 2019 15:56:24 +0000 (UTC) From: Brandon Bergren <bdragon@FreeBSD.org> 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 Message-ID: <201912241556.xBOFuO6l020520@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201912241556.xBOFuO6l020520>