nfs v4 decode_read_plus_hole() insufficient length sanity check

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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] [<ffffffff80346650>] __memset+0x60/0xfc
[   74.637735] [<ffffffff802333ac>] nfs4_xdr_dec_read_plus+0x2d6/0x3fa
[   74.650614] [<ffffffff80617406>] rpcauth_unwrap_resp_decode+0x12/0x1a
[   74.663084] [<ffffffff80618124>] rpcauth_unwrap_resp+0x12/0x1a
[   74.675822] [<ffffffff8060e23a>] call_decode+0x112/0x176
[   74.686253] [<ffffffff8061686c>] __rpc_execute+0x7e/0x21a
[   74.696694] [<ffffffff80616a2c>] rpc_async_schedule+0x24/0x46
[   74.709450] [<ffffffff800209d4>] process_one_work+0x13e/0x28a
[   74.722182] [<ffffffff80020b9c>] worker_thread+0x7c/0x320
[   74.732607] [<ffffffff80027010>] kthread+0x124/0x136
[   74.743073] [<ffffffff8000303e>] ret_from_exception+0x0/0xc
[   74.764059] ---[ end trace ca32aa753f3ddad2 ]---

Attachment: nfs_20.c
Description: Binary data


[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux