From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AD81A3FC2 for ; Tue, 2 Dec 2025 04:09:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764648568; cv=none; b=XmAHJr50kZFAVmOHY5htTUmSFRm9Cg6krj4st+4qtb7X8Ide9Vkx+4jHoV1mGdaZjxmtDF/zXqu8rr+rBtMD5cI7w7+dZOzKrGx6u39T3o+U0fZ+wChOOIWz4SBzk14/Tdia4tUPhArqIv/GjG2Z0qObWJ4q5Ey2BsO6d4MTY2c= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764648568; c=relaxed/simple; bh=xybWfTJkO9Ob5YScpU7iOwj7PXfB0vpZpNzqYUHdaMk=; h=Date:From:To:Cc:Subject:Message-ID:MIME-Version:Content-Type: Content-Disposition; b=RbC1qtv/JsbRTNCqeU/D6HA/EuIDAN28oATSXggdYcQeHgfF310TiOtSDoCx0nJbKf6jK8KJXGQxb2qUoYfDYB0czxYdvut35r/aC1vWtaVP0rze0YvBAdgTgGd3+uThVMHd38UY2zWTLSfjE/8v5dEBHfjpjADwAiQz6RjJnUo= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rAuVbrhb; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="rAuVbrhb" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 45C75C4CEF1; Tue, 2 Dec 2025 04:09:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1764648568; bh=xybWfTJkO9Ob5YScpU7iOwj7PXfB0vpZpNzqYUHdaMk=; h=Date:From:To:Cc:Subject:From; b=rAuVbrhbUVCGH71KomQOsHCE39o8XIXQP1T02ZBEiP8l9XIORG2wq5rjNBia4lQEX k/eJp4C0Ey6vM550OYZkaQyAKx6QvC610NzgDt4d+FhhdTNZqKQ18MW2GMRBFPFkWA mzoYn2DXDiKQDRMT/QI/SU4KihKfuqWXi3ZefIu/oOct/jKMQJ3PU1YCQFkkEoLTf5 2ln5ylDu+RhlrmKZhExU2bzE1mCMRlI2Jw8J5bHQuJIX+LXzXJR03Ne6m8FalOMtgB jBZ9Hek5JvkIgG471u5awxPajKZmcT/Z71xjQNIx7vT6/v0jqtgcFozddLrK0hojhJ Eelm1NdkWymPQ== Date: Tue, 2 Dec 2025 05:09:24 +0100 From: Ingo Molnar To: Peter Zijlstra Cc: linux-kernel@vger.kernel.org, Oleg Nesterov Subject: [PATCH] seqlock, procfs: Fix scoped_seqlock_read() critical section in do_task_stat() Message-ID: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline RCU read-lock should not nest inside a read-seqlock irqsave ->stats_lock IRQs-off critical section, but should go on the outside, like it's done in fs/proc/base.c:do_io_accounting(). Looks like this was a pre-existing bug dating back to: 7601df8031fd ("fs/proc: do_task_stat: use sig->stats_lock to gather the threads/children stats") ... but this recent commit made it more apparent: b76f72bea2c6 ("seqlock: Change do_task_stat() to use scoped_seqlock_read()") To fix it, move the rcu_read_lock() on the outside, and convert it to a guard(rcu)() construct. Add an extra depth to the local scope to make sure the RCU critical section is kept strictly to the intended area. Fixes: b76f72bea2c6 ("seqlock: Change do_task_stat() to use scoped_seqlock_read()") Fixes: 7601df8031fd ("fs/proc: do_task_stat: use sig->stats_lock to gather the threads/children stats") Signed-off-by: Ingo Molnar Cc: Peter Zijlstra --- fs/proc/array.c | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/fs/proc/array.c b/fs/proc/array.c index cbd4bc4a58e4..6a35825c45a6 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -537,27 +537,28 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns, if (permitted && (!whole || num_threads < 2)) wchan = !task_is_running(task); - scoped_seqlock_read (&sig->stats_lock, ss_lock_irqsave) { - cmin_flt = sig->cmin_flt; - cmaj_flt = sig->cmaj_flt; - cutime = sig->cutime; - cstime = sig->cstime; - cgtime = sig->cgtime; - - if (whole) { - struct task_struct *t; - - min_flt = sig->min_flt; - maj_flt = sig->maj_flt; - gtime = sig->gtime; - - rcu_read_lock(); - __for_each_thread(sig, t) { - min_flt += t->min_flt; - maj_flt += t->maj_flt; - gtime += task_gtime(t); + { + guard(rcu)(); + scoped_seqlock_read (&sig->stats_lock, ss_lock_irqsave) { + cmin_flt = sig->cmin_flt; + cmaj_flt = sig->cmaj_flt; + cutime = sig->cutime; + cstime = sig->cstime; + cgtime = sig->cgtime; + + if (whole) { + struct task_struct *t; + + min_flt = sig->min_flt; + maj_flt = sig->maj_flt; + gtime = sig->gtime; + + __for_each_thread(sig, t) { + min_flt += t->min_flt; + maj_flt += t->maj_flt; + gtime += task_gtime(t); + } } - rcu_read_unlock(); } } -- 2.51.0