summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2014-09-13 12:26:33 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-09-23 21:42:10 -0700
commitd89da03acec19b39506f3ef32e09134b50b4adb9 (patch)
tree795eaebec8d0337094eab2de71defee0dd83c0ab /drivers
parent5e61aede477ee108de3f9e57f19cacd8ce3ffe52 (diff)
uas: Check against unexpected completions
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/storage/uas.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c
index 33db53f1ce9..7f56f31ed66 100644
--- a/drivers/usb/storage/uas.c
+++ b/drivers/usb/storage/uas.c
@@ -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__);