Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@suse.de>2011-02-18 22:57:09 +0100
committerRafael J. Wysocki <rjw@suse.de>2011-02-18 22:57:09 +0100
commitda9d3a81ff33970a50cef64e86855f379eac6628 (patch)
treeca3f6266cc770e8345ba39aff3ad5b161bfa3faf
parenta638bb465e2bcd5b08bcca044becf3e475143bee (diff)
- ACPI / debugfs: Fix buffer overflows, double free (bnc#666095).
-rw-r--r--patches.arch/acpi-debugfs-fix-buffer-overflows-double-free.patch75
-rw-r--r--series.conf2
2 files changed, 77 insertions, 0 deletions
diff --git a/patches.arch/acpi-debugfs-fix-buffer-overflows-double-free.patch b/patches.arch/acpi-debugfs-fix-buffer-overflows-double-free.patch
new file mode 100644
index 0000000000..9823213cd4
--- /dev/null
+++ b/patches.arch/acpi-debugfs-fix-buffer-overflows-double-free.patch
@@ -0,0 +1,75 @@
+From: Vasiliy Kulikov <segoon@openwall.com>
+Subject: ACPI / debugfs: Fix buffer overflows, double free
+Patch-mainline: No
+References: bnc#666095
+
+File position is not controlled, it may lead to overwrites of arbitrary
+kernel memory. Also the code may kfree() the same pointer multiple
+times.
+
+One more flaw is still present: if multiple processes open the file then
+all 3 static variables are shared, leading to various race conditions.
+They should be moved to file->private_data.
+
+Signed-off-by: Vasiliy Kulikov <segoon@openwall.com>
+Reviewed-by: WANG Cong <xiyou.wangcong@gmail.com>
+Reviewed-by: Eugene Teo <eugeneteo@kernel.org>
+Signed-off-by: Rafael J. Wysocki <rjw@suse.de>
+---
+drivers/acpi/debugfs.c | 20 ++++++++++++++------
+ drivers/acpi/debugfs.c | 20 ++++++++++++++------
+ 1 file changed, 14 insertions(+), 6 deletions(-)
+
+Index: linux-2.6.37-openSUSE-11.4/drivers/acpi/debugfs.c
+===================================================================
+--- linux-2.6.37-openSUSE-11.4.orig/drivers/acpi/debugfs.c
++++ linux-2.6.37-openSUSE-11.4/drivers/acpi/debugfs.c
+@@ -26,7 +26,9 @@ static ssize_t cm_write(struct file *fil
+ 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 *fil
+ 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 *fil
+ if (!uncopied_bytes) {
+ status = acpi_install_method(buf);
+ kfree(buf);
++ buf = NULL;
+ if (ACPI_FAILURE(status))
+ return -EINVAL;
+ add_taint(TAINT_OVERRIDDEN_ACPI_TABLE);
diff --git a/series.conf b/series.conf
index 2449a846cf..3412f1ec7a 100644
--- a/series.conf
+++ b/series.conf
@@ -268,6 +268,8 @@
patches.fixes/PNP-ACPI-Use-DEVICE_ACPI_HANDLE-for-device-ACPI-handle-access.patch
+ patches.arch/acpi-debugfs-fix-buffer-overflows-double-free.patch
+
########################################################
# CPUFREQ
########################################################