diff mbox series

[v3,8/9] jump_table: move entries into ro_after_init region

Message ID 20180919065144.25010-9-ard.biesheuvel@linaro.org
State Accepted
Commit e872267b8bcbb179e21ccc7118f258873d6e7a59
Headers show
Series add support for relative references in jump tables | expand

Commit Message

Ard Biesheuvel Sept. 19, 2018, 6:51 a.m. UTC
The __jump_table sections emitted into the core kernel and into
each module consist of statically initialized references into
other parts of the code, and with the exception of entries that
point into init code, which are defused at post-init time, these
data structures are never modified.

So let's move them into the ro_after_init section, to prevent them
from being corrupted inadvertently by buggy code, or deliberately
by an attacker.

Reviewed-by: Kees Cook <keescook@chromium.org>

Acked-by: Jessica Yu <jeyu@kernel.org>

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

---
 arch/s390/kernel/vmlinux.lds.S    |  1 +
 include/asm-generic/vmlinux.lds.h | 11 +++++++----
 kernel/module.c                   |  9 +++++++++
 3 files changed, 17 insertions(+), 4 deletions(-)

-- 
2.17.1

Comments

Guenter Roeck Sept. 30, 2018, 3:42 p.m. UTC | #1
Hi,

On Tue, Sep 18, 2018 at 11:51:43PM -0700, Ard Biesheuvel wrote:
> The __jump_table sections emitted into the core kernel and into

> each module consist of statically initialized references into

> other parts of the code, and with the exception of entries that

> point into init code, which are defused at post-init time, these

> data structures are never modified.

> 

> So let's move them into the ro_after_init section, to prevent them

> from being corrupted inadvertently by buggy code, or deliberately

> by an attacker.

> 

> Reviewed-by: Kees Cook <keescook@chromium.org>

> Acked-by: Jessica Yu <jeyu@kernel.org>

> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>


This patch results in build failures when trying to build s390
images.

s390-linux-ld:./arch/s390/kernel/vmlinux.lds:41: syntax error

Bisect log is attached.

Guenter

---
# bad: [4794a36bf08dfa89fe636e5080db9d8350e255dd] Add linux-next specific files for 20180928
# good: [6bf4ca7fbc85d80446ac01c0d1d77db4d91a6d84] Linux 4.19-rc5
git bisect start 'HEAD' 'v4.19-rc5'
# good: [d5b0eb1f139e00e8fd18329d446688b19859755e] Merge remote-tracking branch 'crypto/master'
git bisect good d5b0eb1f139e00e8fd18329d446688b19859755e
# bad: [d9c3085241c16503e659c2d7f43578f297bf30dc] Merge remote-tracking branch 'tip/auto-latest'
git bisect bad d9c3085241c16503e659c2d7f43578f297bf30dc
# good: [db9825c95498280718c4687fcf712016f5b6f5f6] Merge tag 'drm-intel-next-2018-09-21' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
git bisect good db9825c95498280718c4687fcf712016f5b6f5f6
# good: [b22777af06f425911c85d8a2c6b4ed929d4e829f] Merge remote-tracking branch 'mmc/next'
git bisect good b22777af06f425911c85d8a2c6b4ed929d4e829f
# bad: [14cb9d65a396c00eb44e1af967f1c393593f3a4c] Merge branch 'x86/microcode'
git bisect bad 14cb9d65a396c00eb44e1af967f1c393593f3a4c
# good: [c6b5da093a8ba740b71dd0052f3846016986fd21] perf intel-pt: Add decoder flags for trace begin / end
git bisect good c6b5da093a8ba740b71dd0052f3846016986fd21
# bad: [441a6b5c97e0136b416a2c12a0c361423a47c717] Merge branch 'sched/core'
git bisect bad 441a6b5c97e0136b416a2c12a0c361423a47c717
# bad: [d43b23bddade094b1a64a087bc5626a065c3c6e5] Merge branch 'locking/core'
git bisect bad d43b23bddade094b1a64a087bc5626a065c3c6e5
# good: [fa70f0d2ce96a892b38fbbaa60584af536f21f97] Merge tag 'efi-next' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi into efi/core
git bisect good fa70f0d2ce96a892b38fbbaa60584af536f21f97
# bad: [ecf89ab872e94999366834689198c436c06ab68f] Merge branch 'core/core'
git bisect bad ecf89ab872e94999366834689198c436c06ab68f
# good: [9fc0f798ab8a6c042d811e45086260eb59be45c1] x86/jump_label: Switch to jump_entry accessors
git bisect good 9fc0f798ab8a6c042d811e45086260eb59be45c1
# good: [19483677684b6ca01606f58503cb79cdfbbc7c72] jump_label: Annotate entries that operate on __init code earlier
git bisect good 19483677684b6ca01606f58503cb79cdfbbc7c72
# bad: [13ddb52c165ba47d153b7b040931a5cbe9220866] s390/jump_label: Switch to relative references
git bisect bad 13ddb52c165ba47d153b7b040931a5cbe9220866
# bad: [e872267b8bcbb179e21ccc7118f258873d6e7a59] jump_table: Move entries into ro_after_init region
git bisect bad e872267b8bcbb179e21ccc7118f258873d6e7a59
# first bad commit: [e872267b8bcbb179e21ccc7118f258873d6e7a59] jump_table: Move entries into ro_after_init region
diff mbox series

