diff --git a/debian/changelog b/debian/changelog index c48c2ce66..4d07bb11d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -352,6 +352,7 @@ linux (4.9.5-1) UNRELEASED; urgency=medium [ Salvatore Bonaccorso ] * tmpfs: clear S_ISGID when setting posix ACLs (CVE-2017-5551) + * HID: corsair: fix DMA buffers on stack (CVE-2017-5547) [ Roger Shimizu ] * [armel] Add DT support of Buffalo Linkstation Live v3 (LS-CHL) diff --git a/debian/patches/bugfix/all/HID-corsair-fix-DMA-buffers-on-stack.patch b/debian/patches/bugfix/all/HID-corsair-fix-DMA-buffers-on-stack.patch new file mode 100644 index 000000000..a2240bdc4 --- /dev/null +++ b/debian/patches/bugfix/all/HID-corsair-fix-DMA-buffers-on-stack.patch @@ -0,0 +1,144 @@ +From: Johan Hovold +Date: Thu, 12 Jan 2017 18:17:42 +0100 +Subject: HID: corsair: fix DMA buffers on stack +Origin: https://git.kernel.org/linus/6d104af38b570d37aa32a5803b04c354f8ed513d + +Not all platforms support DMA to the stack, and specifically since v4.9 +this is no longer supported on x86 with VMAP_STACK either. + +Note that the macro-mode buffer was larger than necessary. + +Fixes: 6f78193ee9ea ("HID: corsair: Add Corsair Vengeance K90 driver") +Cc: stable +Signed-off-by: Johan Hovold +Signed-off-by: Jiri Kosina +--- + drivers/hid/hid-corsair.c | 54 ++++++++++++++++++++++++++++++++++++----------- + 1 file changed, 42 insertions(+), 12 deletions(-) + +diff --git a/drivers/hid/hid-corsair.c b/drivers/hid/hid-corsair.c +index 717704e..5971907 100644 +--- a/drivers/hid/hid-corsair.c ++++ b/drivers/hid/hid-corsair.c +@@ -148,7 +148,11 @@ static enum led_brightness k90_backlight_get(struct led_classdev *led_cdev) + struct usb_interface *usbif = to_usb_interface(dev->parent); + struct usb_device *usbdev = interface_to_usbdev(usbif); + int brightness; +- char data[8]; ++ char *data; ++ ++ data = kmalloc(8, GFP_KERNEL); ++ if (!data) ++ return -ENOMEM; + + ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), + K90_REQUEST_STATUS, +@@ -158,16 +162,22 @@ static enum led_brightness k90_backlight_get(struct led_classdev *led_cdev) + if (ret < 0) { + dev_warn(dev, "Failed to get K90 initial state (error %d).\n", + ret); +- return -EIO; ++ ret = -EIO; ++ goto out; + } + brightness = data[4]; + if (brightness < 0 || brightness > 3) { + dev_warn(dev, + "Read invalid backlight brightness: %02hhx.\n", + data[4]); +- return -EIO; ++ ret = -EIO; ++ goto out; + } +- return brightness; ++ ret = brightness; ++out: ++ kfree(data); ++ ++ return ret; + } + + static enum led_brightness k90_record_led_get(struct led_classdev *led_cdev) +@@ -253,7 +263,11 @@ static ssize_t k90_show_macro_mode(struct device *dev, + struct usb_interface *usbif = to_usb_interface(dev->parent); + struct usb_device *usbdev = interface_to_usbdev(usbif); + const char *macro_mode; +- char data[8]; ++ char *data; ++ ++ data = kmalloc(2, GFP_KERNEL); ++ if (!data) ++ return -ENOMEM; + + ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), + K90_REQUEST_GET_MODE, +@@ -263,7 +277,8 @@ static ssize_t k90_show_macro_mode(struct device *dev, + if (ret < 0) { + dev_warn(dev, "Failed to get K90 initial mode (error %d).\n", + ret); +- return -EIO; ++ ret = -EIO; ++ goto out; + } + + switch (data[0]) { +@@ -277,10 +292,15 @@ static ssize_t k90_show_macro_mode(struct device *dev, + default: + dev_warn(dev, "K90 in unknown mode: %02hhx.\n", + data[0]); +- return -EIO; ++ ret = -EIO; ++ goto out; + } + +- return snprintf(buf, PAGE_SIZE, "%s\n", macro_mode); ++ ret = snprintf(buf, PAGE_SIZE, "%s\n", macro_mode); ++out: ++ kfree(data); ++ ++ return ret; + } + + static ssize_t k90_store_macro_mode(struct device *dev, +@@ -320,7 +340,11 @@ static ssize_t k90_show_current_profile(struct device *dev, + struct usb_interface *usbif = to_usb_interface(dev->parent); + struct usb_device *usbdev = interface_to_usbdev(usbif); + int current_profile; +- char data[8]; ++ char *data; ++ ++ data = kmalloc(8, GFP_KERNEL); ++ if (!data) ++ return -ENOMEM; + + ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), + K90_REQUEST_STATUS, +@@ -330,16 +354,22 @@ static ssize_t k90_show_current_profile(struct device *dev, + if (ret < 0) { + dev_warn(dev, "Failed to get K90 initial state (error %d).\n", + ret); +- return -EIO; ++ ret = -EIO; ++ goto out; + } + current_profile = data[7]; + if (current_profile < 1 || current_profile > 3) { + dev_warn(dev, "Read invalid current profile: %02hhx.\n", + data[7]); +- return -EIO; ++ ret = -EIO; ++ goto out; + } + +- return snprintf(buf, PAGE_SIZE, "%d\n", current_profile); ++ ret = snprintf(buf, PAGE_SIZE, "%d\n", current_profile); ++out: ++ kfree(data); ++ ++ return ret; + } + + static ssize_t k90_store_current_profile(struct device *dev, +-- +2.1.4 + diff --git a/debian/patches/series b/debian/patches/series index d23c02482..12a301691 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -97,6 +97,7 @@ features/all/securelevel/arm64-add-kernel-config-option-to-set-securelevel-wh.pa # Security fixes debian/i386-686-pae-pci-set-pci-nobios-by-default.patch bugfix/all/tmpfs-clear-S_ISGID-when-setting-posix-ACLs.patch +bugfix/all/HID-corsair-fix-DMA-buffers-on-stack.patch # Fix exported symbol versions bugfix/ia64/revert-ia64-move-exports-to-definitions.patch