2021-11-07 16:50:51

by rtm

[permalink] [raw]
Subject: NFS client can use slot after it is kfree()ed

If the server returns sr_highest_slotid=0xffffffff in an OP_SEQUENCE
reply, nfs41_set_server_slotid_locked() will cause all the slots to be
kfree()ed, including the one that's in use. nfs41_release_slot() will
then dereference pointers extracted from the free'd slot, and possibly
crash. 0xffffffff is special due to this code:

nfs4_shrink_slot_table(tbl, highest_slotid + 1);

I've attached a program that demonstrates the bug. My machine has
slub_debug=FZP.

# uname -a
Linux (none) 5.15.0-rc7-dirty #19 SMP Sat Nov 6 12:55:40 UTC 2021 riscv64 riscv64 riscv64 GNU/Linux
# cc nfs_3.c
# ./a.out
...
[ 18.969075] Unable to handle kernel paging request at virtual address 6b6b6b6b6b6b6b68
[ 18.983273] Oops [#1]
[ 18.988716] Modules linked in:
[ 18.996151] CPU: 0 PID: 60 Comm: mount.nfs Not tainted 5.15.0-rc7-dirty #16
[ 19.008294] Hardware name: ucbbar,riscvemu-bare (DT)
[ 19.017541] epc : nfs41_release_slot+0x20/0xc8
[ 19.026918] ra : nfs41_sequence_done+0x22/0x34
[ 19.036245] epc : ffffffff802206ac ra : ffffffff80225a7a sp : ffffffd00057b7f0
...
[ 19.183462] status: 0000000200000121 badaddr: 6b6b6b6b6b6b6b68 cause: 000000000000000d
[ 19.198066] [<ffffffff802206ac>] nfs41_release_slot+0x20/0xc8
[ 19.210683] [<ffffffff80225a7a>] nfs41_sequence_done+0x22/0x34
[ 19.223249] [<ffffffff80226b5e>] nfs41_call_sync_done+0xe/0x16
[ 19.235828] [<ffffffff8071a328>] rpc_exit_task+0x26/0x74
[ 19.246807] [<ffffffff8071a4b0>] __rpc_execute+0x76/0x216
[ 19.257785] [<ffffffff8071aace>] rpc_execute+0x58/0x7e
[ 19.268764] [<ffffffff80713358>] rpc_run_task+0x12c/0x16c
[ 19.279683] [<ffffffff80220a52>] nfs4_call_sync_custom+0x12/0x32
[ 19.292304] [<ffffffff8022388a>] _nfs41_proc_secinfo_no_name.isra.0+0xca/0x13a
[ 19.306944] [<ffffffff8022886c>] nfs41_find_root_sec+0xc6/0x228
[ 19.319538] [<ffffffff8022bf2e>] nfs4_proc_get_rootfh+0x26/0x9a
[ 19.332128] [<ffffffff80248396>] nfs4_get_rootfh+0x40/0xbc
[ 19.343070] [<ffffffff80248a5a>] nfs4_server_common_setup+0x1ac/0x1be
[ 19.356076] [<ffffffff802498e6>] nfs4_create_server+0x16c/0x208
[ 19.368654] [<ffffffff8024161e>] nfs4_try_get_tree+0x16/0x4c
[ 19.381247] [<ffffffff80218bac>] nfs_get_tree+0x34a/0x3ac
[ 19.392176] [<ffffffff8012bce4>] vfs_get_tree+0x18/0x88
[ 19.403092] [<ffffffff8014a28e>] path_mount+0x4f4/0x77a
[ 19.414080] [<ffffffff8014a560>] do_mount+0x4c/0x7e
[ 19.424644] [<ffffffff8014a912>] sys_mount+0xca/0x14e
[ 19.435623] [<ffffffff80003046>] ret_from_syscall+0x0/0x2


Attachments:
nfs_3.c (6.99 kB)