Skip to content

Commit 3335224

Browse files
jpoimboeIngo Molnar
authored andcommitted
jump_label: Explicitly disable jump labels in __init code
After initmem has been freed, any jump labels in __init code are prevented from being written to by the kernel_text_address() check in __jump_label_update(). However, this check is quite broad. If kernel_text_address() were to return false for any other reason, the jump label write would fail silently with no warning. For jump labels in module init code, entry->code is set to zero to indicate that the entry is disabled. Do the same thing for core kernel init code. This makes the behavior more consistent, and will also make it more straightforward to detect non-init jump label write failures in the next patch. Signed-off-by: Josh Poimboeuf <[email protected]> Acked-by: Peter Zijlstra <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Jason Baron <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Steven Rostedt <[email protected]> Cc: Thomas Gleixner <[email protected]> Link: http://lkml.kernel.org/r/c52825c73f3a174e8398b6898284ec20d4deb126.1519051220.git.jpoimboe@redhat.com Signed-off-by: Ingo Molnar <[email protected]>
1 parent f3d415e commit 3335224

File tree

3 files changed

+21
-0
lines changed

3 files changed

+21
-0
lines changed

include/linux/jump_label.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ extern struct jump_entry __start___jump_table[];
151151
extern struct jump_entry __stop___jump_table[];
152152

153153
extern void jump_label_init(void);
154+
extern void jump_label_invalidate_init(void);
154155
extern void jump_label_lock(void);
155156
extern void jump_label_unlock(void);
156157
extern void arch_jump_label_transform(struct jump_entry *entry,
@@ -198,6 +199,8 @@ static __always_inline void jump_label_init(void)
198199
static_key_initialized = true;
199200
}
200201

202+
static inline void jump_label_invalidate_init(void) {}
203+
201204
static __always_inline bool static_key_false(struct static_key *key)
202205
{
203206
if (unlikely(static_key_count(key) > 0))

init/main.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
#include <linux/io.h>
9090
#include <linux/cache.h>
9191
#include <linux/rodata_test.h>
92+
#include <linux/jump_label.h>
9293

9394
#include <asm/io.h>
9495
#include <asm/bugs.h>
@@ -1000,6 +1001,7 @@ static int __ref kernel_init(void *unused)
10001001
/* need to finish all async __init code before freeing the memory */
10011002
async_synchronize_full();
10021003
ftrace_free_init_mem();
1004+
jump_label_invalidate_init();
10031005
free_initmem();
10041006
mark_readonly();
10051007
system_state = SYSTEM_RUNNING;

kernel/jump_label.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <linux/jump_label_ratelimit.h>
1717
#include <linux/bug.h>
1818
#include <linux/cpu.h>
19+
#include <asm/sections.h>
1920

2021
#ifdef HAVE_JUMP_LABEL
2122

@@ -417,6 +418,20 @@ void __init jump_label_init(void)
417418
cpus_read_unlock();
418419
}
419420

421+
/* Disable any jump label entries in __init code */
422+
void __init jump_label_invalidate_init(void)
423+
{
424+
struct jump_entry *iter_start = __start___jump_table;
425+
struct jump_entry *iter_stop = __stop___jump_table;
426+
struct jump_entry *iter;
427+
428+
for (iter = iter_start; iter < iter_stop; iter++) {
429+
if (iter->code >= (unsigned long)_sinittext &&
430+
iter->code < (unsigned long)_einittext)
431+
iter->code = 0;
432+
}
433+
}
434+
420435
#ifdef CONFIG_MODULES
421436

422437
static enum jump_label_type jump_label_init_type(struct jump_entry *entry)
@@ -633,6 +648,7 @@ static void jump_label_del_module(struct module *mod)
633648
}
634649
}
635650

651+
/* Disable any jump label entries in module init code */
636652
static void jump_label_invalidate_module_init(struct module *mod)
637653
{
638654
struct jump_entry *iter_start = mod->jump_entries;

0 commit comments

Comments
 (0)