]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.14.60/nfsd-fix-potential-use-after-free-in-nfsd4_decode_getdeviceinfo.patch
Fixes for 5.10
[thirdparty/kernel/stable-queue.git] / releases / 4.14.60 / nfsd-fix-potential-use-after-free-in-nfsd4_decode_getdeviceinfo.patch
CommitLineData
a65d4bac
GKH
1From foo@baz Sat Jul 28 10:25:26 CEST 2018
2From: Scott Mayhew <smayhew@redhat.com>
3Date: Fri, 8 Jun 2018 16:31:46 -0400
4Subject: nfsd: fix potential use-after-free in nfsd4_decode_getdeviceinfo
5
6From: Scott Mayhew <smayhew@redhat.com>
7
8[ Upstream commit 3171822fdcdd6e6d536047c425af6dc7a92dc585 ]
9
10When running a fuzz tester against a KASAN-enabled kernel, the following
11splat periodically occurs.
12
13The problem occurs when the test sends a GETDEVICEINFO request with a
14malformed xdr array (size but no data) for gdia_notify_types and the
15array size is > 0x3fffffff, which results in an overflow in the value of
16nbytes which is passed to read_buf().
17
18If the array size is 0x40000000, 0x80000000, or 0xc0000000, then after
19the overflow occurs, the value of nbytes 0, and when that happens the
20pointer returned by read_buf() points to the end of the xdr data (i.e.
21argp->end) when really it should be returning NULL.
22
23Fix this by returning NFS4ERR_BAD_XDR if the array size is > 1000 (this
24value is arbitrary, but it's the same threshold used by
25nfsd4_decode_bitmap()... in could really be any value >= 1 since it's
26expected to get at most a single bitmap in gdia_notify_types).
27
28[ 119.256854] ==================================================================
29[ 119.257611] BUG: KASAN: use-after-free in nfsd4_decode_getdeviceinfo+0x5a4/0x5b0 [nfsd]
30[ 119.258422] Read of size 4 at addr ffff880113ada000 by task nfsd/538
31
32[ 119.259146] CPU: 0 PID: 538 Comm: nfsd Not tainted 4.17.0+ #1
33[ 119.259662] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.9.3-1.fc25 04/01/2014
34[ 119.261202] Call Trace:
35[ 119.262265] dump_stack+0x71/0xab
36[ 119.263371] print_address_description+0x6a/0x270
37[ 119.264609] kasan_report+0x258/0x380
38[ 119.265854] ? nfsd4_decode_getdeviceinfo+0x5a4/0x5b0 [nfsd]
39[ 119.267291] nfsd4_decode_getdeviceinfo+0x5a4/0x5b0 [nfsd]
40[ 119.268549] ? nfs4svc_decode_compoundargs+0xa5b/0x13c0 [nfsd]
41[ 119.269873] ? nfsd4_decode_sequence+0x490/0x490 [nfsd]
42[ 119.271095] nfs4svc_decode_compoundargs+0xa5b/0x13c0 [nfsd]
43[ 119.272393] ? nfsd4_release_compoundargs+0x1b0/0x1b0 [nfsd]
44[ 119.273658] nfsd_dispatch+0x183/0x850 [nfsd]
45[ 119.274918] svc_process+0x161c/0x31a0 [sunrpc]
46[ 119.276172] ? svc_printk+0x190/0x190 [sunrpc]
47[ 119.277386] ? svc_xprt_release+0x451/0x680 [sunrpc]
48[ 119.278622] nfsd+0x2b9/0x430 [nfsd]
49[ 119.279771] ? nfsd_destroy+0x1c0/0x1c0 [nfsd]
50[ 119.281157] kthread+0x2db/0x390
51[ 119.282347] ? kthread_create_worker_on_cpu+0xc0/0xc0
52[ 119.283756] ret_from_fork+0x35/0x40
53
54[ 119.286041] Allocated by task 436:
55[ 119.287525] kasan_kmalloc+0xa0/0xd0
56[ 119.288685] kmem_cache_alloc+0xe9/0x1f0
57[ 119.289900] get_empty_filp+0x7b/0x410
58[ 119.291037] path_openat+0xca/0x4220
59[ 119.292242] do_filp_open+0x182/0x280
60[ 119.293411] do_sys_open+0x216/0x360
61[ 119.294555] do_syscall_64+0xa0/0x2f0
62[ 119.295721] entry_SYSCALL_64_after_hwframe+0x44/0xa9
63
64[ 119.298068] Freed by task 436:
65[ 119.299271] __kasan_slab_free+0x130/0x180
66[ 119.300557] kmem_cache_free+0x78/0x210
67[ 119.301823] rcu_process_callbacks+0x35b/0xbd0
68[ 119.303162] __do_softirq+0x192/0x5ea
69
70[ 119.305443] The buggy address belongs to the object at ffff880113ada000
71 which belongs to the cache filp of size 256
72[ 119.308556] The buggy address is located 0 bytes inside of
73 256-byte region [ffff880113ada000, ffff880113ada100)
74[ 119.311376] The buggy address belongs to the page:
75[ 119.312728] page:ffffea00044eb680 count:1 mapcount:0 mapping:0000000000000000 index:0xffff880113ada780
76[ 119.314428] flags: 0x17ffe000000100(slab)
77[ 119.315740] raw: 0017ffe000000100 0000000000000000 ffff880113ada780 00000001000c0001
78[ 119.317379] raw: ffffea0004553c60 ffffea00045c11e0 ffff88011b167e00 0000000000000000
79[ 119.319050] page dumped because: kasan: bad access detected
80
81[ 119.321652] Memory state around the buggy address:
82[ 119.322993] ffff880113ad9f00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
83[ 119.324515] ffff880113ad9f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
84[ 119.326087] >ffff880113ada000: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
85[ 119.327547] ^
86[ 119.328730] ffff880113ada080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
87[ 119.330218] ffff880113ada100: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
88[ 119.331740] ==================================================================
89
90Signed-off-by: Scott Mayhew <smayhew@redhat.com>
91Signed-off-by: J. Bruce Fields <bfields@redhat.com>
92Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
93Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
94---
95 fs/nfsd/nfs4xdr.c | 2 ++
96 1 file changed, 2 insertions(+)
97
98--- a/fs/nfsd/nfs4xdr.c
99+++ b/fs/nfsd/nfs4xdr.c
100@@ -1586,6 +1586,8 @@ nfsd4_decode_getdeviceinfo(struct nfsd4_
101 gdev->gd_maxcount = be32_to_cpup(p++);
102 num = be32_to_cpup(p++);
103 if (num) {
104+ if (num > 1000)
105+ goto xdr_error;
106 READ_BUF(4 * num);
107 gdev->gd_notify_types = be32_to_cpup(p++);
108 for (i = 1; i < num; i++) {