Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mm: avoid setting up anonymous pages into file mapping

Reading page fault handler code I've noticed that under right
circumstances kernel would map anonymous pages into file mappings: if
the VMA doesn't have vm_ops->fault() and the VMA wasn't fully populated
on ->mmap(), kernel would handle page fault to not populated pte with
do_anonymous_page().

Let's change page fault handler to use do_anonymous_page() only on
anonymous VMA (->vm_ops == NULL) and make sure that the VMA is not
shared.

For file mappings without vm_ops->fault() or shred VMA without vm_ops,
page fault on pte_none() entry would lead to SIGBUS.

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Acked-by: Oleg Nesterov <oleg@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Willy Tarreau <w@1wt.eu>
Cc: stable@vger.kernel.org
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Kirill A. Shutemov and committed by
Linus Torvalds
6b7339f4 883a2dfd

+13 -7
+13 -7
mm/memory.c
··· 2670 2670 2671 2671 pte_unmap(page_table); 2672 2672 2673 + /* File mapping without ->vm_ops ? */ 2674 + if (vma->vm_flags & VM_SHARED) 2675 + return VM_FAULT_SIGBUS; 2676 + 2673 2677 /* Check if we need to add a guard page to the stack */ 2674 2678 if (check_stack_guard_page(vma, address) < 0) 2675 2679 return VM_FAULT_SIGSEGV; ··· 3103 3099 - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff; 3104 3100 3105 3101 pte_unmap(page_table); 3102 + /* The VMA was not fully populated on mmap() or missing VM_DONTEXPAND */ 3103 + if (!vma->vm_ops->fault) 3104 + return VM_FAULT_SIGBUS; 3106 3105 if (!(flags & FAULT_FLAG_WRITE)) 3107 3106 return do_read_fault(mm, vma, address, pmd, pgoff, flags, 3108 3107 orig_pte); ··· 3251 3244 barrier(); 3252 3245 if (!pte_present(entry)) { 3253 3246 if (pte_none(entry)) { 3254 - if (vma->vm_ops) { 3255 - if (likely(vma->vm_ops->fault)) 3256 - return do_fault(mm, vma, address, pte, 3257 - pmd, flags, entry); 3258 - } 3259 - return do_anonymous_page(mm, vma, address, 3260 - pte, pmd, flags); 3247 + if (vma->vm_ops) 3248 + return do_fault(mm, vma, address, pte, pmd, 3249 + flags, entry); 3250 + 3251 + return do_anonymous_page(mm, vma, address, pte, pmd, 3252 + flags); 3261 3253 } 3262 3254 return do_swap_page(mm, vma, address, 3263 3255 pte, pmd, flags, entry);