diff mbox series

vhost: fix null pointer dereference in vhost_del_umem_range

Message ID 20190709114251.24662-1-dkirjanov@suse.com
State Rejected
Delegated to: David Miller
Headers show
Series vhost: fix null pointer dereference in vhost_del_umem_range | expand

Commit Message

Denis Kirjanov July 9, 2019, 11:42 a.m. UTC
> UBSAN: Undefined behaviour in ../drivers/vhost/vhost.c:52:1
> member access within null pointer of type 'struct rb_root'
> CPU: 2 PID: 1450 Comm: syz-executor493 Not tainted
> 4.12.14-525.g4d6309b-default #1 SLE15 (unreleased)
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
> 1.0.0-prebuilt.qemu-project.org 04/01/2014
> Call Trace:
>  __dump_stack lib/dump_stack.c:16 [inline]
>  dump_stack+0xc6/0x159 lib/dump_stack.c:52
>  ubsan_epilogue+0xe/0x81 lib/ubsan.c:164
>  handle_missaligned_access lib/ubsan.c:299 [inline]
>  __ubsan_handle_type_mismatch+0x2ed/0x44e lib/ubsan.c:325
>  vhost_chr_write_iter+0x103e/0x1330 [vhost]
>  call_write_iter include/linux/fs.h:1764 [inline]
>  new_sync_write fs/read_write.c:497 [inline]
>  __vfs_write+0x67c/0x9b0 fs/read_write.c:510
>  vfs_write+0x1a2/0x610 fs/read_write.c:558
>  SYSC_write fs/read_write.c:605 [inline]
>  SyS_write+0xd8/0x1f0 fs/read_write.c:597
>  do_syscall_64+0x26b/0x6e0 arch/x86/entry/common.c:284
>  entry_SYSCALL_64_after_hwframe+0x3d/0xa2
> RIP: 0033:0x7fdb7687a739
> RSP: 002b:00007ffd48719f38 EFLAGS: 00000213 ORIG_RAX: 0000000000000001
> RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fdb7687a739
> RDX: 0000000000000068 RSI: 0000000020000300 RDI: 0000000000000003
> RBP: 00000000004006f0 R08: 0000000000000000 R09: 0000000000000000
> R10: 0000000000000000 R11: 0000000000000213 R12: 00000000004004a0
> R13: 00007ffd4871a020 R14: 0000000000000000 R15: 0000000000000000
> ================================================================================
> kasan: CONFIG_KASAN_INLINE enabled
> kasan: GPF could be caused by NULL-ptr deref or user memory access
> general protection fault: 0000 [#1] SMP KASAN PTI
> Modules linked in: vhost_net tun vhost tap af_packet iscsi_ibft
> iscsi_boot_sysfs bochs_drm ttm ppdev drm_kms_helper drm
> drm_panel_orientation_quirks joydev e1000 syscopyarea sysfillrect
> pcspkr sysimgblt fb_sys_fops i2c_piix4 parport_pc parport qemu_fw_cfg
> button ext4 crc16 jbd2 mbcache sr_mod cdrom sd_mod ata_generic
> ata_piix ahci libahci libata serio_raw floppy sg dm_multipath dm_mod
> scsi_dh_rdac scsi_dh_emc scsi_dh_alua scsi_mod autofs4
> Supported: No, Unreleased kernel
> CPU: 2 PID: 1450 Comm: syz-executor493 Not tainted
> 4.12.14-525.g4d6309b-default #1 SLE15 (unreleased)
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
> 1.0.0-prebuilt.qemu-project.org 04/01/2014
> task: ffff88004b858040 task.stack: ffff88004a820000
> RIP: 0010:vhost_chr_write_iter+0x525/0x1330 [vhost]
> RSP: 0018:ffff88004a827a38 EFLAGS: 00010246
> RAX: dffffc0000000000 RBX: 1ffff10009504f51 RCX: 0000000000000000
> RDX: 0000000000000000 RSI: 0000000000000202 RDI: ffffed0009504f40
> RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000
> R10: 1ffff10009504ec1 R11: 0000000000000000 R12: 0000000020000040
> R13: dffffc0000000000 R14: ffff8800352f0000 R15: ffffed0006a5e005
> FS:  00007fdb76f79740(0000) GS:ffff880060d00000(0000)
> knlGS:0000000000000000
> CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 000055b42161d980 CR3: 000000003422c000 CR4: 00000000000006e0
> Call Trace:
>  call_write_iter include/linux/fs.h:1764 [inline]
>  new_sync_write fs/read_write.c:497 [inline]
>  __vfs_write+0x67c/0x9b0 fs/read_write.c:510
>  vfs_write+0x1a2/0x610 fs/read_write.c:558
>  SYSC_write fs/read_write.c:605 [inline]
>  SyS_write+0xd8/0x1f0 fs/read_write.c:597
>  do_syscall_64+0x26b/0x6e0 arch/x86/entry/common.c:284
>  entry_SYSCALL_64_after_hwframe+0x3d/0xa2
> RIP: 0033:0x7fdb7687a739
> RSP: 002b:00007ffd48719f38 EFLAGS: 00000213 ORIG_RAX: 0000000000000001
> RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fdb7687a739
> RDX: 0000000000000068 RSI: 0000000020000300 RDI: 0000000000000003
> RBP: 00000000004006f0 R08: 0000000000000000 R09: 0000000000000000
> R10: 0000000000000000 R11: 0000000000000213 R12: 00000000004004a0
> R13: 00007ffd4871a020 R14: 0000000000000000 R15: 0000000000000000
> Code: fc ff df 80 3c 02 00 0f 85 3c 0b 00 00 49 8b 6e 60 48 85 ed 0f
> 84 1c 0b 00 00 48 89 ea 48 b8 00 00 00 00 00 fc ff df 48 c1 ea 03 <80>
> 3c 02 00 0f 85 f4 0a 00 00 4c 8b 7d 00 4d 85 ff 0f 84 e7 06
> RIP: vhost_chr_write_iter+0x525/0x1330 [vhost] RSP: ffff88004a827a38
> ---[ end trace 49849730b5255f76 ]---

Fixes: 6b1e6cc7855b ("vhost: new device IOTLB API")

Signed-off-by: Denis Kirjanov <kda@linux-powerpc.org>
---
 drivers/vhost/vhost.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Comments

David Miller July 9, 2019, 7:58 p.m. UTC | #1
From: Denis Kirjanov <kda@linux-powerpc.org>
Date: Tue,  9 Jul 2019 13:42:51 +0200

> @@ -962,7 +962,8 @@ static void vhost_del_umem_range(struct vhost_umem *umem,
>  
>  	while ((node = vhost_umem_interval_tree_iter_first(&umem->umem_tree,
>  							   start, end)))
> -		vhost_umem_free(umem, node);
> +		if (node)
> +			vhost_umem_free(umem, node);

If 'node' is NULL we will not be in the body of the loop as per
the while() condition.

How did you test this?
Denis Kirjanov July 10, 2019, 7:56 a.m. UTC | #2
On 7/9/19, David Miller <davem@davemloft.net> wrote:
> From: Denis Kirjanov <kda@linux-powerpc.org>
> Date: Tue,  9 Jul 2019 13:42:51 +0200
>
>> @@ -962,7 +962,8 @@ static void vhost_del_umem_range(struct vhost_umem
>> *umem,
>>
>>  	while ((node = vhost_umem_interval_tree_iter_first(&umem->umem_tree,
>>  							   start, end)))
>> -		vhost_umem_free(umem, node);
>> +		if (node)
>> +			vhost_umem_free(umem, node);
>
> If 'node' is NULL we will not be in the body of the loop as per
> the while() condition.

The patch is incorrect, please ignore

>
> How did you test this?
>
diff mbox series

Patch

diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index e995c12d8e24..026123a6fc7b 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -962,7 +962,8 @@  static void vhost_del_umem_range(struct vhost_umem *umem,
 
 	while ((node = vhost_umem_interval_tree_iter_first(&umem->umem_tree,
 							   start, end)))
-		vhost_umem_free(umem, node);
+		if (node)
+			vhost_umem_free(umem, node);
 }
 
 static void vhost_iotlb_notify_vq(struct vhost_dev *d,