Skip to content

Commit

Permalink
HID: corsair: fix DMA buffers on stack
Browse files Browse the repository at this point in the history
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: 6f78193 ("HID: corsair: Add Corsair Vengeance K90 driver")
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
  • Loading branch information
Johan Hovold authored and Jiri Kosina committed Jan 13, 2017
1 parent a89af4a commit 6d104af
Showing 1 changed file with 42 additions and 12 deletions.
54 changes: 42 additions & 12 deletions drivers/hid/hid-corsair.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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)
Expand Down Expand Up @@ -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,
Expand All @@ -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]) {
Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand Down

0 comments on commit 6d104af

Please sign in to comment.