mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Davidlohr Bueso <dave@stgolabs.net>
To: Xiang Mei <xmei5@asu.edu>
Cc: linux-kernel@vger.kernel.org, akpm@linux-foundation.org,
	ljs@kernel.org, Liam.Howlett@oracle.com, brauner@kernel.org,
	baolin.wang@linux.alibaba.com, aha310510@gmail.com,
	kees@kernel.org, bestswngs@gmail.com, manfred@colorfullife.com
Subject: Re: [PATCH ipc] ipc/shm: fix race between shm_try_destroy_orphaned and do_shmat
Date: Mon, 6 Apr 2026 12:33:22 -0700	[thread overview]
Message-ID: <20260406193322.cu2rrtfmpixlv7yy@offworld> (raw)
In-Reply-To: <20260329013646.1188553-1-xmei5@asu.edu>

Cc Manfred.

On Sat, 28 Mar 2026, Xiang Mei wrote:

>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!

More like:

   CPU 0 (do_shmat)              CPU 1 (shm_try_destroy_orphaned)
   ipc_lock_object()
				shm_may_destroy() -> reads nattch==0
   shm_nattch++ (0 -> 1)
   ipc_unlock_object()
				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:

I think that an IS_ERR() check should also be added to do_shmat(),
it makes the code more robust (mitigating the actual bug fixed here
to not trigger the 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.

It's probably fine to unconditionally take the object lock in this
path (not performance critical). But I think it might be better to
just re-check shm_may_destroy() after taking the lock.

>
>Fixes: 4c677e2eefdb ("shm: optimize locking and ipc_namespace getting")

Old bug, seems not many users of shm_rmid_forced.

Thanks,
Davidlohr

>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
>

      parent reply	other threads:[~2026-04-06 19:33 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-29  1:36 Xiang Mei
2026-03-29  1:42 ` Xiang Mei
2026-04-06 19:33 ` Davidlohr Bueso [this message]

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=20260406193322.cu2rrtfmpixlv7yy@offworld \
    --to=dave@stgolabs.net \
    --cc=Liam.Howlett@oracle.com \
    --cc=aha310510@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=baolin.wang@linux.alibaba.com \
    --cc=bestswngs@gmail.com \
    --cc=brauner@kernel.org \
    --cc=kees@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ljs@kernel.org \
    --cc=manfred@colorfullife.com \
    --cc=xmei5@asu.edu \
    /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 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®