summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/zd1211rw
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-05-08 01:43:59 +0200
committerJohn W. Linville <linville@tuxdriver.com>2008-05-12 21:22:19 -0400
commitdbabad0c9c026dea3ba803cbd9d768cdffc68e32 (patch)
tree046b607c669724ab4bde3108eab4c79f467eb21d /drivers/net/wireless/zd1211rw
parent6d6936e2ea82ebcbdd12d489b7b5ccf430de52f1 (diff)
zd1211rw: fix potential use-after-free bug
zd_mac_tx_to_dev() could potentially free the skb, or hand it off to mac80211 which might free it. Hence, this code needs to get the usb pointer out of skb->cb before handing it off to that function. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/zd1211rw')
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index 5316074f39f0..12e24f04dddf 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -889,9 +889,13 @@ static void tx_urb_complete(struct urb *urb)
}
free_urb:
skb = (struct sk_buff *)urb->context;
- zd_mac_tx_to_dev(skb, urb->status);
+ /*
+ * grab 'usb' pointer before handing off the skb (since
+ * it might be freed by zd_mac_tx_to_dev or mac80211)
+ */
cb = (struct zd_tx_skb_control_block *)skb->cb;
usb = &zd_hw_mac(cb->hw)->chip.usb;
+ zd_mac_tx_to_dev(skb, urb->status);
free_tx_urb(usb, urb);
tx_dec_submitted_urbs(usb);
return;