From f631177369f62c4e3342f298c92a17250dca84ce Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 14 Jan 2013 10:52:45 -0800 Subject: [PATCH] 3.0-stable patches added patches: dm-ioctl-prevent-unsafe-change-to-dm_ioctl-data_size.patch rdma-nes-fix-for-crash-when-registering-zero-length-mr-for-cq.patch rdma-nes-fix-for-terminate-timer-crash.patch ring-buffer-fix-race-between-integrity-check-and-readers.patch --- ...-unsafe-change-to-dm_ioctl-data_size.patch | 62 ++++++++++++++ ...en-registering-zero-length-mr-for-cq.patch | 32 +++++++ ...ma-nes-fix-for-terminate-timer-crash.patch | 84 +++++++++++++++++++ ...-between-integrity-check-and-readers.patch | 46 ++++++++++ queue-3.0/series | 4 + 5 files changed, 228 insertions(+) create mode 100644 queue-3.0/dm-ioctl-prevent-unsafe-change-to-dm_ioctl-data_size.patch create mode 100644 queue-3.0/rdma-nes-fix-for-crash-when-registering-zero-length-mr-for-cq.patch create mode 100644 queue-3.0/rdma-nes-fix-for-terminate-timer-crash.patch create mode 100644 queue-3.0/ring-buffer-fix-race-between-integrity-check-and-readers.patch diff --git a/queue-3.0/dm-ioctl-prevent-unsafe-change-to-dm_ioctl-data_size.patch b/queue-3.0/dm-ioctl-prevent-unsafe-change-to-dm_ioctl-data_size.patch new file mode 100644 index 00000000000..55e8288c03d --- /dev/null +++ b/queue-3.0/dm-ioctl-prevent-unsafe-change-to-dm_ioctl-data_size.patch @@ -0,0 +1,62 @@ +From e910d7ebecd1aac43125944a8641b6cb1a0dfabe Mon Sep 17 00:00:00 2001 +From: Alasdair G Kergon +Date: Fri, 21 Dec 2012 20:23:30 +0000 +Subject: dm ioctl: prevent unsafe change to dm_ioctl data_size + +From: Alasdair G Kergon + +commit e910d7ebecd1aac43125944a8641b6cb1a0dfabe upstream. + +Abort dm ioctl processing if userspace changes the data_size parameter +after we validated it but before we finished copying the data buffer +from userspace. + +The dm ioctl parameters are processed in the following sequence: + 1. ctl_ioctl() calls copy_params(); + 2. copy_params() makes a first copy of the fixed-sized portion of the + userspace parameters into the local variable "tmp"; + 3. copy_params() then validates tmp.data_size and allocates a new + structure big enough to hold the complete data and copies the whole + userspace buffer there; + 4. ctl_ioctl() reads userspace data the second time and copies the whole + buffer into the pointer "param"; + 5. ctl_ioctl() reads param->data_size without any validation and stores it + in the variable "input_param_size"; + 6. "input_param_size" is further used as the authoritative size of the + kernel buffer. + +The problem is that userspace code could change the contents of user +memory between steps 2 and 4. In particular, the data_size parameter +can be changed to an invalid value after the kernel has validated it. +This lets userspace force the kernel to access invalid kernel memory. + +The fix is to ensure that the size has not changed at step 4. + +This patch shouldn't have a security impact because CAP_SYS_ADMIN is +required to run this code, but it should be fixed anyway. + +Reported-by: Mikulas Patocka +Signed-off-by: Alasdair G Kergon +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-ioctl.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/md/dm-ioctl.c ++++ b/drivers/md/dm-ioctl.c +@@ -1524,6 +1524,14 @@ static int copy_params(struct dm_ioctl _ + if (copy_from_user(dmi, user, tmp.data_size)) + goto bad; + ++ /* ++ * Abort if something changed the ioctl data while it was being copied. ++ */ ++ if (dmi->data_size != tmp.data_size) { ++ DMERR("rejecting ioctl: data size modified while processing parameters"); ++ goto bad; ++ } ++ + /* Wipe the user buffer so we do not return it to userspace */ + if (secure_data && clear_user(user, tmp.data_size)) + goto bad; diff --git a/queue-3.0/rdma-nes-fix-for-crash-when-registering-zero-length-mr-for-cq.patch b/queue-3.0/rdma-nes-fix-for-crash-when-registering-zero-length-mr-for-cq.patch new file mode 100644 index 00000000000..20b51b98f57 --- /dev/null +++ b/queue-3.0/rdma-nes-fix-for-crash-when-registering-zero-length-mr-for-cq.patch @@ -0,0 +1,32 @@ +From 7d9c199a55200c9b9fcad08e150470d02fb385be Mon Sep 17 00:00:00 2001 +From: Tatyana Nikolova +Date: Thu, 6 Dec 2012 20:05:02 +0000 +Subject: RDMA/nes: Fix for crash when registering zero length MR for CQ + +From: Tatyana Nikolova + +commit 7d9c199a55200c9b9fcad08e150470d02fb385be upstream. + +Signed-off-by: Tatyana Nikolova +Signed-off-by: Roland Dreier +Signed-off-by: CAI Qian +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/nes/nes_verbs.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/infiniband/hw/nes/nes_verbs.c ++++ b/drivers/infiniband/hw/nes/nes_verbs.c +@@ -2568,6 +2568,11 @@ static struct ib_mr *nes_reg_user_mr(str + return ibmr; + case IWNES_MEMREG_TYPE_QP: + case IWNES_MEMREG_TYPE_CQ: ++ if (!region->length) { ++ nes_debug(NES_DBG_MR, "Unable to register zero length region for CQ\n"); ++ ib_umem_release(region); ++ return ERR_PTR(-EINVAL); ++ } + nespbl = kzalloc(sizeof(*nespbl), GFP_KERNEL); + if (!nespbl) { + nes_debug(NES_DBG_MR, "Unable to allocate PBL\n"); diff --git a/queue-3.0/rdma-nes-fix-for-terminate-timer-crash.patch b/queue-3.0/rdma-nes-fix-for-terminate-timer-crash.patch new file mode 100644 index 00000000000..b9009243eee --- /dev/null +++ b/queue-3.0/rdma-nes-fix-for-terminate-timer-crash.patch @@ -0,0 +1,84 @@ +From 7bfcfa51c35cdd2d37e0d70fc11790642dd11fb3 Mon Sep 17 00:00:00 2001 +From: Tatyana Nikolova +Date: Thu, 6 Dec 2012 19:58:27 +0000 +Subject: RDMA/nes: Fix for terminate timer crash + +From: Tatyana Nikolova + +commit 7bfcfa51c35cdd2d37e0d70fc11790642dd11fb3 upstream. + +The terminate timer needs to be initialized just once. + +Signed-off-by: Tatyana Nikolova +Signed-off-by: Roland Dreier +Signed-off-by: CAI Qian +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/nes/nes.h | 1 + + drivers/infiniband/hw/nes/nes_hw.c | 9 ++------- + drivers/infiniband/hw/nes/nes_verbs.c | 4 +++- + 3 files changed, 6 insertions(+), 8 deletions(-) + +--- a/drivers/infiniband/hw/nes/nes.h ++++ b/drivers/infiniband/hw/nes/nes.h +@@ -511,6 +511,7 @@ void nes_iwarp_ce_handler(struct nes_dev + int nes_destroy_cqp(struct nes_device *); + int nes_nic_cm_xmit(struct sk_buff *, struct net_device *); + void nes_recheck_link_status(struct work_struct *work); ++void nes_terminate_timeout(unsigned long context); + + /* nes_nic.c */ + struct net_device *nes_netdev_init(struct nes_device *, void __iomem *); +--- a/drivers/infiniband/hw/nes/nes_hw.c ++++ b/drivers/infiniband/hw/nes/nes_hw.c +@@ -75,7 +75,6 @@ static void nes_process_iwarp_aeqe(struc + static void process_critical_error(struct nes_device *nesdev); + static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number); + static unsigned int nes_reset_adapter_ne020(struct nes_device *nesdev, u8 *OneG_Mode); +-static void nes_terminate_timeout(unsigned long context); + static void nes_terminate_start_timer(struct nes_qp *nesqp); + + #ifdef CONFIG_INFINIBAND_NES_DEBUG +@@ -3496,7 +3495,7 @@ static void nes_terminate_received(struc + } + + /* Timeout routine in case terminate fails to complete */ +-static void nes_terminate_timeout(unsigned long context) ++void nes_terminate_timeout(unsigned long context) + { + struct nes_qp *nesqp = (struct nes_qp *)(unsigned long)context; + +@@ -3506,11 +3505,7 @@ static void nes_terminate_timeout(unsign + /* Set a timer in case hw cannot complete the terminate sequence */ + static void nes_terminate_start_timer(struct nes_qp *nesqp) + { +- init_timer(&nesqp->terminate_timer); +- nesqp->terminate_timer.function = nes_terminate_timeout; +- nesqp->terminate_timer.expires = jiffies + HZ; +- nesqp->terminate_timer.data = (unsigned long)nesqp; +- add_timer(&nesqp->terminate_timer); ++ mod_timer(&nesqp->terminate_timer, (jiffies + HZ)); + } + + /** +--- a/drivers/infiniband/hw/nes/nes_verbs.c ++++ b/drivers/infiniband/hw/nes/nes_verbs.c +@@ -1414,6 +1414,9 @@ static struct ib_qp *nes_create_qp(struc + } + + nesqp->sig_all = (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR); ++ init_timer(&nesqp->terminate_timer); ++ nesqp->terminate_timer.function = nes_terminate_timeout; ++ nesqp->terminate_timer.data = (unsigned long)nesqp; + + /* update the QP table */ + nesdev->nesadapter->qp_table[nesqp->hwqp.qp_id-NES_FIRST_QPN] = nesqp; +@@ -1423,7 +1426,6 @@ static struct ib_qp *nes_create_qp(struc + return &nesqp->ibqp; + } + +- + /** + * nes_clean_cq + */ diff --git a/queue-3.0/ring-buffer-fix-race-between-integrity-check-and-readers.patch b/queue-3.0/ring-buffer-fix-race-between-integrity-check-and-readers.patch new file mode 100644 index 00000000000..9c831fbd925 --- /dev/null +++ b/queue-3.0/ring-buffer-fix-race-between-integrity-check-and-readers.patch @@ -0,0 +1,46 @@ +From 9366c1ba13fbc41bdb57702e75ca4382f209c82f Mon Sep 17 00:00:00 2001 +From: Steven Rostedt +Date: Thu, 29 Nov 2012 22:31:16 -0500 +Subject: ring-buffer: Fix race between integrity check and readers + +From: Steven Rostedt + +commit 9366c1ba13fbc41bdb57702e75ca4382f209c82f upstream. + +The function rb_check_pages() was added to make sure the ring buffer's +pages were sane. This check is done when the ring buffer size is modified +as well as when the iterator is released (closing the "trace" file), +as that was considered a non fast path and a good place to do a sanity +check. + +The problem is that the check does not have any locks around it. +If one process were to read the trace file, and another were to read +the raw binary file, the check could happen while the reader is reading +the file. + +The issues with this is that the check requires to clear the HEAD page +before doing the full check and it restores it afterward. But readers +require the HEAD page to exist before it can read the buffer, otherwise +it gives a nasty warning and disables the buffer. + +By adding the reader lock around the check, this keeps the race from +happening. + +Signed-off-by: Steven Rostedt +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/trace/ring_buffer.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/kernel/trace/ring_buffer.c ++++ b/kernel/trace/ring_buffer.c +@@ -2926,6 +2926,8 @@ rb_get_reader_page(struct ring_buffer_pe + * Splice the empty reader page into the list around the head. + */ + reader = rb_set_head_page(cpu_buffer); ++ if (!reader) ++ goto out; + cpu_buffer->reader_page->list.next = rb_list_head(reader->list.next); + cpu_buffer->reader_page->list.prev = reader->list.prev; + diff --git a/queue-3.0/series b/queue-3.0/series index e3b75d00e5a..80fac13cdd2 100644 --- a/queue-3.0/series +++ b/queue-3.0/series @@ -19,3 +19,7 @@ sunrpc-ensure-we-release-the-socket-write-lock-if-the-rpc_task-exits-early.patch jffs2-hold-erase_completion_lock-on-exit.patch i2400m-add-intel-6150-device-ids.patch drm-i915-make-the-panel-fitter-work-on-pipes-b-and-c-on-ivb.patch +rdma-nes-fix-for-crash-when-registering-zero-length-mr-for-cq.patch +rdma-nes-fix-for-terminate-timer-crash.patch +ring-buffer-fix-race-between-integrity-check-and-readers.patch +dm-ioctl-prevent-unsafe-change-to-dm_ioctl-data_size.patch -- 2.47.3