| .. | .. |
|---|
| 32 | 32 | #include <linux/hiddev.h> |
|---|
| 33 | 33 | #include <linux/hid-debug.h> |
|---|
| 34 | 34 | #include <linux/hidraw.h> |
|---|
| 35 | +#include <linux/uhid.h> |
|---|
| 35 | 36 | |
|---|
| 36 | 37 | #include "hid-ids.h" |
|---|
| 37 | 38 | |
|---|
| .. | .. |
|---|
| 258 | 259 | { |
|---|
| 259 | 260 | struct hid_report *report; |
|---|
| 260 | 261 | struct hid_field *field; |
|---|
| 262 | + unsigned int max_buffer_size = HID_MAX_BUFFER_SIZE; |
|---|
| 261 | 263 | unsigned int usages; |
|---|
| 262 | 264 | unsigned int offset; |
|---|
| 263 | 265 | unsigned int i; |
|---|
| .. | .. |
|---|
| 288 | 290 | offset = report->size; |
|---|
| 289 | 291 | report->size += parser->global.report_size * parser->global.report_count; |
|---|
| 290 | 292 | |
|---|
| 293 | + if (IS_ENABLED(CONFIG_UHID) && parser->device->ll_driver == &uhid_hid_driver) |
|---|
| 294 | + max_buffer_size = UHID_DATA_MAX; |
|---|
| 295 | + |
|---|
| 291 | 296 | /* Total size check: Allow for possible report index byte */ |
|---|
| 292 | | - if (report->size > (HID_MAX_BUFFER_SIZE - 1) << 3) { |
|---|
| 297 | + if (report->size > (max_buffer_size - 1) << 3) { |
|---|
| 293 | 298 | hid_err(parser->device, "report is too long\n"); |
|---|
| 294 | 299 | return -1; |
|---|
| 295 | 300 | } |
|---|
| .. | .. |
|---|
| 988 | 993 | * Validating on id 0 means we should examine the first |
|---|
| 989 | 994 | * report in the list. |
|---|
| 990 | 995 | */ |
|---|
| 991 | | - report = list_entry( |
|---|
| 992 | | - hid->report_enum[type].report_list.next, |
|---|
| 996 | + report = list_first_entry_or_null( |
|---|
| 997 | + &hid->report_enum[type].report_list, |
|---|
| 993 | 998 | struct hid_report, list); |
|---|
| 994 | 999 | } else { |
|---|
| 995 | 1000 | report = hid->report_enum[type].report_id_hash[id]; |
|---|
| .. | .. |
|---|
| 1197 | 1202 | __u8 *end; |
|---|
| 1198 | 1203 | __u8 *next; |
|---|
| 1199 | 1204 | int ret; |
|---|
| 1205 | + int i; |
|---|
| 1200 | 1206 | static int (*dispatch_type[])(struct hid_parser *parser, |
|---|
| 1201 | 1207 | struct hid_item *item) = { |
|---|
| 1202 | 1208 | hid_parser_main, |
|---|
| .. | .. |
|---|
| 1247 | 1253 | goto err; |
|---|
| 1248 | 1254 | } |
|---|
| 1249 | 1255 | device->collection_size = HID_DEFAULT_NUM_COLLECTIONS; |
|---|
| 1256 | + for (i = 0; i < HID_DEFAULT_NUM_COLLECTIONS; i++) |
|---|
| 1257 | + device->collection[i].parent_idx = -1; |
|---|
| 1250 | 1258 | |
|---|
| 1251 | 1259 | ret = -EINVAL; |
|---|
| 1252 | 1260 | while ((next = fetch_item(start, end, &item)) != NULL) { |
|---|
| .. | .. |
|---|
| 1749 | 1757 | struct hid_report_enum *report_enum = hid->report_enum + type; |
|---|
| 1750 | 1758 | struct hid_report *report; |
|---|
| 1751 | 1759 | struct hid_driver *hdrv; |
|---|
| 1760 | + int max_buffer_size = HID_MAX_BUFFER_SIZE; |
|---|
| 1752 | 1761 | unsigned int a; |
|---|
| 1753 | 1762 | u32 rsize, csize = size; |
|---|
| 1754 | 1763 | u8 *cdata = data; |
|---|
| .. | .. |
|---|
| 1765 | 1774 | |
|---|
| 1766 | 1775 | rsize = hid_compute_report_size(report); |
|---|
| 1767 | 1776 | |
|---|
| 1768 | | - if (report_enum->numbered && rsize >= HID_MAX_BUFFER_SIZE) |
|---|
| 1769 | | - rsize = HID_MAX_BUFFER_SIZE - 1; |
|---|
| 1770 | | - else if (rsize > HID_MAX_BUFFER_SIZE) |
|---|
| 1771 | | - rsize = HID_MAX_BUFFER_SIZE; |
|---|
| 1777 | + if (IS_ENABLED(CONFIG_UHID) && hid->ll_driver == &uhid_hid_driver) |
|---|
| 1778 | + max_buffer_size = UHID_DATA_MAX; |
|---|
| 1779 | + |
|---|
| 1780 | + if (report_enum->numbered && rsize >= max_buffer_size) |
|---|
| 1781 | + rsize = max_buffer_size - 1; |
|---|
| 1782 | + else if (rsize > max_buffer_size) |
|---|
| 1783 | + rsize = max_buffer_size; |
|---|
| 1772 | 1784 | |
|---|
| 1773 | 1785 | if (csize < rsize) { |
|---|
| 1774 | 1786 | dbg_hid("report %d is too short, (%d < %d)\n", report->id, |
|---|