mirror of
https://github.com/joel16/android_kernel_sony_msm8994_rework.git
synced 2024-11-27 22:00:42 +00:00
HID: provide a helper for validating hid reports
commit 331415ff16a12147d57d5c953f3a961b7ede348b upstream. 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> Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
51f5294797
commit
791abfbee8
@ -759,6 +759,64 @@ int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(hid_parse_report);
|
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
|
* hid_open_report - open a driver-specific device report
|
||||||
*
|
*
|
||||||
|
@ -749,6 +749,10 @@ void hid_output_report(struct hid_report *report, __u8 *data);
|
|||||||
struct hid_device *hid_allocate_device(void);
|
struct hid_device *hid_allocate_device(void);
|
||||||
struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id);
|
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);
|
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_open_report(struct hid_device *device);
|
||||||
int hid_check_keys_pressed(struct hid_device *hid);
|
int hid_check_keys_pressed(struct hid_device *hid);
|
||||||
int hid_connect(struct hid_device *hid, unsigned int connect_mask);
|
int hid_connect(struct hid_device *hid, unsigned int connect_mask);
|
||||||
|
Loading…
Reference in New Issue
Block a user