]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 3 Nov 2021 18:05:54 +0000 (19:05 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 3 Nov 2021 18:05:54 +0000 (19:05 +0100)
added patches:
ib-qib-protect-from-buffer-overflow-in-struct-qib_user_sdma_pkt-fields.patch
ib-qib-use-struct_size-helper.patch

queue-4.19/ib-qib-protect-from-buffer-overflow-in-struct-qib_user_sdma_pkt-fields.patch [new file with mode: 0644]
queue-4.19/ib-qib-use-struct_size-helper.patch [new file with mode: 0644]
queue-4.19/series

diff --git a/queue-4.19/ib-qib-protect-from-buffer-overflow-in-struct-qib_user_sdma_pkt-fields.patch b/queue-4.19/ib-qib-protect-from-buffer-overflow-in-struct-qib_user_sdma_pkt-fields.patch
new file mode 100644 (file)
index 0000000..5963dca
--- /dev/null
@@ -0,0 +1,115 @@
+From d39bf40e55e666b5905fdbd46a0dced030ce87be Mon Sep 17 00:00:00 2001
+From: Mike Marciniszyn <mike.marciniszyn@cornelisnetworks.com>
+Date: Tue, 12 Oct 2021 13:55:19 -0400
+Subject: IB/qib: Protect from buffer overflow in struct qib_user_sdma_pkt fields
+
+From: Mike Marciniszyn <mike.marciniszyn@cornelisnetworks.com>
+
+commit d39bf40e55e666b5905fdbd46a0dced030ce87be upstream.
+
+Overflowing either addrlimit or bytes_togo can allow userspace to trigger
+a buffer overflow of kernel memory. Check for overflows in all the places
+doing math on user controlled buffers.
+
+Fixes: f931551bafe1 ("IB/qib: Add new qib driver for QLogic PCIe InfiniBand adapters")
+Link: https://lore.kernel.org/r/20211012175519.7298.77738.stgit@awfm-01.cornelisnetworks.com
+Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com>
+Reviewed-by: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
+Signed-off-by: Mike Marciniszyn <mike.marciniszyn@cornelisnetworks.com>
+Signed-off-by: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/infiniband/hw/qib/qib_user_sdma.c |   33 ++++++++++++++++++++----------
+ 1 file changed, 23 insertions(+), 10 deletions(-)
+
+--- a/drivers/infiniband/hw/qib/qib_user_sdma.c
++++ b/drivers/infiniband/hw/qib/qib_user_sdma.c
+@@ -606,7 +606,7 @@ done:
+ /*
+  * How many pages in this iovec element?
+  */
+-static int qib_user_sdma_num_pages(const struct iovec *iov)
++static size_t qib_user_sdma_num_pages(const struct iovec *iov)
+ {
+       const unsigned long addr  = (unsigned long) iov->iov_base;
+       const unsigned long  len  = iov->iov_len;
+@@ -662,7 +662,7 @@ static void qib_user_sdma_free_pkt_frag(
+ static int qib_user_sdma_pin_pages(const struct qib_devdata *dd,
+                                  struct qib_user_sdma_queue *pq,
+                                  struct qib_user_sdma_pkt *pkt,
+-                                 unsigned long addr, int tlen, int npages)
++                                 unsigned long addr, int tlen, size_t npages)
+ {
+       struct page *pages[8];
+       int i, j;
+@@ -726,7 +726,7 @@ static int qib_user_sdma_pin_pkt(const s
+       unsigned long idx;
+       for (idx = 0; idx < niov; idx++) {
+-              const int npages = qib_user_sdma_num_pages(iov + idx);
++              const size_t npages = qib_user_sdma_num_pages(iov + idx);
+               const unsigned long addr = (unsigned long) iov[idx].iov_base;
+               ret = qib_user_sdma_pin_pages(dd, pq, pkt, addr,
+@@ -828,8 +828,8 @@ static int qib_user_sdma_queue_pkts(cons
+               unsigned pktnw;
+               unsigned pktnwc;
+               int nfrags = 0;
+-              int npages = 0;
+-              int bytes_togo = 0;
++              size_t npages = 0;
++              size_t bytes_togo = 0;
+               int tiddma = 0;
+               int cfur;
+@@ -889,7 +889,11 @@ static int qib_user_sdma_queue_pkts(cons
+                       npages += qib_user_sdma_num_pages(&iov[idx]);
+-                      bytes_togo += slen;
++                      if (check_add_overflow(bytes_togo, slen, &bytes_togo) ||
++                          bytes_togo > type_max(typeof(pkt->bytes_togo))) {
++                              ret = -EINVAL;
++                              goto free_pbc;
++                      }
+                       pktnwc += slen >> 2;
+                       idx++;
+                       nfrags++;
+@@ -908,8 +912,7 @@ static int qib_user_sdma_queue_pkts(cons
+               }
+               if (frag_size) {
+-                      int tidsmsize, n;
+-                      size_t pktsize;
++                      size_t tidsmsize, n, pktsize, sz, addrlimit;
+                       n = npages*((2*PAGE_SIZE/frag_size)+1);
+                       pktsize = struct_size(pkt, addr, n);
+@@ -927,14 +930,24 @@ static int qib_user_sdma_queue_pkts(cons
+                       else
+                               tidsmsize = 0;
+-                      pkt = kmalloc(pktsize+tidsmsize, GFP_KERNEL);
++                      if (check_add_overflow(pktsize, tidsmsize, &sz)) {
++                              ret = -EINVAL;
++                              goto free_pbc;
++                      }
++                      pkt = kmalloc(sz, GFP_KERNEL);
+                       if (!pkt) {
+                               ret = -ENOMEM;
+                               goto free_pbc;
+                       }
+                       pkt->largepkt = 1;
+                       pkt->frag_size = frag_size;
+-                      pkt->addrlimit = n + ARRAY_SIZE(pkt->addr);
++                      if (check_add_overflow(n, ARRAY_SIZE(pkt->addr),
++                                             &addrlimit) ||
++                          addrlimit > type_max(typeof(pkt->addrlimit))) {
++                              ret = -EINVAL;
++                              goto free_pbc;
++                      }
++                      pkt->addrlimit = addrlimit;
+                       if (tiddma) {
+                               char *tidsm = (char *)pkt + pktsize;
diff --git a/queue-4.19/ib-qib-use-struct_size-helper.patch b/queue-4.19/ib-qib-use-struct_size-helper.patch
new file mode 100644 (file)
index 0000000..0a6a548
--- /dev/null
@@ -0,0 +1,50 @@
+From 829ca44ecf60e9b6f83d0161a6ef10c1304c5060 Mon Sep 17 00:00:00 2001
+From: "Gustavo A. R. Silva" <gustavo@embeddedor.com>
+Date: Wed, 29 May 2019 10:13:26 -0500
+Subject: IB/qib: Use struct_size() helper
+
+From: Gustavo A. R. Silva <gustavo@embeddedor.com>
+
+commit 829ca44ecf60e9b6f83d0161a6ef10c1304c5060 upstream.
+
+Make use of the struct_size() helper instead of an open-coded version
+in order to avoid any potential type mistakes, in particular in the
+context in which this code is being used.
+
+So, replace the following form:
+
+sizeof(*pkt) + sizeof(pkt->addr[0])*n
+
+with:
+
+struct_size(pkt, addr, n)
+
+Also, notice that variable size is unnecessary, hence it is removed.
+
+This code was detected with the help of Coccinelle.
+
+Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
+Reviewed-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
+Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
+Cc: Mile Marciniszyn <mike.marciniszyn@cornelisnetworks.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/infiniband/hw/qib/qib_user_sdma.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/infiniband/hw/qib/qib_user_sdma.c
++++ b/drivers/infiniband/hw/qib/qib_user_sdma.c
+@@ -908,10 +908,11 @@ static int qib_user_sdma_queue_pkts(cons
+               }
+               if (frag_size) {
+-                      int pktsize, tidsmsize, n;
++                      int tidsmsize, n;
++                      size_t pktsize;
+                       n = npages*((2*PAGE_SIZE/frag_size)+1);
+-                      pktsize = sizeof(*pkt) + sizeof(pkt->addr[0])*n;
++                      pktsize = struct_size(pkt, addr, n);
+                       /*
+                        * Determine if this is tid-sdma or just sdma.
index ba0803e4e032339b63f2079258f04c27b242798b..fe2177e12d05a9dd6b8ca86d3ada4e98322bd3be 100644 (file)
@@ -1,2 +1,4 @@
 scsi-core-put-lld-module-refcnt-after-scsi-device-is-released.patch
 media-firewire-firedtv-avc-fix-a-buffer-overflow-in-avc_ca_pmt.patch
+ib-qib-use-struct_size-helper.patch
+ib-qib-protect-from-buffer-overflow-in-struct-qib_user_sdma_pkt-fields.patch