_nfs4_open_and_get_state() calls d_splice_alias() and assumes that a non-NULL returned dentry pointer is valid. However, d_splice_alias() returns ERR_PTR(-ELOOP) if the server assigns the same file handle to a file and its directory. This causes a later crash when nfs_set_verifier() tries to use the dentry pointer. I've attached a demo program, which works for me on kernel 5.15 on riscv, and 5.4.0 on amd64. # cc nfs_5.c # ./a.out ... [ 29.702595] VFS: Lookup of 'x' in nfs4 0:16 would have caused loop [ 29.710258] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000034 [ 29.754320] epc : ffffffff8004e24e ra : ffffffff807a8dc2 sp : ffffffd00056b960 [ 29.843403] status: 0000000200000121 badaddr: 0000000000000034 cause: 000000000000000d [ 29.851434] [<ffffffff8004e24e>] do_raw_spin_lock+0xa/0xd8 [ 29.857532] [<ffffffff807a8dc2>] _raw_spin_lock+0x1a/0x22 [ 29.863650] [<ffffffff80205bf2>] nfs_set_verifier+0x20/0x6e [ 29.869795] [<ffffffff8022a718>] nfs4_do_open.constprop.0+0x3f6/0x774 [ 29.877084] [<ffffffff8022ab2e>] nfs4_atomic_open+0xc/0x1c [ 29.883255] [<ffffffff80208162>] nfs_atomic_open+0x194/0x332 [ 29.890784] [<ffffffff8013756e>] path_openat+0x5ca/0xaf6 [ 29.896912] [<ffffffff80138468>] do_filp_open+0x70/0xd0 [ 29.903003] [<ffffffff801276de>] do_sys_openat2+0x1fc/0x298 [ 29.909150] [<ffffffff80128870>] do_sys_open+0x3c/0x78 [ 29.915308] [<ffffffff801288ee>] sys_openat+0x18/0x20 [ 29.921424] [<ffffffff80003046>] ret_from_syscall+0x0/0x2
Attachment:
nfs_5.c
Description: Binary data