svn commit: r356053 - in head/sys: arm/arm arm64/arm64 i386/i386 kern powerpc/powerpc riscv/riscv sparc64/sparc64 sys

Brandon Bergren bdragon at FreeBSD.org
Tue Dec 24 15:56:26 UTC 2019


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


More information about the svn-src-head mailing list