HID: intel_ish-hid: Move header size check to inside the loop
authorHans de Goede <hdegoede@redhat.com>
Sat, 14 Apr 2018 15:06:44 +0000 (17:06 +0200)
committerJiri Kosina <jkosina@suse.cz>
Wed, 25 Apr 2018 08:52:42 +0000 (10:52 +0200)
With the headersize check outside of the loop, the second time through
the loop the: "payload_len = recv_msg->hdr.size;" statement may deref
recv_msg while it is pointing outside of our input buffer.

Move the headersize check to inside the loop to fix this.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
drivers/hid/intel-ish-hid/ishtp-hid-client.c

index 157b44aacdffb60203cb154680f9d02a94115fdc..6ce1856bb368f8f5609116aca2abf865d58125a7 100644 (file)
@@ -77,21 +77,21 @@ static void process_recv(struct ishtp_cl *hid_ishtp_cl, void *recv_buf,
        struct ishtp_cl_data *client_data = hid_ishtp_cl->client_data;
        int curr_hid_dev = client_data->cur_hid_dev;
 
-       if (data_len < sizeof(struct hostif_msg_hdr)) {
-               dev_err(&client_data->cl_device->dev,
-                       "[hid-ish]: error, received %u which is less than data header %u\n",
-                       (unsigned int)data_len,
-                       (unsigned int)sizeof(struct hostif_msg_hdr));
-               ++client_data->bad_recv_cnt;
-               ish_hw_reset(hid_ishtp_cl->dev);
-               return;
-       }
-
        payload = recv_buf + sizeof(struct hostif_msg_hdr);
        total_len = data_len;
        cur_pos = 0;
 
        do {
+               if (cur_pos + sizeof(struct hostif_msg) > total_len) {
+                       dev_err(&client_data->cl_device->dev,
+                               "[hid-ish]: error, received %u which is less than data header %u\n",
+                               (unsigned int)data_len,
+                               (unsigned int)sizeof(struct hostif_msg_hdr));
+                       ++client_data->bad_recv_cnt;
+                       ish_hw_reset(hid_ishtp_cl->dev);
+                       break;
+               }
+
                recv_msg = (struct hostif_msg *)(recv_buf + cur_pos);
                payload_len = recv_msg->hdr.size;