提交 36d09fa1 编写于 作者: L Liu Shixin 提交者: openeuler-sync-bot

mm/memcg_memfs_info: fix potential oom_lock recursion deadlock

hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I6ADCF
CVE: NA

--------------------------------

syzbot is reporting GFP_KERNEL allocation with oom_lock held when
reporting memcg OOM [1]. If this allocation triggers the global OOM
situation then the system can livelock because the GFP_KERNEL
allocation with oom_lock held cannot trigger the global OOM killer
because __alloc_pages_may_oom() fails to hold oom_lock.

The problem mentioned above has been fixed by patch[2]. The is the same
problem in memcg_memfs_info feature too. Refer to the patch[2], fix it by
removing the allocation from mem_cgroup_print_memfs_info() completely,
and pass static buffer when calling from memcg OOM path.

Link: https://syzkaller.appspot.com/bug?extid=2d2aeadc6ce1e1f11d45 [1]
Link: https://lkml.kernel.org/r/86afb39f-8c65-bec2-6cfc-c5e3cd600c0b@I-love.SAKURA.ne.jp [2]
Fixes: 6b1d4d3a ("mm/memcg_memfs_info: show files that having pages charged in mem_cgroup")
Signed-off-by: NLiu Shixin <liushixin2@huawei.com>
Reviewed-by: NKefeng Wang <wangkefeng.wang@huawei.com>
Reviewed-by: NCai Xinchen <caixinchen1@huawei.com>
Signed-off-by: NJialin Zhang <zhangjialin11@huawei.com>
(cherry picked from commit d2218535)
上级 3f533ee3
......@@ -6,11 +6,13 @@
#include <linux/seq_file.h>
#ifdef CONFIG_MEMCG_MEMFS_INFO
void mem_cgroup_print_memfs_info(struct mem_cgroup *memcg, struct seq_file *m);
void mem_cgroup_print_memfs_info(struct mem_cgroup *memcg, char *pathbuf,
struct seq_file *m);
int mem_cgroup_memfs_files_show(struct seq_file *m, void *v);
void mem_cgroup_memfs_info_init(void);
#else
static inline void mem_cgroup_print_memfs_info(struct mem_cgroup *memcg,
char *pathbuf,
struct seq_file *m)
{
}
......
......@@ -157,7 +157,8 @@ static void memfs_show_files_in_mem_cgroup(struct super_block *sb, void *data)
mntput(pfc->vfsmnt);
}
void mem_cgroup_print_memfs_info(struct mem_cgroup *memcg, struct seq_file *m)
void mem_cgroup_print_memfs_info(struct mem_cgroup *memcg, char *pathbuf,
struct seq_file *m)
{
struct print_files_control pfc = {
.memcg = memcg,
......@@ -165,17 +166,11 @@ void mem_cgroup_print_memfs_info(struct mem_cgroup *memcg, struct seq_file *m)
.max_print_files = memfs_max_print_files,
.size_threshold = memfs_size_threshold,
};
char *pathbuf;
int i;
if (!memfs_enable || !memcg)
return;
pathbuf = kmalloc(PATH_MAX, GFP_KERNEL);
if (!pathbuf) {
SEQ_printf(m, "Show memfs failed due to OOM\n");
return;
}
pfc.pathbuf = pathbuf;
pfc.pathbuf_size = PATH_MAX;
......@@ -192,15 +187,20 @@ void mem_cgroup_print_memfs_info(struct mem_cgroup *memcg, struct seq_file *m)
SEQ_printf(m, "total files: %lu, total memory-size: %lukB\n",
pfc.total_print_files, pfc.total_files_size >> 10);
}
kfree(pfc.pathbuf);
}
int mem_cgroup_memfs_files_show(struct seq_file *m, void *v)
{
struct mem_cgroup *memcg = mem_cgroup_from_css(seq_css(m));
char *pathbuf;
mem_cgroup_print_memfs_info(memcg, m);
pathbuf = kmalloc(PATH_MAX, GFP_KERNEL);
if (!pathbuf) {
SEQ_printf(m, "Show memfs abort: failed to allocate memory\n");
return 0;
}
mem_cgroup_print_memfs_info(memcg, pathbuf, m);
kfree(pathbuf);
return 0;
}
......
......@@ -1611,6 +1611,7 @@ void mem_cgroup_print_oom_meminfo(struct mem_cgroup *memcg)
{
/* Use static buffer, for the caller is holding oom_lock. */
static char buf[PAGE_SIZE];
static char pathbuf[PATH_MAX];
lockdep_assert_held(&oom_lock);
......@@ -1636,7 +1637,7 @@ void mem_cgroup_print_oom_meminfo(struct mem_cgroup *memcg)
memory_stat_format(memcg, buf, sizeof(buf));
pr_info("%s", buf);
mem_cgroup_print_memfs_info(memcg, NULL);
mem_cgroup_print_memfs_info(memcg, pathbuf, NULL);
}
/*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册