From: Greg Kroah-Hartman Date: Sun, 10 Apr 2016 18:09:04 +0000 (-0700) Subject: 3.14-stable patches X-Git-Tag: v4.5.1~14 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=88e8fe77ee9cf9dfb1eecb3fd095129d75585782;p=thirdparty%2Fkernel%2Fstable-queue.git 3.14-stable patches added patches: input-ati_remote2-fix-crashes-on-detecting-device-with-invalid-descriptor.patch input-ims-pcu-sanity-check-against-missing-interfaces.patch mtd-onenand-fix-deadlock-in-onenand_block_markbad.patch ocfs2-dlm-fix-bug-in-dlm_move_lockres_to_recovery_list.patch ocfs2-dlm-fix-race-between-convert-and-recovery.patch --- diff --git a/queue-3.14/input-ati_remote2-fix-crashes-on-detecting-device-with-invalid-descriptor.patch b/queue-3.14/input-ati_remote2-fix-crashes-on-detecting-device-with-invalid-descriptor.patch new file mode 100644 index 00000000000..425d5320f51 --- /dev/null +++ b/queue-3.14/input-ati_remote2-fix-crashes-on-detecting-device-with-invalid-descriptor.patch @@ -0,0 +1,108 @@ +From 950336ba3e4a1ffd2ca60d29f6ef386dd2c7351d Mon Sep 17 00:00:00 2001 +From: Vladis Dronov +Date: Wed, 23 Mar 2016 11:53:46 -0700 +Subject: Input: ati_remote2 - fix crashes on detecting device with invalid descriptor + +From: Vladis Dronov + +commit 950336ba3e4a1ffd2ca60d29f6ef386dd2c7351d upstream. + +The ati_remote2 driver expects at least two interfaces with one +endpoint each. If given malicious descriptor that specify one +interface or no endpoints, it will crash in the probe function. +Ensure there is at least two interfaces and one endpoint for each +interface before using it. + +The full disclosure: http://seclists.org/bugtraq/2016/Mar/90 + +Reported-by: Ralf Spenneberg +Signed-off-by: Vladis Dronov +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/input/misc/ati_remote2.c | 36 ++++++++++++++++++++++++++++++------ + 1 file changed, 30 insertions(+), 6 deletions(-) + +--- a/drivers/input/misc/ati_remote2.c ++++ b/drivers/input/misc/ati_remote2.c +@@ -817,26 +817,49 @@ static int ati_remote2_probe(struct usb_ + + ar2->udev = udev; + ++ /* Sanity check, first interface must have an endpoint */ ++ if (alt->desc.bNumEndpoints < 1 || !alt->endpoint) { ++ dev_err(&interface->dev, ++ "%s(): interface 0 must have an endpoint\n", __func__); ++ r = -ENODEV; ++ goto fail1; ++ } + ar2->intf[0] = interface; + ar2->ep[0] = &alt->endpoint[0].desc; + ++ /* Sanity check, the device must have two interfaces */ + ar2->intf[1] = usb_ifnum_to_if(udev, 1); ++ if ((udev->actconfig->desc.bNumInterfaces < 2) || !ar2->intf[1]) { ++ dev_err(&interface->dev, "%s(): need 2 interfaces, found %d\n", ++ __func__, udev->actconfig->desc.bNumInterfaces); ++ r = -ENODEV; ++ goto fail1; ++ } ++ + r = usb_driver_claim_interface(&ati_remote2_driver, ar2->intf[1], ar2); + if (r) + goto fail1; ++ ++ /* Sanity check, second interface must have an endpoint */ + alt = ar2->intf[1]->cur_altsetting; ++ if (alt->desc.bNumEndpoints < 1 || !alt->endpoint) { ++ dev_err(&interface->dev, ++ "%s(): interface 1 must have an endpoint\n", __func__); ++ r = -ENODEV; ++ goto fail2; ++ } + ar2->ep[1] = &alt->endpoint[0].desc; + + r = ati_remote2_urb_init(ar2); + if (r) +- goto fail2; ++ goto fail3; + + ar2->channel_mask = channel_mask; + ar2->mode_mask = mode_mask; + + r = ati_remote2_setup(ar2, ar2->channel_mask); + if (r) +- goto fail2; ++ goto fail3; + + usb_make_path(udev, ar2->phys, sizeof(ar2->phys)); + strlcat(ar2->phys, "/input0", sizeof(ar2->phys)); +@@ -845,11 +868,11 @@ static int ati_remote2_probe(struct usb_ + + r = sysfs_create_group(&udev->dev.kobj, &ati_remote2_attr_group); + if (r) +- goto fail2; ++ goto fail3; + + r = ati_remote2_input_init(ar2); + if (r) +- goto fail3; ++ goto fail4; + + usb_set_intfdata(interface, ar2); + +@@ -857,10 +880,11 @@ static int ati_remote2_probe(struct usb_ + + return 0; + +- fail3: ++ fail4: + sysfs_remove_group(&udev->dev.kobj, &ati_remote2_attr_group); +- fail2: ++ fail3: + ati_remote2_urb_cleanup(ar2); ++ fail2: + usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]); + fail1: + kfree(ar2); diff --git a/queue-3.14/input-ims-pcu-sanity-check-against-missing-interfaces.patch b/queue-3.14/input-ims-pcu-sanity-check-against-missing-interfaces.patch new file mode 100644 index 00000000000..c2a35aab46c --- /dev/null +++ b/queue-3.14/input-ims-pcu-sanity-check-against-missing-interfaces.patch @@ -0,0 +1,40 @@ +From a0ad220c96692eda76b2e3fd7279f3dcd1d8a8ff Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Thu, 17 Mar 2016 14:00:17 -0700 +Subject: Input: ims-pcu - sanity check against missing interfaces + +From: Oliver Neukum + +commit a0ad220c96692eda76b2e3fd7279f3dcd1d8a8ff upstream. + +A malicious device missing interface can make the driver oops. +Add sanity checking. + +Signed-off-by: Oliver Neukum +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/input/misc/ims-pcu.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/input/misc/ims-pcu.c ++++ b/drivers/input/misc/ims-pcu.c +@@ -1433,6 +1433,8 @@ static int ims_pcu_parse_cdc_data(struct + + pcu->ctrl_intf = usb_ifnum_to_if(pcu->udev, + union_desc->bMasterInterface0); ++ if (!pcu->ctrl_intf) ++ return -EINVAL; + + alt = pcu->ctrl_intf->cur_altsetting; + pcu->ep_ctrl = &alt->endpoint[0].desc; +@@ -1440,6 +1442,8 @@ static int ims_pcu_parse_cdc_data(struct + + pcu->data_intf = usb_ifnum_to_if(pcu->udev, + union_desc->bSlaveInterface0); ++ if (!pcu->data_intf) ++ return -EINVAL; + + alt = pcu->data_intf->cur_altsetting; + if (alt->desc.bNumEndpoints != 2) { diff --git a/queue-3.14/mtd-onenand-fix-deadlock-in-onenand_block_markbad.patch b/queue-3.14/mtd-onenand-fix-deadlock-in-onenand_block_markbad.patch new file mode 100644 index 00000000000..e7b422893da --- /dev/null +++ b/queue-3.14/mtd-onenand-fix-deadlock-in-onenand_block_markbad.patch @@ -0,0 +1,43 @@ +From 5e64c29e98bfbba1b527b0a164f9493f3db9e8cb Mon Sep 17 00:00:00 2001 +From: Aaro Koskinen +Date: Sat, 20 Feb 2016 22:27:48 +0200 +Subject: mtd: onenand: fix deadlock in onenand_block_markbad + +From: Aaro Koskinen + +commit 5e64c29e98bfbba1b527b0a164f9493f3db9e8cb upstream. + +Commit 5942ddbc500d ("mtd: introduce mtd_block_markbad interface") +incorrectly changed onenand_block_markbad() to call mtd_block_markbad +instead of onenand_chip's block_markbad function. As a result the function +will now recurse and deadlock. Fix by reverting the change. + +Fixes: 5942ddbc500d ("mtd: introduce mtd_block_markbad interface") +Signed-off-by: Aaro Koskinen +Acked-by: Artem Bityutskiy +Signed-off-by: Brian Norris +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mtd/onenand/onenand_base.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/mtd/onenand/onenand_base.c ++++ b/drivers/mtd/onenand/onenand_base.c +@@ -2606,6 +2606,7 @@ static int onenand_default_block_markbad + */ + static int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs) + { ++ struct onenand_chip *this = mtd->priv; + int ret; + + ret = onenand_block_isbad(mtd, ofs); +@@ -2617,7 +2618,7 @@ static int onenand_block_markbad(struct + } + + onenand_get_device(mtd, FL_WRITING); +- ret = mtd_block_markbad(mtd, ofs); ++ ret = this->block_markbad(mtd, ofs); + onenand_release_device(mtd); + return ret; + } diff --git a/queue-3.14/ocfs2-dlm-fix-bug-in-dlm_move_lockres_to_recovery_list.patch b/queue-3.14/ocfs2-dlm-fix-bug-in-dlm_move_lockres_to_recovery_list.patch new file mode 100644 index 00000000000..bfb0e496536 --- /dev/null +++ b/queue-3.14/ocfs2-dlm-fix-bug-in-dlm_move_lockres_to_recovery_list.patch @@ -0,0 +1,66 @@ +From be12b299a83fc807bbaccd2bcb8ec50cbb0cb55c Mon Sep 17 00:00:00 2001 +From: Joseph Qi +Date: Fri, 25 Mar 2016 14:21:29 -0700 +Subject: ocfs2/dlm: fix BUG in dlm_move_lockres_to_recovery_list + +From: Joseph Qi + +commit be12b299a83fc807bbaccd2bcb8ec50cbb0cb55c upstream. + +When master handles convert request, it queues ast first and then +returns status. This may happen that the ast is sent before the request +status because the above two messages are sent by two threads. And +right after the ast is sent, if master down, it may trigger BUG in +dlm_move_lockres_to_recovery_list in the requested node because ast +handler moves it to grant list without clear lock->convert_pending. So +remove BUG_ON statement and check if the ast is processed in +dlmconvert_remote. + +Signed-off-by: Joseph Qi +Reported-by: Yiwen Jiang +Cc: Junxiao Bi +Cc: Mark Fasheh +Cc: Joel Becker +Cc: Tariq Saeed +Cc: Junxiao Bi +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ocfs2/dlm/dlmconvert.c | 13 +++++++++++++ + fs/ocfs2/dlm/dlmrecovery.c | 1 - + 2 files changed, 13 insertions(+), 1 deletion(-) + +--- a/fs/ocfs2/dlm/dlmconvert.c ++++ b/fs/ocfs2/dlm/dlmconvert.c +@@ -288,6 +288,19 @@ enum dlm_status dlmconvert_remote(struct + status = DLM_DENIED; + goto bail; + } ++ ++ if (lock->ml.type == type && lock->ml.convert_type == LKM_IVMODE) { ++ mlog(0, "last convert request returned DLM_RECOVERING, but " ++ "owner has already queued and sent ast to me. res %.*s, " ++ "(cookie=%u:%llu, type=%d, conv=%d)\n", ++ res->lockname.len, res->lockname.name, ++ dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)), ++ dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)), ++ lock->ml.type, lock->ml.convert_type); ++ status = DLM_NORMAL; ++ goto bail; ++ } ++ + res->state |= DLM_LOCK_RES_IN_PROGRESS; + /* move lock to local convert queue */ + /* do not alter lock refcount. switching lists. */ +--- a/fs/ocfs2/dlm/dlmrecovery.c ++++ b/fs/ocfs2/dlm/dlmrecovery.c +@@ -2040,7 +2040,6 @@ void dlm_move_lockres_to_recovery_list(s + dlm_lock_get(lock); + if (lock->convert_pending) { + /* move converting lock back to granted */ +- BUG_ON(i != DLM_CONVERTING_LIST); + mlog(0, "node died with convert pending " + "on %.*s. move back to granted list.\n", + res->lockname.len, res->lockname.name); diff --git a/queue-3.14/ocfs2-dlm-fix-race-between-convert-and-recovery.patch b/queue-3.14/ocfs2-dlm-fix-race-between-convert-and-recovery.patch new file mode 100644 index 00000000000..e36670404cf --- /dev/null +++ b/queue-3.14/ocfs2-dlm-fix-race-between-convert-and-recovery.patch @@ -0,0 +1,87 @@ +From ac7cf246dfdbec3d8fed296c7bf30e16f5099dac Mon Sep 17 00:00:00 2001 +From: Joseph Qi +Date: Fri, 25 Mar 2016 14:21:26 -0700 +Subject: ocfs2/dlm: fix race between convert and recovery + +From: Joseph Qi + +commit ac7cf246dfdbec3d8fed296c7bf30e16f5099dac upstream. + +There is a race window between dlmconvert_remote and +dlm_move_lockres_to_recovery_list, which will cause a lock with +OCFS2_LOCK_BUSY in grant list, thus system hangs. + +dlmconvert_remote +{ + spin_lock(&res->spinlock); + list_move_tail(&lock->list, &res->converting); + lock->convert_pending = 1; + spin_unlock(&res->spinlock); + + status = dlm_send_remote_convert_request(); + >>>>>> race window, master has queued ast and return DLM_NORMAL, + and then down before sending ast. + this node detects master down and calls + dlm_move_lockres_to_recovery_list, which will revert the + lock to grant list. + Then OCFS2_LOCK_BUSY won't be cleared as new master won't + send ast any more because it thinks already be authorized. + + spin_lock(&res->spinlock); + lock->convert_pending = 0; + if (status != DLM_NORMAL) + dlm_revert_pending_convert(res, lock); + spin_unlock(&res->spinlock); +} + +In this case, check if res->state has DLM_LOCK_RES_RECOVERING bit set +(res is still in recovering) or res master changed (new master has +finished recovery), reset the status to DLM_RECOVERING, then it will +retry convert. + +Signed-off-by: Joseph Qi +Reported-by: Yiwen Jiang +Reviewed-by: Junxiao Bi +Cc: Mark Fasheh +Cc: Joel Becker +Cc: Tariq Saeed +Cc: Junxiao Bi +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ocfs2/dlm/dlmconvert.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +--- a/fs/ocfs2/dlm/dlmconvert.c ++++ b/fs/ocfs2/dlm/dlmconvert.c +@@ -262,6 +262,7 @@ enum dlm_status dlmconvert_remote(struct + struct dlm_lock *lock, int flags, int type) + { + enum dlm_status status; ++ u8 old_owner = res->owner; + + mlog(0, "type=%d, convert_type=%d, busy=%d\n", lock->ml.type, + lock->ml.convert_type, res->state & DLM_LOCK_RES_IN_PROGRESS); +@@ -316,11 +317,19 @@ enum dlm_status dlmconvert_remote(struct + spin_lock(&res->spinlock); + res->state &= ~DLM_LOCK_RES_IN_PROGRESS; + lock->convert_pending = 0; +- /* if it failed, move it back to granted queue */ ++ /* if it failed, move it back to granted queue. ++ * if master returns DLM_NORMAL and then down before sending ast, ++ * it may have already been moved to granted queue, reset to ++ * DLM_RECOVERING and retry convert */ + if (status != DLM_NORMAL) { + if (status != DLM_NOTQUEUED) + dlm_error(status); + dlm_revert_pending_convert(res, lock); ++ } else if ((res->state & DLM_LOCK_RES_RECOVERING) || ++ (old_owner != res->owner)) { ++ mlog(0, "res %.*s is in recovering or has been recovered.\n", ++ res->lockname.len, res->lockname.name); ++ status = DLM_RECOVERING; + } + bail: + spin_unlock(&res->spinlock); diff --git a/queue-3.14/series b/queue-3.14/series index e6b2f50ce94..aa66e848054 100644 --- a/queue-3.14/series +++ b/queue-3.14/series @@ -66,3 +66,8 @@ bitops-do-not-default-to-__clear_bit-for-__clear_bit_unlock.patch scripts-coccinelle-modernize.patch kbuild-mkspec-fix-grub2-installkernel-issue.patch target-fix-target_release_cmd_kref-shutdown-comp-leak.patch +input-ims-pcu-sanity-check-against-missing-interfaces.patch +input-ati_remote2-fix-crashes-on-detecting-device-with-invalid-descriptor.patch +ocfs2-dlm-fix-race-between-convert-and-recovery.patch +ocfs2-dlm-fix-bug-in-dlm_move_lockres_to_recovery_list.patch +mtd-onenand-fix-deadlock-in-onenand_block_markbad.patch