decode_read_plus_hole() reads a 64-bit length from the server's RPC reply. There's a sanity-check: if (length + res->count > args->count) { but it doesn't work if length is big enough that the sum wraps, e.g. 0xffffffffffffffff. In that case, eventually the loop in xdr_buf_pages_zero() calls memset() on the wrong memory. I've attached a demo: # uname -a Linux (none) 5.16.0-rc7-00108-g800829388818-dirty #23 SMP Tue Jan 4 19:38:52 UTC 2022 riscv64 riscv64 riscv64 GNU/Linux # cc nfs_20.c # ./a.out ... [ 74.362358] Unable to handle kernel paging request at virtual address 92492d8ddff40000 [ 74.612471] status: 0000000200000121 badaddr: 92492d8ddff40000 cause: 000000000000000f [ 74.626913] [] __memset+0x60/0xfc [ 74.637735] [] nfs4_xdr_dec_read_plus+0x2d6/0x3fa [ 74.650614] [] rpcauth_unwrap_resp_decode+0x12/0x1a [ 74.663084] [] rpcauth_unwrap_resp+0x12/0x1a [ 74.675822] [] call_decode+0x112/0x176 [ 74.686253] [] __rpc_execute+0x7e/0x21a [ 74.696694] [] rpc_async_schedule+0x24/0x46 [ 74.709450] [] process_one_work+0x13e/0x28a [ 74.722182] [] worker_thread+0x7c/0x320 [ 74.732607] [] kthread+0x124/0x136 [ 74.743073] [] ret_from_exception+0x0/0xc [ 74.764059] ---[ end trace ca32aa753f3ddad2 ]---