Commit 63aaf308 authored by Arjan van de Ven's avatar Arjan van de Ven Committed by Linus Torvalds

[PATCH] x86/x86_64: mark rodata section read only: x86 parts

x86 specific parts to make the .rodata section read only
Signed-off-by: default avatarArjan van de Ven <arjan@infradead.org>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarAdrian Bunk <bunk@stusta.de>
Cc: Andi Kleen <ak@muc.de>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 37b73c82
...@@ -42,6 +42,16 @@ config DEBUG_PAGEALLOC ...@@ -42,6 +42,16 @@ config DEBUG_PAGEALLOC
This results in a large slowdown, but helps to find certain types This results in a large slowdown, but helps to find certain types
of memory corruptions. of memory corruptions.
config DEBUG_RODATA
bool "Write protect kernel read-only data structures"
depends on DEBUG_KERNEL
help
Mark the kernel read-only data as write-protected in the pagetables,
in order to catch accidental (and incorrect) writes to such const
data. This option may have a slight performance impact because a
portion of the kernel code won't be covered by a 2MB TLB anymore.
If in doubt, say "N".
config 4KSTACKS config 4KSTACKS
bool "Use 4Kb for kernel stacks instead of 8Kb" bool "Use 4Kb for kernel stacks instead of 8Kb"
depends on DEBUG_KERNEL depends on DEBUG_KERNEL
......
...@@ -735,6 +735,30 @@ void free_initmem(void) ...@@ -735,6 +735,30 @@ void free_initmem(void)
printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (__init_end - __init_begin) >> 10); printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (__init_end - __init_begin) >> 10);
} }
#ifdef CONFIG_DEBUG_RODATA
extern char __start_rodata, __end_rodata;
void mark_rodata_ro(void)
{
unsigned long addr = (unsigned long)&__start_rodata;
for (; addr < (unsigned long)&__end_rodata; addr += PAGE_SIZE)
change_page_attr(virt_to_page(addr), 1, PAGE_KERNEL_RO);
printk ("Write protecting the kernel read-only data: %luk\n",
(unsigned long)(&__end_rodata - &__start_rodata) >> 10);
/*
* change_page_attr() requires a global_flush_tlb() call after it.
* We do this after the printk so that if something went wrong in the
* change, the printk gets out at least to give a better debug hint
* of who is the culprit.
*/
global_flush_tlb();
}
#endif
#ifdef CONFIG_BLK_DEV_INITRD #ifdef CONFIG_BLK_DEV_INITRD
void free_initrd_mem(unsigned long start, unsigned long end) void free_initrd_mem(unsigned long start, unsigned long end)
{ {
......
...@@ -31,4 +31,8 @@ int change_page_attr(struct page *page, int numpages, pgprot_t prot); ...@@ -31,4 +31,8 @@ int change_page_attr(struct page *page, int numpages, pgprot_t prot);
void kernel_map_pages(struct page *page, int numpages, int enable); void kernel_map_pages(struct page *page, int numpages, int enable);
#endif #endif
#ifdef CONFIG_DEBUG_RODATA
void mark_rodata_ro(void);
#endif
#endif /* _I386_CACHEFLUSH_H */ #endif /* _I386_CACHEFLUSH_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment