Commit 502f6604 authored by Suresh Siddha's avatar Suresh Siddha Committed by Ingo Molnar

x86, cpa: Fix kernel text RO checks in static_protection()

Steven Rostedt reported that we are unconditionally making the
kernel text mapping as read-only. i.e., if someone does cpa() to
the kernel text area for setting/clearing any page table
attribute, we unconditionally clear the read-write attribute for
the kernel text mapping that is set at compile time.

We should delay (to forbid the write attribute) and enforce only
after the kernel has mapped the text as read-only.
Reported-by: default avatarSteven Rostedt <rostedt@goodmis.org>
Signed-off-by: default avatarSuresh Siddha <suresh.b.siddha@intel.com>
Acked-by: default avatarSteven Rostedt <rostedt@goodmis.org>
Tested-by: default avatarSteven Rostedt <rostedt@goodmis.org>
LKML-Reference: <20091029024820.996634347@sbs-t61.sc.intel.com>
[ marked kernel_set_to_readonly as __read_mostly ]
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 883242dd
...@@ -176,6 +176,7 @@ void clflush_cache_range(void *addr, unsigned int size); ...@@ -176,6 +176,7 @@ void clflush_cache_range(void *addr, unsigned int size);
#ifdef CONFIG_DEBUG_RODATA #ifdef CONFIG_DEBUG_RODATA
void mark_rodata_ro(void); void mark_rodata_ro(void);
extern const int rodata_test_data; extern const int rodata_test_data;
extern int kernel_set_to_readonly;
void set_kernel_text_rw(void); void set_kernel_text_rw(void);
void set_kernel_text_ro(void); void set_kernel_text_ro(void);
#else #else
......
...@@ -997,7 +997,7 @@ static noinline int do_test_wp_bit(void) ...@@ -997,7 +997,7 @@ static noinline int do_test_wp_bit(void)
const int rodata_test_data = 0xC3; const int rodata_test_data = 0xC3;
EXPORT_SYMBOL_GPL(rodata_test_data); EXPORT_SYMBOL_GPL(rodata_test_data);
static int kernel_set_to_readonly; int kernel_set_to_readonly __read_mostly;
void set_kernel_text_rw(void) void set_kernel_text_rw(void)
{ {
......
...@@ -695,7 +695,7 @@ void __init mem_init(void) ...@@ -695,7 +695,7 @@ void __init mem_init(void)
const int rodata_test_data = 0xC3; const int rodata_test_data = 0xC3;
EXPORT_SYMBOL_GPL(rodata_test_data); EXPORT_SYMBOL_GPL(rodata_test_data);
static int kernel_set_to_readonly; int kernel_set_to_readonly;
void set_kernel_text_rw(void) void set_kernel_text_rw(void)
{ {
......
...@@ -282,14 +282,16 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long address, ...@@ -282,14 +282,16 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long address,
#if defined(CONFIG_X86_64) && defined(CONFIG_DEBUG_RODATA) && \ #if defined(CONFIG_X86_64) && defined(CONFIG_DEBUG_RODATA) && \
!defined(CONFIG_DYNAMIC_FTRACE) !defined(CONFIG_DYNAMIC_FTRACE)
/* /*
* Kernel text mappings for the large page aligned .rodata section * Once the kernel maps the text as RO (kernel_set_to_readonly is set),
* will be read-only. For the kernel identity mappings covering * kernel text mappings for the large page aligned text, rodata sections
* the holes caused by this alignment can be anything. * will be always read-only. For the kernel identity mappings covering
* the holes caused by this alignment can be anything that user asks.
* *
* This will preserve the large page mappings for kernel text/data * This will preserve the large page mappings for kernel text/data
* at no extra cost. * at no extra cost.
*/ */
if (within(address, (unsigned long)_text, if (kernel_set_to_readonly &&
within(address, (unsigned long)_text,
(unsigned long)__end_rodata_hpage_align)) (unsigned long)__end_rodata_hpage_align))
pgprot_val(forbidden) |= _PAGE_RW; pgprot_val(forbidden) |= _PAGE_RW;
#endif #endif
......
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