--- /dev/null
+From 5bdb0f02add5994b0bc17494f4726925ca5d6ba1 Mon Sep 17 00:00:00 2001
+From: Yann Droneaud <ydroneaud@opteya.com>
+Date: Mon, 10 Mar 2014 23:06:25 +0100
+Subject: IB/ehca: Returns an error on ib_copy_to_udata() failure
+
+From: Yann Droneaud <ydroneaud@opteya.com>
+
+commit 5bdb0f02add5994b0bc17494f4726925ca5d6ba1 upstream.
+
+In case of error when writing to userspace, function ehca_create_cq()
+does not set an error code before following its error path.
+
+This patch sets the error code to -EFAULT when ib_copy_to_udata()
+fails.
+
+This was caught when using spatch (aka. coccinelle)
+to rewrite call to ib_copy_{from,to}_udata().
+
+Link: https://www.gitorious.org/opteya/coccib/source/75ebf2c1033c64c1d81df13e4ae44ee99c989eba:ib_copy_udata.cocci
+Link: http://marc.info/?i=cover.1394485254.git.ydroneaud@opteya.com
+Signed-off-by: Yann Droneaud <ydroneaud@opteya.com>
+Signed-off-by: Roland Dreier <roland@purestorage.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/hw/ehca/ehca_cq.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/infiniband/hw/ehca/ehca_cq.c
++++ b/drivers/infiniband/hw/ehca/ehca_cq.c
+@@ -283,6 +283,7 @@ struct ib_cq *ehca_create_cq(struct ib_d
+ (my_cq->galpas.user.fw_handle & (PAGE_SIZE - 1));
+ if (ib_copy_to_udata(udata, &resp, sizeof(resp))) {
+ ehca_err(device, "Copy to udata failed.");
++ cq = ERR_PTR(-EFAULT);
+ goto create_cq_exit4;
+ }
+ }
--- /dev/null
+From a2cb0eb8a64adb29a99fd864013de957028f36ae Mon Sep 17 00:00:00 2001
+From: Dennis Dalessandro <dennis.dalessandro@intel.com>
+Date: Thu, 20 Feb 2014 11:02:53 -0500
+Subject: IB/ipath: Fix potential buffer overrun in sending diag packet routine
+
+From: Dennis Dalessandro <dennis.dalessandro@intel.com>
+
+commit a2cb0eb8a64adb29a99fd864013de957028f36ae upstream.
+
+Guard against a potential buffer overrun. The size to read from the
+user is passed in, and due to the padding that needs to be taken into
+account, as well as the place holder for the ICRC it is possible to
+overflow the 32bit value which would cause more data to be copied from
+user space than is allocated in the buffer.
+
+Reported-by: Nico Golde <nico@ngolde.de>
+Reported-by: Fabian Yamaguchi <fabs@goesec.de>
+Reviewed-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
+Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
+Signed-off-by: Roland Dreier <roland@purestorage.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/hw/ipath/ipath_diag.c | 66 +++++++++++--------------------
+ 1 file changed, 25 insertions(+), 41 deletions(-)
+
+--- a/drivers/infiniband/hw/ipath/ipath_diag.c
++++ b/drivers/infiniband/hw/ipath/ipath_diag.c
+@@ -326,7 +326,7 @@ static ssize_t ipath_diagpkt_write(struc
+ size_t count, loff_t *off)
+ {
+ u32 __iomem *piobuf;
+- u32 plen, clen, pbufn;
++ u32 plen, pbufn, maxlen_reserve;
+ struct ipath_diag_pkt odp;
+ struct ipath_diag_xpkt dp;
+ u32 *tmpbuf = NULL;
+@@ -335,51 +335,29 @@ static ssize_t ipath_diagpkt_write(struc
+ u64 val;
+ u32 l_state, lt_state; /* LinkState, LinkTrainingState */
+
+- if (count < sizeof(odp)) {
+- ret = -EINVAL;
+- goto bail;
+- }
+
+ if (count == sizeof(dp)) {
+ if (copy_from_user(&dp, data, sizeof(dp))) {
+ ret = -EFAULT;
+ goto bail;
+ }
+- } else if (copy_from_user(&odp, data, sizeof(odp))) {
+- ret = -EFAULT;
++ } else if (count == sizeof(odp)) {
++ if (copy_from_user(&odp, data, sizeof(odp))) {
++ ret = -EFAULT;
++ goto bail;
++ }
++ } else {
++ ret = -EINVAL;
+ goto bail;
+ }
+
+- /*
+- * Due to padding/alignment issues (lessened with new struct)
+- * the old and new structs are the same length. We need to
+- * disambiguate them, which we can do because odp.len has never
+- * been less than the total of LRH+BTH+DETH so far, while
+- * dp.unit (same offset) unit is unlikely to get that high.
+- * Similarly, dp.data, the pointer to user at the same offset
+- * as odp.unit, is almost certainly at least one (512byte)page
+- * "above" NULL. The if-block below can be omitted if compatibility
+- * between a new driver and older diagnostic code is unimportant.
+- * compatibility the other direction (new diags, old driver) is
+- * handled in the diagnostic code, with a warning.
+- */
+- if (dp.unit >= 20 && dp.data < 512) {
+- /* very probable version mismatch. Fix it up */
+- memcpy(&odp, &dp, sizeof(odp));
+- /* We got a legacy dp, copy elements to dp */
+- dp.unit = odp.unit;
+- dp.data = odp.data;
+- dp.len = odp.len;
+- dp.pbc_wd = 0; /* Indicate we need to compute PBC wd */
+- }
+-
+ /* send count must be an exact number of dwords */
+ if (dp.len & 3) {
+ ret = -EINVAL;
+ goto bail;
+ }
+
+- clen = dp.len >> 2;
++ plen = dp.len >> 2;
+
+ dd = ipath_lookup(dp.unit);
+ if (!dd || !(dd->ipath_flags & IPATH_PRESENT) ||
+@@ -422,16 +400,22 @@ static ssize_t ipath_diagpkt_write(struc
+ goto bail;
+ }
+
+- /* need total length before first word written */
+- /* +1 word is for the qword padding */
+- plen = sizeof(u32) + dp.len;
+-
+- if ((plen + 4) > dd->ipath_ibmaxlen) {
++ /*
++ * need total length before first word written, plus 2 Dwords. One Dword
++ * is for padding so we get the full user data when not aligned on
++ * a word boundary. The other Dword is to make sure we have room for the
++ * ICRC which gets tacked on later.
++ */
++ maxlen_reserve = 2 * sizeof(u32);
++ if (dp.len > dd->ipath_ibmaxlen - maxlen_reserve) {
+ ipath_dbg("Pkt len 0x%x > ibmaxlen %x\n",
+- plen - 4, dd->ipath_ibmaxlen);
++ dp.len, dd->ipath_ibmaxlen);
+ ret = -EINVAL;
+- goto bail; /* before writing pbc */
++ goto bail;
+ }
++
++ plen = sizeof(u32) + dp.len;
++
+ tmpbuf = vmalloc(plen);
+ if (!tmpbuf) {
+ dev_info(&dd->pcidev->dev, "Unable to allocate tmp buffer, "
+@@ -473,11 +457,11 @@ static ssize_t ipath_diagpkt_write(struc
+ */
+ if (dd->ipath_flags & IPATH_PIO_FLUSH_WC) {
+ ipath_flush_wc();
+- __iowrite32_copy(piobuf + 2, tmpbuf, clen - 1);
++ __iowrite32_copy(piobuf + 2, tmpbuf, plen - 1);
+ ipath_flush_wc();
+- __raw_writel(tmpbuf[clen - 1], piobuf + clen + 1);
++ __raw_writel(tmpbuf[plen - 1], piobuf + plen + 1);
+ } else
+- __iowrite32_copy(piobuf + 2, tmpbuf, clen);
++ __iowrite32_copy(piobuf + 2, tmpbuf, plen);
+
+ ipath_flush_wc();
+
--- /dev/null
+From 08e74c4b00c30c232d535ff368554959403d0432 Mon Sep 17 00:00:00 2001
+From: Yann Droneaud <ydroneaud@opteya.com>
+Date: Mon, 10 Mar 2014 23:06:26 +0100
+Subject: IB/mthca: Return an error on ib_copy_to_udata() failure
+
+From: Yann Droneaud <ydroneaud@opteya.com>
+
+commit 08e74c4b00c30c232d535ff368554959403d0432 upstream.
+
+In case of error when writing to userspace, the function mthca_create_cq()
+does not set an error code before following its error path.
+
+This patch sets the error code to -EFAULT when ib_copy_to_udata() fails.
+
+This was caught when using spatch (aka. coccinelle)
+to rewrite call to ib_copy_{from,to}_udata().
+
+Link: https://www.gitorious.org/opteya/coccib/source/75ebf2c1033c64c1d81df13e4ae44ee99c989eba:ib_copy_udata.cocci
+Link: http://marc.info/?i=cover.1394485254.git.ydroneaud@opteya.com
+Signed-off-by: Yann Droneaud <ydroneaud@opteya.com>
+Signed-off-by: Roland Dreier <roland@purestorage.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/hw/mthca/mthca_provider.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/infiniband/hw/mthca/mthca_provider.c
++++ b/drivers/infiniband/hw/mthca/mthca_provider.c
+@@ -695,6 +695,7 @@ static struct ib_cq *mthca_create_cq(str
+
+ if (context && ib_copy_to_udata(udata, &cq->cqn, sizeof (__u32))) {
+ mthca_free_cq(to_mdev(ibdev), cq);
++ err = -EFAULT;
+ goto err_free;
+ }
+
--- /dev/null
+From 9d194d1025f463392feafa26ff8c2d8247f71be1 Mon Sep 17 00:00:00 2001
+From: Yann Droneaud <ydroneaud@opteya.com>
+Date: Mon, 10 Mar 2014 23:06:27 +0100
+Subject: IB/nes: Return an error on ib_copy_from_udata() failure instead of NULL
+
+From: Yann Droneaud <ydroneaud@opteya.com>
+
+commit 9d194d1025f463392feafa26ff8c2d8247f71be1 upstream.
+
+In case of error while accessing to userspace memory, function
+nes_create_qp() returns NULL instead of an error code wrapped through
+ERR_PTR(). But NULL is not expected by ib_uverbs_create_qp(), as it
+check for error with IS_ERR().
+
+As page 0 is likely not mapped, it is going to trigger an Oops when
+the kernel will try to dereference NULL pointer to access to struct
+ib_qp's fields.
+
+In some rare cases, page 0 could be mapped by userspace, which could
+turn this bug to a vulnerability that could be exploited: the function
+pointers in struct ib_device will be under userspace total control.
+
+This was caught when using spatch (aka. coccinelle)
+to rewrite calls to ib_copy_{from,to}_udata().
+
+Link: https://www.gitorious.org/opteya/ib-hw-nes-create-qp-null
+Link: https://www.gitorious.org/opteya/coccib/source/75ebf2c1033c64c1d81df13e4ae44ee99c989eba:ib_copy_udata.cocci
+Link: http://marc.info/?i=cover.1394485254.git.ydroneaud@opteya.com
+Signed-off-by: Yann Droneaud <ydroneaud@opteya.com>
+Signed-off-by: Roland Dreier <roland@purestorage.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/hw/nes/nes_verbs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/infiniband/hw/nes/nes_verbs.c
++++ b/drivers/infiniband/hw/nes/nes_verbs.c
+@@ -1186,7 +1186,7 @@ static struct ib_qp *nes_create_qp(struc
+ nes_free_resource(nesadapter, nesadapter->allocated_qps, qp_num);
+ kfree(nesqp->allocated_buffer);
+ nes_debug(NES_DBG_QP, "ib_copy_from_udata() Failed \n");
+- return NULL;
++ return ERR_PTR(-EFAULT);
+ }
+ if (req.user_wqe_buffers) {
+ virt_wqs = 1;