From ea25e3c7915b24e0ef93ee85190f3fada037dfb1 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 21 Apr 2026 12:11:25 -0400 Subject: [PATCH] sunrpc: prevent out-of-bounds read in __cache_seq_start() Commit 7b546bd89975 ("sunrpc/cache: improve RCU safety in cache_list walking.") changed the tail of __cache_seq_start() to unconditionally store *pos = ((long long)hash << 32) + 1 before returning, dropping a prior "hash >= cd->hash_size" guard. When the while loop exits because every remaining bucket was empty, hash equals cd->hash_size, so the stored *pos is one position past the table's last valid bucket. seq_read_iter() caches that index in m->index. A subsequent pread(2) at the same file offset skips traverse() and hands the stored index back to __cache_seq_start(), which decodes hash = cd->hash_size and dereferences cd->hash_table[cd->hash_size] -- one hlist_head past the end of the kzalloc'd table. KASAN reports an eight-byte slab-out-of-bounds read at the tail of the 2048-byte hash_table allocation for the NFSD export cache (EXPORT_HASHMAX * sizeof(struct hlist_head) == 256 * 8). Reject an input hash that is out of range before touching the hash table. cache_seq_next() already bounds-checks its own loop; the start routine needs to be symmetric. Reported-by: syzbot+60cfa08822470bbebe44@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=60cfa08822470bbebe44 Fixes: 7b546bd89975 ("sunrpc/cache: improve RCU safety in cache_list walking.") Reviewed-by: Benjamin Coddington Reviewed-by: NeilBrown Signed-off-by: Chuck Lever --- net/sunrpc/cache.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index b5474ce534fb..27dd6b58b8ff 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c @@ -1348,6 +1348,9 @@ static void *__cache_seq_start(struct seq_file *m, loff_t *pos) hash = n >> 32; entry = n & ((1LL<<32) - 1); + if (hash >= cd->hash_size) + return NULL; + hlist_for_each_entry_rcu(ch, &cd->hash_table[hash], cache_list) if (!entry--) return ch;