greybus: es1/2: fix use-after-free in completion callback
authorJohan Hovold <johan@hovoldconsulting.com>
Sat, 26 Sep 2015 21:37:59 +0000 (14:37 -0700)
committerGreg Kroah-Hartman <gregkh@google.com>
Tue, 29 Sep 2015 17:09:06 +0000 (19:09 +0200)
Reset the hcpriv field before returning the message to greybus core in
the OUT-URB completion callback.

This fixes a use-after-free bug when sending responses to incoming
requests as the final reference is then dropped when the message is
returned.

Reported-by: Michael Scott <michael.scott@linaro.org>
Signed-off-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
drivers/staging/greybus/es1.c
drivers/staging/greybus/es2.c

index f2853ff4535d6149d816089d6eb4e9a0f6b41bc2..2c56aaf55b429808105c6e67d193fc346c28ced0 100644 (file)
@@ -397,16 +397,16 @@ static void cport_out_callback(struct urb *urb)
 
        gb_message_cport_clear(message->header);
 
+       spin_lock_irqsave(&es1->cport_out_urb_lock, flags);
+       message->hcpriv = NULL;
+       spin_unlock_irqrestore(&es1->cport_out_urb_lock, flags);
+
        /*
         * Tell the submitter that the message send (attempt) is
         * complete, and report the status.
         */
        greybus_message_sent(hd, message, status);
 
-       spin_lock_irqsave(&es1->cport_out_urb_lock, flags);
-       message->hcpriv = NULL;
-       spin_unlock_irqrestore(&es1->cport_out_urb_lock, flags);
-
        free_urb(es1, urb);
 }
 
index 8fee1162aea1b3fdc66b6e5722a1ad54911760ba..22b67d2ff9df062ce4e0cbe1a6d1d710b4f4c01e 100644 (file)
@@ -506,16 +506,16 @@ static void cport_out_callback(struct urb *urb)
 
        gb_message_cport_clear(message->header);
 
+       spin_lock_irqsave(&es1->cport_out_urb_lock, flags);
+       message->hcpriv = NULL;
+       spin_unlock_irqrestore(&es1->cport_out_urb_lock, flags);
+
        /*
         * Tell the submitter that the message send (attempt) is
         * complete, and report the status.
         */
        greybus_message_sent(hd, message, status);
 
-       spin_lock_irqsave(&es1->cport_out_urb_lock, flags);
-       message->hcpriv = NULL;
-       spin_unlock_irqrestore(&es1->cport_out_urb_lock, flags);
-
        free_urb(es1, urb);
 }