[PATCH 3/3] fold me "mm, oom: skip vforked tasks from being selected"

From: Michal Hocko
Date: Tue May 31 2016 - 01:45:45 EST


per Oleg:
- copy_process() doesn't disallow CLONE_VFORK without CLONE_VM, so with
this patch it would be trivial to make the exploit which hides a
memory hog from oom-killer.

Signed-off-by: Michal Hocko <mhocko@xxxxxxxx>
---
include/linux/sched.h | 16 ++++++++++++++++
mm/oom_kill.c | 2 +-
2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index ec636400669f..e1877f4da4cc 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1883,6 +1883,22 @@ extern int arch_task_struct_size __read_mostly;
#define TNF_FAULT_LOCAL 0x08
#define TNF_MIGRATE_FAIL 0x10

+/* expects to be called with task_lock held */
+static inline bool in_vfork(struct task_struct *tsk)
+{
+ bool ret;
+
+ /*
+ * need RCU to access ->real_parent if CLONE_VM was used along with
+ * CLONE_PARENT
+ */
+ rcu_read_lock();
+ ret = tsk->vfork_done && tsk->real_parent->mm == tsk->mm;
+ rcu_read_unlock();
+
+ return ret;
+}
+
#ifdef CONFIG_NUMA_BALANCING
extern void task_numa_fault(int last_node, int node, int pages, int flags);
extern pid_t task_numa_group_id(struct task_struct *p);
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index aa28315ac310..d1e24deb79b9 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -182,7 +182,7 @@ unsigned long oom_badness(struct task_struct *p, struct mem_cgroup *memcg,
adj = (long)p->signal->oom_score_adj;
if (adj == OOM_SCORE_ADJ_MIN ||
test_bit(MMF_OOM_REAPED, &p->mm->flags) ||
- p->vfork_done) {
+ in_vfork(p)) {
task_unlock(p);
return 0;
}
--
2.8.1


--
Michal Hocko
SUSE Labs