From: Greg Kroah-Hartman Date: Mon, 9 Aug 2021 08:54:28 +0000 (+0200) Subject: 4.14-stable patches X-Git-Tag: v4.4.280~58 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=28d172646203bbe57fdbbe7af8c4c65904b84c6c;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches added patches: usb-gadget-f_hid-added-get_idle-and-set_idle-handlers.patch usb-gadget-f_hid-fixed-null-pointer-dereference.patch usb-gadget-f_hid-idle-uses-the-highest-byte-for-duration.patch usb-otg-fsm-fix-hrtimer-list-corruption.patch --- diff --git a/queue-4.14/series b/queue-4.14/series index 0ba9218affb..d48b4cfee74 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -16,3 +16,7 @@ usb-usbtmc-fix-rcu-stall-warning.patch usb-serial-option-add-telit-fd980-composition-0x1056.patch usb-serial-ch341-fix-character-loss-at-high-transfer-rates.patch usb-serial-ftdi_sio-add-device-id-for-auto-m3-op-com-v2.patch +usb-gadget-f_hid-added-get_idle-and-set_idle-handlers.patch +usb-gadget-f_hid-fixed-null-pointer-dereference.patch +usb-gadget-f_hid-idle-uses-the-highest-byte-for-duration.patch +usb-otg-fsm-fix-hrtimer-list-corruption.patch diff --git a/queue-4.14/usb-gadget-f_hid-added-get_idle-and-set_idle-handlers.patch b/queue-4.14/usb-gadget-f_hid-added-get_idle-and-set_idle-handlers.patch new file mode 100644 index 00000000000..f119e5a629d --- /dev/null +++ b/queue-4.14/usb-gadget-f_hid-added-get_idle-and-set_idle-handlers.patch @@ -0,0 +1,74 @@ +From afcff6dc690e24d636a41fd4bee6057e7c70eebd Mon Sep 17 00:00:00 2001 +From: Maxim Devaev +Date: Wed, 21 Jul 2021 21:03:51 +0300 +Subject: usb: gadget: f_hid: added GET_IDLE and SET_IDLE handlers + +From: Maxim Devaev + +commit afcff6dc690e24d636a41fd4bee6057e7c70eebd upstream. + +The USB HID standard declares mandatory support for GET_IDLE and SET_IDLE +requests for Boot Keyboard. Most hosts can handle their absence, but others +like some old/strange UEFIs and BIOSes consider this a critical error +and refuse to work with f_hid. + +This primitive implementation of saving and returning idle is sufficient +to meet the requirements of the standard and these devices. + +Acked-by: Felipe Balbi +Cc: stable +Signed-off-by: Maxim Devaev +Link: https://lore.kernel.org/r/20210721180351.129450-1-mdevaev@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/f_hid.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +--- a/drivers/usb/gadget/function/f_hid.c ++++ b/drivers/usb/gadget/function/f_hid.c +@@ -45,6 +45,7 @@ struct f_hidg { + unsigned char bInterfaceSubClass; + unsigned char bInterfaceProtocol; + unsigned char protocol; ++ unsigned char idle; + unsigned short report_desc_length; + char *report_desc; + unsigned short report_length; +@@ -533,6 +534,14 @@ static int hidg_setup(struct usb_functio + goto respond; + break; + ++ case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 ++ | HID_REQ_GET_IDLE): ++ VDBG(cdev, "get_idle\n"); ++ length = min_t(unsigned int, length, 1); ++ ((u8 *) req->buf)[0] = hidg->idle; ++ goto respond; ++ break; ++ + case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 + | HID_REQ_SET_REPORT): + VDBG(cdev, "set_report | wLength=%d\n", ctrl->wLength); +@@ -556,6 +565,14 @@ static int hidg_setup(struct usb_functio + goto stall; + break; + ++ case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 ++ | HID_REQ_SET_IDLE): ++ VDBG(cdev, "set_idle\n"); ++ length = 0; ++ hidg->idle = value; ++ goto respond; ++ break; ++ + case ((USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_INTERFACE) << 8 + | USB_REQ_GET_DESCRIPTOR): + switch (value >> 8) { +@@ -783,6 +800,7 @@ static int hidg_bind(struct usb_configur + hidg_interface_desc.bInterfaceSubClass = hidg->bInterfaceSubClass; + hidg_interface_desc.bInterfaceProtocol = hidg->bInterfaceProtocol; + hidg->protocol = HID_REPORT_PROTOCOL; ++ hidg->idle = 1; + hidg_ss_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length); + hidg_ss_in_comp_desc.wBytesPerInterval = + cpu_to_le16(hidg->report_length); diff --git a/queue-4.14/usb-gadget-f_hid-fixed-null-pointer-dereference.patch b/queue-4.14/usb-gadget-f_hid-fixed-null-pointer-dereference.patch new file mode 100644 index 00000000000..b34b8477ddb --- /dev/null +++ b/queue-4.14/usb-gadget-f_hid-fixed-null-pointer-dereference.patch @@ -0,0 +1,79 @@ +From 2867652e4766360adf14dfda3832455e04964f2a Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Fri, 23 Jul 2021 18:59:30 +0300 +Subject: usb: gadget: f_hid: fixed NULL pointer dereference + +From: Phil Elwell + +commit 2867652e4766360adf14dfda3832455e04964f2a upstream. + +Disconnecting and reconnecting the USB cable can lead to crashes +and a variety of kernel log spam. + +The problem was found and reproduced on the Raspberry Pi [1] +and the original fix was created in Raspberry's own fork [2]. + +Link: https://github.com/raspberrypi/linux/issues/3870 [1] +Link: https://github.com/raspberrypi/linux/commit/a6e47d5f4efbd2ea6a0b6565cd2f9b7bb217ded5 [2] +Signed-off-by: Maxim Devaev +Signed-off-by: Phil Elwell +Cc: stable +Link: https://lore.kernel.org/r/20210723155928.210019-1-mdevaev@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/f_hid.c | 26 ++++++++++++++++++++------ + 1 file changed, 20 insertions(+), 6 deletions(-) + +--- a/drivers/usb/gadget/function/f_hid.c ++++ b/drivers/usb/gadget/function/f_hid.c +@@ -349,6 +349,11 @@ static ssize_t f_hidg_write(struct file + + spin_lock_irqsave(&hidg->write_spinlock, flags); + ++ if (!hidg->req) { ++ spin_unlock_irqrestore(&hidg->write_spinlock, flags); ++ return -ESHUTDOWN; ++ } ++ + #define WRITE_COND (!hidg->write_pending) + try_again: + /* write queue */ +@@ -369,8 +374,14 @@ try_again: + count = min_t(unsigned, count, hidg->report_length); + + spin_unlock_irqrestore(&hidg->write_spinlock, flags); +- status = copy_from_user(req->buf, buffer, count); + ++ if (!req) { ++ ERROR(hidg->func.config->cdev, "hidg->req is NULL\n"); ++ status = -ESHUTDOWN; ++ goto release_write_pending; ++ } ++ ++ status = copy_from_user(req->buf, buffer, count); + if (status != 0) { + ERROR(hidg->func.config->cdev, + "copy_from_user error\n"); +@@ -398,14 +409,17 @@ try_again: + + spin_unlock_irqrestore(&hidg->write_spinlock, flags); + ++ if (!hidg->in_ep->enabled) { ++ ERROR(hidg->func.config->cdev, "in_ep is disabled\n"); ++ status = -ESHUTDOWN; ++ goto release_write_pending; ++ } ++ + status = usb_ep_queue(hidg->in_ep, req, GFP_ATOMIC); +- if (status < 0) { +- ERROR(hidg->func.config->cdev, +- "usb_ep_queue error on int endpoint %zd\n", status); ++ if (status < 0) + goto release_write_pending; +- } else { ++ else + status = count; +- } + + return status; + release_write_pending: diff --git a/queue-4.14/usb-gadget-f_hid-idle-uses-the-highest-byte-for-duration.patch b/queue-4.14/usb-gadget-f_hid-idle-uses-the-highest-byte-for-duration.patch new file mode 100644 index 00000000000..1c1402a7d01 --- /dev/null +++ b/queue-4.14/usb-gadget-f_hid-idle-uses-the-highest-byte-for-duration.patch @@ -0,0 +1,32 @@ +From fa20bada3f934e3b3e4af4c77e5b518cd5a282e5 Mon Sep 17 00:00:00 2001 +From: Maxim Devaev +Date: Tue, 27 Jul 2021 21:58:00 +0300 +Subject: usb: gadget: f_hid: idle uses the highest byte for duration + +From: Maxim Devaev + +commit fa20bada3f934e3b3e4af4c77e5b518cd5a282e5 upstream. + +SET_IDLE value must be shifted 8 bits to the right to get duration. +This confirmed by USBCV test. + +Fixes: afcff6dc690e ("usb: gadget: f_hid: added GET_IDLE and SET_IDLE handlers") +Cc: stable +Signed-off-by: Maxim Devaev +Link: https://lore.kernel.org/r/20210727185800.43796-1-mdevaev@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/f_hid.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/gadget/function/f_hid.c ++++ b/drivers/usb/gadget/function/f_hid.c +@@ -583,7 +583,7 @@ static int hidg_setup(struct usb_functio + | HID_REQ_SET_IDLE): + VDBG(cdev, "set_idle\n"); + length = 0; +- hidg->idle = value; ++ hidg->idle = value >> 8; + goto respond; + break; + diff --git a/queue-4.14/usb-otg-fsm-fix-hrtimer-list-corruption.patch b/queue-4.14/usb-otg-fsm-fix-hrtimer-list-corruption.patch new file mode 100644 index 00000000000..a84ff97bf33 --- /dev/null +++ b/queue-4.14/usb-otg-fsm-fix-hrtimer-list-corruption.patch @@ -0,0 +1,64 @@ +From bf88fef0b6f1488abeca594d377991171c00e52a Mon Sep 17 00:00:00 2001 +From: Dmitry Osipenko +Date: Sat, 17 Jul 2021 21:21:27 +0300 +Subject: usb: otg-fsm: Fix hrtimer list corruption + +From: Dmitry Osipenko + +commit bf88fef0b6f1488abeca594d377991171c00e52a upstream. + +The HNP work can be re-scheduled while it's still in-fly. This results in +re-initialization of the busy work, resetting the hrtimer's list node of +the work and crashing kernel with null dereference within kernel/timer +once work's timer is expired. It's very easy to trigger this problem by +re-plugging USB cable quickly. Initialize HNP work only once to fix this +trouble. + + Unable to handle kernel NULL pointer dereference at virtual address 00000126) + ... + PC is at __run_timers.part.0+0x150/0x228 + LR is at __next_timer_interrupt+0x51/0x9c + ... + (__run_timers.part.0) from [] (run_timer_softirq+0x2f/0x50) + (run_timer_softirq) from [] (__do_softirq+0xd5/0x2f0) + (__do_softirq) from [] (irq_exit+0xab/0xb8) + (irq_exit) from [] (handle_domain_irq+0x45/0x60) + (handle_domain_irq) from [] (gic_handle_irq+0x6b/0x7c) + (gic_handle_irq) from [] (__irq_svc+0x65/0xac) + +Cc: stable@vger.kernel.org +Acked-by: Peter Chen +Signed-off-by: Dmitry Osipenko +Link: https://lore.kernel.org/r/20210717182134.30262-6-digetx@gmail.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/common/usb-otg-fsm.c | 6 +++++- + include/linux/usb/otg-fsm.h | 1 + + 2 files changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/usb/common/usb-otg-fsm.c ++++ b/drivers/usb/common/usb-otg-fsm.c +@@ -206,7 +206,11 @@ static void otg_start_hnp_polling(struct + if (!fsm->host_req_flag) + return; + +- INIT_DELAYED_WORK(&fsm->hnp_polling_work, otg_hnp_polling_work); ++ if (!fsm->hnp_work_inited) { ++ INIT_DELAYED_WORK(&fsm->hnp_polling_work, otg_hnp_polling_work); ++ fsm->hnp_work_inited = true; ++ } ++ + schedule_delayed_work(&fsm->hnp_polling_work, + msecs_to_jiffies(T_HOST_REQ_POLL)); + } +--- a/include/linux/usb/otg-fsm.h ++++ b/include/linux/usb/otg-fsm.h +@@ -195,6 +195,7 @@ struct otg_fsm { + struct mutex lock; + u8 *host_req_flag; + struct delayed_work hnp_polling_work; ++ bool hnp_work_inited; + bool state_changed; + }; +