Patch

diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index b43f8d33a369..4042bbf3f9ad 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -66,6 +66,7 @@  SECTIONS
 		 *(.data..ro_after_init)
 	}
 	EXCEPTION_TABLE(16)
+	JUMP_TABLE_DATA
 	. = ALIGN(PAGE_SIZE);
 	__end_ro_after_init = .;
 
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 7b75ff6e2fce..f09ee3c544bc 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -253,10 +253,6 @@ 
 	STRUCT_ALIGN();							\
 	*(__tracepoints)						\
 	/* implement dynamic printk debug */				\
-	. = ALIGN(8);                                                   \
-	__start___jump_table = .;					\
-	KEEP(*(__jump_table))                                           \
-	__stop___jump_table = .;					\
 	. = ALIGN(8);							\
 	__start___verbose = .;						\
 	KEEP(*(__verbose))                                              \
@@ -300,6 +296,12 @@ 
 	. = __start_init_task + THREAD_SIZE;				\
 	__end_init_task = .;
 
+#define JUMP_TABLE_DATA							\
+	. = ALIGN(8);							\
+	__start___jump_table = .;					\
+	KEEP(*(__jump_table))						\
+	__stop___jump_table = .;
+
 /*
  * Allow architectures to handle ro_after_init data on their
  * own by defining an empty RO_AFTER_INIT_DATA.
@@ -308,6 +310,7 @@ 
 #define RO_AFTER_INIT_DATA						\
 	__start_ro_after_init = .;					\
 	*(.data..ro_after_init)						\
+	JUMP_TABLE_DATA							\
 	__end_ro_after_init = .;
 #endif
 
diff --git a/kernel/module.c b/kernel/module.c
index 6746c85511fe..49a405891587 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -3315,6 +3315,15 @@  static struct module *layout_and_allocate(struct load_info *info, int flags)
 	 * Note: ro_after_init sections also have SHF_{WRITE,ALLOC} set.
 	 */
 	ndx = find_sec(info, ".data..ro_after_init");
+	if (ndx)
+		info->sechdrs[ndx].sh_flags |= SHF_RO_AFTER_INIT;
+	/*
+	 * Mark the __jump_table section as ro_after_init as well: these data
+	 * structures are never modified, with the exception of entries that
+	 * refer to code in the __init section, which are annotated as such
+	 * at module load time.
+	 */
+	ndx = find_sec(info, "__jump_table");
 	if (ndx)
 		info->sechdrs[ndx].sh_flags |= SHF_RO_AFTER_INIT;