[PATCH -next] media: usb: fix a UAF bug in em28xx_v4l2_init

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

 



In the em23xx module init function, we need to unregister video
device in some error case. There is a concurrent scenario as shown
below:
 CPU0                         CPU1
 em28xx_v4l2_init
  mutex_lock(&dev->lock))
 video_register_device
 --register vdev
                                 v4l2_open
                                 em28xx_v4l2_open

 v4l2_mc_create_media_graph
 --failed to create media graph
 kref_put
   free v4l2 ptr
 mutex_unlock(&dev->lock))
                                  mutex_lock(&dev->lock))
                                  em28xx_resolution_set
                                  access v4l2 ptr trigger a UAF problem

Fix the bug by add register status check after grab the mutex in
v4l2_fh_open.
general protection fault, probably for non-canonical address 0xdffffc0000000383: 0000 [#1] PREEMPT SMP KASAN
KASAN: probably user-memory-access in range [0x0000000000001c18-0x0000000000001c1f]
CPU: 3 PID: 11033 Comm: v4l_id Tainted: G    B   W          6.1.0-rc2-00062-ga970174d7a10-dirty #10
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.15.0-0-g2dd4b9b3f840-prebuilt.qemu.org 04/01/2014
RIP: 0010:em28xx_resolution_set.isra.0+0xe8/0x730
Code: 0f 85 cf 05 00 00 44 0f b6 a5 3c 01 00 00 48 8d bb 18 1c 00 00 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 41 83 e4 10 <80> 3c 02 00 0f 85 1b 06 00 00 48 8b 83 18 1c 00 00 31 ff 44 89 e6
RSP: 0018:ffffc9001c817818 EFLAGS: 00010246
RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000000000000
RDX: 0000000000000383 RSI: ffffffff863b628d RDI: 0000000000001c18
RBP: ffff8880536d8000 R08: 0000000000000005 R09: 0000000000000002
R10: 0000000000000000 R11: 0000000000000001 R12: 0000000000000000
R13: ffff8880536d8000 R14: ffff8880536d813c R15: 0000000000000000
FS:  00007f0809077700(0000) GS:ffff888135d00000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f79d74a3d78 CR3: 00000000413c3000 CR4: 00000000001526e0
Call Trace:
 <TASK>
 em28xx_v4l2_open+0x455/0x570
 v4l2_open+0x21c/0x3f0
 chrdev_open+0x266/0x770
 do_dentry_open+0x67f/0x13c0
 path_openat+0x1bad/0x27c0
 do_filp_open+0x1c5/0x410
 do_sys_openat2+0x16d/0x4c0
 __x64_sys_open+0x119/0x1c0
 do_syscall_64+0x35/0x80
 entry_SYSCALL_64_after_hwframe+0x63/0xcd
RIP: 0033:0x7f0808baf650
Code: 64 48 8b 14 25 00 00 00 00 c7 04 02 02 00 00 00 83 c8 ff e9 fa fe ff ff 66 90 83 3d ad e2 2a 00 00 75 10 b8 02 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 31 c3 48 83 ec 08 e8 1e a8 01 00 48 89 04 24
RSP: 002b:00007ffc9ad7ba88 EFLAGS: 00000246 ORIG_RAX: 0000000000000002
RAX: ffffffffffffffda RBX: 00007ffc9ad7bc48 RCX: 00007f0808baf650
RDX: 0000000000000002 RSI: 0000000000000000 RDI: 00007ffc9ad7cf17
RBP: 0000000000000000 R08: 00007f0808c1c889 R09: 0000000000000000
R10: 00007ffc9ad7b860 R11: 0000000000000246 R12: 0000000000400700
R13: 00007ffc9ad7bc40 R14: 0000000000000000 R15: 0000000000000000
 </TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
RIP: 0010:em28xx_resolution_set.isra.0+0xe8/0x730
Code: 0f 85 cf 05 00 00 44 0f b6 a5 3c 01 00 00 48 8d bb 18 1c 00 00 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 41 83 e4 10 <80> 3c 02 00 0f 85 1b 06 00 00 48 8b 83 18 1c 00 00 31 ff 44 89 e6
RSP: 0018:ffffc9001c817818 EFLAGS: 00010246
RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000000000000
RDX: 0000000000000383 RSI: ffffffff863b628d RDI: 0000000000001c18
RBP: ffff8880536d8000 R08: 0000000000000005 R09: 0000000000000002
R10: 0000000000000000 R11: 0000000000000001 R12: 0000000000000000
R13: ffff8880536d8000 R14: ffff8880536d813c R15: 0000000000000000
FS:  00007f0809077700(0000) GS:ffff888135d00000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f79d7482d78 CR3: 00000000413c3000 CR4: 00000000001526e0
----------------
Code disassembly (best guess):
   0:	0f 85 cf 05 00 00    	jne    0x5d5
   6:	44 0f b6 a5 3c 01 00 	movzbl 0x13c(%rbp),%r12d
   d:	00
   e:	48 8d bb 18 1c 00 00 	lea    0x1c18(%rbx),%rdi
  15:	48 b8 00 00 00 00 00 	movabs $0xdffffc0000000000,%rax
  1c:	fc ff df
  1f:	48 89 fa             	mov    %rdi,%rdx
  22:	48 c1 ea 03          	shr    $0x3,%rdx
  26:	41 83 e4 10          	and    $0x10,%r12d
* 2a:	80 3c 02 00          	cmpb   $0x0,(%rdx,%rax,1) <-- trapping instruction
  2e:	0f 85 1b 06 00 00    	jne    0x64f
  34:	48 8b 83 18 1c 00 00 	mov    0x1c18(%rbx),%rax
  3b:	31 ff                	xor    %edi,%edi
  3d:	44 89 e6             	mov    %r12d,%esi
Signed-off-by: Lihong Kou <koulihong@xxxxxxxxxx>
---
 drivers/media/usb/em28xx/em28xx-video.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c
index 25e0620deff1..b8ab42e46c9b 100644
--- a/drivers/media/usb/em28xx/em28xx-video.c
+++ b/drivers/media/usb/em28xx/em28xx-video.c
@@ -2150,6 +2150,15 @@ static int em28xx_v4l2_open(struct file *filp)
 	if (mutex_lock_interruptible(&dev->lock))
 		return -ERESTARTSYS;
 
+	if (!video_is_registered(vdev)) {
+		ret = -ENODEV;
+		dev_err(&dev->intf->dev,
+			"%s: v4l2_fh_open() returned error %d\n",
+		       __func__, ret);
+		mutex_unlock(&dev->lock);
+		return ret;
+	}
+
 	ret = v4l2_fh_open(filp);
 	if (ret) {
 		dev_err(&dev->intf->dev,
-- 
2.31.1




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux