diff options
author | James Morris <jmorris@namei.org> | 2011-03-08 10:55:06 +1100 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2011-03-08 10:55:06 +1100 |
commit | 1cc26bada9f6807814806db2f0d78792eecdac71 (patch) | |
tree | 5509b5139db04af6c13db0a580c84116a4a54039 /drivers/acpi/debugfs.c | |
parent | eae61f3c829439f8f9121b5cd48a14be04df451f (diff) | |
parent | 214d93b02c4fe93638ad268613c9702a81ed9192 (diff) |
Merge branch 'master'; commit 'v2.6.38-rc7' into next
Diffstat (limited to 'drivers/acpi/debugfs.c')
-rw-r--r-- | drivers/acpi/debugfs.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/drivers/acpi/debugfs.c b/drivers/acpi/debugfs.c index 5df67f1d6c6..384f7abcff7 100644 --- a/drivers/acpi/debugfs.c +++ b/drivers/acpi/debugfs.c @@ -26,7 +26,9 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf, size_t count, loff_t *ppos) { static char *buf; - static int uncopied_bytes; + static u32 max_size; + static u32 uncopied_bytes; + struct acpi_table_header table; acpi_status status; @@ -37,19 +39,24 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf, if (copy_from_user(&table, user_buf, sizeof(struct acpi_table_header))) return -EFAULT; - uncopied_bytes = table.length; - buf = kzalloc(uncopied_bytes, GFP_KERNEL); + uncopied_bytes = max_size = table.length; + buf = kzalloc(max_size, GFP_KERNEL); if (!buf) return -ENOMEM; } - if (uncopied_bytes < count) { - kfree(buf); + if (buf == NULL) + return -EINVAL; + + if ((*ppos > max_size) || + (*ppos + count > max_size) || + (*ppos + count < count) || + (count > uncopied_bytes)) return -EINVAL; - } if (copy_from_user(buf + (*ppos), user_buf, count)) { kfree(buf); + buf = NULL; return -EFAULT; } @@ -59,6 +66,7 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf, if (!uncopied_bytes) { status = acpi_install_method(buf); kfree(buf); + buf = NULL; if (ACPI_FAILURE(status)) return -EINVAL; add_taint(TAINT_OVERRIDDEN_ACPI_TABLE); |