]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
jump_table: Move entries into ro_after_init region
authorArd Biesheuvel <ard.biesheuvel@linaro.org>
Wed, 19 Sep 2018 06:51:43 +0000 (23:51 -0700)
committerThomas Gleixner <tglx@linutronix.de>
Thu, 27 Sep 2018 15:56:49 +0000 (17:56 +0200)
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.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Kees Cook <keescook@chromium.org>
Acked-by: Jessica Yu <jeyu@kernel.org>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-s390@vger.kernel.org
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Link: https://lkml.kernel.org/r/20180919065144.25010-9-ard.biesheuvel@linaro.org
arch/s390/kernel/vmlinux.lds.S
include/asm-generic/vmlinux.lds.h
kernel/module.c

index b43f8d33a3697de32e7c9f7dae4cbf2e7cf3bc46..4042bbf3f9ad4e58ddb6d5c5ae23bac0c2ed94a0 100644 (file)
@@ -66,6 +66,7 @@ SECTIONS
                 *(.data..ro_after_init)
        }
        EXCEPTION_TABLE(16)
+       JUMP_TABLE_DATA
        . = ALIGN(PAGE_SIZE);
        __end_ro_after_init = .;
 
index 7b75ff6e2fceeb407e828c4e171176afc5ae7281..f09ee3c544bc78097555bec82d787e79398589c1 100644 (file)
        STRUCT_ALIGN();                                                 \
        *(__tracepoints)                                                \
        /* implement dynamic printk debug */                            \
-       . = ALIGN(8);                                                   \
-       __start___jump_table = .;                                       \
-       KEEP(*(__jump_table))                                           \
-       __stop___jump_table = .;                                        \
        . = ALIGN(8);                                                   \
        __start___verbose = .;                                          \
        KEEP(*(__verbose))                                              \
        . = __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.
 #define RO_AFTER_INIT_DATA                                             \
        __start_ro_after_init = .;                                      \
        *(.data..ro_after_init)                                         \
+       JUMP_TABLE_DATA                                                 \
        __end_ro_after_init = .;
 #endif
 
index 6746c85511fefe40f335207245df81d3e246a0c8..49a4058915870cac3c54f336ff252703594e3bf0 100644 (file)
@@ -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;