--- /dev/null
+From 9f15bde671355c351cf20d9f879004b234353100 Mon Sep 17 00:00:00 2001
+From: Jing Xia <jing.xia.mail@gmail.com>
+Date: Fri, 20 Jul 2018 17:53:48 -0700
+Subject: mm: memcg: fix use after free in mem_cgroup_iter()
+
+From: Jing Xia <jing.xia.mail@gmail.com>
+
+commit 9f15bde671355c351cf20d9f879004b234353100 upstream.
+
+It was reported that a kernel crash happened in mem_cgroup_iter(), which
+can be triggered if the legacy cgroup-v1 non-hierarchical mode is used.
+
+Unable to handle kernel paging request at virtual address 6b6b6b6b6b6b8f
+......
+Call trace:
+ mem_cgroup_iter+0x2e0/0x6d4
+ shrink_zone+0x8c/0x324
+ balance_pgdat+0x450/0x640
+ kswapd+0x130/0x4b8
+ kthread+0xe8/0xfc
+ ret_from_fork+0x10/0x20
+
+ mem_cgroup_iter():
+ ......
+ if (css_tryget(css)) <-- crash here
+ break;
+ ......
+
+The crashing reason is that mem_cgroup_iter() uses the memcg object whose
+pointer is stored in iter->position, which has been freed before and
+filled with POISON_FREE(0x6b).
+
+And the root cause of the use-after-free issue is that
+invalidate_reclaim_iterators() fails to reset the value of iter->position
+to NULL when the css of the memcg is released in non- hierarchical mode.
+
+Link: http://lkml.kernel.org/r/1531994807-25639-1-git-send-email-jing.xia@unisoc.com
+Fixes: 6df38689e0e9 ("mm: memcontrol: fix possible memcg leak due to interrupted reclaim")
+Signed-off-by: Jing Xia <jing.xia.mail@gmail.com>
+Acked-by: Michal Hocko <mhocko@suse.com>
+Cc: Johannes Weiner <hannes@cmpxchg.org>
+Cc: Vladimir Davydov <vdavydov.dev@gmail.com>
+Cc: <chunyan.zhang@unisoc.com>
+Cc: Shakeel Butt <shakeelb@google.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ mm/memcontrol.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/mm/memcontrol.c
++++ b/mm/memcontrol.c
+@@ -996,7 +996,7 @@ static void invalidate_reclaim_iterators
+ int nid, zid;
+ int i;
+
+- while ((memcg = parent_mem_cgroup(memcg))) {
++ for (; memcg; memcg = parent_mem_cgroup(memcg)) {
+ for_each_node(nid) {
+ for (zid = 0; zid < MAX_NR_ZONES; zid++) {
+ mz = &memcg->nodeinfo[nid]->zoneinfo[zid];