clientstr_hashval() always hashes 8 bytes of the client name, but since commit 6b1891052a3f ("nfsd: make nfs4_client_reclaim use an xdr_netobj instead of a fixed char array") the name is a kmemdup()'d xdr_netobj of arbitrary length. A 1-7 byte ownerid is legal, so the hash reads past the allocation: BUG: KASAN: slab-out-of-bounds in nfsd4_find_reclaim_client Read of size 1 at addr ffff888010acf1a1 by task nfsd/141 Call Trace: kasan_report (mm/kasan/report.c:595) nfsd4_find_reclaim_client (fs/nfsd/nfs4state.c:1622) nfsd4_reclaim_complete (fs/nfsd/nfs4state.c:5286) nfsd4_proc_compound (fs/nfsd/nfs4proc.c:3313) nfsd_dispatch (fs/nfsd/nfssvc.c:1038) svc_process_common (net/sunrpc/svc.c:1527) svc_process (net/sunrpc/svc.c:1682) svc_recv (net/sunrpc/svc_xprt.c:886) nfsd (fs/nfsd/nfssvc.c:919) The hash only selects a bucket; compare_blob() does the real comparison. Hash the actual length, like ownerstr_hashval() does. Fixes: 6b1891052a3f ("nfsd: make nfs4_client_reclaim use an xdr_netobj instead of a fixed char array") Cc: stable@vger.kernel.org Reported-by: co+7aebac19e62711ff@bugs.sh Signed-off-by: Boyan Liu --- fs/nfsd/nfs4state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 18e17232c..6c50286fa 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -1619,7 +1619,7 @@ static unsigned int clientid_hashval(u32 id) static unsigned int clientstr_hashval(struct xdr_netobj name) { - return opaque_hashval(name.data, 8) & CLIENT_HASH_MASK; + return opaque_hashval(name.data, name.len) & CLIENT_HASH_MASK; } /* -- 2.43.0