dell-wmi: Fix access out of memory
authorPali Rohár <pali.rohar@gmail.com>
Mon, 29 Sep 2014 13:10:51 +0000 (15:10 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 21 Nov 2014 17:23:05 +0000 (09:23 -0800)
commit a666b6ffbc9b6705a3ced704f52c3fe9ea8bf959 upstream.

Without this patch, dell-wmi is trying to access elements of dynamically
allocated array without checking the array size. This can lead to memory
corruption or a kernel panic. This patch adds the missing checks for
array size.

Signed-off-by: Pali Rohár <pali.rohar@gmail.com>
Signed-off-by: Darren Hart <dvhart@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/platform/x86/dell-wmi.c

index 390e8e3..25721bf 100644 (file)
@@ -163,18 +163,24 @@ static void dell_wmi_notify(u32 value, void *context)
                const struct key_entry *key;
                int reported_key;
                u16 *buffer_entry = (u16 *)obj->buffer.pointer;
+               int buffer_size = obj->buffer.length/2;
 
-               if (dell_new_hk_type && (buffer_entry[1] != 0x10)) {
+               if (buffer_size >= 2 && dell_new_hk_type && buffer_entry[1] != 0x10) {
                        pr_info("Received unknown WMI event (0x%x)\n",
                                buffer_entry[1]);
                        kfree(obj);
                        return;
                }
 
-               if (dell_new_hk_type || buffer_entry[1] == 0x0)
+               if (buffer_size >= 3 && (dell_new_hk_type || buffer_entry[1] == 0x0))
                        reported_key = (int)buffer_entry[2];
-               else
+               else if (buffer_size >= 2)
                        reported_key = (int)buffer_entry[1] & 0xffff;
+               else {
+                       pr_info("Received unknown WMI event\n");
+                       kfree(obj);
+                       return;
+               }
 
                key = sparse_keymap_entry_from_scancode(dell_wmi_input_dev,
                                                        reported_key);