aboutsummaryrefslogtreecommitdiffstats
path: root/main/linux-vanilla/mm-do-not-collapse-stack-guard-into-thp.patch
blob: dc39202112cd4b0b6e8a298054887a3adda66b95 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
From cc9020f7502a59088e23e34d2a4999435f804cd2 Mon Sep 17 00:00:00 2001
From: Michal Hocko <mhocko@suse.com>
Date: Thu, 25 May 2017 08:12:42 +0200
Subject: mm: do not collapse stack gap into THP

Oleg has noticed that khugepaged will happilly collapse stack vma (as
long as it is not an early stack - see is_vma_temporary_stack) and
it might effectively remove the stack gap area as well because a larger
part of the stack vma is usually populated. The same applies to the
page fault handler.

Fix this by checking stack_guard_area when revalidating a VMA
in hugepage_vma_revalidate.  We do not want to hook/replace
is_vma_temporary_stack() check because THP might be still useful for
stack, all we need is excluding the gap from collapsing into a THP.

Also check the to-be-created THP in do_huge_pmd_anonymous_page to
make sure it is completely outside of the gap area because we we could
create THP covering the gap area.

CVE-2017-1000364

Noticed-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Michal Hocko <mhocko@suse.com>
[move khugepaged.c code into huge_memory.c]
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
---
 mm/huge_memory.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index aa3cf81..85c4ee5 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -815,6 +815,9 @@ int do_huge_pmd_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma,
 
 	if (haddr < vma->vm_start || haddr + HPAGE_PMD_SIZE > vma->vm_end)
 		return VM_FAULT_FALLBACK;
+	if (stack_guard_area(vma, haddr) ||
+			stack_guard_area(vma, haddr + HPAGE_PMD_SIZE))
+		return VM_FAULT_FALLBACK;
 	if (unlikely(anon_vma_prepare(vma)))
 		return VM_FAULT_OOM;
 	if (unlikely(khugepaged_enter(vma, vma->vm_flags)))
@@ -2561,6 +2564,9 @@ static void collapse_huge_page(struct mm_struct *mm,
 		goto out;
 	if (!hugepage_vma_check(vma))
 		goto out;
+	/* never try to collapse stack gap */
+	if (stack_guard_area(vma, hstart) || stack_guard_area(vma, hend))
+		goto out;
 	pmd = mm_find_pmd(mm, address);
 	if (!pmd)
 		goto out;
-- 
cgit v0.11.2