lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date:	Tue, 17 Nov 2015 15:55:37 -0800
From:	Ashutosh Dixit <ashutosh.dixit@...el.com>
To:	Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
	linux-kernel@...r.kernel.org
Cc:	Arnd Bergmann <arnd@...db.de>,
	Ashutosh Dixit <ashutosh.dixit@...el.com>,
	Sudeep Dutt <sudeep.dutt@...el.com>
Subject: [PATCH] misc: mic: Fix crash when MIC reset is invoked in RESET_FAILED state

This patch fixes the following crash seen when MIC reset is invoked in
RESET_FAILED state due to device_del being called a second time on an
already deleted device:

[<ffffffff813b2295>] device_del+0x45/0x1d0
[<ffffffff813b243e>] device_unregister+0x1e/0x60
[<ffffffffa040f1c2>] scif_unregister_device+0x12/0x20 [scif_bus]
[<ffffffffa042f75a>] cosm_stop+0xaa/0xe0 [mic_cosm]
[<ffffffffa042f844>] cosm_reset_trigger_work+0x14/0x20 [mic_cosm]

The fix consists in realizing that because cosm_reset changes the
state to MIC_RESETTING, cosm_stop needs the previous state, before it
changed to MIC_RESETTING, to decide whether a hw_ops->stop had
previously been issued. This is now provided in a new cosm_device
member cdev->prev_state.

Reviewed-by: Sudeep Dutt <sudeep.dutt@...el.com>
Signed-off-by: Ashutosh Dixit <ashutosh.dixit@...el.com>
---
 drivers/misc/mic/bus/cosm_bus.h   |  2 ++
 drivers/misc/mic/cosm/cosm_main.c | 13 +++++++++----
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/misc/mic/bus/cosm_bus.h b/drivers/misc/mic/bus/cosm_bus.h
index f7c57f2..8b63418 100644
--- a/drivers/misc/mic/bus/cosm_bus.h
+++ b/drivers/misc/mic/bus/cosm_bus.h
@@ -30,6 +30,7 @@
  * @attr_group: Pointer to list of sysfs attribute groups.
  * @sdev: Device for sysfs entries.
  * @state: MIC state.
+ * @prev_state: MIC state previous to MIC_RESETTING
  * @shutdown_status: MIC status reported by card for shutdown/crashes.
  * @shutdown_status_int: Internal shutdown status maintained by the driver
  * @cosm_mutex: Mutex for synchronizing access to data structures.
@@ -55,6 +56,7 @@ struct cosm_device {
 	const struct attribute_group **attr_group;
 	struct device *sdev;
 	u8 state;
+	u8 prev_state;
 	u8 shutdown_status;
 	u8 shutdown_status_int;
 	struct mutex cosm_mutex;
diff --git a/drivers/misc/mic/cosm/cosm_main.c b/drivers/misc/mic/cosm/cosm_main.c
index 4b4b356..7005cb1 100644
--- a/drivers/misc/mic/cosm/cosm_main.c
+++ b/drivers/misc/mic/cosm/cosm_main.c
@@ -153,8 +153,10 @@ void cosm_stop(struct cosm_device *cdev, bool force)
 		 * stop(..) calls device_unregister and will crash the system if
 		 * called multiple times.
 		 */
-		bool call_hw_ops = cdev->state != MIC_RESET_FAILED &&
-					cdev->state != MIC_READY;
+		u8 state = cdev->state == MIC_RESETTING ?
+					cdev->prev_state : cdev->state;
+		bool call_hw_ops = state != MIC_RESET_FAILED &&
+					state != MIC_READY;
 
 		if (cdev->state != MIC_RESETTING)
 			cosm_set_state(cdev, MIC_RESETTING);
@@ -195,8 +197,11 @@ int cosm_reset(struct cosm_device *cdev)
 
 	mutex_lock(&cdev->cosm_mutex);
 	if (cdev->state != MIC_READY) {
-		cosm_set_state(cdev, MIC_RESETTING);
-		schedule_work(&cdev->reset_trigger_work);
+		if (cdev->state != MIC_RESETTING) {
+			cdev->prev_state = cdev->state;
+			cosm_set_state(cdev, MIC_RESETTING);
+			schedule_work(&cdev->reset_trigger_work);
+		}
 	} else {
 		dev_err(&cdev->dev, "%s %d MIC is READY\n", __func__, __LINE__);
 		rc = -EINVAL;
-- 
2.0.0.rc3.2.g998f840

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