| From 6de0b13cc0b4ba10e98a9263d7a83b940720b77a Mon Sep 17 00:00:00 2001 |
| From: Aaron Ma <aaron.ma@canonical.com> |
| Date: Mon, 8 Jan 2018 10:41:41 +0800 |
| Subject: HID: core: Fix size as type u32 |
| |
| From: Aaron Ma <aaron.ma@canonical.com> |
| |
| commit 6de0b13cc0b4ba10e98a9263d7a83b940720b77a upstream. |
| |
| When size is negative, calling memset will make segment fault. |
| Declare the size as type u32 to keep memset safe. |
| |
| size in struct hid_report is unsigned, fix return type of |
| hid_report_len to u32. |
| |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Aaron Ma <aaron.ma@canonical.com> |
| Signed-off-by: Jiri Kosina <jkosina@suse.cz> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/hid/hid-core.c | 10 +++++----- |
| include/linux/hid.h | 6 +++--- |
| 2 files changed, 8 insertions(+), 8 deletions(-) |
| |
| --- a/drivers/hid/hid-core.c |
| +++ b/drivers/hid/hid-core.c |
| @@ -1370,7 +1370,7 @@ u8 *hid_alloc_report_buf(struct hid_repo |
| * of implement() working on 8 byte chunks |
| */ |
| |
| - int len = hid_report_len(report) + 7; |
| + u32 len = hid_report_len(report) + 7; |
| |
| return kmalloc(len, flags); |
| } |
| @@ -1435,7 +1435,7 @@ void __hid_request(struct hid_device *hi |
| { |
| char *buf; |
| int ret; |
| - int len; |
| + u32 len; |
| |
| buf = hid_alloc_report_buf(report, GFP_KERNEL); |
| if (!buf) |
| @@ -1461,14 +1461,14 @@ out: |
| } |
| EXPORT_SYMBOL_GPL(__hid_request); |
| |
| -int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, |
| +int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size, |
| int interrupt) |
| { |
| struct hid_report_enum *report_enum = hid->report_enum + type; |
| struct hid_report *report; |
| struct hid_driver *hdrv; |
| unsigned int a; |
| - int rsize, csize = size; |
| + u32 rsize, csize = size; |
| u8 *cdata = data; |
| int ret = 0; |
| |
| @@ -1526,7 +1526,7 @@ EXPORT_SYMBOL_GPL(hid_report_raw_event); |
| * |
| * This is data entry for lower layers. |
| */ |
| -int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int interrupt) |
| +int hid_input_report(struct hid_device *hid, int type, u8 *data, u32 size, int interrupt) |
| { |
| struct hid_report_enum *report_enum; |
| struct hid_driver *hdrv; |
| --- a/include/linux/hid.h |
| +++ b/include/linux/hid.h |
| @@ -801,7 +801,7 @@ extern int hidinput_connect(struct hid_d |
| extern void hidinput_disconnect(struct hid_device *); |
| |
| int hid_set_field(struct hid_field *, unsigned, __s32); |
| -int hid_input_report(struct hid_device *, int type, u8 *, int, int); |
| +int hid_input_report(struct hid_device *, int type, u8 *, u32, int); |
| int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field); |
| struct hid_field *hidinput_get_led_field(struct hid_device *hid); |
| unsigned int hidinput_count_leds(struct hid_device *hid); |
| @@ -1106,13 +1106,13 @@ static inline void hid_hw_wait(struct hi |
| * |
| * @report: the report we want to know the length |
| */ |
| -static inline int hid_report_len(struct hid_report *report) |
| +static inline u32 hid_report_len(struct hid_report *report) |
| { |
| /* equivalent to DIV_ROUND_UP(report->size, 8) + !!(report->id > 0) */ |
| return ((report->size - 1) >> 3) + 1 + (report->id > 0); |
| } |
| |
| -int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, |
| +int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size, |
| int interrupt); |
| |
| /* HID quirks API */ |