lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220309002550.103786-1-npache@redhat.com>
Date:   Tue,  8 Mar 2022 17:25:50 -0700
From:   Nico Pache <npache@...hat.com>
To:     linux-mm@...ck.org, linux-kernel@...r.kernel.org
Cc:     Rafael Aquini <aquini@...hat.com>,
        Waiman Long <longman@...hat.com>, Baoquan He <bhe@...hat.com>,
        Christoph von Recklinghausen <crecklin@...hat.com>,
        Don Dutile <ddutile@...hat.com>,
        "Herton R . Krzesinski" <herton@...hat.com>,
        David Rientjes <rientjes@...gle.com>,
        Michal Hocko <mhocko@...e.com>,
        Andrea Arcangeli <aarcange@...hat.com>,
        Andrew Morton <akpm@...ux-foundation.org>, tglx@...utronix.de,
        mingo@...hat.com, dvhart@...radead.org, dave@...olabs.net,
        andrealmeid@...labora.com, peterz@...radead.org,
        Joel Savitz <jsavitz@...hat.com>
Subject: [PATCH v4] mm/oom_kill.c: futex: Don't OOM reap a process with a futex robust list

The pthread struct is allocated on PRIVATE|ANONYMOUS memory [1] which can
be targeted by the oom reaper. This mapping is also used to store the futex
robust list; the kernel does not keep a copy of the robust list and instead
references a userspace address to maintain the robustness during a process
death. A race can occur between exit_mm and the oom reaper that allows
the oom reaper to clear the memory of the futex robust list before the
exit path has handled the futex death.

Prevent the OOM reaper from concurrently reaping the mappings if the dying
process contains a robust_list. If the dying task_struct does not contain
a pointer in tsk->robust_list, we can assume there was either never one
setup for this task struct, or futex_cleanup has properly handled the
futex death and we can safely reap this memory.

Reproducer: https://gitlab.com/jsavitz/oom_futex_reproducer

[1] https://elixir.bootlin.com/glibc/latest/source/nptl/allocatestack.c#L370

Fixes: 212925802454 ("mm: oom: let oom_reap_task and exit_mmap run concurrently")
Cc: Rafael Aquini <aquini@...hat.com>
Cc: Waiman Long <longman@...hat.com>
Cc: Baoquan He <bhe@...hat.com>
Cc: Christoph von Recklinghausen <crecklin@...hat.com>
Cc: Don Dutile <ddutile@...hat.com>
Cc: Herton R. Krzesinski <herton@...hat.com>
Cc: David Rientjes <rientjes@...gle.com>
Cc: Michal Hocko <mhocko@...e.com>
Cc: Andrea Arcangeli <aarcange@...hat.com>
Cc: Andrew Morton <akpm@...ux-foundation.org>
Cc: <tglx@...utronix.de>
Cc: <mingo@...hat.com>
Cc: <dvhart@...radead.org>
Cc: <dave@...olabs.net>
Cc: <andrealmeid@...labora.com>
Cc: <peterz@...radead.org>
Co-developed-by: Joel Savitz <jsavitz@...hat.com>
Signed-off-by: Joel Savitz <jsavitz@...hat.com>
Signed-off-by: Nico Pache <npache@...hat.com>
---
 mm/oom_kill.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 989f35a2bbb1..37af902494d8 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -587,6 +587,25 @@ static bool oom_reap_task_mm(struct task_struct *tsk, struct mm_struct *mm)
 		goto out_unlock;
 	}
 
+	/* Don't reap a process holding a robust_list as the pthread
+	 * struct is allocated in userspace using PRIVATE | ANONYMOUS
+	 * memory which when reaped before futex_cleanup() can leave
+	 * the waiting process stuck.
+	 */
+#ifdef CONFIG_FUTEX
+	bool robust = false;
+
+	robust = tsk->robust_list != NULL;
+#ifdef CONFIG_COMPAT
+	robust |= tsk->compat_robust_list != NULL;
+#endif
+	if (robust) {
+		trace_skip_task_reaping(tsk->pid);
+		pr_info("oom_reaper: skipping task as it contains a robust list");
+		goto out_finish;
+	}
+#endif
+
 	trace_start_task_reaping(tsk->pid);
 
 	/* failed to reap part of the address space. Try again later */
-- 
2.35.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