x86/mm: Ease W^X enforcement back to just a warning
Currently, the "change_page_attr" (CPA) code refuses to create W+X mappings on 64-bit kernels. There have been reports both from 32-bit[1] and from BPF[2] users where this change kept the system from booting. These reports are showing up even after about a month of soak time in -next. To avoid breaking anything, never enforce W^X. Always warn and return the requested permissions even if a problem is detected. 1. https://lore.kernel.org/all/CAMj1kXHcF_iK_g0OZSkSv56Wmr=eQGQwNstcNjLEfS=mm7a06w@mail.gmail.com/ 2. https://lore.kernel.org/bpf/c84cc27c1a5031a003039748c3c099732a718aec.camel@kernel.org/T/#u Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ingo Molnar <mingo@redhat.com> Cc: Borislav Petkov <bp@alien8.de> Cc: x86@kernel.org Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Kees Cook <keescook@chromium.org> Cc: Peter Zijlstra <peterz@infradead.org>
This commit is contained in:
parent
8c4934f475
commit
c5129ecc12
@ -580,7 +580,7 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long start,
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate and enforce strict W^X semantics.
|
||||
* Validate strict W^X semantics.
|
||||
*/
|
||||
static inline pgprot_t verify_rwx(pgprot_t old, pgprot_t new, unsigned long start,
|
||||
unsigned long pfn, unsigned long npg)
|
||||
@ -595,7 +595,7 @@ static inline pgprot_t verify_rwx(pgprot_t old, pgprot_t new, unsigned long star
|
||||
if (IS_ENABLED(CONFIG_X86_32))
|
||||
return new;
|
||||
|
||||
/* Only enforce when NX is supported: */
|
||||
/* Only verify when NX is supported: */
|
||||
if (!(__supported_pte_mask & _PAGE_NX))
|
||||
return new;
|
||||
|
||||
@ -606,13 +606,17 @@ static inline pgprot_t verify_rwx(pgprot_t old, pgprot_t new, unsigned long star
|
||||
return new;
|
||||
|
||||
end = start + npg * PAGE_SIZE - 1;
|
||||
WARN_ONCE(1, "CPA refuse W^X violation: %016llx -> %016llx range: 0x%016lx - 0x%016lx PFN %lx\n",
|
||||
WARN_ONCE(1, "CPA detected W^X violation: %016llx -> %016llx range: 0x%016lx - 0x%016lx PFN %lx\n",
|
||||
(unsigned long long)pgprot_val(old),
|
||||
(unsigned long long)pgprot_val(new),
|
||||
start, end, pfn);
|
||||
|
||||
/* refuse the transition into WX */
|
||||
return old;
|
||||
/*
|
||||
* For now, allow all permission change attempts by returning the
|
||||
* attempted permissions. This can 'return old' to actively
|
||||
* refuse the permission change at a later time.
|
||||
*/
|
||||
return new;
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user