public inbox for linux-kbuild@vger.kernel.org
 help / color / mirror / Atom feed
From: Russ Dill <Russ.Dill@ti.com>
To: linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, linux-omap@vger.kernel.org
Cc: linux-kbuild@vger.kernel.org,
	Ard Biesheuvel <ard.biesheuvel@linaro.org>,
	mans@mansr.com, Shawn Guo <shawn.guo@linaro.org>,
	Dave Martin <Dave.Martin@arm.com>,
	Russell King - ARM Linux <linux@arm.linux.org.uk>
Subject: [RFC PATCH 06/11] ARM: PIE: Add position independent executable embedding to ARM
Date: Tue, 17 Sep 2013 05:43:32 -0700	[thread overview]
Message-ID: <1379421817-15759-7-git-send-email-Russ.Dill@ti.com> (raw)
In-Reply-To: <1379421817-15759-1-git-send-email-Russ.Dill@ti.com>

Add support to ARM for embedding PIEs into the kernel, loading them into
genalloc pools (such as SRAM) and executing them. Support for ARM means
performing R_ARM_RELATIVE fixups within the .rel.dyn section.

Signed-off-by: Russ Dill <Russ.Dill@ti.com>
---
 arch/arm/Kconfig              |  1 +
 arch/arm/Makefile             |  5 +++
 arch/arm/include/asm/elf.h    |  1 +
 arch/arm/kernel/.gitignore    |  1 +
 arch/arm/kernel/Makefile      |  4 ++-
 arch/arm/kernel/pie.c         | 83 +++++++++++++++++++++++++++++++++++++++++++
 arch/arm/kernel/pie.lds.S     | 40 +++++++++++++++++++++
 arch/arm/kernel/vmlinux.lds.S |  2 ++
 arch/arm/libpie/.gitignore    |  3 ++
 arch/arm/libpie/Makefile      | 32 +++++++++++++++++
 arch/arm/libpie/empty.S       | 12 +++++++
 11 files changed, 183 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/kernel/pie.c
 create mode 100644 arch/arm/kernel/pie.lds.S
 create mode 100644 arch/arm/libpie/.gitignore
 create mode 100644 arch/arm/libpie/Makefile
 create mode 100644 arch/arm/libpie/empty.S

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 43594d5..de7b7603 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -49,6 +49,7 @@ config ARM
 	select HAVE_MEMBLOCK
 	select HAVE_OPROFILE if (HAVE_PERF_EVENTS)
 	select HAVE_PERF_EVENTS
+	select HAVE_PIE
 	select HAVE_REGS_AND_STACK_ACCESS_API
 	select HAVE_SYSCALL_TRACEPOINTS
 	select HAVE_UID16
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 6fd2cea..a673d36 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -128,6 +128,8 @@ KBUILD_AFLAGS	+=$(CFLAGS_ABI) $(AFLAGS_ISA) $(arch-y) $(tune-y) -include asm/uni
 
 CHECKFLAGS	+= -D__arm__
 
+OBJCOPY_OUTPUT_FORMAT := elf32-littlearm
+
 #Default value
 head-y		:= arch/arm/kernel/head$(MMUEXT).o
 textofs-y	:= 0x00008000
@@ -273,6 +275,9 @@ drivers-$(CONFIG_OPROFILE)      += arch/arm/oprofile/
 
 libs-y				:= arch/arm/lib/ $(libs-y)
 
+PIE_LDS				:= arch/arm/kernel/pie.lds
+libpie-$(CONFIG_PIE)		+= arch/arm/libpie/
+
 # Default target when executing plain make
 ifeq ($(CONFIG_XIP_KERNEL),y)
 KBUILD_IMAGE := xipImage
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index 56211f2..a8d036b 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -50,6 +50,7 @@ typedef struct user_fp elf_fpregset_t;
 #define R_ARM_NONE		0
 #define R_ARM_PC24		1
 #define R_ARM_ABS32		2
+#define R_ARM_RELATIVE		23
 #define R_ARM_CALL		28
 #define R_ARM_JUMP24		29
 #define R_ARM_V4BX		40
diff --git a/arch/arm/kernel/.gitignore b/arch/arm/kernel/.gitignore
index c5f676c..a055a48 100644
--- a/arch/arm/kernel/.gitignore
+++ b/arch/arm/kernel/.gitignore
@@ -1 +1,2 @@
 vmlinux.lds
+pie.lds
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 86d10dd..652312e 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -96,4 +96,6 @@ obj-y				+= psci.o
 obj-$(CONFIG_SMP)		+= psci_smp.o
 endif
 
