Loading arch/x86/include/asm/cacheflush.h +5 −0 Original line number Diff line number Diff line Loading @@ -104,6 +104,11 @@ void clflush_cache_range(void *addr, unsigned int size); #ifdef CONFIG_DEBUG_RODATA void mark_rodata_ro(void); extern const int rodata_test_data; void set_kernel_text_rw(void); void set_kernel_text_ro(void); #else static inline void set_kernel_text_rw(void) { } static inline void set_kernel_text_ro(void) { } #endif #ifdef CONFIG_DEBUG_RODATA_TEST Loading arch/x86/kernel/ftrace.c +17 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <linux/init.h> #include <linux/list.h> #include <asm/cacheflush.h> #include <asm/ftrace.h> #include <linux/ftrace.h> #include <asm/nops.h> Loading @@ -26,6 +27,18 @@ #ifdef CONFIG_DYNAMIC_FTRACE int ftrace_arch_code_modify_prepare(void) { set_kernel_text_rw(); return 0; } int ftrace_arch_code_modify_post_process(void) { set_kernel_text_ro(); return 0; } union ftrace_code_union { char code[MCOUNT_INSN_SIZE]; struct { Loading Loading @@ -111,6 +124,10 @@ static void ftrace_mod_code(void) */ mod_code_status = probe_kernel_write(mod_code_ip, mod_code_newcode, MCOUNT_INSN_SIZE); /* if we fail, then kill any new writers */ if (mod_code_status) mod_code_write = 0; } void ftrace_nmi_enter(void) Loading arch/x86/kernel/vmiclock_32.c +4 −1 Original line number Diff line number Diff line Loading @@ -283,10 +283,13 @@ void __devinit vmi_time_ap_init(void) #endif /** vmi clocksource */ static struct clocksource clocksource_vmi; static cycle_t read_real_cycles(void) { return vmi_timer_ops.get_cycle_counter(VMI_CYCLES_REAL); cycle_t ret = (cycle_t)vmi_timer_ops.get_cycle_counter(VMI_CYCLES_REAL); return ret >= clocksource_vmi.cycle_last ? ret : clocksource_vmi.cycle_last; } static struct clocksource clocksource_vmi = { Loading arch/x86/mm/init_32.c +32 −3 Original line number Diff line number Diff line Loading @@ -1155,17 +1155,47 @@ static noinline int do_test_wp_bit(void) const int rodata_test_data = 0xC3; EXPORT_SYMBOL_GPL(rodata_test_data); static int kernel_set_to_readonly; void set_kernel_text_rw(void) { unsigned long start = PFN_ALIGN(_text); unsigned long size = PFN_ALIGN(_etext) - start; if (!kernel_set_to_readonly) return; pr_debug("Set kernel text: %lx - %lx for read write\n", start, start+size); set_pages_rw(virt_to_page(start), size >> PAGE_SHIFT); } void set_kernel_text_ro(void) { unsigned long start = PFN_ALIGN(_text); unsigned long size = PFN_ALIGN(_etext) - start; if (!kernel_set_to_readonly) return; pr_debug("Set kernel text: %lx - %lx for read only\n", start, start+size); set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT); } void mark_rodata_ro(void) { unsigned long start = PFN_ALIGN(_text); unsigned long size = PFN_ALIGN(_etext) - start; #ifndef CONFIG_DYNAMIC_FTRACE /* Dynamic tracing modifies the kernel text section */ set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT); printk(KERN_INFO "Write protecting the kernel text: %luk\n", size >> 10); kernel_set_to_readonly = 1; #ifdef CONFIG_CPA_DEBUG printk(KERN_INFO "Testing CPA: Reverting %lx-%lx\n", start, start+size); Loading @@ -1174,7 +1204,6 @@ void mark_rodata_ro(void) printk(KERN_INFO "Testing CPA: write protecting again\n"); set_pages_ro(virt_to_page(start), size>>PAGE_SHIFT); #endif #endif /* CONFIG_DYNAMIC_FTRACE */ start += size; size = (unsigned long)__end_rodata - start; Loading arch/x86/mm/init_64.c +32 −5 Original line number Diff line number Diff line Loading @@ -986,21 +986,48 @@ void free_initmem(void) const int rodata_test_data = 0xC3; EXPORT_SYMBOL_GPL(rodata_test_data); static int kernel_set_to_readonly; void set_kernel_text_rw(void) { unsigned long start = PFN_ALIGN(_stext); unsigned long end = PFN_ALIGN(__start_rodata); if (!kernel_set_to_readonly) return; pr_debug("Set kernel text: %lx - %lx for read write\n", start, end); set_memory_rw(start, (end - start) >> PAGE_SHIFT); } void set_kernel_text_ro(void) { unsigned long start = PFN_ALIGN(_stext); unsigned long end = PFN_ALIGN(__start_rodata); if (!kernel_set_to_readonly) return; pr_debug("Set kernel text: %lx - %lx for read only\n", start, end); set_memory_ro(start, (end - start) >> PAGE_SHIFT); } void mark_rodata_ro(void) { unsigned long start = PFN_ALIGN(_stext), end = PFN_ALIGN(__end_rodata); unsigned long rodata_start = ((unsigned long)__start_rodata + PAGE_SIZE - 1) & PAGE_MASK; #ifdef CONFIG_DYNAMIC_FTRACE /* Dynamic tracing modifies the kernel text section */ start = rodata_start; #endif printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n", (end - start) >> 10); set_memory_ro(start, (end - start) >> PAGE_SHIFT); kernel_set_to_readonly = 1; /* * The rodata section (but not the kernel text!) should also be * not-executable. Loading Loading
arch/x86/include/asm/cacheflush.h +5 −0 Original line number Diff line number Diff line Loading @@ -104,6 +104,11 @@ void clflush_cache_range(void *addr, unsigned int size); #ifdef CONFIG_DEBUG_RODATA void mark_rodata_ro(void); extern const int rodata_test_data; void set_kernel_text_rw(void); void set_kernel_text_ro(void); #else static inline void set_kernel_text_rw(void) { } static inline void set_kernel_text_ro(void) { } #endif #ifdef CONFIG_DEBUG_RODATA_TEST Loading
arch/x86/kernel/ftrace.c +17 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <linux/init.h> #include <linux/list.h> #include <asm/cacheflush.h> #include <asm/ftrace.h> #include <linux/ftrace.h> #include <asm/nops.h> Loading @@ -26,6 +27,18 @@ #ifdef CONFIG_DYNAMIC_FTRACE int ftrace_arch_code_modify_prepare(void) { set_kernel_text_rw(); return 0; } int ftrace_arch_code_modify_post_process(void) { set_kernel_text_ro(); return 0; } union ftrace_code_union { char code[MCOUNT_INSN_SIZE]; struct { Loading Loading @@ -111,6 +124,10 @@ static void ftrace_mod_code(void) */ mod_code_status = probe_kernel_write(mod_code_ip, mod_code_newcode, MCOUNT_INSN_SIZE); /* if we fail, then kill any new writers */ if (mod_code_status) mod_code_write = 0; } void ftrace_nmi_enter(void) Loading
arch/x86/kernel/vmiclock_32.c +4 −1 Original line number Diff line number Diff line Loading @@ -283,10 +283,13 @@ void __devinit vmi_time_ap_init(void) #endif /** vmi clocksource */ static struct clocksource clocksource_vmi; static cycle_t read_real_cycles(void) { return vmi_timer_ops.get_cycle_counter(VMI_CYCLES_REAL); cycle_t ret = (cycle_t)vmi_timer_ops.get_cycle_counter(VMI_CYCLES_REAL); return ret >= clocksource_vmi.cycle_last ? ret : clocksource_vmi.cycle_last; } static struct clocksource clocksource_vmi = { Loading
arch/x86/mm/init_32.c +32 −3 Original line number Diff line number Diff line Loading @@ -1155,17 +1155,47 @@ static noinline int do_test_wp_bit(void) const int rodata_test_data = 0xC3; EXPORT_SYMBOL_GPL(rodata_test_data); static int kernel_set_to_readonly; void set_kernel_text_rw(void) { unsigned long start = PFN_ALIGN(_text); unsigned long size = PFN_ALIGN(_etext) - start; if (!kernel_set_to_readonly) return; pr_debug("Set kernel text: %lx - %lx for read write\n", start, start+size); set_pages_rw(virt_to_page(start), size >> PAGE_SHIFT); } void set_kernel_text_ro(void) { unsigned long start = PFN_ALIGN(_text); unsigned long size = PFN_ALIGN(_etext) - start; if (!kernel_set_to_readonly) return; pr_debug("Set kernel text: %lx - %lx for read only\n", start, start+size); set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT); } void mark_rodata_ro(void) { unsigned long start = PFN_ALIGN(_text); unsigned long size = PFN_ALIGN(_etext) - start; #ifndef CONFIG_DYNAMIC_FTRACE /* Dynamic tracing modifies the kernel text section */ set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT); printk(KERN_INFO "Write protecting the kernel text: %luk\n", size >> 10); kernel_set_to_readonly = 1; #ifdef CONFIG_CPA_DEBUG printk(KERN_INFO "Testing CPA: Reverting %lx-%lx\n", start, start+size); Loading @@ -1174,7 +1204,6 @@ void mark_rodata_ro(void) printk(KERN_INFO "Testing CPA: write protecting again\n"); set_pages_ro(virt_to_page(start), size>>PAGE_SHIFT); #endif #endif /* CONFIG_DYNAMIC_FTRACE */ start += size; size = (unsigned long)__end_rodata - start; Loading
arch/x86/mm/init_64.c +32 −5 Original line number Diff line number Diff line Loading @@ -986,21 +986,48 @@ void free_initmem(void) const int rodata_test_data = 0xC3; EXPORT_SYMBOL_GPL(rodata_test_data); static int kernel_set_to_readonly; void set_kernel_text_rw(void) { unsigned long start = PFN_ALIGN(_stext); unsigned long end = PFN_ALIGN(__start_rodata); if (!kernel_set_to_readonly) return; pr_debug("Set kernel text: %lx - %lx for read write\n", start, end); set_memory_rw(start, (end - start) >> PAGE_SHIFT); } void set_kernel_text_ro(void) { unsigned long start = PFN_ALIGN(_stext); unsigned long end = PFN_ALIGN(__start_rodata); if (!kernel_set_to_readonly) return; pr_debug("Set kernel text: %lx - %lx for read only\n", start, end); set_memory_ro(start, (end - start) >> PAGE_SHIFT); } void mark_rodata_ro(void) { unsigned long start = PFN_ALIGN(_stext), end = PFN_ALIGN(__end_rodata); unsigned long rodata_start = ((unsigned long)__start_rodata + PAGE_SIZE - 1) & PAGE_MASK; #ifdef CONFIG_DYNAMIC_FTRACE /* Dynamic tracing modifies the kernel text section */ start = rodata_start; #endif printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n", (end - start) >> 10); set_memory_ro(start, (end - start) >> PAGE_SHIFT); kernel_set_to_readonly = 1; /* * The rodata section (but not the kernel text!) should also be * not-executable. Loading