]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.3-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 27 Nov 2019 13:43:16 +0000 (14:43 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 27 Nov 2019 13:43:16 +0000 (14:43 +0100)
added patches:
media-b2c2-flexcop-usb-add-sanity-checking.patch
media-cxusb-detect-cxusb_ctrl_msg-error-in-query.patch
media-imon-invalid-dereference-in-imon_touch_event.patch
media-mceusb-fix-out-of-bounds-read-in-mce-receiver-buffer.patch
media-uvcvideo-fix-error-path-in-control-parsing-failure.patch

queue-5.3/media-b2c2-flexcop-usb-add-sanity-checking.patch [new file with mode: 0644]
queue-5.3/media-cxusb-detect-cxusb_ctrl_msg-error-in-query.patch [new file with mode: 0644]
queue-5.3/media-imon-invalid-dereference-in-imon_touch_event.patch [new file with mode: 0644]
queue-5.3/media-mceusb-fix-out-of-bounds-read-in-mce-receiver-buffer.patch [new file with mode: 0644]
queue-5.3/media-uvcvideo-fix-error-path-in-control-parsing-failure.patch [new file with mode: 0644]
queue-5.3/series

diff --git a/queue-5.3/media-b2c2-flexcop-usb-add-sanity-checking.patch b/queue-5.3/media-b2c2-flexcop-usb-add-sanity-checking.patch
new file mode 100644 (file)
index 0000000..f9fa6c9
--- /dev/null
@@ -0,0 +1,34 @@
+From 1b976fc6d684e3282914cdbe7a8d68fdce19095c Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oneukum@suse.com>
+Date: Tue, 30 Jul 2019 09:48:27 +0200
+Subject: media: b2c2-flexcop-usb: add sanity checking
+
+From: Oliver Neukum <oneukum@suse.com>
+
+commit 1b976fc6d684e3282914cdbe7a8d68fdce19095c upstream.
+
+The driver needs an isochronous endpoint to be present. It will
+oops in its absence. Add checking for it.
+
+Reported-by: syzbot+d93dff37e6a89431c158@syzkaller.appspotmail.com
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Signed-off-by: Sean Young <sean@mess.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/usb/b2c2/flexcop-usb.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/media/usb/b2c2/flexcop-usb.c
++++ b/drivers/media/usb/b2c2/flexcop-usb.c
+@@ -538,6 +538,9 @@ static int flexcop_usb_probe(struct usb_
+       struct flexcop_device *fc = NULL;
+       int ret;
++      if (intf->cur_altsetting->desc.bNumEndpoints < 1)
++              return -ENODEV;
++
+       if ((fc = flexcop_device_kmalloc(sizeof(struct flexcop_usb))) == NULL) {
+               err("out of memory\n");
+               return -ENOMEM;
diff --git a/queue-5.3/media-cxusb-detect-cxusb_ctrl_msg-error-in-query.patch b/queue-5.3/media-cxusb-detect-cxusb_ctrl_msg-error-in-query.patch
new file mode 100644 (file)
index 0000000..94c3174
--- /dev/null
@@ -0,0 +1,78 @@
+From ca8f245f284eeffa56f3b7a5eb6fc503159ee028 Mon Sep 17 00:00:00 2001
+From: Vito Caputo <vcaputo@pengaru.com>
+Date: Sun, 13 Oct 2019 23:08:45 -0300
+Subject: media: cxusb: detect cxusb_ctrl_msg error in query
+
+From: Vito Caputo <vcaputo@pengaru.com>
+
+commit ca8f245f284eeffa56f3b7a5eb6fc503159ee028 upstream.
+
+Don't use uninitialized ircode[] in cxusb_rc_query() when
+cxusb_ctrl_msg() fails to populate its contents.
+
+syzbot reported:
+
+dvb-usb: bulk message failed: -22 (1/-30591)
+=====================================================
+BUG: KMSAN: uninit-value in ir_lookup_by_scancode drivers/media/rc/rc-main.c:494 [inline]
+BUG: KMSAN: uninit-value in rc_g_keycode_from_table drivers/media/rc/rc-main.c:582 [inline]
+BUG: KMSAN: uninit-value in rc_keydown+0x1a6/0x6f0 drivers/media/rc/rc-main.c:816
+CPU: 1 PID: 11436 Comm: kworker/1:2 Not tainted 5.3.0-rc7+ #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+Workqueue: events dvb_usb_read_remote_control
+Call Trace:
+ __dump_stack lib/dump_stack.c:77 [inline]
+ dump_stack+0x191/0x1f0 lib/dump_stack.c:113
+ kmsan_report+0x13a/0x2b0 mm/kmsan/kmsan_report.c:108
+ __msan_warning+0x73/0xe0 mm/kmsan/kmsan_instr.c:250
+ bsearch+0x1dd/0x250 lib/bsearch.c:41
+ ir_lookup_by_scancode drivers/media/rc/rc-main.c:494 [inline]
+ rc_g_keycode_from_table drivers/media/rc/rc-main.c:582 [inline]
+ rc_keydown+0x1a6/0x6f0 drivers/media/rc/rc-main.c:816
+ cxusb_rc_query+0x2e1/0x360 drivers/media/usb/dvb-usb/cxusb.c:548
+ dvb_usb_read_remote_control+0xf9/0x290 drivers/media/usb/dvb-usb/dvb-usb-remote.c:261
+ process_one_work+0x1572/0x1ef0 kernel/workqueue.c:2269
+ worker_thread+0x111b/0x2460 kernel/workqueue.c:2415
+ kthread+0x4b5/0x4f0 kernel/kthread.c:256
+ ret_from_fork+0x35/0x40 arch/x86/entry/entry_64.S:355
+
+Uninit was stored to memory at:
+ kmsan_save_stack_with_flags mm/kmsan/kmsan.c:150 [inline]
+ kmsan_internal_chain_origin+0xd2/0x170 mm/kmsan/kmsan.c:314
+ __msan_chain_origin+0x6b/0xe0 mm/kmsan/kmsan_instr.c:184
+ rc_g_keycode_from_table drivers/media/rc/rc-main.c:583 [inline]
+ rc_keydown+0x2c4/0x6f0 drivers/media/rc/rc-main.c:816
+ cxusb_rc_query+0x2e1/0x360 drivers/media/usb/dvb-usb/cxusb.c:548
+ dvb_usb_read_remote_control+0xf9/0x290 drivers/media/usb/dvb-usb/dvb-usb-remote.c:261
+ process_one_work+0x1572/0x1ef0 kernel/workqueue.c:2269
+ worker_thread+0x111b/0x2460 kernel/workqueue.c:2415
+ kthread+0x4b5/0x4f0 kernel/kthread.c:256
+ ret_from_fork+0x35/0x40 arch/x86/entry/entry_64.S:355
+
+Local variable description: ----ircode@cxusb_rc_query
+Variable was created at:
+ cxusb_rc_query+0x4d/0x360 drivers/media/usb/dvb-usb/cxusb.c:543
+ dvb_usb_read_remote_control+0xf9/0x290 drivers/media/usb/dvb-usb/dvb-usb-remote.c:261
+
+Signed-off-by: Vito Caputo <vcaputo@pengaru.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Sean Young <sean@mess.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/usb/dvb-usb/cxusb.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/media/usb/dvb-usb/cxusb.c
++++ b/drivers/media/usb/dvb-usb/cxusb.c
+@@ -542,7 +542,8 @@ static int cxusb_rc_query(struct dvb_usb
+ {
+       u8 ircode[4];
+-      cxusb_ctrl_msg(d, CMD_GET_IR_CODE, NULL, 0, ircode, 4);
++      if (cxusb_ctrl_msg(d, CMD_GET_IR_CODE, NULL, 0, ircode, 4) < 0)
++              return 0;
+       if (ircode[2] || ircode[3])
+               rc_keydown(d->rc_dev, RC_PROTO_NEC,
diff --git a/queue-5.3/media-imon-invalid-dereference-in-imon_touch_event.patch b/queue-5.3/media-imon-invalid-dereference-in-imon_touch_event.patch
new file mode 100644 (file)
index 0000000..35e08c7
--- /dev/null
@@ -0,0 +1,88 @@
+From f3f5ba42c58d56d50f539854d8cc188944e96087 Mon Sep 17 00:00:00 2001
+From: Sean Young <sean@mess.org>
+Date: Wed, 16 Oct 2019 14:19:15 -0300
+Subject: media: imon: invalid dereference in imon_touch_event
+
+From: Sean Young <sean@mess.org>
+
+commit f3f5ba42c58d56d50f539854d8cc188944e96087 upstream.
+
+The touch timer is set up in intf1. If the second interface does not exist,
+the timer and touch input device are not setup and we get the following
+error, when touch events are reported via intf0.
+
+kernel BUG at kernel/time/timer.c:956!
+invalid opcode: 0000 [#1] SMP KASAN
+CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.4.0-rc1+ #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+RIP: 0010:__mod_timer kernel/time/timer.c:956 [inline]
+RIP: 0010:__mod_timer kernel/time/timer.c:949 [inline]
+RIP: 0010:mod_timer+0x5a2/0xb50 kernel/time/timer.c:1100
+Code: 45 10 c7 44 24 14 ff ff ff ff 48 89 44 24 08 48 8d 45 20 48 c7 44 24 18 00 00 00 00 48 89 04 24 e9 5a fc ff ff e8 ae ce 0e 00 <0f> 0b e8 a7 ce 0e 00 4c 89 74 24 20 e9 37 fe ff ff e8 98 ce 0e 00
+RSP: 0018:ffff8881db209930 EFLAGS: 00010006
+RAX: ffffffff86c2b200 RBX: 00000000ffffa688 RCX: ffffffff83efc583
+RDX: 0000000000000100 RSI: ffffffff812f4d82 RDI: ffff8881d2356200
+RBP: ffff8881d23561e8 R08: ffffffff86c2b200 R09: ffffed103a46abeb
+R10: ffffed103a46abea R11: ffff8881d2355f53 R12: dffffc0000000000
+R13: 1ffff1103b64132d R14: ffff8881d2355f50 R15: 0000000000000006
+FS:  0000000000000000(0000) GS:ffff8881db200000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00007f75e2799000 CR3: 00000001d3b07000 CR4: 00000000001406f0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+Call Trace:
+ <IRQ>
+ imon_touch_event drivers/media/rc/imon.c:1348 [inline]
+ imon_incoming_packet.isra.0+0x2546/0x2f10 drivers/media/rc/imon.c:1603
+ usb_rx_callback_intf0+0x151/0x1e0 drivers/media/rc/imon.c:1734
+ __usb_hcd_giveback_urb+0x1f2/0x470 drivers/usb/core/hcd.c:1654
+ usb_hcd_giveback_urb+0x368/0x420 drivers/usb/core/hcd.c:1719
+ dummy_timer+0x120f/0x2fa2 drivers/usb/gadget/udc/dummy_hcd.c:1965
+ call_timer_fn+0x179/0x650 kernel/time/timer.c:1404
+ expire_timers kernel/time/timer.c:1449 [inline]
+ __run_timers kernel/time/timer.c:1773 [inline]
+ __run_timers kernel/time/timer.c:1740 [inline]
+ run_timer_softirq+0x5e3/0x1490 kernel/time/timer.c:1786
+ __do_softirq+0x221/0x912 kernel/softirq.c:292
+ invoke_softirq kernel/softirq.c:373 [inline]
+ irq_exit+0x178/0x1a0 kernel/softirq.c:413
+ exiting_irq arch/x86/include/asm/apic.h:536 [inline]
+ smp_apic_timer_interrupt+0x12f/0x500 arch/x86/kernel/apic/apic.c:1137
+ apic_timer_interrupt+0xf/0x20 arch/x86/entry/entry_64.S:830
+ </IRQ>
+RIP: 0010:default_idle+0x28/0x2e0 arch/x86/kernel/process.c:581
+Code: 90 90 41 56 41 55 65 44 8b 2d 44 3a 8f 7a 41 54 55 53 0f 1f 44 00 00 e8 36 ee d0 fb e9 07 00 00 00 0f 00 2d fa dd 4f 00 fb f4 <65> 44 8b 2d 20 3a 8f 7a 0f 1f 44 00 00 5b 5d 41 5c 41 5d 41 5e c3
+RSP: 0018:ffffffff86c07da8 EFLAGS: 00000246 ORIG_RAX: ffffffffffffff13
+RAX: 0000000000000007 RBX: ffffffff86c2b200 RCX: 0000000000000000
+RDX: 0000000000000000 RSI: 0000000000000006 RDI: ffffffff86c2ba4c
+RBP: fffffbfff0d85640 R08: ffffffff86c2b200 R09: 0000000000000000
+R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
+R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
+ cpuidle_idle_call kernel/sched/idle.c:154 [inline]
+ do_idle+0x3b6/0x500 kernel/sched/idle.c:263
+ cpu_startup_entry+0x14/0x20 kernel/sched/idle.c:355
+ start_kernel+0x82a/0x864 init/main.c:784
+ secondary_startup_64+0xa4/0xb0 arch/x86/kernel/head_64.S:241
+Modules linked in:
+
+Reported-by: syzbot+f49d12d34f2321cf4df2@syzkaller.appspotmail.com
+Signed-off-by: Sean Young <sean@mess.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/rc/imon.c |    3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/media/rc/imon.c
++++ b/drivers/media/rc/imon.c
+@@ -1598,8 +1598,7 @@ static void imon_incoming_packet(struct
+       spin_unlock_irqrestore(&ictx->kc_lock, flags);
+       /* send touchscreen events through input subsystem if touchpad data */
+-      if (ictx->display_type == IMON_DISPLAY_TYPE_VGA && len == 8 &&
+-          buf[7] == 0x86) {
++      if (ictx->touch && len == 8 && buf[7] == 0x86) {
+               imon_touch_event(ictx, buf);
+               return;
diff --git a/queue-5.3/media-mceusb-fix-out-of-bounds-read-in-mce-receiver-buffer.patch b/queue-5.3/media-mceusb-fix-out-of-bounds-read-in-mce-receiver-buffer.patch
new file mode 100644 (file)
index 0000000..5a410e8
--- /dev/null
@@ -0,0 +1,360 @@
+From e43148645d18efc3072b1ba45afaa3f385299e55 Mon Sep 17 00:00:00 2001
+From: A Sun <as1033x@comcast.net>
+Date: Fri, 6 Sep 2019 09:17:20 -0300
+Subject: media: mceusb: fix out of bounds read in MCE receiver buffer
+
+From: A Sun <as1033x@comcast.net>
+
+commit e43148645d18efc3072b1ba45afaa3f385299e55 upstream.
+
+Fix multiple cases of out of bounds (OOB) read associated with
+MCE device receive/input data handling.
+
+In reference for the OOB cases below, the incoming/read (byte) data
+format when the MCE device responds to a command is:
+    { cmd_prefix, subcmd, data0, data1, ... }
+where cmd_prefix are:
+    MCE_CMD_PORT_SYS
+    MCE_CMD_PORT_IR
+and subcmd examples are:
+    MCE_RSP_GETPORTSTATUS
+    MCE_RSP_EQIRNUMPORTS
+    ...
+Response size dynamically depends on cmd_prefix and subcmd.
+So data0, data1, ... may or may not be present on input.
+Multiple responses may return in a single receiver buffer.
+
+The trigger condition for OOB read is typically random or
+corrupt input data that fills the mceusb receiver buffer.
+
+Case 1:
+
+mceusb_handle_command() reads data0 (var hi) and data1 (var lo)
+regardless of whether the response includes such data.
+If { cmd_prefix, subcmd } is at the end of the receiver buffer,
+read past end of buffer occurs.
+
+This case was reported by
+KASAN: slab-out-of-bounds Read in mceusb_dev_recv
+https://syzkaller.appspot.com/bug?extid=c7fdb6cb36e65f2fe8c9
+
+Fix: In mceusb_handle_command(), change variable hi and lo to
+pointers, and dereference only when required.
+
+Case 2:
+
+If response with data is truncated at end of buffer after
+{ cmd_prefix, subcmd }, mceusb_handle_command() reads past
+end of buffer for data0, data1, ...
+
+Fix: In mceusb_process_ir_data(), check response size with
+remaining buffer size before invoking mceusb_handle_command().
++    if (i + ir->rem < buf_len)
+            mceusb_handle_command(ir, &ir->buf_in[i - 1]);
+
+Case 3:
+
+mceusb_handle_command() handles invalid/bad response such as
+{ 0x??, MCE_RSP_GETPORTSTATUS } of length 2 as a response
+{ MCE_CMD_PORT_SYS, MCE_RSP_GETPORTSTATUS, data0, ... }
+of length 7. Read OOB occurs for non-existent data0, data1, ...
+Cause is mceusb_handle_command() does not check cmd_prefix value.
+
+Fix: mceusb_handle_command() must test both cmd_prefix and subcmd.
+
+Case 4:
+
+mceusb_process_ir_data() receiver parser state SUBCMD is
+possible at start (i=0) of receiver buffer resulting in buffer
+offset=-1 passed to mceusb_dev_printdata().
+Bad offset results in OOB read before start of buffer.
+
+[1214218.580308] mceusb 1-1.3:1.0: rx data[0]: 00 80 (length=2)
+[1214218.580323] mceusb 1-1.3:1.0: Unknown command 0x00 0x80
+...
+[1214218.580406] mceusb 1-1.3:1.0: rx data[14]: 7f 7f (length=2)
+[1214218.679311] mceusb 1-1.3:1.0: rx data[-1]: 80 90 (length=2)
+[1214218.679325] mceusb 1-1.3:1.0: End of raw IR data
+[1214218.679340] mceusb 1-1.3:1.0: rx data[1]: 7f 7f (length=2)
+
+Fix: If parser_state is SUBCMD after processing receiver buffer,
+reset parser_state to CMD_HEADER.
+In effect, discard cmd_prefix at end of receiver buffer.
+In mceusb_dev_printdata(), abort if buffer offset is out of bounds.
+
+Case 5:
+
+If response with data is truncated at end of buffer after
+{ cmd_prefix, subcmd }, mceusb_dev_printdata() reads past
+end of buffer for data0, data1, ...
+while decoding the response to print out.
+
+Fix: In mceusb_dev_printdata(), remove unneeded buffer offset
+adjustments (var start and var skip) associated with MCE gen1 header.
+Test for truncated MCE cmd response (compare offset+len with buf_len)
+and skip decoding of incomplete response.
+Move IR data tracing to execute before the truncation test.
+
+Signed-off-by: A Sun <as1033x@comcast.net>
+Signed-off-by: Sean Young <sean@mess.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/rc/mceusb.c |  141 +++++++++++++++++++++++++++++++---------------
+ 1 file changed, 98 insertions(+), 43 deletions(-)
+
+--- a/drivers/media/rc/mceusb.c
++++ b/drivers/media/rc/mceusb.c
+@@ -562,7 +562,7 @@ static int mceusb_cmd_datasize(u8 cmd, u
+                       datasize = 4;
+                       break;
+               case MCE_CMD_G_REVISION:
+-                      datasize = 2;
++                      datasize = 4;
+                       break;
+               case MCE_RSP_EQWAKESUPPORT:
+               case MCE_RSP_GETWAKESOURCE:
+@@ -598,14 +598,9 @@ static void mceusb_dev_printdata(struct
+       char *inout;
+       u8 cmd, subcmd, *data;
+       struct device *dev = ir->dev;
+-      int start, skip = 0;
+       u32 carrier, period;
+-      /* skip meaningless 0xb1 0x60 header bytes on orig receiver */
+-      if (ir->flags.microsoft_gen1 && !out && !offset)
+-              skip = 2;
+-
+-      if (len <= skip)
++      if (offset < 0 || offset >= buf_len)
+               return;
+       dev_dbg(dev, "%cx data[%d]: %*ph (len=%d sz=%d)",
+@@ -614,11 +609,32 @@ static void mceusb_dev_printdata(struct
+       inout = out ? "Request" : "Got";
+-      start  = offset + skip;
+-      cmd    = buf[start] & 0xff;
+-      subcmd = buf[start + 1] & 0xff;
+-      data = buf + start + 2;
++      cmd    = buf[offset];
++      subcmd = (offset + 1 < buf_len) ? buf[offset + 1] : 0;
++      data   = &buf[offset] + 2;
++
++      /* Trace meaningless 0xb1 0x60 header bytes on original receiver */
++      if (ir->flags.microsoft_gen1 && !out && !offset) {
++              dev_dbg(dev, "MCE gen 1 header");
++              return;
++      }
++      /* Trace IR data header or trailer */
++      if (cmd != MCE_CMD_PORT_IR &&
++          (cmd & MCE_PORT_MASK) == MCE_COMMAND_IRDATA) {
++              if (cmd == MCE_IRDATA_TRAILER)
++                      dev_dbg(dev, "End of raw IR data");
++              else
++                      dev_dbg(dev, "Raw IR data, %d pulse/space samples",
++                              cmd & MCE_PACKET_LENGTH_MASK);
++              return;
++      }
++
++      /* Unexpected end of buffer? */
++      if (offset + len > buf_len)
++              return;
++
++      /* Decode MCE command/response */
+       switch (cmd) {
+       case MCE_CMD_NULL:
+               if (subcmd == MCE_CMD_NULL)
+@@ -642,7 +658,7 @@ static void mceusb_dev_printdata(struct
+                               dev_dbg(dev, "Get hw/sw rev?");
+                       else
+                               dev_dbg(dev, "hw/sw rev %*ph",
+-                                      4, &buf[start + 2]);
++                                      4, &buf[offset + 2]);
+                       break;
+               case MCE_CMD_RESUME:
+                       dev_dbg(dev, "Device resume requested");
+@@ -744,13 +760,6 @@ static void mceusb_dev_printdata(struct
+       default:
+               break;
+       }
+-
+-      if (cmd == MCE_IRDATA_TRAILER)
+-              dev_dbg(dev, "End of raw IR data");
+-      else if ((cmd != MCE_CMD_PORT_IR) &&
+-               ((cmd & MCE_PORT_MASK) == MCE_COMMAND_IRDATA))
+-              dev_dbg(dev, "Raw IR data, %d pulse/space samples",
+-                      cmd & MCE_PACKET_LENGTH_MASK);
+ #endif
+ }
+@@ -1127,32 +1136,62 @@ static int mceusb_set_rx_carrier_report(
+ }
+ /*
++ * Handle PORT_SYS/IR command response received from the MCE device.
++ *
++ * Assumes single response with all its data (not truncated)
++ * in buf_in[]. The response itself determines its total length
++ * (mceusb_cmd_datasize() + 2) and hence the minimum size of buf_in[].
++ *
+  * We don't do anything but print debug spew for many of the command bits
+  * we receive from the hardware, but some of them are useful information
+  * we want to store so that we can use them.
+  */
+-static void mceusb_handle_command(struct mceusb_dev *ir, int index)
++static void mceusb_handle_command(struct mceusb_dev *ir, u8 *buf_in)
+ {
++      u8 cmd = buf_in[0];
++      u8 subcmd = buf_in[1];
++      u8 *hi = &buf_in[2];            /* read only when required */
++      u8 *lo = &buf_in[3];            /* read only when required */
+       struct ir_raw_event rawir = {};
+-      u8 hi = ir->buf_in[index + 1] & 0xff;
+-      u8 lo = ir->buf_in[index + 2] & 0xff;
+       u32 carrier_cycles;
+       u32 cycles_fix;
+-      switch (ir->buf_in[index]) {
+-      /* the one and only 5-byte return value command */
+-      case MCE_RSP_GETPORTSTATUS:
+-              if ((ir->buf_in[index + 4] & 0xff) == 0x00)
+-                      ir->txports_cabled |= 1 << hi;
+-              break;
++      if (cmd == MCE_CMD_PORT_SYS) {
++              switch (subcmd) {
++              /* the one and only 5-byte return value command */
++              case MCE_RSP_GETPORTSTATUS:
++                      if (buf_in[5] == 0)
++                              ir->txports_cabled |= 1 << *hi;
++                      break;
++              /* 1-byte return value commands */
++              case MCE_RSP_EQEMVER:
++                      ir->emver = *hi;
++                      break;
++
++              /* No return value commands */
++              case MCE_RSP_CMD_ILLEGAL:
++                      ir->need_reset = true;
++                      break;
++
++              default:
++                      break;
++              }
++
++              return;
++      }
++
++      if (cmd != MCE_CMD_PORT_IR)
++              return;
++
++      switch (subcmd) {
+       /* 2-byte return value commands */
+       case MCE_RSP_EQIRTIMEOUT:
+-              ir->rc->timeout = US_TO_NS((hi << 8 | lo) * MCE_TIME_UNIT);
++              ir->rc->timeout = US_TO_NS((*hi << 8 | *lo) * MCE_TIME_UNIT);
+               break;
+       case MCE_RSP_EQIRNUMPORTS:
+-              ir->num_txports = hi;
+-              ir->num_rxports = lo;
++              ir->num_txports = *hi;
++              ir->num_rxports = *lo;
+               break;
+       case MCE_RSP_EQIRRXCFCNT:
+               /*
+@@ -1165,7 +1204,7 @@ static void mceusb_handle_command(struct
+                */
+               if (ir->carrier_report_enabled && ir->learning_active &&
+                   ir->pulse_tunit > 0) {
+-                      carrier_cycles = (hi << 8 | lo);
++                      carrier_cycles = (*hi << 8 | *lo);
+                       /*
+                        * Adjust carrier cycle count by adding
+                        * 1 missed count per pulse "on"
+@@ -1183,24 +1222,24 @@ static void mceusb_handle_command(struct
+               break;
+       /* 1-byte return value commands */
+-      case MCE_RSP_EQEMVER:
+-              ir->emver = hi;
+-              break;
+       case MCE_RSP_EQIRTXPORTS:
+-              ir->tx_mask = hi;
++              ir->tx_mask = *hi;
+               break;
+       case MCE_RSP_EQIRRXPORTEN:
+-              ir->learning_active = ((hi & 0x02) == 0x02);
+-              if (ir->rxports_active != hi) {
++              ir->learning_active = ((*hi & 0x02) == 0x02);
++              if (ir->rxports_active != *hi) {
+                       dev_info(ir->dev, "%s-range (0x%x) receiver active",
+-                               ir->learning_active ? "short" : "long", hi);
+-                      ir->rxports_active = hi;
++                               ir->learning_active ? "short" : "long", *hi);
++                      ir->rxports_active = *hi;
+               }
+               break;
++
++      /* No return value commands */
+       case MCE_RSP_CMD_ILLEGAL:
+       case MCE_RSP_TX_TIMEOUT:
+               ir->need_reset = true;
+               break;
++
+       default:
+               break;
+       }
+@@ -1226,7 +1265,8 @@ static void mceusb_process_ir_data(struc
+                       ir->rem = mceusb_cmd_datasize(ir->cmd, ir->buf_in[i]);
+                       mceusb_dev_printdata(ir, ir->buf_in, buf_len, i - 1,
+                                            ir->rem + 2, false);
+-                      mceusb_handle_command(ir, i);
++                      if (i + ir->rem < buf_len)
++                              mceusb_handle_command(ir, &ir->buf_in[i - 1]);
+                       ir->parser_state = CMD_DATA;
+                       break;
+               case PARSE_IRDATA:
+@@ -1255,15 +1295,22 @@ static void mceusb_process_ir_data(struc
+                       ir->rem--;
+                       break;
+               case CMD_HEADER:
+-                      /* decode mce packets of the form (84),AA,BB,CC,DD */
+-                      /* IR data packets can span USB messages - rem */
+                       ir->cmd = ir->buf_in[i];
+                       if ((ir->cmd == MCE_CMD_PORT_IR) ||
+                           ((ir->cmd & MCE_PORT_MASK) !=
+                            MCE_COMMAND_IRDATA)) {
++                              /*
++                               * got PORT_SYS, PORT_IR, or unknown
++                               * command response prefix
++                               */
+                               ir->parser_state = SUBCMD;
+                               continue;
+                       }
++                      /*
++                       * got IR data prefix (0x80 + num_bytes)
++                       * decode MCE packets of the form {0x83, AA, BB, CC}
++                       * IR data packets can span USB messages
++                       */
+                       ir->rem = (ir->cmd & MCE_PACKET_LENGTH_MASK);
+                       mceusb_dev_printdata(ir, ir->buf_in, buf_len,
+                                            i, ir->rem + 1, false);
+@@ -1287,6 +1334,14 @@ static void mceusb_process_ir_data(struc
+               if (ir->parser_state != CMD_HEADER && !ir->rem)
+                       ir->parser_state = CMD_HEADER;
+       }
++
++      /*
++       * Accept IR data spanning multiple rx buffers.
++       * Reject MCE command response spanning multiple rx buffers.
++       */
++      if (ir->parser_state != PARSE_IRDATA || !ir->rem)
++              ir->parser_state = CMD_HEADER;
++
+       if (event) {
+               dev_dbg(ir->dev, "processed IR data");
+               ir_raw_event_handle(ir->rc);
diff --git a/queue-5.3/media-uvcvideo-fix-error-path-in-control-parsing-failure.patch b/queue-5.3/media-uvcvideo-fix-error-path-in-control-parsing-failure.patch
new file mode 100644 (file)
index 0000000..9478b27
--- /dev/null
@@ -0,0 +1,68 @@
+From 8c279e9394cade640ed86ec6c6645a0e7df5e0b6 Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Mon, 29 Jul 2019 23:14:55 -0300
+Subject: media: uvcvideo: Fix error path in control parsing failure
+
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+
+commit 8c279e9394cade640ed86ec6c6645a0e7df5e0b6 upstream.
+
+When parsing the UVC control descriptors fails, the error path tries to
+cleanup a media device that hasn't been initialised, potentially
+resulting in a crash. Fix this by initialising the media device before
+the error handling path can be reached.
+
+Fixes: 5a254d751e52 ("[media] uvcvideo: Register a v4l2_device")
+Reported-by: syzbot+c86454eb3af9e8a4da20@syzkaller.appspotmail.com
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/usb/uvc/uvc_driver.c |   28 +++++++++++++++-------------
+ 1 file changed, 15 insertions(+), 13 deletions(-)
+
+--- a/drivers/media/usb/uvc/uvc_driver.c
++++ b/drivers/media/usb/uvc/uvc_driver.c
+@@ -2151,6 +2151,20 @@ static int uvc_probe(struct usb_interfac
+                          sizeof(dev->name) - len);
+       }
++      /* Initialize the media device. */
++#ifdef CONFIG_MEDIA_CONTROLLER
++      dev->mdev.dev = &intf->dev;
++      strscpy(dev->mdev.model, dev->name, sizeof(dev->mdev.model));
++      if (udev->serial)
++              strscpy(dev->mdev.serial, udev->serial,
++                      sizeof(dev->mdev.serial));
++      usb_make_path(udev, dev->mdev.bus_info, sizeof(dev->mdev.bus_info));
++      dev->mdev.hw_revision = le16_to_cpu(udev->descriptor.bcdDevice);
++      media_device_init(&dev->mdev);
++
++      dev->vdev.mdev = &dev->mdev;
++#endif
++
+       /* Parse the Video Class control descriptor. */
+       if (uvc_parse_control(dev) < 0) {
+               uvc_trace(UVC_TRACE_PROBE, "Unable to parse UVC "
+@@ -2171,19 +2185,7 @@ static int uvc_probe(struct usb_interfac
+                       "linux-uvc-devel mailing list.\n");
+       }
+-      /* Initialize the media device and register the V4L2 device. */
+-#ifdef CONFIG_MEDIA_CONTROLLER
+-      dev->mdev.dev = &intf->dev;
+-      strscpy(dev->mdev.model, dev->name, sizeof(dev->mdev.model));
+-      if (udev->serial)
+-              strscpy(dev->mdev.serial, udev->serial,
+-                      sizeof(dev->mdev.serial));
+-      usb_make_path(udev, dev->mdev.bus_info, sizeof(dev->mdev.bus_info));
+-      dev->mdev.hw_revision = le16_to_cpu(udev->descriptor.bcdDevice);
+-      media_device_init(&dev->mdev);
+-
+-      dev->vdev.mdev = &dev->mdev;
+-#endif
++      /* Register the V4L2 device. */
+       if (v4l2_device_register(&intf->dev, &dev->vdev) < 0)
+               goto error;
index e7898f23aef15b4f13ff3fb3b0dcde22b6c5f6d2..2a9d97029dcf9c53faf30e6d530efbf37122ed6e 100644 (file)
@@ -72,3 +72,8 @@ media-vivid-fix-wrong-locking-that-causes-race-conditions-on-streaming-stop.patc
 media-usbvision-fix-invalid-accesses-after-device-disconnect.patch
 media-usbvision-fix-races-among-open-close-and-disconnect.patch
 cpufreq-add-null-checks-to-show-and-store-methods-of-cpufreq.patch
+media-uvcvideo-fix-error-path-in-control-parsing-failure.patch
+media-b2c2-flexcop-usb-add-sanity-checking.patch
+media-cxusb-detect-cxusb_ctrl_msg-error-in-query.patch
+media-imon-invalid-dereference-in-imon_touch_event.patch
+media-mceusb-fix-out-of-bounds-read-in-mce-receiver-buffer.patch