-extra-y := $(head-y) vmlinux.lds
+obj-$(CONFIG_PIE)		+= pie.o
+
+extra-y := $(head-y) vmlinux.lds pie.lds
diff --git a/arch/arm/kernel/pie.c b/arch/arm/kernel/pie.c
new file mode 100644
index 0000000..5dff5d6
--- /dev/null
+++ b/arch/arm/kernel/pie.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2013 Texas Instruments, Inc.
+ *	Russ Dill <russ.dill@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pie.h>
+#include <linux/elf.h>
+
+#include <asm/elf.h>
+
+extern char __pie_rel_dyn_start[];
+extern char __pie_rel_dyn_end[];
+extern char __pie_tail_offset[];
+
+struct arm_pie_tail {
+	int count;
+	uintptr_t offset[0];
+};
+
+int pie_arch_fill_tail(void *tail, void *common_start, void *common_end,
+			void *overlay_start, void *code_start, void *code_end)
+{
+	Elf32_Rel *rel;
+	int records;
+	int i;
+	struct arm_pie_tail *pie_tail = tail;
+	int count;
+
+	rel = (Elf32_Rel *) __pie_rel_dyn_start;
+	records = (__pie_rel_dyn_end - __pie_rel_dyn_start) /
+						sizeof(*rel);
+
+	count = 0;
+	for (i = 0; i < records; i++, rel++) {
+		void *kern_off;
+		if (ELF32_R_TYPE(rel->r_info) != R_ARM_RELATIVE)
+			return -ENOEXEC;
+
+		/* Adjust offset to match area in kernel */
+		kern_off = common_start + rel->r_offset;
+
+		if (kern_off >= common_start && kern_off < code_end) {
+			if (tail)
+				pie_tail->offset[count] = rel->r_offset;
+			count++;
+		} else if (kern_off >= code_start && kern_off < code_end) {
+			if (tail)
+				pie_tail->offset[count] = rel->r_offset -
+						(code_start - overlay_start);
+			count++;
+		}
+	}
+
+	if (tail)
+		pie_tail->count = count;
+
+	return count * sizeof(uintptr_t) + sizeof(*pie_tail);
+}
+EXPORT_SYMBOL_GPL(pie_arch_fill_tail);
+
+/*
+ * R_ARM_RELATIVE: B(S) + A
+ * B(S) - Addressing origin of the output segment defining the symbol S.
+ * A - Addend for the relocation.
+ */
+int pie_arch_fixup(struct pie_chunk *chunk, void *base, void *tail,
+						unsigned long offset)
+{
+	struct arm_pie_tail *pie_tail = tail;
+	int i;
+
+	/* Perform relocation fixups for given offset */
+	for (i = 0; i < pie_tail->count; i++)
+		*((uintptr_t *) (pie_tail->offset[i] + base)) += offset;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(pie_arch_fixup);
diff --git a/arch/arm/kernel/pie.lds.S b/arch/arm/kernel/pie.lds.S
new file mode 100644
index 0000000..4fd5ac5
--- /dev/null
+++ b/arch/arm/kernel/pie.lds.S
@@ -0,0 +1,40 @@
+/*
+ * ld script to make ARM PIEs
+ * taken from the ARM vmlinux.lds.S version by Russ Dill <russ.dill@ti.com.
+ */
+
+#include <asm-generic/pie.lds.h>
+
+OUTPUT_ARCH(arm)
+
+SECTIONS
+{
+	. = 0x0;
+
+	PIE_COMMON_START
+	.got.plt : {
+		*(.got)
+		*(.got.plt)
+	}
+	.text : {
+		PIE_TEXT_TEXT
+	}
+	PIE_COMMON_END
+
+	PIE_OVERLAY_START
+	OVERLAY : NOCROSSREFS {
+	}
+	PIE_OVERLAY_SEND
+
+	__pie_rel_dyn_start : {
+		VMLINUX_SYMBOL(__pie_rel_dyn_start) = .;
+	}
+	.rel.dyn : {
+		KEEP(*(.rel*))
+	}
+	__pie_rel_dyn_end : {
+		VMLINUX_SYMBOL(__pie_rel_dyn_end) = .;
+	}
+
+	PIE_DISCARDS
+}
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 7bcee5c..8c11235 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -77,6 +77,8 @@ SECTIONS
 #ifndef CONFIG_SMP_ON_UP
 		*(.alt.smp.init)
 #endif
+		*(.pie.*)
+		*(.ARM.exidx.pie.*.text)
 		*(.discard)
 		*(.discard.*)
 	}
