|
@@ -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);
|