HID: core: prevent out-of-bound readings
[pandora-kernel.git] / drivers / hid / hid-core.c
index 9ac4389..1ec8825 100644 (file)
@@ -754,7 +754,17 @@ struct hid_report *hid_validate_values(struct hid_device *hid,
         * ->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 (id == 0) {
+               /*
+                * Validating on id 0 means we should examine the first
+                * report in the list.
+                */
+               report = list_entry(
+                               hid->report_enum[type].report_list.next,
+                               struct hid_report, list);
+       } else {
+               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;
@@ -979,6 +989,7 @@ static void hid_input_field(struct hid_device *hid, struct hid_field *field,
                /* Ignore report if ErrorRollOver */
                if (!(field->flags & HID_MAIN_ITEM_VARIABLE) &&
                    value[n] >= min && value[n] <= max &&
+                   value[n] - min < field->maxusage &&
                    field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1)
                        goto exit;
        }
@@ -991,11 +1002,13 @@ static void hid_input_field(struct hid_device *hid, struct hid_field *field,
                }
 
                if (field->value[n] >= min && field->value[n] <= max
+                       && field->value[n] - min < field->maxusage
                        && field->usage[field->value[n] - min].hid
                        && search(value, field->value[n], count))
                                hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt);
 
                if (value[n] >= min && value[n] <= max
+                       && value[n] - min < field->maxusage
                        && field->usage[value[n] - min].hid
                        && search(field->value, value[n], count))
                                hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt);
@@ -1285,7 +1298,7 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
                "Multi-Axis Controller"
        };
        const char *type, *bus;
-       char buf[64];
+       char buf[64] = "";
        unsigned int i;
        int len;
        int ret;