From: Greg Kroah-Hartman Date: Mon, 22 Mar 2021 09:15:10 +0000 (+0100) Subject: 4.4-stable patches X-Git-Tag: v4.4.263~39 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f202bebe75bfc4e5e4d5cfa81fac72a99ed8fc8a;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: usb-gadget-configfs-fix-kasan-use-after-free.patch usb-replace-hardcode-maximum-usb-string-length-by-definition.patch --- diff --git a/queue-4.4/series b/queue-4.4/series index 7a8825cd0ec..b619e36d542 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -5,3 +5,5 @@ platform-chrome-cros_ec_dev-fix-security-issue.patch btrfs-fix-race-when-cloning-extent-buffer-during-rewind-of-an-old-root.patch nfsd-repair-misuse-of-sv_lock-in-5.10.16-rt30.patch scsi-lpfc-fix-some-error-codes-in-debugfs.patch +usb-replace-hardcode-maximum-usb-string-length-by-definition.patch +usb-gadget-configfs-fix-kasan-use-after-free.patch diff --git a/queue-4.4/usb-gadget-configfs-fix-kasan-use-after-free.patch b/queue-4.4/usb-gadget-configfs-fix-kasan-use-after-free.patch new file mode 100644 index 00000000000..97a4c0bf4c1 --- /dev/null +++ b/queue-4.4/usb-gadget-configfs-fix-kasan-use-after-free.patch @@ -0,0 +1,83 @@ +From 98f153a10da403ddd5e9d98a3c8c2bb54bb5a0b6 Mon Sep 17 00:00:00 2001 +From: Jim Lin +Date: Thu, 11 Mar 2021 14:42:41 +0800 +Subject: usb: gadget: configfs: Fix KASAN use-after-free + +From: Jim Lin + +commit 98f153a10da403ddd5e9d98a3c8c2bb54bb5a0b6 upstream. + +When gadget is disconnected, running sequence is like this. +. composite_disconnect +. Call trace: + usb_string_copy+0xd0/0x128 + gadget_config_name_configuration_store+0x4 + gadget_config_name_attr_store+0x40/0x50 + configfs_write_file+0x198/0x1f4 + vfs_write+0x100/0x220 + SyS_write+0x58/0xa8 +. configfs_composite_unbind +. configfs_composite_bind + +In configfs_composite_bind, it has +"cn->strings.s = cn->configuration;" + +When usb_string_copy is invoked. it would +allocate memory, copy input string, release previous pointed memory space, +and use new allocated memory. + +When gadget is connected, host sends down request to get information. +Call trace: + usb_gadget_get_string+0xec/0x168 + lookup_string+0x64/0x98 + composite_setup+0xa34/0x1ee8 + +If gadget is disconnected and connected quickly, in the failed case, +cn->configuration memory has been released by usb_string_copy kfree but +configfs_composite_bind hasn't been run in time to assign new allocated +"cn->configuration" pointer to "cn->strings.s". + +When "strlen(s->s) of usb_gadget_get_string is being executed, the dangling +memory is accessed, "BUG: KASAN: use-after-free" error occurs. + +Cc: stable@vger.kernel.org +Signed-off-by: Jim Lin +Signed-off-by: Macpaul Lin +Link: https://lore.kernel.org/r/1615444961-13376-1-git-send-email-macpaul.lin@mediatek.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/configfs.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +--- a/drivers/usb/gadget/configfs.c ++++ b/drivers/usb/gadget/configfs.c +@@ -111,6 +111,8 @@ struct gadget_config_name { + struct list_head list; + }; + ++#define USB_MAX_STRING_WITH_NULL_LEN (USB_MAX_STRING_LEN+1) ++ + static int usb_string_copy(const char *s, char **s_copy) + { + int ret; +@@ -120,12 +122,16 @@ static int usb_string_copy(const char *s + if (ret > USB_MAX_STRING_LEN) + return -EOVERFLOW; + +- str = kstrdup(s, GFP_KERNEL); +- if (!str) +- return -ENOMEM; ++ if (copy) { ++ str = copy; ++ } else { ++ str = kmalloc(USB_MAX_STRING_WITH_NULL_LEN, GFP_KERNEL); ++ if (!str) ++ return -ENOMEM; ++ } ++ strcpy(str, s); + if (str[ret - 1] == '\n') + str[ret - 1] = '\0'; +- kfree(copy); + *s_copy = str; + return 0; + } diff --git a/queue-4.4/usb-replace-hardcode-maximum-usb-string-length-by-definition.patch b/queue-4.4/usb-replace-hardcode-maximum-usb-string-length-by-definition.patch new file mode 100644 index 00000000000..ea9c806c5a2 --- /dev/null +++ b/queue-4.4/usb-replace-hardcode-maximum-usb-string-length-by-definition.patch @@ -0,0 +1,80 @@ +From 81c7462883b0cc0a4eeef0687f80ad5b5baee5f6 Mon Sep 17 00:00:00 2001 +From: Macpaul Lin +Date: Thu, 18 Jun 2020 17:13:38 +0800 +Subject: USB: replace hardcode maximum usb string length by definition + +From: Macpaul Lin + +commit 81c7462883b0cc0a4eeef0687f80ad5b5baee5f6 upstream. + +Replace hardcoded maximum USB string length (126 bytes) by definition +"USB_MAX_STRING_LEN". + +Signed-off-by: Macpaul Lin +Acked-by: Alan Stern +Link: https://lore.kernel.org/r/1592471618-29428-1-git-send-email-macpaul.lin@mediatek.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/composite.c | 4 ++-- + drivers/usb/gadget/configfs.c | 2 +- + drivers/usb/gadget/usbstring.c | 4 ++-- + include/uapi/linux/usb/ch9.h | 3 +++ + 4 files changed, 8 insertions(+), 5 deletions(-) + +--- a/drivers/usb/gadget/composite.c ++++ b/drivers/usb/gadget/composite.c +@@ -933,7 +933,7 @@ static void collect_langs(struct usb_gad + while (*sp) { + s = *sp; + language = cpu_to_le16(s->language); +- for (tmp = buf; *tmp && tmp < &buf[126]; tmp++) { ++ for (tmp = buf; *tmp && tmp < &buf[USB_MAX_STRING_LEN]; tmp++) { + if (*tmp == language) + goto repeat; + } +@@ -1008,7 +1008,7 @@ static int get_string(struct usb_composi + collect_langs(sp, s->wData); + } + +- for (len = 0; len <= 126 && s->wData[len]; len++) ++ for (len = 0; len <= USB_MAX_STRING_LEN && s->wData[len]; len++) + continue; + if (!len) + return -EINVAL; +--- a/drivers/usb/gadget/configfs.c ++++ b/drivers/usb/gadget/configfs.c +@@ -117,7 +117,7 @@ static int usb_string_copy(const char *s + char *str; + char *copy = *s_copy; + ret = strlen(s); +- if (ret > 126) ++ if (ret > USB_MAX_STRING_LEN) + return -EOVERFLOW; + + str = kstrdup(s, GFP_KERNEL); +--- a/drivers/usb/gadget/usbstring.c ++++ b/drivers/usb/gadget/usbstring.c +@@ -59,9 +59,9 @@ usb_gadget_get_string (struct usb_gadget + return -EINVAL; + + /* string descriptors have length, tag, then UTF16-LE text */ +- len = min ((size_t) 126, strlen (s->s)); ++ len = min((size_t)USB_MAX_STRING_LEN, strlen(s->s)); + len = utf8s_to_utf16s(s->s, len, UTF16_LITTLE_ENDIAN, +- (wchar_t *) &buf[2], 126); ++ (wchar_t *) &buf[2], USB_MAX_STRING_LEN); + if (len < 0) + return -EINVAL; + buf [0] = (len + 1) * 2; +--- a/include/uapi/linux/usb/ch9.h ++++ b/include/uapi/linux/usb/ch9.h +@@ -333,6 +333,9 @@ struct usb_config_descriptor { + + /*-------------------------------------------------------------------------*/ + ++/* USB String descriptors can contain at most 126 characters. */ ++#define USB_MAX_STRING_LEN 126 ++ + /* USB_DT_STRING: String descriptor */ + struct usb_string_descriptor { + __u8 bLength;