From 26fade1f5b2e0acefaed054efeea4dd6bc100906 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 14 Aug 2016 17:58:05 +0200 Subject: [PATCH] 3.14-stable patches added patches: --- ...-restrict-use-of-the-write-interface.patch | 156 ++++++++++++++++-- 1 file changed, 139 insertions(+), 17 deletions(-) diff --git a/queue-3.14/ib-security-restrict-use-of-the-write-interface.patch b/queue-3.14/ib-security-restrict-use-of-the-write-interface.patch index 3656e2d7a7d..3c451058226 100644 --- a/queue-3.14/ib-security-restrict-use-of-the-write-interface.patch +++ b/queue-3.14/ib-security-restrict-use-of-the-write-interface.patch @@ -1,34 +1,105 @@ -From ben@decadent.org.uk Sun Aug 14 17:34:33 2016 -From: Ben Hutchings -Date: Tue, 31 May 2016 03:40:50 +0100 +From e6bd18f57aad1a2d1ef40e646d03ed0f2515c9e3 Mon Sep 17 00:00:00 2001 +From: Jason Gunthorpe +Date: Sun, 10 Apr 2016 19:13:13 -0600 Subject: IB/security: Restrict use of the write() interface -To: stable@vger.kernel.org -Cc: Jason Gunthorpe , Doug Ledford , linux-rdma@vger.kernel.org -Message-ID: <20160531024050.GL7555@decadent.org.uk> -Content-Disposition: inline -From: Ben Hutchings +From: Jason Gunthorpe -Commit e6bd18f57aad ("IB/security: Restrict use of the write() -interface") fixed a security problem with various write() -implementations in the Infiniband subsystem. In older kernel versions -the ipath_write() function has the same problem and needs the same -restriction. (The ipath driver has been completely removed upstream.) +commit e6bd18f57aad1a2d1ef40e646d03ed0f2515c9e3 upstream. -Signed-off-by: Ben Hutchings -Signed-off-by: Greg Kroah-Hartman +The drivers/infiniband stack uses write() as a replacement for +bi-directional ioctl(). This is not safe. There are ways to +trigger write calls that result in the return structure that +is normally written to user space being shunted off to user +specified kernel memory instead. + +For the immediate repair, detect and deny suspicious accesses to +the write API. + +For long term, update the user space libraries and the kernel API +to something that doesn't present the same security vulnerabilities +(likely a structured ioctl() interface). +The impacted uAPI interfaces are generally only available if +hardware from drivers/infiniband is installed in the system. + +Reported-by: Jann Horn +Signed-off-by: Linus Torvalds +Signed-off-by: Jason Gunthorpe +[ Expanded check to all known write() entry points ] +Signed-off-by: Doug Ledford +[ Expanded to include removed ipath driver, and dropped non-existent + hfi1 driver ] +Signed-off-by: Greg Kroah-Hartman --- + drivers/infiniband/core/ucm.c | 4 ++++ + drivers/infiniband/core/ucma.c | 3 +++ + drivers/infiniband/core/uverbs_main.c | 5 +++++ drivers/infiniband/hw/ipath/ipath_file_ops.c | 5 +++++ - 1 file changed, 5 insertions(+) + drivers/infiniband/hw/qib/qib_file_ops.c | 5 +++++ + include/rdma/ib.h | 16 ++++++++++++++++ + 6 files changed, 38 insertions(+) +--- a/drivers/infiniband/core/ucm.c ++++ b/drivers/infiniband/core/ucm.c +@@ -48,6 +48,7 @@ + + #include + ++#include + #include + #include + #include +@@ -1104,6 +1105,9 @@ static ssize_t ib_ucm_write(struct file + struct ib_ucm_cmd_hdr hdr; + ssize_t result; + ++ if (WARN_ON_ONCE(!ib_safe_file_access(filp))) ++ return -EACCES; ++ + if (len < sizeof(hdr)) + return -EINVAL; + +--- a/drivers/infiniband/core/ucma.c ++++ b/drivers/infiniband/core/ucma.c +@@ -1487,6 +1487,9 @@ static ssize_t ucma_write(struct file *f + struct rdma_ucm_cmd_hdr hdr; + ssize_t ret; + ++ if (WARN_ON_ONCE(!ib_safe_file_access(filp))) ++ return -EACCES; ++ + if (len < sizeof(hdr)) + return -EINVAL; + +--- a/drivers/infiniband/core/uverbs_main.c ++++ b/drivers/infiniband/core/uverbs_main.c +@@ -48,6 +48,8 @@ + + #include + ++#include ++ + #include "uverbs.h" + + MODULE_AUTHOR("Roland Dreier"); +@@ -605,6 +607,9 @@ static ssize_t ib_uverbs_write(struct fi + struct ib_uverbs_cmd_hdr hdr; + __u32 flags; + ++ if (WARN_ON_ONCE(!ib_safe_file_access(filp))) ++ return -EACCES; ++ + if (count < sizeof hdr) + return -EINVAL; + --- a/drivers/infiniband/hw/ipath/ipath_file_ops.c +++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c @@ -45,6 +45,8 @@ #include #include -+#include ++#include "rdma/ib.h" + #include "ipath_kernel.h" #include "ipath_common.h" @@ -37,9 +108,60 @@ Signed-off-by: Greg Kroah-Hartman ssize_t ret = 0; void *dest; ++ if (WARN_ON_ONCE(!ib_safe_file_access(filp))) ++ return -EACCES; ++ + if (count < sizeof(cmd.type)) { + ret = -EINVAL; + goto bail; +--- a/drivers/infiniband/hw/qib/qib_file_ops.c ++++ b/drivers/infiniband/hw/qib/qib_file_ops.c +@@ -45,6 +45,8 @@ + #include + #include + ++#include ++ + #include "qib.h" + #include "qib_common.h" + #include "qib_user_sdma.h" +@@ -2058,6 +2060,9 @@ static ssize_t qib_write(struct file *fp + ssize_t ret = 0; + void *dest; + + if (WARN_ON_ONCE(!ib_safe_file_access(fp))) + return -EACCES; + if (count < sizeof(cmd.type)) { ret = -EINVAL; goto bail; +--- a/include/rdma/ib.h ++++ b/include/rdma/ib.h +@@ -34,6 +34,7 @@ + #define _RDMA_IB_H + + #include ++#include + + struct ib_addr { + union { +@@ -86,4 +87,19 @@ struct sockaddr_ib { + __u64 sib_scope_id; + }; + ++/* ++ * The IB interfaces that use write() as bi-directional ioctl() are ++ * fundamentally unsafe, since there are lots of ways to trigger "write()" ++ * calls from various contexts with elevated privileges. That includes the ++ * traditional suid executable error message writes, but also various kernel ++ * interfaces that can write to file descriptors. ++ * ++ * This function provides protection for the legacy API by restricting the ++ * calling context. ++ */ ++static inline bool ib_safe_file_access(struct file *filp) ++{ ++ return filp->f_cred == current_cred() && segment_eq(get_fs(), USER_DS); ++} ++ + #endif /* _RDMA_IB_H */ -- 2.47.3