diff --git a/arch/arm/libpie/.gitignore b/arch/arm/libpie/.gitignore
new file mode 100644
index 0000000..02e3cd5
--- /dev/null
+++ b/arch/arm/libpie/.gitignore
@@ -0,0 +1,3 @@
+lib1funcs.S
+ashldi3.S
+string.c
diff --git a/arch/arm/libpie/Makefile b/arch/arm/libpie/Makefile
new file mode 100644
index 0000000..5662e99
--- /dev/null
+++ b/arch/arm/libpie/Makefile
@@ -0,0 +1,32 @@
+#
+# linux/arch/arm/libpie/Makefile
+#
+ccflags-y	:= -fpic -mno-single-pic-base -fno-builtin
+
+obj-y		:= empty.o
+obj-y		+= lib1funcs.o ashldi3.o string.o
+
+# string library code (-Os is enforced to keep it much smaller)
+string = $(obj)/string.o
+CFLAGS_string.o := -Os
+
+$(obj)/string.c: $(srctree)/arch/$(SRCARCH)/boot/compressed/string.c
+	$(call cmd,shipped)
+
+# For __aeabi_uidivmod
+lib1funcs = $(obj)/lib1funcs.o
+
+$(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S
+	$(call cmd,shipped)
+
+# For __aeabi_llsl
+ashldi3 = $(obj)/ashldi3.o
+
+$(obj)/ashldi3.S: $(srctree)/arch/$(SRCARCH)/lib/ashldi3.S
+	$(call cmd,shipped)
+
+$(obj)/libpie.o: $(string) $(lib1funcs) $(ashldi3) $(addprefix $(obj)/,$(OBJS))
+	$(call if_changed,ld)
+
+# Make sure files are removed during clean
+extra-y		+= string.c lib1funcs.S ashldi3.S
diff --git a/arch/arm/libpie/empty.S b/arch/arm/libpie/empty.S
new file mode 100644
index 0000000..2416862
--- /dev/null
+++ b/arch/arm/libpie/empty.S
@@ -0,0 +1,12 @@
+#include <linux/linkage.h>
+
+ENTRY(__div0)
+ENTRY(__aeabi_unwind_cpp_pr0)
+ENTRY(__aeabi_unwind_cpp_pr1)
+ENTRY(__aeabi_unwind_cpp_pr2)
+	mov	pc, lr
+ENDPROC(__div0)
+ENDPROC(__aeabi_unwind_cpp_pr0)
+ENDPROC(__aeabi_unwind_cpp_pr1)
+ENDPROC(__aeabi_unwind_cpp_pr2)
+
-- 
1.8.3.2


  parent reply	other threads:[~2013-09-17 12:44 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-09-17 12:43 [RFC PATCH 00/11] Embeddable Position Independent Executable Russ Dill
2013-09-17 12:43 ` [RFC PATCH 01/11] asm-generic: io: Add exec versions of ioremap Russ Dill
2013-09-17 12:43 ` [RFC PATCH 02/11] lib: devres: Add exec versions of devm_ioremap_resource and friends Russ Dill
2013-09-17 12:43 ` [RFC PATCH 03/11] misc: SRAM: Add option to map SRAM to allow code execution Russ Dill
2013-09-17 12:43 ` [RFC PATCH 04/11] asm-generic: fncpy: Add function copying macros Russ Dill
2013-09-17 14:23   ` Geert Uytterhoeven
2013-09-17 12:43 ` [RFC PATCH 05/11] PIE: Support embedding position independent executables Russ Dill
2013-09-17 12:43 ` Russ Dill [this message]
2013-09-17 12:43 ` [RFC PATCH 07/11] ARM: PIE: Add support for updating PIE relocations Russ Dill
2013-09-17 12:43 ` [RFC PATCH 08/11] ARM: PIE: Add macro for generating PIE resume trampoline Russ Dill
2013-09-17 12:43 ` [RFC PATCH 09/11] ARM: dts: AM33XX: Associate SRAM with MPU and mark it exec Russ Dill
2013-09-17 12:43 ` [RFC PATCH 10/11] ARM: OMAP2+: AM33XX: Add PIE support for AM33XX Russ Dill
2013-09-17 12:43 ` [RFC PATCH 11/11] ARM: OMAP2+: AM33XX: Basic suspend resume support Russ Dill
2013-10-23 14:11 ` [RFC PATCH 00/11] Embeddable Position Independent Executable Linus Walleij
2013-10-24  8:09 ` Heiko Stübner
2014-04-22  8:15   ` Heiko Stübner
2014-06-04 13:36     ` Pascal Hürst
2013-11-07 23:29 ` Kevin Hilman
2013-11-08 18:09 ` Dave Martin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1379421817-15759-7-git-send-email-Russ.Dill@ti.com \
    --to=russ.dill@ti.com \
    --cc=Dave.Martin@arm.com \
    --cc=ard.biesheuvel@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kbuild@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-omap@vger.kernel.org \
    --cc=linux@arm.linux.org.uk \
    --cc=mans@mansr.com \
    --cc=shawn.guo@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox