Skip to content

Commit 502f660

Browse files
Suresh SiddhaIngo Molnar
authored andcommitted
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: Steven Rostedt <[email protected]> Signed-off-by: Suresh Siddha <[email protected]> Acked-by: Steven Rostedt <[email protected]> Tested-by: Steven Rostedt <[email protected]> LKML-Reference: <[email protected]> [ marked kernel_set_to_readonly as __read_mostly ] Signed-off-by: Ingo Molnar <[email protected]>
1 parent 883242d commit 502f660

File tree

4 files changed

+9
-6
lines changed

4 files changed

+9
-6
lines changed

arch/x86/include/asm/cacheflush.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ void clflush_cache_range(void *addr, unsigned int size);
176176
#ifdef CONFIG_DEBUG_RODATA
177177
void mark_rodata_ro(void);
178178
extern const int rodata_test_data;
179+
extern int kernel_set_to_readonly;
179180
void set_kernel_text_rw(void);
180181
void set_kernel_text_ro(void);
181182
#else

arch/x86/mm/init_32.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -997,7 +997,7 @@ static noinline int do_test_wp_bit(void)
997997
const int rodata_test_data = 0xC3;
998998
EXPORT_SYMBOL_GPL(rodata_test_data);
999999

1000-
static int kernel_set_to_readonly;
1000+
int kernel_set_to_readonly __read_mostly;
10011001

10021002
void set_kernel_text_rw(void)
10031003
{

arch/x86/mm/init_64.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -695,7 +695,7 @@ void __init mem_init(void)
695695
const int rodata_test_data = 0xC3;
696696
EXPORT_SYMBOL_GPL(rodata_test_data);
697697

698-
static int kernel_set_to_readonly;
698+
int kernel_set_to_readonly;
699699

700700
void set_kernel_text_rw(void)
701701
{

arch/x86/mm/pageattr.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -282,14 +282,16 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long address,
282282
#if defined(CONFIG_X86_64) && defined(CONFIG_DEBUG_RODATA) && \
283283
!defined(CONFIG_DYNAMIC_FTRACE)
284284
/*
285-
* Kernel text mappings for the large page aligned .rodata section
286-
* will be read-only. For the kernel identity mappings covering
287-
* the holes caused by this alignment can be anything.
285+
* Once the kernel maps the text as RO (kernel_set_to_readonly is set),
286+
* kernel text mappings for the large page aligned text, rodata sections
287+
* will be always read-only. For the kernel identity mappings covering
288+
* the holes caused by this alignment can be anything that user asks.
288289
*
289290
* This will preserve the large page mappings for kernel text/data
290291
* at no extra cost.
291292
*/
292-
if (within(address, (unsigned long)_text,
293+
if (kernel_set_to_readonly &&
294+
within(address, (unsigned long)_text,
293295
(unsigned long)__end_rodata_hpage_align))
294296
pgprot_val(forbidden) |= _PAGE_RW;
295297
#endif

0 commit comments

Comments
 (0)