From: Carlos Corbacho <[EMAIL PROTECTED]>
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 <[EMAIL PROTECTED]>
---
(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 [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html