arm: Add support for KERNEL_TEXT_RDONLY

When using FORCE_PAGES to allocate the kernel memory into pages,
provide an option to mark the the kernel text section as read only.
Since the kernel text pages are always mapped in the kernel, anyone
can write to the page if they have the address.
Enable this option to mark the kernel text pages as read only to
trigger a fault if any code attempts to write to a page that is
part of the kernel text section.

Change-Id: I27de98e2e82cf6dfe9370695239e1fae26ad0e97
Signed-off-by: Prasad Sodagudi <psodagud@codeaurora.org>
This commit is contained in:
Prasad Sodagudi 2014-11-15 22:48:10 +05:30
parent 4a8b6c6435
commit 8ac0074944
3 changed files with 30 additions and 0 deletions

View file

@ -98,6 +98,19 @@ config FREE_PAGES_RDONLY
If unsure, say N.
config KERNEL_TEXT_RDONLY
bool "Set kernel text section pages as read only"
depends on FREE_PAGES_RDONLY
help
The kernel text pages are always mapped in the kernel.
This means that anyone can write to the page if they have
the address. Enable this option to mark the kernel text pages
as read only to trigger a fault if any code attempts to write
to a page part of the kernel text section. This may have a
performance impact.
If unsure, say N.
# These options are only for real kernel hackers who want to get their hands dirty.
config DEBUG_LL
bool "Kernel low-level debugging functions (read help!)"

View file

@ -463,6 +463,12 @@ int set_memory_rw(unsigned long addr, int numpages);
int set_memory_x(unsigned long addr, int numpages);
int set_memory_nx(unsigned long addr, int numpages);
#ifdef CONFIG_KERNEL_TEXT_RDONLY
void set_kernel_text_ro(void);
#else
static inline void set_kernel_text_ro(void) { }
#endif
#ifdef CONFIG_FREE_PAGES_RDONLY
#define mark_addr_rdonly(a) set_memory_ro((unsigned long)a, 1);
#define mark_addr_rdwrite(a) set_memory_rw((unsigned long)a, 1);

View file

@ -883,3 +883,14 @@ static int __init msm_krait_wfe_init(void)
}
pure_initcall(msm_krait_wfe_init);
#endif
#ifdef CONFIG_KERNEL_TEXT_RDONLY
void set_kernel_text_ro(void)
{
unsigned long start = PFN_ALIGN(_stext);
unsigned long end = PFN_ALIGN(_etext);
/* Set the kernel identity mapping for text RO. */
set_memory_ro(start, (end - start) >> PAGE_SHIFT);
}
#endif