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

x86 specific parts to make the .rodata section read only

Signed-off-by: Arjan van de Ven <arjan@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Adrian Bunk <bunk@stusta.de>
Cc: Andi Kleen <ak@muc.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
Arjan van de Ven
2006-01-06 00:12:02 -08:00
committed by Linus Torvalds
parent 37b73c8281
commit 63aaf3086b
3 changed files with 38 additions and 0 deletions

View File

@@ -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

View File

@@ -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)
{ {

View File

@@ -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 */