diff options
author | Andreas Wellving <andreas.wellving@enea.com> | 2018-10-17 14:44:21 +0200 |
---|---|---|
committer | Adrian Mangeac <Adrian.Mangeac@enea.com> | 2018-10-24 12:44:46 +0200 |
commit | 4249123a9fe6922ad8abf912db7d18c2d436dc6d (patch) | |
tree | e30fab10b7f0e819e6a3f5af21bca07ccbed5796 | |
parent | f22f4f9800c32ecad2ca00f2ea780fd6f7719490 (diff) | |
download | enea-kernel-cache-4249123a9fe6922ad8abf912db7d18c2d436dc6d.tar.gz |
mlock: CVE-2017-18221
mlock: fix mlock count can not decrease in race condition
References:
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=linux-4.1.y&id=00fc586ea7410ee8664bfd4f4ea246c60ea0482c
Change-Id: I10ada2a00c1b3cf2b0d455d47ecdb9cbeaae62e0
Signed-off-by: Andreas Wellving <andreas.wellving@enea.com>
-rw-r--r-- | patches/cve/4.1.x.scc | 1 | ||||
-rw-r--r-- | patches/cve/CVE-2017-18221-mlock-fix-mlock-count-can-not-decrease-in-race-condi.patch | 121 |
2 files changed, 122 insertions, 0 deletions
diff --git a/patches/cve/4.1.x.scc b/patches/cve/4.1.x.scc index 27a4241..2f3ae79 100644 --- a/patches/cve/4.1.x.scc +++ b/patches/cve/4.1.x.scc | |||
@@ -10,3 +10,4 @@ patch CVE-2017-7895-nfsd-stricter-decoding-of-write-like-NFSv2-v3-ops.patch | |||
10 | 10 | ||
11 | #fixed in 4.1.41 | 11 | #fixed in 4.1.41 |
12 | patch CVE-2017-10661-timerfd-Protect-the-might-cancel-mechanism-proper.patch | 12 | patch CVE-2017-10661-timerfd-Protect-the-might-cancel-mechanism-proper.patch |
13 | patch CVE-2017-18221-mlock-fix-mlock-count-can-not-decrease-in-race-condi.patch | ||
diff --git a/patches/cve/CVE-2017-18221-mlock-fix-mlock-count-can-not-decrease-in-race-condi.patch b/patches/cve/CVE-2017-18221-mlock-fix-mlock-count-can-not-decrease-in-race-condi.patch new file mode 100644 index 0000000..9ccf1a8 --- /dev/null +++ b/patches/cve/CVE-2017-18221-mlock-fix-mlock-count-can-not-decrease-in-race-condi.patch | |||
@@ -0,0 +1,121 @@ | |||
1 | From 00fc586ea7410ee8664bfd4f4ea246c60ea0482c Mon Sep 17 00:00:00 2001 | ||
2 | From: Yisheng Xie <xieyisheng1@huawei.com> | ||
3 | Date: Fri, 2 Jun 2017 14:46:43 -0700 | ||
4 | Subject: [PATCH] mlock: fix mlock count can not decrease in race condition | ||
5 | |||
6 | [ Upstream commit 70feee0e1ef331b22cc51f383d532a0d043fbdcc ] | ||
7 | |||
8 | Kefeng reported that when running the follow test, the mlock count in | ||
9 | meminfo will increase permanently: | ||
10 | |||
11 | [1] testcase | ||
12 | linux:~ # cat test_mlockal | ||
13 | grep Mlocked /proc/meminfo | ||
14 | for j in `seq 0 10` | ||
15 | do | ||
16 | for i in `seq 4 15` | ||
17 | do | ||
18 | ./p_mlockall >> log & | ||
19 | done | ||
20 | sleep 0.2 | ||
21 | done | ||
22 | # wait some time to let mlock counter decrease and 5s may not enough | ||
23 | sleep 5 | ||
24 | grep Mlocked /proc/meminfo | ||
25 | |||
26 | linux:~ # cat p_mlockall.c | ||
27 | #include <sys/mman.h> | ||
28 | #include <stdlib.h> | ||
29 | #include <stdio.h> | ||
30 | |||
31 | #define SPACE_LEN 4096 | ||
32 | |||
33 | int main(int argc, char ** argv) | ||
34 | { | ||
35 | int ret; | ||
36 | void *adr = malloc(SPACE_LEN); | ||
37 | if (!adr) | ||
38 | return -1; | ||
39 | |||
40 | ret = mlockall(MCL_CURRENT | MCL_FUTURE); | ||
41 | printf("mlcokall ret = %d\n", ret); | ||
42 | |||
43 | ret = munlockall(); | ||
44 | printf("munlcokall ret = %d\n", ret); | ||
45 | |||
46 | free(adr); | ||
47 | return 0; | ||
48 | } | ||
49 | |||
50 | In __munlock_pagevec() we should decrement NR_MLOCK for each page where | ||
51 | we clear the PageMlocked flag. Commit 1ebb7cc6a583 ("mm: munlock: batch | ||
52 | NR_MLOCK zone state updates") has introduced a bug where we don't | ||
53 | decrement NR_MLOCK for pages where we clear the flag, but fail to | ||
54 | isolate them from the lru list (e.g. when the pages are on some other | ||
55 | cpu's percpu pagevec). Since PageMlocked stays cleared, the NR_MLOCK | ||
56 | accounting gets permanently disrupted by this. | ||
57 | |||
58 | Fix it by counting the number of page whose PageMlock flag is cleared. | ||
59 | |||
60 | Fixes: 1ebb7cc6a583 (" mm: munlock: batch NR_MLOCK zone state updates") | ||
61 | Link: http://lkml.kernel.org/r/1495678405-54569-1-git-send-email-xieyisheng1@huawei.com | ||
62 | |||
63 | CVE: CVE-2017-18221 | ||
64 | Upstream-Status: Backport | ||
65 | |||
66 | Signed-off-by: Yisheng Xie <xieyisheng1@huawei.com> | ||
67 | Reported-by: Kefeng Wang <wangkefeng.wang@huawei.com> | ||
68 | Tested-by: Kefeng Wang <wangkefeng.wang@huawei.com> | ||
69 | Cc: Vlastimil Babka <vbabka@suse.cz> | ||
70 | Cc: Joern Engel <joern@logfs.org> | ||
71 | Cc: Mel Gorman <mgorman@suse.de> | ||
72 | Cc: Michel Lespinasse <walken@google.com> | ||
73 | Cc: Hugh Dickins <hughd@google.com> | ||
74 | Cc: Rik van Riel <riel@redhat.com> | ||
75 | Cc: Johannes Weiner <hannes@cmpxchg.org> | ||
76 | Cc: Michal Hocko <mhocko@suse.cz> | ||
77 | Cc: Xishi Qiu <qiuxishi@huawei.com> | ||
78 | Cc: zhongjiang <zhongjiang@huawei.com> | ||
79 | Cc: Hanjun Guo <guohanjun@huawei.com> | ||
80 | Cc: <stable@vger.kernel.org> | ||
81 | Signed-off-by: Andrew Morton <akpm@linux-foundation.org> | ||
82 | Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> | ||
83 | Signed-off-by: Sasha Levin <alexander.levin@verizon.com> | ||
84 | Signed-off-by: Andreas Wellving <andreas.wellving@enea.com> | ||
85 | --- | ||
86 | mm/mlock.c | 5 +++-- | ||
87 | 1 file changed, 3 insertions(+), 2 deletions(-) | ||
88 | |||
89 | diff --git a/mm/mlock.c b/mm/mlock.c | ||
90 | index 3d3ee6ca..00ff8c7 100644 | ||
91 | --- a/mm/mlock.c | ||
92 | +++ b/mm/mlock.c | ||
93 | @@ -277,7 +277,7 @@ static void __munlock_pagevec(struct pagevec *pvec, struct zone *zone) | ||
94 | { | ||
95 | int i; | ||
96 | int nr = pagevec_count(pvec); | ||
97 | - int delta_munlocked; | ||
98 | + int delta_munlocked = -nr; | ||
99 | struct pagevec pvec_putback; | ||
100 | int pgrescued = 0; | ||
101 | |||
102 | @@ -297,6 +297,8 @@ static void __munlock_pagevec(struct pagevec *pvec, struct zone *zone) | ||
103 | continue; | ||
104 | else | ||
105 | __munlock_isolation_failed(page); | ||
106 | + } else { | ||
107 | + delta_munlocked++; | ||
108 | } | ||
109 | |||
110 | /* | ||
111 | @@ -308,7 +310,6 @@ static void __munlock_pagevec(struct pagevec *pvec, struct zone *zone) | ||
112 | pagevec_add(&pvec_putback, pvec->pages[i]); | ||
113 | pvec->pages[i] = NULL; | ||
114 | } | ||
115 | - delta_munlocked = -nr + pagevec_count(&pvec_putback); | ||
116 | __mod_zone_page_state(zone, NR_MLOCK, delta_munlocked); | ||
117 | spin_unlock_irq(&zone->lru_lock); | ||
118 | |||
119 | -- | ||
120 | 2.7.4 | ||
121 | |||