]> xenbits.xensource.com Git - people/jgross/linux.git/commitdiff
MIPS: Don't clear _PAGE_SPECIAL in _PAGE_CHG_MASK
authorHenry Willard <henry.willard@oracle.com>
Wed, 12 Apr 2023 21:29:53 +0000 (15:29 -0600)
committerThomas Bogendoerfer <tsbogend@alpha.franken.de>
Mon, 24 Apr 2023 07:48:51 +0000 (09:48 +0200)
In the special case where

p = mmap(NULL, ALLOC_SIZE, PROT_READ,
                MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0);

is followed by

rc = mprotect(p, ALLOC_SIZE, PROT_NONE);

the _PAGE_SPECIAL bit in the page tables will be cleared by
mistake and the later unmapped operations will incorrectly
modify the struct page for the the zero page. This sequence
occurs in the madvise05 test of the Linux Test Project
suite of tests.

This was discovered while testing an older version of the kernel
(5.4.17) on a MIPS device. Unfortunately, support for this device
is not available in newer kernels, so I can't test this with the
latest Linux kernel code. It looks like the problem exists in
newer kernels, but I can't verify it. Except for the LTP test,
this sequence of calls is probably not common.

Passing it along in the hope it will be useful to someone.

Signed-off-by: Henry Willard <henry.willard@oracle.com>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
arch/mips/include/asm/pgtable-bits.h

index 2362842ee2b51b08f585dbb8be97f5e409497eb2..1c576679aa87685692e9de3f73129a635a2af1fe 100644 (file)
@@ -280,6 +280,7 @@ static inline uint64_t pte_to_entrylo(unsigned long pte_val)
 #define __WRITEABLE    (_PAGE_SILENT_WRITE | _PAGE_WRITE | _PAGE_MODIFIED)
 
 #define _PAGE_CHG_MASK (_PAGE_ACCESSED | _PAGE_MODIFIED |      \
-                        _PAGE_SOFT_DIRTY | _PFN_MASK | _CACHE_MASK)
+                        _PAGE_SOFT_DIRTY | _PFN_MASK |   \
+                        _CACHE_MASK | _PAGE_SPECIAL)
 
 #endif /* _ASM_PGTABLE_BITS_H */