Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mm/init: Add 'rodata=off' boot cmdline parameter to disable read-only kernel mappings

It may be useful to debug writes to the readonly sections of memory,
so provide a cmdline "rodata=off" to allow for this. This can be
expanded in the future to support "log" and "write" modes, but that
will need to be architecture-specific.

This also makes KDB software breakpoints more usable, as read-only
mappings can now be disabled on any kernel.

Suggested-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: David Brown <david.brown@linaro.org>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: Emese Revfy <re.emese@gmail.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mathias Krause <minipli@googlemail.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: PaX Team <pageexec@freemail.hu>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: kernel-hardening@lists.openwall.com
Cc: linux-arch <linux-arch@vger.kernel.org>
Link: http://lkml.kernel.org/r/1455748879-21872-3-git-send-email-keescook@chromium.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>

authored by

Kees Cook and committed by
Ingo Molnar
d2aa1aca e267d97b

+28 -7
+4
Documentation/kernel-parameters.txt
··· 3491 3491 3492 3492 ro [KNL] Mount root device read-only on boot 3493 3493 3494 + rodata= [KNL] 3495 + on Mark read-only kernel memory as read-only (default). 3496 + off Leave read-only kernel memory writable for debugging. 3497 + 3494 3498 root= [KNL] Root filesystem 3495 3499 See name_to_dev_t comment in init/do_mounts.c. 3496 3500
+23 -4
init/main.c
··· 93 93 extern void init_IRQ(void); 94 94 extern void fork_init(void); 95 95 extern void radix_tree_init(void); 96 - #ifndef CONFIG_DEBUG_RODATA 97 - static inline void mark_rodata_ro(void) { } 98 - #endif 99 96 100 97 /* 101 98 * Debug helper: via this flag we know that we are in 'early bootup code' ··· 926 929 927 930 static noinline void __init kernel_init_freeable(void); 928 931 932 + #ifdef CONFIG_DEBUG_RODATA 933 + static bool rodata_enabled = true; 934 + static int __init set_debug_rodata(char *str) 935 + { 936 + return strtobool(str, &rodata_enabled); 937 + } 938 + __setup("rodata=", set_debug_rodata); 939 + 940 + static void mark_readonly(void) 941 + { 942 + if (rodata_enabled) 943 + mark_rodata_ro(); 944 + else 945 + pr_info("Kernel memory protection disabled.\n"); 946 + } 947 + #else 948 + static inline void mark_readonly(void) 949 + { 950 + pr_warn("This architecture does not have kernel memory protection.\n"); 951 + } 952 + #endif 953 + 929 954 static int __ref kernel_init(void *unused) 930 955 { 931 956 int ret; ··· 956 937 /* need to finish all async __init code before freeing the memory */ 957 938 async_synchronize_full(); 958 939 free_initmem(); 959 - mark_rodata_ro(); 940 + mark_readonly(); 960 941 system_state = SYSTEM_RUNNING; 961 942 numa_default_policy(); 962 943
+1 -3
kernel/debug/kdb/kdb_bp.c
··· 153 153 } else { 154 154 kdb_printf("%s: failed to set breakpoint at 0x%lx\n", 155 155 __func__, bp->bp_addr); 156 - #ifdef CONFIG_DEBUG_RODATA 157 156 if (!bp->bp_type) { 158 157 kdb_printf("Software breakpoints are unavailable.\n" 159 - " Change the kernel CONFIG_DEBUG_RODATA=n\n" 158 + " Boot the kernel with rodata=off\n" 160 159 " OR use hw breaks: help bph\n"); 161 160 } 162 - #endif 163 161 return 1; 164 162 } 165 163 return 0;