patch "firmware loader: fix pending_fw_head list corruption" added to driver-core tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    firmware loader: fix pending_fw_head list corruption

to my driver-core git tree which can be found at
    git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git
in the driver-core-next branch.

The patch will show up in the next release of the linux-next tree
(usually sometime within the next 24 hours during the week.)

The patch will also be merged in the next major kernel release
during the merge window.

If you have any questions about this process, please let me know.


>From 1eeeef153c02f5856ec109fa532eb5f31c39f85c Mon Sep 17 00:00:00 2001
From: Maxime Bizon <mbizon@xxxxxxxxxx>
Date: Thu, 29 Aug 2013 20:28:13 +0200
Subject: firmware loader: fix pending_fw_head list corruption

Got the following oops just before reboot:

Unable to handle kernel NULL pointer dereference at virtual address 00000000
[<8028d300>] (__list_del_entry+0x44/0xac)
[<802e3320>] (__fw_load_abort.part.13+0x1c/0x50)
[<802e337c>] (fw_shutdown_notify+0x28/0x50)
[<80034f80>] (notifier_call_chain.isra.1+0x5c/0x9c)
[<800350ec>] (__blocking_notifier_call_chain+0x44/0x58)
[<80035114>] (blocking_notifier_call_chain+0x14/0x18)
[<80035d64>] (kernel_restart_prepare+0x14/0x38)
[<80035d94>] (kernel_restart+0xc/0x50)

The following race condition triggers here:

  _request_firmware_load()
  device_create_file(...)
  kobject_uevent(...)
  (schedule)
                                       (resume)
                                       firmware_loading_store(1)
                                       firmware_loading_store(0)
                                       list_del_init(&buf->pending_list)
                                       (schedule)
  (resume)
  list_add(&buf->pending_list, &pending_fw_head);
  wait_for_completion(&buf->completion);

causing an oops later when walking pending_list after the firmware has
been released.

The proposed fix is to move the list_add() before sysfs attribute
creation.

Signed-off-by: Maxime Bizon <mbizon@xxxxxxxxxx>
Acked-by: Ming Lei <ming.lei@xxxxxxxxxxxxx>
Cc: stable <stable@xxxxxxxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
---
 drivers/base/firmware_class.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index e4107d5..10a4467 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -865,8 +865,15 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent,
 		goto err_del_dev;
 	}
 
+	mutex_lock(&fw_lock);
+	list_add(&buf->pending_list, &pending_fw_head);
+	mutex_unlock(&fw_lock);
+
 	retval = device_create_file(f_dev, &dev_attr_loading);
 	if (retval) {
+		mutex_lock(&fw_lock);
+		list_del_init(&buf->pending_list);
+		mutex_unlock(&fw_lock);
 		dev_err(f_dev, "%s: device_create_file failed\n", __func__);
 		goto err_del_bin_attr;
 	}
@@ -881,10 +888,6 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent,
 		kobject_uevent(&fw_priv->dev.kobj, KOBJ_ADD);
 	}
 
-	mutex_lock(&fw_lock);
-	list_add(&buf->pending_list, &pending_fw_head);
-	mutex_unlock(&fw_lock);
-
 	wait_for_completion(&buf->completion);
 
 	cancel_delayed_work_sync(&fw_priv->timeout_work);
-- 
1.8.4.6.g82e253f.dirty


--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]