mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-10-31 16:54:21 +00:00 
			
		
		
		
	HID: provide a helper for validating hid reports
Many drivers need to validate the characteristics of their HID report during initialization to avoid misusing the reports. This adds a common helper to perform validation of the report exisitng, the field existing, and the expected number of values within the field. Signed-off-by: Kees Cook <keescook@chromium.org> Cc: stable@vger.kernel.org Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
This commit is contained in:
		
							parent
							
								
									b04c99e3b8
								
							
						
					
					
						commit
						331415ff16
					
				
					 2 changed files with 62 additions and 0 deletions
				
			
		|  | @ -801,6 +801,64 @@ int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size) | |||
| } | ||||
| EXPORT_SYMBOL_GPL(hid_parse_report); | ||||
| 
 | ||||
| static const char * const hid_report_names[] = { | ||||
| 	"HID_INPUT_REPORT", | ||||
| 	"HID_OUTPUT_REPORT", | ||||
| 	"HID_FEATURE_REPORT", | ||||
| }; | ||||
| /**
 | ||||
|  * hid_validate_values - validate existing device report's value indexes | ||||
|  * | ||||
|  * @device: hid device | ||||
|  * @type: which report type to examine | ||||
|  * @id: which report ID to examine (0 for first) | ||||
|  * @field_index: which report field to examine | ||||
|  * @report_counts: expected number of values | ||||
|  * | ||||
|  * Validate the number of values in a given field of a given report, after | ||||
|  * parsing. | ||||
|  */ | ||||
| struct hid_report *hid_validate_values(struct hid_device *hid, | ||||
| 				       unsigned int type, unsigned int id, | ||||
| 				       unsigned int field_index, | ||||
| 				       unsigned int report_counts) | ||||
| { | ||||
| 	struct hid_report *report; | ||||
| 
 | ||||
| 	if (type > HID_FEATURE_REPORT) { | ||||
| 		hid_err(hid, "invalid HID report type %u\n", type); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	if (id >= HID_MAX_IDS) { | ||||
| 		hid_err(hid, "invalid HID report id %u\n", id); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Explicitly not using hid_get_report() here since it depends on | ||||
| 	 * ->numbered being checked, which may not always be the case when | ||||
| 	 * drivers go to access report values. | ||||
| 	 */ | ||||
| 	report = hid->report_enum[type].report_id_hash[id]; | ||||
| 	if (!report) { | ||||
| 		hid_err(hid, "missing %s %u\n", hid_report_names[type], id); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	if (report->maxfield <= field_index) { | ||||
| 		hid_err(hid, "not enough fields in %s %u\n", | ||||
| 			hid_report_names[type], id); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	if (report->field[field_index]->report_count < report_counts) { | ||||
| 		hid_err(hid, "not enough values in %s %u field %u\n", | ||||
| 			hid_report_names[type], id, field_index); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	return report; | ||||
| } | ||||
| EXPORT_SYMBOL_GPL(hid_validate_values); | ||||
| 
 | ||||
| /**
 | ||||
|  * hid_open_report - open a driver-specific device report | ||||
|  * | ||||
|  |  | |||
|  | @ -756,6 +756,10 @@ u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags); | |||
| struct hid_device *hid_allocate_device(void); | ||||
| struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id); | ||||
| int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); | ||||
| struct hid_report *hid_validate_values(struct hid_device *hid, | ||||
| 				       unsigned int type, unsigned int id, | ||||
| 				       unsigned int field_index, | ||||
| 				       unsigned int report_counts); | ||||
| int hid_open_report(struct hid_device *device); | ||||
| int hid_check_keys_pressed(struct hid_device *hid); | ||||
| int hid_connect(struct hid_device *hid, unsigned int connect_mask); | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Kees Cook
						Kees Cook