[PATCH] mm, oom: Introduce time limit for dump_tasks duration.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 2018/09/06 18:54, Dmitry Vyukov wrote:
> On Thu, Sep 6, 2018 at 7:53 AM, Tetsuo Handa
> <penguin-kernel@xxxxxxxxxxxxxxxxxxx> wrote:
>> Dmitry Vyukov wrote:
>>>> Also, another notable thing is that the backtrace for some reason includes
>>>>
>>>> [ 1048.211540]  ? oom_killer_disable+0x3a0/0x3a0
>>>>
>>>> line. Was syzbot testing process freezing functionality?
>>>
>>> What's the API for this?
>>>
>>
>> I'm not a user of suspend/hibernation. But it seems that usage of the API
>> is to write one of words listed in /sys/power/state into /sys/power/state .
>>
>> # echo suspend > /sys/power/state
> 
> syzkaller should not write to /sys/power/state. The only mention of
> "power" is in some selinux contexts.
> 

OK. Then, I have no idea.
Anyway, I think we can apply this patch.

>From 18876f287dd69a7c33f65c91cfcda3564233f55e Mon Sep 17 00:00:00 2001
From: Tetsuo Handa <penguin-kernel@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 6 Sep 2018 19:53:18 +0900
Subject: [PATCH] mm, oom: Introduce time limit for dump_tasks duration.

Since printk() is slow, printing one line takes nearly 0.01 second.
As a result, syzbot is stalling for 52 seconds trying to dump 5600
tasks at for_each_process() under RCU. Since such situation is almost
inflight fork bomb attack (the OOM killer will print similar tasks for
so many times), it makes little sense to print all candidate tasks.
Thus, this patch introduces 3 seconds limit for printing.

Signed-off-by: Tetsuo Handa <penguin-kernel@xxxxxxxxxxxxxxxxxxx>
Cc: Dmitry Vyukov <dvyukov@xxxxxxxxxx>
---
 mm/oom_kill.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index f10aa53..48e5bf6 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -399,14 +399,22 @@ static void dump_tasks(struct mem_cgroup *memcg, const nodemask_t *nodemask)
 {
 	struct task_struct *p;
 	struct task_struct *task;
+	unsigned long start;
+	unsigned int skipped = 0;
 
 	pr_info("Tasks state (memory values in pages):\n");
 	pr_info("[  pid  ]   uid  tgid total_vm      rss pgtables_bytes swapents oom_score_adj name\n");
 	rcu_read_lock();
+	start = jiffies;
 	for_each_process(p) {
 		if (oom_unkillable_task(p, memcg, nodemask))
 			continue;
 
+		if (time_after(jiffies, start + 3 * HZ)) {
+			skipped++;
+			continue;
+		}
+
 		task = find_lock_task_mm(p);
 		if (!task) {
 			/*
@@ -426,6 +434,8 @@ static void dump_tasks(struct mem_cgroup *memcg, const nodemask_t *nodemask)
 		task_unlock(task);
 	}
 	rcu_read_unlock();
+	if (skipped)
+		pr_info("Printing %u tasks omitted.\n", skipped);
 }
 
 static void dump_header(struct oom_control *oc, struct task_struct *p)
-- 
1.8.3.1




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux