]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.7.3/uprobes-fix-the-memcg-accounting.patch
5.1-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.7.3 / uprobes-fix-the-memcg-accounting.patch
CommitLineData
885585e5
GKH
1From 6c4687cc17a788a6dd8de3e27dbeabb7cbd3e066 Mon Sep 17 00:00:00 2001
2From: Oleg Nesterov <oleg@redhat.com>
3Date: Wed, 17 Aug 2016 17:36:29 +0200
4Subject: uprobes: Fix the memcg accounting
5
6From: Oleg Nesterov <oleg@redhat.com>
7
8commit 6c4687cc17a788a6dd8de3e27dbeabb7cbd3e066 upstream.
9
10__replace_page() wronlgy calls mem_cgroup_cancel_charge() in "success" path,
11it should only do this if page_check_address() fails.
12
13This means that every enable/disable leads to unbalanced mem_cgroup_uncharge()
14from put_page(old_page), it is trivial to underflow the page_counter->count
15and trigger OOM.
16
17Reported-and-tested-by: Brenden Blanco <bblanco@plumgrid.com>
18Signed-off-by: Oleg Nesterov <oleg@redhat.com>
19Reviewed-by: Johannes Weiner <hannes@cmpxchg.org>
20Acked-by: Michal Hocko <mhocko@kernel.org>
21Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
22Cc: Alexei Starovoitov <alexei.starovoitov@gmail.com>
23Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
24Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
25Cc: Jiri Olsa <jolsa@redhat.com>
26Cc: Linus Torvalds <torvalds@linux-foundation.org>
27Cc: Peter Zijlstra <peterz@infradead.org>
28Cc: Thomas Gleixner <tglx@linutronix.de>
29Cc: Vladimir Davydov <vdavydov@virtuozzo.com>
30Fixes: 00501b531c47 ("mm: memcontrol: rewrite charge API")
31Link: http://lkml.kernel.org/r/20160817153629.GB29724@redhat.com
32Signed-off-by: Ingo Molnar <mingo@kernel.org>
33Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
34
35---
36 kernel/events/uprobes.c | 5 +++--
37 1 file changed, 3 insertions(+), 2 deletions(-)
38
39--- a/kernel/events/uprobes.c
40+++ b/kernel/events/uprobes.c
41@@ -172,8 +172,10 @@ static int __replace_page(struct vm_area
42 mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
43 err = -EAGAIN;
44 ptep = page_check_address(page, mm, addr, &ptl, 0);
45- if (!ptep)
46+ if (!ptep) {
47+ mem_cgroup_cancel_charge(kpage, memcg, false);
48 goto unlock;
49+ }
50
51 get_page(kpage);
52 page_add_new_anon_rmap(kpage, vma, addr, false);
53@@ -200,7 +202,6 @@ static int __replace_page(struct vm_area
54
55 err = 0;
56 unlock:
57- mem_cgroup_cancel_charge(kpage, memcg, false);
58 mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
59 unlock_page(page);
60 return err;