mirror of
https://github.com/torvalds/linux.git
synced 2026-09-14 16:10:02 +02:00
nfsd: defer vfree of compound ops to fix rpc_status UAF
The rpc_status netlink dumpit walks every in-flight svc_rqst under
rcu_read_lock and, for NFSv4 requests, reads opnums out of
args->ops[]. But args->ops is a separate vmalloc buffer freed
synchronously by vfree() in nfsd4_release_compoundargs() at the end
of every compound. The dumpit's rcu_read_lock pins the svc_rqst
struct itself (freed via kfree_rcu), but nothing defers the vfree
of the ops buffer across the RCU grace period. A concurrent compound
completion can therefore free the buffer while the dumpit is reading
it — a use-after-free on vmalloc memory.
The trailing seqcount recheck (smp_load_acquire of rq_status_counter)
cannot undo a load that already retired against freed memory.
Fix by replacing vfree(args->ops) with kvfree_rcu_mightsleep(), which
defers the free until after an RCU grace period. This makes the
existing rcu_read_lock in the dumpit sufficient to protect the read.
The tradeoff is that completed compound ops buffers (up to
200 * sizeof(struct nfsd4_op)) persist in memory slightly longer,
across one grace period, before being reclaimed.
Fixes: bd9d6a3efa ("NFSD: add rpc_status netlink support")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-6
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260602-nfsd-testing-v2-1-e4ea62e3cd5c@kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
parent
5b06f70637
commit
fca26a3fc1
|
|
@ -6435,8 +6435,10 @@ void nfsd4_release_compoundargs(struct svc_rqst *rqstp)
|
|||
struct nfsd4_compoundargs *args = rqstp->rq_argp;
|
||||
|
||||
if (args->ops != args->iops) {
|
||||
vfree(args->ops);
|
||||
void *old_ops = args->ops;
|
||||
|
||||
args->ops = args->iops;
|
||||
kvfree_rcu_mightsleep(old_ops);
|
||||
}
|
||||
while (args->to_free) {
|
||||
struct svcxdr_tmpbuf *tb = args->to_free;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user