isdn/gigaset: fix usb_gigaset write_cmd result race
authorTilman Schmidt <tilman@imap.cc>
Sat, 11 Oct 2014 11:46:30 +0000 (13:46 +0200)
committerDavid S. Miller <davem@davemloft.net>
Tue, 14 Oct 2014 19:05:35 +0000 (15:05 -0400)
In usb_gigaset function gigaset_write_cmd(), the length field of
the command buffer structure could be cleared by the transmit
tasklet before it was used for the function's return value.
Fix by copying to a local variable before scheduling the tasklet.

Signed-off-by: Tilman Schmidt <tilman@imap.cc>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/isdn/gigaset/usb-gigaset.c

index 82e91ba1acd343ed296d1b8969a83f86ade2173f..a8e652dac54d8aed3691fdb98920328a51a45e49 100644 (file)
@@ -497,6 +497,7 @@ static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb)
 static int gigaset_write_cmd(struct cardstate *cs, struct cmdbuf_t *cb)
 {
        unsigned long flags;
+       int len;
 
        gigaset_dbg_buffer(cs->mstate != MS_LOCKED ?
                           DEBUG_TRANSCMD : DEBUG_LOCKCMD,
@@ -515,10 +516,11 @@ static int gigaset_write_cmd(struct cardstate *cs, struct cmdbuf_t *cb)
        spin_unlock_irqrestore(&cs->cmdlock, flags);
 
        spin_lock_irqsave(&cs->lock, flags);
+       len = cb->len;
        if (cs->connected)
                tasklet_schedule(&cs->write_tasklet);
        spin_unlock_irqrestore(&cs->lock, flags);
-       return cb->len;
+       return len;
 }
 
 static int gigaset_write_room(struct cardstate *cs)