Re: [PATCH] [4.2 fix] x86, mpx: do not set ->vm_ops on mpx VMAs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Aug 03, 2015 at 01:36:23PM -0700, Greg KH wrote:
> On Mon, Aug 03, 2015 at 10:40:55PM +0300, Kirill A. Shutemov wrote:
> > On Mon, Aug 03, 2015 at 09:19:14AM -0700, Greg KH wrote:
> > > On Mon, Aug 03, 2015 at 01:34:28PM +0300, Kirill A. Shutemov wrote:
> > > > Greg KH wrote:
> > > > > On Mon, Jul 20, 2015 at 02:29:58PM -0700, Dave Hansen wrote:
> > > > > > 
> > > > > > (sorry for the spam, I screwed up the stable@ address).
> > > > > > 
> > > > > > BTW, thanks to Kirill for doing this patch!  He posted it to LKML
> > > > > > but we need to ensure it is picked up for 4.2 and any -stable
> > > > > > kernels where this commit is applied:
> > > > > > 
> > > > > >     	6b7339f4: mm: avoid setting up anonymous pages into file mapping
> > > > > > 
> > > > > > That broke MPX support because MPX sets a vma->vm_ops on an
> > > > > > anonymous VMA.  We need this patch to make it work again,
> > > > > > basically removing MPX's use of ->vm_ops.  Kirill made me aware
> > > > > > of this long ago, but I didn't double-check that his fix got
> > > > > > submitted and merged.
> > > > > > 
> > > > > > I (Dave) fixed up a minor merge conflict and added the
> > > > > > try_unmap_single_bt() use of is_mpx_vma() (which were added
> > > > > > post-4.1).
> > > > > > 
> > > > > > Note for -stable: The first hunk may not apply cleanly because of
> > > > > > other activity in arch/x86/mm/mmap.c, but should be trivial to
> > > > > > apply by hand.  Hunk #5 on mpx.c is only present on 4.2-rc kernels.
> > > > > 
> > > > > Can someone send a version that is known to apply, you don't want to
> > > > > rely on me to get it right :)
> > > > 
> > > > Here it is.
> > > > 
> > > > MPX support was introduced in 3.19, so it only need to be applied to
> > > > 4.1-stable.
> > > 
> > > Thanks, now applied.
> > 
> > Just to make clear: we don't need MPX patch for older stables, but we
> > *do* need 6b7339f4 (mm: avoid setting up anonymous pages into file
> > mapping) to be ported into all stables.
> 
> Can you provide that backport, it isn't a direct cherry-pick.

Patches are in attach.

0001-mm-avoid-setting-up-anonymous-pages-3.18.patch is rebased onto v3.18.

0001-mm-avoid-setting-up-anonymous-pages-3.14.patch is rebased onto v3.14,
also applies cleanly to v3.12, v3.10, v3.4, v3.2.

0001-mm-avoid-setting-up-anonymous-pages-2.6.32.patch is rebased onto
v2.6.32.

Build tested for all these versions.

-- 
 Kirill A. Shutemov
>From 41456c4806bb0b4561602e037183790020a13532 Mon Sep 17 00:00:00 2001
From: "Kirill A. Shutemov" <kirill.shutemov@xxxxxxxxxxxxxxx>
Date: Mon, 6 Jul 2015 23:18:37 +0300
Subject: [PATCH] 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@xxxxxxxxxxxxxxx>
Acked-by: Oleg Nesterov <oleg@xxxxxxxxxx>
Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
Cc: Willy Tarreau <w@xxxxxx>
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx>
---
 mm/memory.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/mm/memory.c b/mm/memory.c
index d5f2ae9c4a23..04979a2b3eb4 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2636,6 +2636,10 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma,
 
 	pte_unmap(page_table);
 
+	/* File mapping without ->vm_ops ? */
+	if (vma->vm_flags & VM_SHARED)
+		return VM_FAULT_SIGBUS;
+
 	/* Check if we need to add a guard page to the stack */
 	if (check_stack_guard_page(vma, address) < 0)
 		return VM_FAULT_SIGBUS;
