mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH ipc] ipc/shm: fix race between shm_try_destroy_orphaned and do_shmat
@ 2026-03-29  1:36 Xiang Mei
  2026-03-29  1:42 ` Xiang Mei
  2026-04-06 19:33 ` Davidlohr Bueso
  0 siblings, 2 replies; 3+ messages in thread
From: Xiang Mei @ 2026-03-29  1:36 UTC (permalink / raw)
  To: linux-kernel
  Cc: akpm, ljs, Liam.Howlett, brauner, baolin.wang, aha310510, kees,
	bestswngs, Xiang Mei

shm_try_destroy_orphaned() reads shm_nattch via shm_may_destroy()
without holding the per-object spinlock, relying on rwsem alone for
synchronization. However, do_shmat() modifies shm_nattch under the
per-object spinlock (not rwsem), creating a TOCTOU race:

  CPU 0 (do_shmat)              CPU 1 (shm_try_destroy_orphaned)
  ipc_lock_object()
  shm_nattch++ (0 -> 1)
  ipc_unlock_object()
                                shm_may_destroy() -> reads stale nattch==0
                                shm_lock_by_ptr()
                                shm_destroy()  // nattch is actually 1!

The segment is destroyed while do_shmat() has already incremented
shm_nattch and is proceeding with the mmap setup.  When do_shmat()
later reaches out_nattch, shm_lock() returns ERR_PTR (the IDR entry
was removed by shm_destroy) and the code dereferences it without an
IS_ERR() check, causing a null-ptr-deref crash:

 BUG: kernel NULL pointer dereference, address: 0000000000000072
 RIP: 0010:do_shmat (ipc/shm.c:1678)
 Call Trace:
  __x64_sys_shmat (ipc/shm.c:1699 ipc/shm.c:1693 ipc/shm.c:1693)
  do_syscall_64 (arch/x86/entry/syscall_64.c:94)
  [...]

Fix by taking the object lock before checking shm_may_destroy() in
shm_try_destroy_orphaned(), so the check sees the up-to-date value
of shm_nattch.

Fixes: 4c677e2eefdb ("shm: optimize locking and ipc_namespace getting")
Reported-by: Weiming Shi <bestswngs@gmail.com>
Signed-off-by: Xiang Mei <xmei5@asu.edu>
---
 ipc/shm.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/ipc/shm.c b/ipc/shm.c
index a95dae447707..50f9aa7ff33a 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -416,17 +416,18 @@ static int shm_try_destroy_orphaned(int id, void *p, void *data)
 
 	/*
 	 * We want to destroy segments without users and with already
-	 * exit'ed originating process.
-	 *
-	 * As shp->* are changed under rwsem, it's safe to skip shp locking.
+	 * exit'ed originating process. Take the object lock before
+	 * checking shm_may_destroy() since shm_nattch can be modified
+	 * under the object lock alone (e.g. by do_shmat).
 	 */
 	if (!list_empty(&shp->shm_clist))
 		return 0;
 
-	if (shm_may_destroy(shp)) {
-		shm_lock_by_ptr(shp);
+	shm_lock_by_ptr(shp);
+	if (shm_may_destroy(shp))
 		shm_destroy(ns, shp);
-	}
+	else
+		shm_unlock(shp);
 	return 0;
 }
 
-- 
2.43.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-04-06 19:33 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-03-29  1:36 [PATCH ipc] ipc/shm: fix race between shm_try_destroy_orphaned and do_shmat Xiang Mei
2026-03-29  1:42 ` Xiang Mei
2026-04-06 19:33 ` Davidlohr Bueso

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®