]>
Commit | Line | Data |
---|---|---|
a65d4bac GKH |
1 | From foo@baz Sat Jul 28 10:25:26 CEST 2018 |
2 | From: Scott Mayhew <smayhew@redhat.com> | |
3 | Date: Fri, 8 Jun 2018 16:31:46 -0400 | |
4 | Subject: nfsd: fix potential use-after-free in nfsd4_decode_getdeviceinfo | |
5 | ||
6 | From: Scott Mayhew <smayhew@redhat.com> | |
7 | ||
8 | [ Upstream commit 3171822fdcdd6e6d536047c425af6dc7a92dc585 ] | |
9 | ||
10 | When running a fuzz tester against a KASAN-enabled kernel, the following | |
11 | splat periodically occurs. | |
12 | ||
13 | The problem occurs when the test sends a GETDEVICEINFO request with a | |
14 | malformed xdr array (size but no data) for gdia_notify_types and the | |
15 | array size is > 0x3fffffff, which results in an overflow in the value of | |
16 | nbytes which is passed to read_buf(). | |
17 | ||
18 | If the array size is 0x40000000, 0x80000000, or 0xc0000000, then after | |
19 | the overflow occurs, the value of nbytes 0, and when that happens the | |
20 | pointer returned by read_buf() points to the end of the xdr data (i.e. | |
21 | argp->end) when really it should be returning NULL. | |
22 | ||
23 | Fix this by returning NFS4ERR_BAD_XDR if the array size is > 1000 (this | |
24 | value is arbitrary, but it's the same threshold used by | |
25 | nfsd4_decode_bitmap()... in could really be any value >= 1 since it's | |
26 | expected 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 | ||
90 | Signed-off-by: Scott Mayhew <smayhew@redhat.com> | |
91 | Signed-off-by: J. Bruce Fields <bfields@redhat.com> | |
92 | Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> | |
93 | Signed-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++) { |