From cf08f8f098db96ab9bd25a5610be14d802e0e6e8 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 9 Aug 2021 10:54:43 +0200 Subject: [PATCH] 4.19-stable patches added patches: alsa-usb-audio-add-registration-quirk-for-jbl-quantum-600.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 --- ...gistration-quirk-for-jbl-quantum-600.patch | 31 ++++++++ queue-4.19/series | 5 ++ ...added-get_idle-and-set_idle-handlers.patch | 74 +++++++++++++++++ ...f_hid-fixed-null-pointer-dereference.patch | 79 +++++++++++++++++++ ...e-uses-the-highest-byte-for-duration.patch | 32 ++++++++ ...-otg-fsm-fix-hrtimer-list-corruption.patch | 64 +++++++++++++++ 6 files changed, 285 insertions(+) create mode 100644 queue-4.19/alsa-usb-audio-add-registration-quirk-for-jbl-quantum-600.patch create mode 100644 queue-4.19/usb-gadget-f_hid-added-get_idle-and-set_idle-handlers.patch create mode 100644 queue-4.19/usb-gadget-f_hid-fixed-null-pointer-dereference.patch create mode 100644 queue-4.19/usb-gadget-f_hid-idle-uses-the-highest-byte-for-duration.patch create mode 100644 queue-4.19/usb-otg-fsm-fix-hrtimer-list-corruption.patch diff --git a/queue-4.19/alsa-usb-audio-add-registration-quirk-for-jbl-quantum-600.patch b/queue-4.19/alsa-usb-audio-add-registration-quirk-for-jbl-quantum-600.patch new file mode 100644 index 00000000000..1d8fd69df21 --- /dev/null +++ b/queue-4.19/alsa-usb-audio-add-registration-quirk-for-jbl-quantum-600.patch @@ -0,0 +1,31 @@ +From 4b0556b96e1fe7723629bd40e3813a30cd632faf Mon Sep 17 00:00:00 2001 +From: Alexander Tsoy +Date: Tue, 27 Jul 2021 12:33:26 +0300 +Subject: ALSA: usb-audio: Add registration quirk for JBL Quantum 600 + +From: Alexander Tsoy + +commit 4b0556b96e1fe7723629bd40e3813a30cd632faf upstream. + +Apparently JBL Quantum 600 has multiple hardware revisions. Apply +registration quirk to another device id as well. + +Signed-off-by: Alexander Tsoy +Cc: +Link: https://lore.kernel.org/r/20210727093326.1153366-1-alexander@tsoy.me +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + sound/usb/quirks.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -1555,6 +1555,7 @@ static const struct registration_quirk r + REG_QUIRK_ENTRY(0x0951, 0x16ea, 2), /* Kingston HyperX Cloud Flight S */ + REG_QUIRK_ENTRY(0x0ecb, 0x1f46, 2), /* JBL Quantum 600 */ + REG_QUIRK_ENTRY(0x0ecb, 0x2039, 2), /* JBL Quantum 400 */ ++ REG_QUIRK_ENTRY(0x0ecb, 0x203c, 2), /* JBL Quantum 600 */ + REG_QUIRK_ENTRY(0x0ecb, 0x203e, 2), /* JBL Quantum 800 */ + { 0 } /* terminator */ + }; diff --git a/queue-4.19/series b/queue-4.19/series index 69819e010b9..921167ed232 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -24,3 +24,8 @@ 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 firmware_loader-use-etimedout-instead-of-eagain-in-fw_load_sysfs_fallback.patch firmware_loader-fix-use-after-free-in-firmware_fallback_sysfs.patch +alsa-usb-audio-add-registration-quirk-for-jbl-quantum-600.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.19/usb-gadget-f_hid-added-get_idle-and-set_idle-handlers.patch b/queue-4.19/usb-gadget-f_hid-added-get_idle-and-set_idle-handlers.patch new file mode 100644 index 00000000000..c23f4b7e88b --- /dev/null +++ b/queue-4.19/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 +@@ -41,6 +41,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; +@@ -529,6 +530,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); +@@ -552,6 +561,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) { +@@ -779,6 +796,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.19/usb-gadget-f_hid-fixed-null-pointer-dereference.patch b/queue-4.19/usb-gadget-f_hid-fixed-null-pointer-dereference.patch new file mode 100644 index 00000000000..645d7553ba4 --- /dev/null +++ b/queue-4.19/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 +@@ -345,6 +345,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 */ +@@ -365,8 +370,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"); +@@ -394,14 +405,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.19/usb-gadget-f_hid-idle-uses-the-highest-byte-for-duration.patch b/queue-4.19/usb-gadget-f_hid-idle-uses-the-highest-byte-for-duration.patch new file mode 100644 index 00000000000..c570cf504f3 --- /dev/null +++ b/queue-4.19/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 +@@ -579,7 +579,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.19/usb-otg-fsm-fix-hrtimer-list-corruption.patch b/queue-4.19/usb-otg-fsm-fix-hrtimer-list-corruption.patch new file mode 100644 index 00000000000..41ddaf4009a --- /dev/null +++ b/queue-4.19/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 +@@ -193,7 +193,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 +@@ -196,6 +196,7 @@ struct otg_fsm { + struct mutex lock; + u8 *host_req_flag; + struct delayed_work hnp_polling_work; ++ bool hnp_work_inited; + bool state_changed; + }; + -- 2.47.3