diff options
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, | |||
| 26 | size_t count, loff_t *ppos) | 26 | size_t count, loff_t *ppos) |
| 27 | { | 27 | { |
| 28 | static char *buf; | 28 | static char *buf; |
| 29 | static int uncopied_bytes; | 29 | static u32 max_size; |
| 30 | static u32 uncopied_bytes; | ||
| 31 | |||
| 30 | struct acpi_table_header table; | 32 | struct acpi_table_header table; |
| 31 | acpi_status status; | 33 | acpi_status status; |
| 32 | 34 | ||
| @@ -37,19 +39,24 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf, | |||
| 37 | if (copy_from_user(&table, user_buf, | 39 | if (copy_from_user(&table, user_buf, |
| 38 | sizeof(struct acpi_table_header))) | 40 | sizeof(struct acpi_table_header))) |
| 39 | return -EFAULT; | 41 | return -EFAULT; |
| 40 | uncopied_bytes = table.length; | 42 | uncopied_bytes = max_size = table.length; |
| 41 | buf = kzalloc(uncopied_bytes, GFP_KERNEL); | 43 | buf = kzalloc(max_size, GFP_KERNEL); |
| 42 | if (!buf) | 44 | if (!buf) |
| 43 | return -ENOMEM; | 45 | return -ENOMEM; |
| 44 | } | 46 | } |
| 45 | 47 | ||
| 46 | if (uncopied_bytes < count) { | 48 | if (buf == NULL) |
| 47 | kfree(buf); | 49 | return -EINVAL; |
| 50 | |||
| 51 | if ((*ppos > max_size) || | ||
| 52 | (*ppos + count > max_size) || | ||
| 53 | (*ppos + count < count) || | ||
| 54 | (count > uncopied_bytes)) | ||
| 48 | return -EINVAL; | 55 | return -EINVAL; |
| 49 | } | ||
| 50 | 56 | ||
| 51 | if (copy_from_user(buf + (*ppos), user_buf, count)) { | 57 | if (copy_from_user(buf + (*ppos), user_buf, count)) { |
| 52 | kfree(buf); | 58 | kfree(buf); |
| 59 | buf = NULL; | ||
| 53 | return -EFAULT; | 60 | return -EFAULT; |
| 54 | } | 61 | } |
| 55 | 62 | ||
| @@ -59,6 +66,7 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf, | |||
| 59 | if (!uncopied_bytes) { | 66 | if (!uncopied_bytes) { |
| 60 | status = acpi_install_method(buf); | 67 | status = acpi_install_method(buf); |
| 61 | kfree(buf); | 68 | kfree(buf); |
| 69 | buf = NULL; | ||
| 62 | if (ACPI_FAILURE(status)) | 70 | if (ACPI_FAILURE(status)) |
| 63 | return -EINVAL; | 71 | return -EINVAL; |
| 64 | add_taint(TAINT_OVERRIDDEN_ACPI_TABLE); | 72 | add_taint(TAINT_OVERRIDDEN_ACPI_TABLE); |
