From b92eac01c3c6ad5dab5c74d3bc32ac8e9bf4dae7 Mon Sep 17 00:00:00 2001 From: "Stanislaw W. Gruszka" Date: Tue, 28 Jun 2005 20:44:51 -0700 Subject: [PATCH] request_firmware(): avoid race conditions Avoid race occurs when some process have open file descriptor for class device attributes and already firmware allocated memory are freed. Don't allow negative loading timeout. Signed-off-by: Stanislaw W. Gruszka Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/base/firmware_class.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers/base') diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 97fe13f7f07..652281402c9 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -74,6 +74,8 @@ static ssize_t firmware_timeout_store(struct class *class, const char *buf, size_t count) { loading_timeout = simple_strtol(buf, NULL, 10); + if (loading_timeout < 0) + loading_timeout = 0; return count; } @@ -138,6 +140,10 @@ firmware_loading_store(struct class_device *class_dev, switch (loading) { case 1: down(&fw_lock); + if (!fw_priv->fw) { + up(&fw_lock); + break; + } vfree(fw_priv->fw->data); fw_priv->fw->data = NULL; fw_priv->fw->size = 0; @@ -178,7 +184,7 @@ firmware_data_read(struct kobject *kobj, down(&fw_lock); fw = fw_priv->fw; - if (test_bit(FW_STATUS_DONE, &fw_priv->status)) { + if (!fw || test_bit(FW_STATUS_DONE, &fw_priv->status)) { ret_count = -ENODEV; goto out; } @@ -238,9 +244,10 @@ firmware_data_write(struct kobject *kobj, if (!capable(CAP_SYS_RAWIO)) return -EPERM; + down(&fw_lock); fw = fw_priv->fw; - if (test_bit(FW_STATUS_DONE, &fw_priv->status)) { + if (!fw || test_bit(FW_STATUS_DONE, &fw_priv->status)) { retval = -ENODEV; goto out; } @@ -418,7 +425,7 @@ request_firmware(const struct firmware **firmware_p, const char *name, fw_priv = class_get_devdata(class_dev); - if (loading_timeout) { + if (loading_timeout > 0) { fw_priv->timeout.expires = jiffies + loading_timeout * HZ; add_timer(&fw_priv->timeout); } -- cgit v1.2.3