[PATCH, RFC] ACPI: WMI: Add locking to sysfs files for methods and data

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

 



From: Carlos Corbacho <cathectic@xxxxxxxxx>

To ensure that we don't start overwriting the method_id or input data
when executing methods, or handling data GUID's, add a mutex lock
around data read/ write and method_id write sysfs functions.

Signed-off-by: Carlos Corbacho <cathectic@xxxxxxxxx>
---
(This patch applies on top of ACPI: WMI: version 5).

Len,

I'm not sure if this is the right way to go about adding locking to
the userspace functions (I imagine it's possible to refine the
positioning of the locks better).

However, I feel we need some locking, as without this, there is the
possibility that the input data (and possibly method_id) can change
from userspace before we make our ACPI call (e.g. we prepare a buffer
to send down to ACPI, and in the middle, the method_id suddenly
gets changed, or userspace starts trying to write new data in).

Userspace would still have to do some of it's own file locking, but
we shouldn't let them shoot themselves in the foot too much (maybe
just a toe).

 drivers/acpi/wmi.c |   17 +++++++++++++++++
 1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/drivers/acpi/wmi.c b/drivers/acpi/wmi.c
index 8d53cb5..0944739 100644
--- a/drivers/acpi/wmi.c
+++ b/drivers/acpi/wmi.c
@@ -43,6 +43,7 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/sysfs.h>
+#include <linux/mutex.h>
 #include <acpi/acpi_drivers.h>
 
 #define ACPI_WMI_CLASS "wmi"
@@ -50,6 +51,8 @@
 #undef PREFIX
 #define PREFIX "ACPI: WMI: "
 
+static DEFINE_MUTEX(wmi_data_lock);
+
 struct guid_block
 {
 	char guid[16];
@@ -576,6 +579,8 @@ static ssize_t wmi_data_read(struct kobject *kobj, struct bin_attribute
 
 	guid = kobject_name(kobj->parent);
 
+	mutex_lock(&wmi_data_lock);
+
 	for (i = 0; i < guids.total; i++) {
 		gkobj = &wmi_guid_kobj[i];
 		if (memcmp(kobject_name(&gkobj->guid_kobj), guid, 36) == 0) {
@@ -604,6 +609,8 @@ static ssize_t wmi_data_read(struct kobject *kobj, struct bin_attribute
 	obj = (union acpi_object *) out.pointer;
 	buf = obj->buffer.pointer;
 
+	mutex_unlock(&wmi_data_lock);
+
 	return 0;
 }
 
@@ -611,6 +618,8 @@ static ssize_t wmi_data_write(struct kobject *kobj, struct bin_attribute
 			*bin_attr, char *buf, loff_t offset, size_t count){
 	int i;
 
+	mutex_lock(&wmi_data_lock);
+
 	for (i = 0; i < guids.total; i++) {
 		if (memcmp(kobject_name(&wmi_guid_kobj[i].guid_kobj),
 				kobject_name(kobj->parent), 36) == 0) {
@@ -618,9 +627,11 @@ static ssize_t wmi_data_write(struct kobject *kobj, struct bin_attribute
 			wmi_guid_kobj[i].data = kzalloc(count, GFP_KERNEL);
 			memcpy(wmi_guid_kobj[i].data, buf, count);
 			wmi_guid_kobj[i].data_size = count;
+			mutex_unlock(&wmi_data_lock);
 			return count;
 		}
 	}
+	mutex_unlock(&wmi_data_lock);
 	return -EINVAL;
 }
 
@@ -697,13 +708,19 @@ static ssize_t set_guid_method_id(struct kobject *kobj, const char *buf,
 
 	method_id = simple_strtoul(buf, NULL, 10);
 
+	mutex_lock(&wmi_data_lock);
+
 	for (i = 0; i < guids.total; i++) {
 		if (memcmp(kobject_name(&wmi_guid_kobj[i].guid_kobj),
 			kobject_name(kobj->parent), 36) == 0) {
 			wmi_guid_kobj[i].method_id = method_id;
+			mutex_unlock(&wmi_data_lock);
 			return count;
 		}
 	}
+
+	mutex_unlock(&wmi_data_lock);
+
 	return -EINVAL;
 }
 static WMI_ATTR(method_id, S_IWUGO | S_IRUGO, show_guid_method_id,
-- 
1.5.3.4

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

[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux