All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Cen Zhang (Microsoft)" <blbllhy@gmail.com>
To: brauner@kernel.org
Cc: oleg@redhat.com, jack@suse.cz, avagin@gmail.com,
	ptikhomirov@virtuozzo.com, mjguzik@gmail.com,
	linux-kernel@vger.kernel.org,
	AutonomousCodeSecurity@microsoft.com,
	tgopinath@linux.microsoft.com, kys@microsoft.com,
	blbllhy@gmail.com
Subject: [PATCH] pid: fix cad_pid use-after-free race in proc_do_cad_pid()
Date: Fri, 17 Jul 2026 17:01:43 -0400	[thread overview]
Message-ID: <20260717210143.4734-1-blbllhy@gmail.com> (raw)

proc_do_cad_pid() reads the global cad_pid pointer and passes it to
pid_vnr() without protecting the lifetime of the referenced struct pid.
A concurrent writer can replace cad_pid and drop the final reference to
the old struct pid after the reader has loaded the pointer but before
pid_vnr() has finished dereferencing it, causing a use-after-free.

Fix this by wrapping the read side in an RCU read-side critical section
and waiting for a grace period before dropping the old cad_pid reference
on the write side. Do not use call_rcu(&old_pid->rcu, ...) here:
struct pid::rcu is already used by free_pid(), so queueing it again can
corrupt the RCU callback list.

KASAN crash stack:
  kernel/pid.c:545 pid_nr_ns()          # reads freed pid->level
  kernel/pid.c:556 pid_vnr()
  kernel/pid.c:775 proc_do_cad_pid()
  fs/proc/proc_sysctl.c proc_sys_call_handler()
  fs/read_write.c vfs_read()
  fs/read_write.c __x64_sys_pread64()

Fixes: 9ec52099e4b8 ("[PATCH] replace cad_pid by a struct pid")
Reported-by: AutonomousCodeSecurity@microsoft.com
Signed-off-by: Cen Zhang (Microsoft) <blbllhy@gmail.com>
---
 kernel/pid.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/kernel/pid.c b/kernel/pid.c
index f55189a3d07d..fee62b2c0c7b 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -768,11 +768,15 @@ static int proc_do_cad_pid(const struct ctl_table *table, int write, void *buffe
 		size_t *lenp, loff_t *ppos)
 {
 	struct pid *new_pid;
+	struct pid *old_pid;
 	pid_t tmp_pid;
 	int r;
 	struct ctl_table tmp_table = *table;
 
+	rcu_read_lock();
 	tmp_pid = pid_vnr(cad_pid);
+	rcu_read_unlock();
+
 	tmp_table.data = &tmp_pid;
 
 	r = proc_dointvec(&tmp_table, write, buffer, lenp, ppos);
@@ -783,7 +787,9 @@ static int proc_do_cad_pid(const struct ctl_table *table, int write, void *buffe
 	if (!new_pid)
 		return -ESRCH;
 
-	put_pid(xchg(&cad_pid, new_pid));
+	old_pid = xchg(&cad_pid, new_pid);
+	synchronize_rcu();
+	put_pid(old_pid);
 	return 0;
 }
 
-- 
2.53.0


             reply	other threads:[~2026-07-17 21:01 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-17 21:01 Cen Zhang (Microsoft) [this message]
2026-07-17 21:35 ` [PATCH] pid: fix cad_pid use-after-free race in proc_do_cad_pid() Mateusz Guzik
2026-07-17 23:14   ` Bradley Morgan
2026-07-18  1:33     ` Cen Zhang (Microsoft)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260717210143.4734-1-blbllhy@gmail.com \
    --to=blbllhy@gmail.com \
    --cc=AutonomousCodeSecurity@microsoft.com \
    --cc=avagin@gmail.com \
    --cc=brauner@kernel.org \
    --cc=jack@suse.cz \
    --cc=kys@microsoft.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mjguzik@gmail.com \
    --cc=oleg@redhat.com \
    --cc=ptikhomirov@virtuozzo.com \
    --cc=tgopinath@linux.microsoft.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.