@@ -3040,6 +3044,9 @@ static int do_linear_fault(struct mm_struct *mm, struct vm_area_struct *vma,
 			- vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
 
 	pte_unmap(page_table);
+	/* The VMA was not fully populated on mmap() or missing VM_DONTEXPAND */
+	if (!vma->vm_ops->fault)
+		return VM_FAULT_SIGBUS;
 	if (!(flags & FAULT_FLAG_WRITE))
 		return do_read_fault(mm, vma, address, pmd, pgoff, flags,
 				orig_pte);
@@ -3205,11 +3212,10 @@ static int handle_pte_fault(struct mm_struct *mm,
 	entry = ACCESS_ONCE(*pte);
 	if (!pte_present(entry)) {
 		if (pte_none(entry)) {
-			if (vma->vm_ops) {
-				if (likely(vma->vm_ops->fault))
-					return do_linear_fault(mm, vma, address,
+			if (vma->vm_ops)
+				return do_linear_fault(mm, vma, address,
 						pte, pmd, flags, entry);
-			}
+
 			return do_anonymous_page(mm, vma, address,
 						 pte, pmd, flags);
 		}
-- 
2.4.6

>From 1d549cf546de91706f6c199f37bf62b6af656c44 Mon Sep 17 00:00:00 2001
From: "Kirill A. Shutemov" <kirill.shutemov@xxxxxxxxxxxxxxx>
Date: Mon, 6 Jul 2015 23:18:37 +0300
Subject: [PATCH] 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@xxxxxxxxxxxxxxx>
Acked-by: Oleg Nesterov <oleg@xxxxxxxxxx>
Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
Cc: Willy Tarreau <w@xxxxxx>
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx>
---
 mm/memory.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/mm/memory.c b/mm/memory.c
index 22dfa617bddb..86c09a8284cd 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -3228,6 +3228,10 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma,
 
 	pte_unmap(page_table);
 
+	/* File mapping without ->vm_ops ? */
+	if (vma->vm_flags & VM_SHARED)
+		return VM_FAULT_SIGBUS;
+
 	/* Check if we need to add a guard page to the stack */
 	if (check_stack_guard_page(vma, address) < 0)
 		return VM_FAULT_SIGBUS;
@@ -3496,6 +3500,9 @@ static int do_linear_fault(struct mm_struct *mm, struct vm_area_struct *vma,
 			- vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
 
 	pte_unmap(page_table);
+	/* The VMA was not fully populated on mmap() or missing VM_DONTEXPAND */
+	if (!vma->vm_ops->fault)
+		return VM_FAULT_SIGBUS;
 	return __do_fault(mm, vma, address, pmd, pgoff, flags, orig_pte);
 }
 
@@ -3644,11 +3651,9 @@ static int handle_pte_fault(struct mm_struct *mm,
 	entry = *pte;
 	if (!pte_present(entry)) {
 		if (pte_none(entry)) {
-			if (vma->vm_ops) {
-				if (likely(vma->vm_ops->fault))
-					return do_linear_fault(mm, vma, address,
+			if (vma->vm_ops)
+				return do_linear_fault(mm, vma, address,
 						pte, pmd, flags, entry);
-			}
 			return do_anonymous_page(mm, vma, address,
 						 pte, pmd, flags);
 		}
-- 
2.4.6

>From 1d3aa3b9021f908a0411ae5d743434e076f3feab Mon Sep 17 00:00:00 2001
From: "Kirill A. Shutemov" <kirill.shutemov@xxxxxxxxxxxxxxx>
Date: Mon, 6 Jul 2015 23:18:37 +0300
Subject: [PATCH] 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@xxxxxxxxxxxxxxx>
Acked-by: Oleg Nesterov <oleg@xxxxxxxxxx>
Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
Cc: Willy Tarreau <w@xxxxxx>
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx>
---
 mm/memory.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/mm/memory.c b/mm/memory.c
index 6ab19dd4a199..06d2a0e74248 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2645,6 +2645,10 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma,
 	/* Allocate our own private page. */
 	pte_unmap(page_table);
 
+	/* File mapping without ->vm_ops ? */
+	if (vma->vm_flags & VM_SHARED)
+		return VM_FAULT_SIGBUS;
+
 	if (unlikely(anon_vma_prepare(vma)))
 		goto oom;
 	page = alloc_zeroed_user_highpage_movable(vma, address);
@@ -2882,6 +2886,9 @@ static int do_linear_fault(struct mm_struct *mm, struct vm_area_struct *vma,
 			- vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
 
 	pte_unmap(page_table);
+	/* The VMA was not fully populated on mmap() or missing VM_DONTEXPAND */
+	if (!vma->vm_ops->fault)
+		return VM_FAULT_SIGBUS;
 	return __do_fault(mm, vma, address, pmd, pgoff, flags, orig_pte);
 }
 
@@ -2940,11 +2947,9 @@ static inline int handle_pte_fault(struct mm_struct *mm,
 	entry = *pte;
 	if (!pte_present(entry)) {
 		if (pte_none(entry)) {
-			if (vma->vm_ops) {
-				if (likely(vma->vm_ops->fault))
-					return do_linear_fault(mm, vma, address,
+			if (vma->vm_ops)
+				return do_linear_fault(mm, vma, address,
 						pte, pmd, flags, entry);
-			}
 			return do_anonymous_page(mm, vma, address,
 						 pte, pmd, flags);
 		}
-- 
2.4.6


[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]