]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 3 Apr 2018 09:55:50 +0000 (11:55 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 3 Apr 2018 09:55:50 +0000 (11:55 +0200)
added patches:
usb-gadget-align-buffer-size-when-allocating-for-out-endpoint.patch
usb-gadget-change-len-to-size_t-on-alloc_ep_req.patch
usb-gadget-define-free_ep_req-as-universal-function.patch
usb-gadget-f_hid-fix-prevent-accessing-released-memory.patch
usb-gadget-fix-usb_ep_align_maybe-endianness-and-new-usb_ep_align.patch

queue-3.18/series
queue-3.18/usb-gadget-align-buffer-size-when-allocating-for-out-endpoint.patch [new file with mode: 0644]
queue-3.18/usb-gadget-change-len-to-size_t-on-alloc_ep_req.patch [new file with mode: 0644]
queue-3.18/usb-gadget-define-free_ep_req-as-universal-function.patch [new file with mode: 0644]
queue-3.18/usb-gadget-f_hid-fix-prevent-accessing-released-memory.patch [new file with mode: 0644]
queue-3.18/usb-gadget-fix-usb_ep_align_maybe-endianness-and-new-usb_ep_align.patch [new file with mode: 0644]

index 31de45579f8e4ee329988c45f59e359a9a9299a9..3885c0d9d12d3904f9c3c3e7aba80d3a7660b983 100644 (file)
@@ -39,3 +39,8 @@ alsa-pcm-use-dma_bytes-as-size-parameter-in-dma_mmap_coherent.patch
 alsa-pcm-potential-uninitialized-return-values.patch
 perf-hwbp-simplify-the-perf-hwbp-code-fix-documentation.patch
 partitions-msdos-unable-to-mount-ufs-44bsd-partitions.patch
+usb-gadget-define-free_ep_req-as-universal-function.patch
+usb-gadget-change-len-to-size_t-on-alloc_ep_req.patch
+usb-gadget-fix-usb_ep_align_maybe-endianness-and-new-usb_ep_align.patch
+usb-gadget-align-buffer-size-when-allocating-for-out-endpoint.patch
+usb-gadget-f_hid-fix-prevent-accessing-released-memory.patch
diff --git a/queue-3.18/usb-gadget-align-buffer-size-when-allocating-for-out-endpoint.patch b/queue-3.18/usb-gadget-align-buffer-size-when-allocating-for-out-endpoint.patch
new file mode 100644 (file)
index 0000000..7369d55
--- /dev/null
@@ -0,0 +1,67 @@
+From e0466156ee2e944fb47a3fa00932c3698a6d2c67 Mon Sep 17 00:00:00 2001
+From: "Felipe F. Tonello" <eu@felipetonello.com>
+Date: Mon, 8 Aug 2016 21:30:06 +0100
+Subject: usb: gadget: align buffer size when allocating for OUT endpoint
+
+From: Felipe F. Tonello <eu@felipetonello.com>
+
+commit e0466156ee2e944fb47a3fa00932c3698a6d2c67 upstream.
+
+Using usb_ep_align() makes sure that the buffer size for OUT endpoints is
+always aligned with wMaxPacketSize (512 usually). This makes sure
+that no buffer has the wrong size, which can cause nasty bugs.
+
+Signed-off-by: Felipe F. Tonello <eu@felipetonello.com>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/u_f.c |    3 +++
+ drivers/usb/gadget/u_f.h |   16 +++++++++++++++-
+ 2 files changed, 18 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/gadget/u_f.c
++++ b/drivers/usb/gadget/u_f.c
+@@ -12,6 +12,7 @@
+  */
+ #include "u_f.h"
++#include <linux/usb/ch9.h>
+ struct usb_request *alloc_ep_req(struct usb_ep *ep, size_t len, int default_len)
+ {
+@@ -20,6 +21,8 @@ struct usb_request *alloc_ep_req(struct
+       req = usb_ep_alloc_request(ep, GFP_ATOMIC);
+       if (req) {
+               req->length = len ?: default_len;
++              if (usb_endpoint_dir_out(ep->desc))
++                      req->length = usb_ep_align(ep, req->length);
+               req->buf = kmalloc(req->length, GFP_ATOMIC);
+               if (!req->buf) {
+                       usb_ep_free_request(ep, req);
+--- a/drivers/usb/gadget/u_f.h
++++ b/drivers/usb/gadget/u_f.h
+@@ -47,8 +47,22 @@
+ struct usb_ep;
+ struct usb_request;
+-/* Requests allocated via alloc_ep_req() must be freed by free_ep_req(). */
++/**
++ * alloc_ep_req - returns a usb_request allocated by the gadget driver and
++ * allocates the request's buffer.
++ *
++ * @ep: the endpoint to allocate a usb_request
++ * @len: usb_requests's buffer suggested size
++ * @default_len: used if @len is not provided, ie, is 0
++ *
++ * In case @ep direction is OUT, the @len will be aligned to ep's
++ * wMaxPacketSize. In order to avoid memory leaks or drops, *always* use
++ * usb_requests's length (req->length) to refer to the allocated buffer size.
++ * Requests allocated via alloc_ep_req() *must* be freed by free_ep_req().
++ */
+ struct usb_request *alloc_ep_req(struct usb_ep *ep, size_t len, int default_len);
++
++/* Frees a usb_request previously allocated by alloc_ep_req() */
+ static inline void free_ep_req(struct usb_ep *ep, struct usb_request *req)
+ {
+       kfree(req->buf);
diff --git a/queue-3.18/usb-gadget-change-len-to-size_t-on-alloc_ep_req.patch b/queue-3.18/usb-gadget-change-len-to-size_t-on-alloc_ep_req.patch
new file mode 100644 (file)
index 0000000..aefaf7d
--- /dev/null
@@ -0,0 +1,44 @@
+From 69bb99738b5c6d56d2b1a75db9cbb4d187453c1a Mon Sep 17 00:00:00 2001
+From: "Felipe F. Tonello" <eu@felipetonello.com>
+Date: Mon, 8 Aug 2016 21:30:05 +0100
+Subject: usb: gadget: change len to size_t on alloc_ep_req()
+
+From: Felipe F. Tonello <eu@felipetonello.com>
+
+commit 69bb99738b5c6d56d2b1a75db9cbb4d187453c1a upstream.
+
+Length of buffers should be of type size_t whenever possible. Altough
+recommended, this change has no real practical change, unless a driver has a
+uses a huge or negative buffer size - it might help find these bugs.
+
+Signed-off-by: Felipe F. Tonello <eu@felipetonello.com>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/u_f.c |    2 +-
+ drivers/usb/gadget/u_f.h |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/gadget/u_f.c
++++ b/drivers/usb/gadget/u_f.c
+@@ -13,7 +13,7 @@
+ #include "u_f.h"
+-struct usb_request *alloc_ep_req(struct usb_ep *ep, int len, int default_len)
++struct usb_request *alloc_ep_req(struct usb_ep *ep, size_t len, int default_len)
+ {
+       struct usb_request      *req;
+--- a/drivers/usb/gadget/u_f.h
++++ b/drivers/usb/gadget/u_f.h
+@@ -48,7 +48,7 @@ struct usb_ep;
+ struct usb_request;
+ /* Requests allocated via alloc_ep_req() must be freed by free_ep_req(). */
+-struct usb_request *alloc_ep_req(struct usb_ep *ep, int len, int default_len);
++struct usb_request *alloc_ep_req(struct usb_ep *ep, size_t len, int default_len);
+ static inline void free_ep_req(struct usb_ep *ep, struct usb_request *req)
+ {
+       kfree(req->buf);
diff --git a/queue-3.18/usb-gadget-define-free_ep_req-as-universal-function.patch b/queue-3.18/usb-gadget-define-free_ep_req-as-universal-function.patch
new file mode 100644 (file)
index 0000000..89a1982
--- /dev/null
@@ -0,0 +1,101 @@
+From 079fe5a6da616891cca1a26e803e1df2a87e9ae5 Mon Sep 17 00:00:00 2001
+From: "Felipe F. Tonello" <eu@felipetonello.com>
+Date: Tue, 10 Nov 2015 17:52:05 +0000
+Subject: usb: gadget: define free_ep_req as universal function
+
+From: Felipe F. Tonello <eu@felipetonello.com>
+
+commit 079fe5a6da616891cca1a26e803e1df2a87e9ae5 upstream.
+
+This function is shared between gadget functions, so this avoid unnecessary
+duplicated code and potentially avoid memory leaks.
+
+Reviewed-by: Robert Baldyga <r.baldyga@samsung.com>
+Signed-off-by: Felipe F. Tonello <eu@felipetonello.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/function/f_midi.c       |    6 ------
+ drivers/usb/gadget/function/f_sourcesink.c |    6 ------
+ drivers/usb/gadget/function/g_zero.h       |    1 -
+ drivers/usb/gadget/u_f.c                   |    1 -
+ drivers/usb/gadget/u_f.h                   |   10 ++++++++--
+ 5 files changed, 8 insertions(+), 16 deletions(-)
+
+--- a/drivers/usb/gadget/function/f_midi.c
++++ b/drivers/usb/gadget/function/f_midi.c
+@@ -199,12 +199,6 @@ static inline struct usb_request *midi_a
+       return alloc_ep_req(ep, length, length);
+ }
+-static void free_ep_req(struct usb_ep *ep, struct usb_request *req)
+-{
+-      kfree(req->buf);
+-      usb_ep_free_request(ep, req);
+-}
+-
+ static const uint8_t f_midi_cin_length[] = {
+       0, 0, 2, 3, 3, 1, 2, 3, 3, 3, 3, 3, 2, 2, 3, 1
+ };
+--- a/drivers/usb/gadget/function/f_sourcesink.c
++++ b/drivers/usb/gadget/function/f_sourcesink.c
+@@ -435,12 +435,6 @@ static inline struct usb_request *ss_all
+       return alloc_ep_req(ep, len, buflen);
+ }
+-void free_ep_req(struct usb_ep *ep, struct usb_request *req)
+-{
+-      kfree(req->buf);
+-      usb_ep_free_request(ep, req);
+-}
+-
+ static void disable_ep(struct usb_composite_dev *cdev, struct usb_ep *ep)
+ {
+       int                     value;
+--- a/drivers/usb/gadget/function/g_zero.h
++++ b/drivers/usb/gadget/function/g_zero.h
+@@ -69,7 +69,6 @@ void lb_modexit(void);
+ int lb_modinit(void);
+ /* common utilities */
+-void free_ep_req(struct usb_ep *ep, struct usb_request *req);
+ void disable_endpoints(struct usb_composite_dev *cdev,
+               struct usb_ep *in, struct usb_ep *out,
+               struct usb_ep *iso_in, struct usb_ep *iso_out,
+--- a/drivers/usb/gadget/u_f.c
++++ b/drivers/usb/gadget/u_f.c
+@@ -11,7 +11,6 @@
+  * published by the Free Software Foundation.
+  */
+-#include <linux/usb/gadget.h>
+ #include "u_f.h"
+ struct usb_request *alloc_ep_req(struct usb_ep *ep, int len, int default_len)
+--- a/drivers/usb/gadget/u_f.h
++++ b/drivers/usb/gadget/u_f.h
+@@ -16,6 +16,8 @@
+ #ifndef __U_F_H__
+ #define __U_F_H__
++#include <linux/usb/gadget.h>
++
+ /* Variable Length Array Macros **********************************************/
+ #define vla_group(groupname) size_t groupname##__next = 0
+ #define vla_group_size(groupname) groupname##__next
+@@ -45,8 +47,12 @@
+ struct usb_ep;
+ struct usb_request;
++/* Requests allocated via alloc_ep_req() must be freed by free_ep_req(). */
+ struct usb_request *alloc_ep_req(struct usb_ep *ep, int len, int default_len);
++static inline void free_ep_req(struct usb_ep *ep, struct usb_request *req)
++{
++      kfree(req->buf);
++      usb_ep_free_request(ep, req);
++}
+ #endif /* __U_F_H__ */
+-
+-
diff --git a/queue-3.18/usb-gadget-f_hid-fix-prevent-accessing-released-memory.patch b/queue-3.18/usb-gadget-f_hid-fix-prevent-accessing-released-memory.patch
new file mode 100644 (file)
index 0000000..61a6f9a
--- /dev/null
@@ -0,0 +1,93 @@
+From aa65d11aa008f4de58a9cee7e121666d9d68505e Mon Sep 17 00:00:00 2001
+From: Krzysztof Opasiak <kopasiak90@gmail.com>
+Date: Thu, 19 Jan 2017 18:55:28 +0100
+Subject: usb: gadget: f_hid: fix: Prevent accessing released memory
+
+From: Krzysztof Opasiak <kopasiak90@gmail.com>
+
+commit aa65d11aa008f4de58a9cee7e121666d9d68505e upstream.
+
+When we unlock our spinlock to copy data to user we may get
+disabled by USB host and free the whole list of completed out
+requests including the one from which we are copying the data
+to user memory.
+
+To prevent from this let's remove our working element from
+the list and place it back only if there is sth left when we
+finish with it.
+
+Fixes: 99c515005857 ("usb: gadget: hidg: register OUT INT endpoint for SET_REPORT")
+Cc: stable@vger.kernel.org
+Tested-by: David Lechner <david@lechnology.com>
+Signed-off-by: Krzysztof Opasiak <k.opasiak@samsung.com>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+Cc: Jerry Zhang <zhangjerry@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/function/f_hid.c |   24 ++++++++++++++++++++----
+ 1 file changed, 20 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/gadget/function/f_hid.c
++++ b/drivers/usb/gadget/function/f_hid.c
+@@ -197,6 +197,13 @@ static ssize_t f_hidg_read(struct file *
+       /* pick the first one */
+       list = list_first_entry(&hidg->completed_out_req,
+                               struct f_hidg_req_list, list);
++
++      /*
++       * Remove this from list to protect it from beign free()
++       * while host disables our function
++       */
++      list_del(&list->list);
++
+       req = list->req;
+       count = min_t(unsigned int, count, req->actual - list->pos);
+       spin_unlock_irqrestore(&hidg->spinlock, flags);
+@@ -212,15 +219,20 @@ static ssize_t f_hidg_read(struct file *
+        * call, taking into account its current read position.
+        */
+       if (list->pos == req->actual) {
+-              spin_lock_irqsave(&hidg->spinlock, flags);
+-              list_del(&list->list);
+               kfree(list);
+-              spin_unlock_irqrestore(&hidg->spinlock, flags);
+               req->length = hidg->report_length;
+               ret = usb_ep_queue(hidg->out_ep, req, GFP_KERNEL);
+-              if (ret < 0)
++              if (ret < 0) {
++                      free_ep_req(hidg->out_ep, req);
+                       return ret;
++              }
++      } else {
++              spin_lock_irqsave(&hidg->spinlock, flags);
++              list_add(&list->list, &hidg->completed_out_req);
++              spin_unlock_irqrestore(&hidg->spinlock, flags);
++
++              wake_up(&hidg->read_queue);
+       }
+       return count;
+@@ -455,6 +467,7 @@ static void hidg_disable(struct usb_func
+ {
+       struct f_hidg *hidg = func_to_hidg(f);
+       struct f_hidg_req_list *list, *next;
++      unsigned long flags;
+       usb_ep_disable(hidg->in_ep);
+       hidg->in_ep->driver_data = NULL;
+@@ -462,10 +475,13 @@ static void hidg_disable(struct usb_func
+       usb_ep_disable(hidg->out_ep);
+       hidg->out_ep->driver_data = NULL;
++      spin_lock_irqsave(&hidg->spinlock, flags);
+       list_for_each_entry_safe(list, next, &hidg->completed_out_req, list) {
++              free_ep_req(hidg->out_ep, list->req);
+               list_del(&list->list);
+               kfree(list);
+       }
++      spin_unlock_irqrestore(&hidg->spinlock, flags);
+ }
+ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
diff --git a/queue-3.18/usb-gadget-fix-usb_ep_align_maybe-endianness-and-new-usb_ep_align.patch b/queue-3.18/usb-gadget-fix-usb_ep_align_maybe-endianness-and-new-usb_ep_align.patch
new file mode 100644 (file)
index 0000000..4db4b02
--- /dev/null
@@ -0,0 +1,59 @@
+From 16b114a6d7973cf027e4c2b23eae1076eaf98c25 Mon Sep 17 00:00:00 2001
+From: "Felipe F. Tonello" <eu@felipetonello.com>
+Date: Mon, 8 Aug 2016 21:30:04 +0100
+Subject: usb: gadget: fix usb_ep_align_maybe endianness and new usb_ep_align
+
+From: Felipe F. Tonello <eu@felipetonello.com>
+
+commit 16b114a6d7973cf027e4c2b23eae1076eaf98c25 upstream.
+
+USB spec specifies wMaxPacketSize to be little endian (as other properties),
+so when using this variable in the driver we should convert to the current
+CPU endianness if necessary.
+
+This patch also introduces usb_ep_align() which does always returns the
+aligned buffer size for an endpoint. This is useful to be used by USB requests
+allocator functions.
+
+Signed-off-by: Felipe F. Tonello <eu@felipetonello.com>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/usb/gadget.h |   17 ++++++++++++++---
+ 1 file changed, 14 insertions(+), 3 deletions(-)
+
+--- a/include/linux/usb/gadget.h
++++ b/include/linux/usb/gadget.h
+@@ -582,8 +582,20 @@ static inline struct usb_gadget *dev_to_
+ /**
++ * usb_ep_align - returns @len aligned to ep's maxpacketsize.
++ * @ep: the endpoint whose maxpacketsize is used to align @len
++ * @len: buffer size's length to align to @ep's maxpacketsize
++ *
++ * This helper is used to align buffer's size to an ep's maxpacketsize.
++ */
++static inline size_t usb_ep_align(struct usb_ep *ep, size_t len)
++{
++      return round_up(len, (size_t)le16_to_cpu(ep->desc->wMaxPacketSize));
++}
++
++/**
+  * usb_ep_align_maybe - returns @len aligned to ep's maxpacketsize if gadget
+- *    requires quirk_ep_out_aligned_size, otherwise reguens len.
++ *    requires quirk_ep_out_aligned_size, otherwise returns len.
+  * @g: controller to check for quirk
+  * @ep: the endpoint whose maxpacketsize is used to align @len
+  * @len: buffer size's length to align to @ep's maxpacketsize
+@@ -594,8 +606,7 @@ static inline struct usb_gadget *dev_to_
+ static inline size_t
+ usb_ep_align_maybe(struct usb_gadget *g, struct usb_ep *ep, size_t len)
+ {
+-      return !g->quirk_ep_out_aligned_size ? len :
+-                      round_up(len, (size_t)ep->desc->wMaxPacketSize);
++      return g->quirk_ep_out_aligned_size ? usb_ep_align(ep, len) : len;
+ }
+ /**