]> err.no Git - linux-2.6/commitdiff
[S390] protect _PAGE_SPECIAL bit against mprotect
authorNick Piggin <npiggin@suse.de>
Tue, 8 Jul 2008 09:31:06 +0000 (11:31 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Tue, 8 Jul 2008 09:31:15 +0000 (11:31 +0200)
Stop mprotect's pte_modify from wiping out the s390 pte_special bit, which
caused oops thereafter when vm_normal_page thought X's abnormal was normal.

Debugged-by: Ryan Hope <rmh3093@gmail.com>
Debugged-by: Zan Lynx <zlynx@acm.org>
Acked-by: Hugh Dickins <hugh@veritas.com>
Signed-off-by: Nick Piggin <npiggin@suse.de>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
include/asm-s390/pgtable.h

index c7f4f8e3e297188310955e325c20717510acc590..bd0ea191dfa9d17030f89e5f2115407e56140dc8 100644 (file)
@@ -223,6 +223,9 @@ extern char empty_zero_page[PAGE_SIZE];
 #define _PAGE_SPECIAL  0x004           /* SW associated with special page */
 #define __HAVE_ARCH_PTE_SPECIAL
 
+/* Set of bits not changed in pte_modify */
+#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_SPECIAL)
+
 /* Six different types of pages. */
 #define _PAGE_TYPE_EMPTY       0x400
 #define _PAGE_TYPE_NONE                0x401
@@ -681,7 +684,7 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *pt
  */
 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 {
-       pte_val(pte) &= PAGE_MASK;
+       pte_val(pte) &= _PAGE_CHG_MASK;
        pte_val(pte) |= pgprot_val(newprot);
        return pte;
 }