diff mbox series

[1/3] mm: don't prepare anon_vma if vma has VM_WIPEONFORK

Message ID 1581150928-3214-2-git-send-email-lixinhai.lxh@gmail.com (mailing list archive)
State New, archived
Headers show
Series mm: Fix misuse of parent anon_vma in dup_mmap path | expand

Commit Message

Li Xinhai Feb. 8, 2020, 8:35 a.m. UTC
In dup_mmap(), anon_vma_prepare() is called for vma has VM_WIPEONFORK,
and parameter 'tmp' (i.e., the new vma of child) has same ->vm_next and
->vm_prev as its parent vma. That allows anon_vma used by parent been
mistakenly shared by child (find_mergeable_anon_vma() will do this reuse
work).

Besides this issue, call anon_vma_prepare() should be avoided because we
don't copy page for this vma. Preparing anon_vma will be handled during
fault.

Fixes: d2cd9ede6e19 ("mm,fork: introduce MADV_WIPEONFORK")
Signed-off-by: Li Xinhai <lixinhai.lxh@gmail.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Matthew Wilcox <willy@infradead.org>
---
 kernel/fork.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

Comments

Li Xinhai Feb. 8, 2020, 8:53 a.m. UTC | #1
sorry, should send to Rik van Riel<riel@surriel.com>

On 2020-02-08 at 16:35 Li Xinhai wrote:
>In dup_mmap(), anon_vma_prepare() is called for vma has VM_WIPEONFORK,
>and parameter 'tmp' (i.e., the new vma of child) has same ->vm_next and
>->vm_prev as its parent vma. That allows anon_vma used by parent been
>mistakenly shared by child (find_mergeable_anon_vma() will do this reuse
>work).
>
>Besides this issue, call anon_vma_prepare() should be avoided because we
>don't copy page for this vma. Preparing anon_vma will be handled during
>fault.
>
>Fixes: d2cd9ede6e19 ("mm,fork: introduce MADV_WIPEONFORK")
>Signed-off-by: Li Xinhai <lixinhai.lxh@gmail.com>
>Cc: Rik van Riel <riel@redhat.com>
>Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
>Cc: Matthew Wilcox <willy@infradead.org>
>---
> kernel/fork.c | 8 +++++---
> 1 file changed, 5 insertions(+), 3 deletions(-)
>
>diff --git a/kernel/fork.c b/kernel/fork.c
>index 0808095..1bbd49a 100644
>--- a/kernel/fork.c
>+++ b/kernel/fork.c
>@@ -552,10 +552,12 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
> if (retval)
> goto fail_nomem_anon_vma_fork;
> if (tmp->vm_flags & VM_WIPEONFORK) {
>-	/* VM_WIPEONFORK gets a clean slate in the child. */
>+	/*
>+	* VM_WIPEONFORK gets a clean slate in the child.
>+	* Don't prepare anon_vma until fault since we don't
>+	* copy page for current vma.
>+	*/
> tmp->anon_vma = NULL;
>-	if (anon_vma_prepare(tmp))
>-	goto fail_nomem_anon_vma_fork;
> } else if (anon_vma_fork(tmp, mpnt))
> goto fail_nomem_anon_vma_fork;
> tmp->vm_flags &= ~(VM_LOCKED | VM_LOCKONFAULT);
>--
>1.8.3.1
>
Kirill A. Shutemov April 2, 2020, 1:45 p.m. UTC | #2
On Sat, Feb 08, 2020 at 08:35:26AM +0000, Li Xinhai wrote:
> In dup_mmap(), anon_vma_prepare() is called for vma has VM_WIPEONFORK,
> and parameter 'tmp' (i.e., the new vma of child) has same ->vm_next and
> ->vm_prev as its parent vma. That allows anon_vma used by parent been
> mistakenly shared by child (find_mergeable_anon_vma() will do this reuse
> work).
> 
> Besides this issue, call anon_vma_prepare() should be avoided because we
> don't copy page for this vma. Preparing anon_vma will be handled during
> fault.
> 
> Fixes: d2cd9ede6e19 ("mm,fork: introduce MADV_WIPEONFORK")
> Signed-off-by: Li Xinhai <lixinhai.lxh@gmail.com>
> Cc: Rik van Riel <riel@redhat.com>
> Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
> Cc: Matthew Wilcox <willy@infradead.org>

Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
diff mbox series

Patch

diff --git a/kernel/fork.c b/kernel/fork.c
index 0808095..1bbd49a 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -552,10 +552,12 @@  static __latent_entropy int dup_mmap(struct mm_struct *mm,
 		if (retval)
 			goto fail_nomem_anon_vma_fork;
 		if (tmp->vm_flags & VM_WIPEONFORK) {
-			/* VM_WIPEONFORK gets a clean slate in the child. */
+			/*
+			 * VM_WIPEONFORK gets a clean slate in the child.
+			 * Don't prepare anon_vma until fault since we don't
+			 * copy page for current vma.
+			 */
 			tmp->anon_vma = NULL;
-			if (anon_vma_prepare(tmp))
-				goto fail_nomem_anon_vma_fork;
 		} else if (anon_vma_fork(tmp, mpnt))
 			goto fail_nomem_anon_vma_fork;
 		tmp->vm_flags &= ~(VM_LOCKED | VM_LOCKONFAULT);