[Devel] [PATCH RH7] vhost/net: don't read and process iotlb message with bad lenth
Pavel Tikhomirov
ptikhomirov at virtuozzo.com
Thu Dec 13 11:28:23 MSK 2018
Resend as first one missed the list.
On kernel vz7.73.18+ we had a stack:
==================================================================
BUG: KASan: out of bounds on stack in memcpy_fromiovecend net/core/iovec.c:142 [inline] at addr ffff88000413fcd0
BUG: KASan: out of bounds on stack in memcpy_fromiovecend+0x18c/0x1c0 net/core/iovec.c:128 at addr ffff88000413fcd0
Read of size 8 by task syz-executor/757712
page:ffffea0000104fc0 count:0 mapcount:0 mapping: (null) index:0x0
page flags: 0x1fffff00000000()
page dumped because: kasan: bad access detected
CPU: 1 PID: 757712 Comm: syz-executor ve: 0 Kdump: loaded Not tainted 3.10.0-862.20.2.ovz.73.18 #95 73.18
Hardware name: Virtuozzo KVM, BIOS rel-1.10.2-0-g5f4c7b1-prebuilt.qemu-project.org 04/01/2014
Call Trace:
[<ffffffff893d44b9>] dump_stack+0x1e/0x20 lib/dump_stack.c:18
[<ffffffff893c6fec>] print_address_description mm/kasan/report.c:188 [inline]
[<ffffffff893c6fec>] kasan_report_error mm/kasan/report.c:263 [inline]
[<ffffffff893c6fec>] kasan_report.cold+0x26e/0x3d6 mm/kasan/report.c:297
[<ffffffff88281a39>] __asan_report_load8_noabort+0x19/0x20 mm/kasan/report.c:318
[<ffffffff88f20bcc>] memcpy_fromiovecend net/core/iovec.c:142 [inline]
[<ffffffff88f20bcc>] memcpy_fromiovecend+0x18c/0x1c0 net/core/iovec.c:128
[<ffffffffc189eee0>] vhost_chr_write_iter+0x90/0xf50 [vhost]
[<ffffffffc18b8d27>] vhost_net_aio_write+0xd7/0x120 [vhost_net]
[<ffffffff882f3d0c>] do_sync_write+0x17c/0x270 fs/read_write.c:493
[<ffffffff882f62ff>] vfs_write+0x4bf/0x630 fs/read_write.c:547
[<ffffffff882f9065>] SYSC_write fs/read_write.c:594 [inline]
[<ffffffff882f9065>] SyS_write+0x185/0x380 fs/read_write.c:586
[<ffffffff894329db>] system_call_fastpath+0x22/0x27
Memory state around the buggy address:
ffff88000413fb80: 00 00 00 00 00 00 00 00 00 f3 f3 f3 f3 00 00 00
ffff88000413fc00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>ffff88000413fc80: 00 00 f1 f1 f1 f1 f1 f1 00 00 f2 f2 00 00 00 00
^
ffff88000413fd00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
ffff88000413fd80: 00 00 f3 f3 f3 f3 f3 f3 f3 f3 00 00 00 00 00 00
==================================================================
The syzcaller process likely was 32-bit, that means it has vhost_msg -
sizeof(struct vhost_msg) == 0x44, but 64-bit kernel expects to see
sizeof(struct vhost_msg) == 0x48 because of 4 byte hole for alignment.
Thus len in memcpy_fromiovecend is 0x48 but there is only 0x44 bytes in
iov, and we do iov++ moving to next iovec (which does not exist) and
acces iov->iov_base out of bounds at net/core/iovec.c:142.
I think that commit 429711aec282 ("vhost: switch to use new message
format") fixes the problem only if VHOST_BACKEND_F_IOTLB_V2 is enabled
on vhost device and if also syzcaller uses new vhost_msg_v2 type,
I doubt that it is so now, as vhost_msg_v2 feature is only 5 months old.
For old vhost_msg path nothing is changed AFAICS and we will still fail.
MS kernel is not affected as they use copy_from_iter() instead of
memcpy_fromiovecend() and it does not allow reading more data than
given by iovecs.
So lets silently return if iovecs len is less than vhost_msg, ms does
effectively the same in vhost_chr_write_iter.
https://jira.sw.ru/browse/PSBM-90291
Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
---
drivers/vhost/net.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index ee3477aaf71b..c3010a82dfa1 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -1305,6 +1305,9 @@ static ssize_t vhost_net_aio_write(struct kiocb *iocb,
if (len < 0)
return -EINVAL;
+ if (len < sizeof(struct vhost_msg))
+ return len;
+
return vhost_chr_write_iter(dev, from);
}
--
2.17.1
More information about the Devel
mailing list