decode_devicenotify_args() says:
if (n <= 0)
goto out;
...;
args->devs = kmalloc_array(n, sizeof(*args->devs), GFP_KERNEL);
If the server sends n <= 0 in the callback RPC, the function returns
with status=0 (no error) but args->devs is not initialized. Subsequently
nfs4_callback_devicenotify() says:
kfree(args->devs)
which dereferences a wild pointer.
I've attached a demo program:
# uname -a
Linux (none) 5.16.0-rc7-00108-g800829388818-dirty #10 SMP Mon Jan 3 17:30:59 UTC 2022 riscv64 riscv64 riscv64 GNU/Linux
# cc nfs_17.c
# ./a.out
...
[ 74.542294] Unable to handle kernel paging request at virtual address 00037fe02133aa08
[ 74.768159] status: 0000000200000121 badaddr: 00037fe02133aa08 cause: 000000000000000d
[ 74.781690] [<ffffffff801218ba>] kfree+0x50/0x290
[ 74.792101] [<ffffffff80247c1e>] nfs4_callback_devicenotify+0xac/0xd6
[ 74.804090] [<ffffffff80246484>] nfs4_callback_compound+0x342/0x526
[ 74.816500] [<ffffffff80245aaa>] nfs_callback_dispatch+0xd0/0xe4
[ 74.828874] [<ffffffff8061a324>] svc_process_common+0x2f4/0x56c
[ 74.841161] [<ffffffff8061a77c>] bc_svc_process+0xde/0x1a4
[ 74.851179] [<ffffffff80245296>] nfs41_callback_svc+0x106/0x188
[ 74.863615] [<ffffffff80027010>] kthread+0x124/0x136
[ 74.873686] [<ffffffff8000303e>] ret_from_exception+0x0/0xc
[ 74.892645] ---[ end trace e784fbe07231bbd1 ]---