Linux NFS development
 help / color / mirror / Atom feed
From: Chuck Lever <chuck.lever@oracle.com>
To: Olga Kornievskaia <okorniev@redhat.com>
Cc: linux-nfs@vger.kernel.org, Jeff Layton <jlayton@kernel.org>,
	rtm@csail.mit.edu
Subject: Re: use-after-free in nfs4stat.c _free_cpntf_state_locked()
Date: Fri, 3 Oct 2025 13:40:07 -0400	[thread overview]
Message-ID: <d8f064c1-a26f-4eed-b4f0-1f7f608f415f@oracle.com> (raw)
In-Reply-To: <83337.1759494865@localhost>

On 10/3/25 8:34 AM, rtm@csail.mit.edu wrote:
> If an NFS 4.2 client has a COPY_NOTIFY registered, and then
> re-establishes its session with EXCHANGE_ID with a new verifier and
> CREATE_SESSION, nfsd4_create_session() calls expire_client() for the
> old session, which frees the nfs4_stid associated with the
> COPY_NOTIFY. But the COPY_NOTIFY's nfs4_cpntf_state still exists; when
> nfs4_laundromat() expires it, _free_cpntf_state_locked()'s
> list_del(&cps->cp_list) uses the freed memory of the nfs4_stid.
> 
> A demo:
> 
> # uname -r
> 6.17.0-01737-g50c19e20ed2e-dirty
> # cat /etc/exports
> /tmp 127.0.0.1(rw,subtree_check,pnfs)
> # wget http://www.rtmrtm.org/rtm/nfsd185b.c
> # cc nfsd185b.c
> # ./a.out
> (wait 10 or 20 seconds for nfs4_laundromat())
> (you may have to run a.out more than once)
> list_del corruption. prev->next should be ffff8881068669d8, but was 6b6b6b6b6b6b6b6b. (prev=ffff888105190010)
> kernel BUG at lib/list_debug.c:62!
> Oops: invalid opcode: 0000 [#1] SMP DEBUG_PAGEALLOC PTI
> CPU: 2 UID: 0 PID: 268 Comm: kworker/u51:2 Tainted: G        W           6.17.0-01737-g50c19e20ed2e-dirty #33 PREEMPT(voluntary) 
> Workqueue: nfsd4 laundromat_main
> RIP: 0010:__list_del_entry_valid_or_report+0xdd/0x110
> Call Trace:
>  _free_cpntf_state_locked+0x40/0xb0
>  laundromat_main+0x5ec/0xaf0
> 
> The nfs4_cpntf_state is allocated and linked into the
> nfs4_stid.sc_cp_list here:
> 
> #0  list_add (head=<optimized out>, new=<optimized out>)
>     at fs/nfsd/nfs4state.c:985
> #1  nfs4_alloc_init_cpntf_state (nn=nn@entry=0xffffffd602d82000, 
>     p_stid=0xffffffd606858008) at fs/nfsd/nfs4state.c:985
> #2  0xffffffff804b04e0 in nfsd4_copy_notify (rqstp=0xffffffd6040fb800, 
>     cstate=<optimized out>, u=0xffffffd6052e2720) at fs/nfsd/nfs4proc.c:2078
> (gdb) print cps
> $1 = (struct nfs4_cpntf_state *) 0xffffffd603fe9020
> (gdb) print p_stid
> $2 = (struct nfs4_stid *) 0xffffffd606858008
> 
> The nfs4_stid is freed here:
> 
> #0  nfs4_free_ol_stateid (stid=0xffffffd606858008) at fs/nfsd/nfs4state.c:1502
> #1  0xffffffff804c3ed2 in free_ol_stateid_reaplist (
>     reaplist=reaplist@entry=0xffffffc60031baf8) at fs/nfsd/nfs4state.c:1602
> #2  0xffffffff804c46fa in release_openowner (oo=0xffffffd606857008)
>     at fs/nfsd/nfs4state.c:1696
> #3  0xffffffff804c4898 in __destroy_client (clp=clp@entry=0xffffffd605308008)
>     at fs/nfsd/nfs4state.c:2483
> #4  0xffffffff804c49fa in expire_client (clp=0xffffffd605308008)
>     at fs/nfsd/nfs4state.c:2533
> #5  0xffffffff804c7a26 in nfsd4_create_session (rqstp=0xffffffd6040fb800, 
>     cstate=<optimized out>, u=0xffffffd6052e2060) at fs/nfsd/nfs4state.c:4041
> (gdb) print stid
> $3 = (struct nfs4_stid *) 0xffffffd606858008
> (gdb) print stid->sc_cp_list
> $4 = {next = 0xffffffd603fe9038, prev = 0xffffffd603fe9038}
> 
> Freeing the nfs4_cpntf_state trips over the free nfs4_stid here:
> 
> #0  _free_cpntf_state_locked (nn=nn@entry=0xffffffd602d82000, 
>     cps=0xffffffd603fe9020) at fs/nfsd/nfs4state.c:7226
> #1  0xffffffff804c6210 in nfs4_laundromat (nn=0xffffffd602d82000)
>     at fs/nfsd/nfs4state.c:6836
> #2  laundromat_main (laundry=0xffffffd602d820d0) at fs/nfsd/nfs4state.c:6926
> (gdb) print cps
> $5 = (struct nfs4_cpntf_state *) 0xffffffd603fe9020
> (gdb) print cps->cp_list
> $6 = {next = 0xffffffd606858010, prev = 0xffffffd606858010}
> (gdb) print cps->cp_list.next.prev
> $7 = (struct list_head *) 0x6b6b6b6b6b6b6b6b
> 
> Robert Morris
> rtm@mit.edu

Olga, do you have a few moments to triage this?


-- 
Chuck Lever

      reply	other threads:[~2025-10-03 17:40 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-10-03 12:34 use-after-free in nfs4stat.c _free_cpntf_state_locked() rtm
2025-10-03 17:40 ` Chuck Lever [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=d8f064c1-a26f-4eed-b4f0-1f7f608f415f@oracle.com \
    --to=chuck.lever@oracle.com \
    --cc=jlayton@kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=okorniev@redhat.com \
    --cc=rtm@csail.mit.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