Skip to content

Commit

Permalink
rtl8187: fix use after free on failure path in rtl8187_init_urbs()
Browse files Browse the repository at this point in the history
In case of __dev_alloc_skb() failure rtl8187_init_urbs()
calls usb_free_urb(entry) where 'entry' can points to urb
allocated at the previous iteration. That means refcnt will be
decremented incorrectly and the urb can be used after memory
deallocation.

The patch fixes the issue and implements error handling of init_urbs
in rtl8187_start().

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Alexey Khoroshilov authored and John W. Linville committed Sep 9, 2013
1 parent c4bff5d commit 8a10da2
Showing 1 changed file with 10 additions and 5 deletions.
15 changes: 10 additions & 5 deletions drivers/net/wireless/rtl818x/rtl8187/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -438,17 +438,16 @@ static int rtl8187_init_urbs(struct ieee80211_hw *dev)
skb_queue_tail(&priv->rx_queue, skb);
usb_anchor_urb(entry, &priv->anchored);
ret = usb_submit_urb(entry, GFP_KERNEL);
usb_put_urb(entry);
if (ret) {
skb_unlink(skb, &priv->rx_queue);
usb_unanchor_urb(entry);
goto err;
}
usb_free_urb(entry);
}
return ret;

err:
usb_free_urb(entry);
kfree_skb(skb);
usb_kill_anchored_urbs(&priv->anchored);
return ret;
Expand Down Expand Up @@ -956,8 +955,12 @@ static int rtl8187_start(struct ieee80211_hw *dev)
(RETRY_COUNT << 8 /* short retry limit */) |
(RETRY_COUNT << 0 /* long retry limit */) |
(7 << 21 /* MAX TX DMA */));
rtl8187_init_urbs(dev);
rtl8187b_init_status_urb(dev);
ret = rtl8187_init_urbs(dev);
if (ret)
goto rtl8187_start_exit;
ret = rtl8187b_init_status_urb(dev);
if (ret)
usb_kill_anchored_urbs(&priv->anchored);
goto rtl8187_start_exit;
}

Expand All @@ -966,7 +969,9 @@ static int rtl8187_start(struct ieee80211_hw *dev)
rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0);
rtl818x_iowrite32(priv, &priv->map->MAR[1], ~0);

rtl8187_init_urbs(dev);
ret = rtl8187_init_urbs(dev);
if (ret)
goto rtl8187_start_exit;

reg = RTL818X_RX_CONF_ONLYERLPKT |
RTL818X_RX_CONF_RX_AUTORESETPHY |
Expand Down

0 comments on commit 8a10da2

Please sign in to comment.