uas: Check against unexpected completions
authorHans de Goede <hdegoede@redhat.com>
Sat, 13 Sep 2014 10:26:33 +0000 (12:26 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 24 Sep 2014 04:42:10 +0000 (21:42 -0700)
The status urb should not complete before the command has been submitted, nor
should we get a second status urb for the same tag after a IU_ID_STATUS.

Data urbs should not complete before the command has been submitted, but may
complete after the IU_ID_STATUS.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/storage/uas.c

index 33db53f1ce9ef7b060cf4004efb341327676273b..7f56f31ed6613fbf93a6c32f3266dd75deb7e174 100644 (file)
@@ -371,6 +371,12 @@ static void uas_stat_cmplt(struct urb *urb)
 
        cmnd = devinfo->cmnd[idx];
        cmdinfo = (void *)&cmnd->SCp;
+
+       if (!(cmdinfo->state & COMMAND_INFLIGHT)) {
+               scmd_printk(KERN_ERR, cmnd, "unexpected status cmplt\n");
+               goto out;
+       }
+
        switch (iu->iu_id) {
        case IU_ID_STATUS:
                if (urb->actual_length < 16)
@@ -436,6 +442,12 @@ static void uas_data_cmplt(struct urb *urb)
        if (devinfo->resetting)
                goto out;
 
+       /* Data urbs should not complete before the cmd urb is submitted */
+       if (cmdinfo->state & SUBMIT_CMD_URB) {
+               scmd_printk(KERN_ERR, cmnd, "unexpected data cmplt\n");
+               goto out;
+       }
+
        if (urb->status) {
                if (urb->status != -ECONNRESET) {
                        uas_log_cmd_state(cmnd, __func__);