* Re: [PATCH] rtl8187: fix use after free on failure path in rtl8187_init_urbs()
@ 2013-09-02 6:34 Hin-Tak Leung
2013-09-03 20:09 ` Alexey Khoroshilov
0 siblings, 1 reply; 5+ messages in thread
From: Hin-Tak Leung @ 2013-09-02 6:34 UTC (permalink / raw)
To: khoroshilov
Cc: larry.finger, linville, linux-wireless, netdev, linux-kernel,
ldv-project, gregkh
------------------------------
On Mon, Sep 2, 2013 05:06 BST Alexey Khoroshilov wrote:
>On 01.09.2013 10:51, Hin-Tak Leung wrote:
>> ------------------------------
>> On Sat, Aug 31, 2013 22:18 BST Alexey Khoroshilov wrote:
>>
>> 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>
>> ---
>> drivers/net/wireless/rtl818x/rtl8187/dev.c | 15 ++++++++++-----
>> 1 file changed, 10 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c
>> index f49220e..e83d53c 100644
>> --- a/drivers/net/wireless/rtl818x/rtl8187/dev.c
>> +++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c
>> @@ -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_free_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;
>> This part looks wrong - you free_urb(entry) then unanchor_urb(entry).
>I do not see any problems here.
>usb_free_urb() just decrements refcnt of the urb.
>While usb_anchor_urb() and usb_unanchor_urb() increment and decrement it
>as well.
>So actual memory deallocation will happen in usb_unanchor_urb().
If the routines work as you say, they probably are misnamed, and/or prototyped wrongly?
Also, you are making assumptions about how they are implemented, and relying
on the implementation details to be fixed for eternity.
I am just saying,
XXX_free(some_entity);
if(condtion)
do_stuff(some_entity);
looks wrong, and if that's intentional, those routines really shouldn't be named as such.
Hin-Tak
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] rtl8187: fix use after free on failure path in rtl8187_init_urbs()
2013-09-02 6:34 [PATCH] rtl8187: fix use after free on failure path in rtl8187_init_urbs() Hin-Tak Leung
@ 2013-09-03 20:09 ` Alexey Khoroshilov
0 siblings, 0 replies; 5+ messages in thread
From: Alexey Khoroshilov @ 2013-09-03 20:09 UTC (permalink / raw)
To: htl10
Cc: larry.finger, linville, linux-wireless, netdev, linux-kernel,
ldv-project, gregkh
On 02.09.2013 10:34, Hin-Tak Leung wrote:
> ------------------------------
> On Mon, Sep 2, 2013 05:06 BST Alexey Khoroshilov wrote:
>
>> On 01.09.2013 10:51, Hin-Tak Leung wrote:
>>> ------------------------------
>>> On Sat, Aug 31, 2013 22:18 BST Alexey Khoroshilov wrote:
>>>
>>> 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>
>>> ---
>>> drivers/net/wireless/rtl818x/rtl8187/dev.c | 15 ++++++++++-----
>>> 1 file changed, 10 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c
>>> index f49220e..e83d53c 100644
>>> --- a/drivers/net/wireless/rtl818x/rtl8187/dev.c
>>> +++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c
>>> @@ -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_free_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;
>>> This part looks wrong - you free_urb(entry) then unanchor_urb(entry).
>> I do not see any problems here.
>> usb_free_urb() just decrements refcnt of the urb.
>> While usb_anchor_urb() and usb_unanchor_urb() increment and decrement it
>> as well.
>> So actual memory deallocation will happen in usb_unanchor_urb().
> If the routines work as you say, they probably are misnamed, and/or prototyped wrongly?
> Also, you are making assumptions about how they are implemented, and relying
> on the implementation details to be fixed for eternity.
>
> I am just saying,
>
> XXX_free(some_entity);
> if(condtion)
> do_stuff(some_entity);
>
> looks wrong, and if that's intentional, those routines really shouldn't be named as such.
There is an alias for usb_free_urb() named usb_put_urb().
I will resend the patch with such substitution.
--
Alexey
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] rtl8187: fix use after free on failure path in rtl8187_init_urbs()
2013-09-01 7:51 Hin-Tak Leung
@ 2013-09-02 4:06 ` Alexey Khoroshilov
0 siblings, 0 replies; 5+ messages in thread
From: Alexey Khoroshilov @ 2013-09-02 4:06 UTC (permalink / raw)
To: htl10
Cc: larry.finger, linville, linux-wireless, netdev, linux-kernel,
ldv-project, Greg Kroah-Hartman
On 01.09.2013 10:51, Hin-Tak Leung wrote:
> ------------------------------
> On Sat, Aug 31, 2013 22:18 BST Alexey Khoroshilov wrote:
>
>> 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>
>> ---
>> drivers/net/wireless/rtl818x/rtl8187/dev.c | 15 ++++++++++-----
>> 1 file changed, 10 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c
>> index f49220e..e83d53c 100644
>> --- a/drivers/net/wireless/rtl818x/rtl8187/dev.c
>> +++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c
>> @@ -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_free_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;
> This part looks wrong - you free_urb(entry) then unanchor_urb(entry).
I do not see any problems here.
usb_free_urb() just decrements refcnt of the urb.
While usb_anchor_urb() and usb_unanchor_urb() increment and decrement it
as well.
So actual memory deallocation will happen in usb_unanchor_urb().
>
>> @@ -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;
>> }
>>
>> @@ -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 |
>> --
>> 1.8.1.2
>>
>
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] rtl8187: fix use after free on failure path in rtl8187_init_urbs()
@ 2013-09-01 7:51 Hin-Tak Leung
2013-09-02 4:06 ` Alexey Khoroshilov
0 siblings, 1 reply; 5+ messages in thread
From: Hin-Tak Leung @ 2013-09-01 7:51 UTC (permalink / raw)
To: khoroshilov, herton, larry.finger
Cc: linville, linux-wireless, netdev, linux-kernel, ldv-project
------------------------------
On Sat, Aug 31, 2013 22:18 BST Alexey Khoroshilov wrote:
>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>
>---
> drivers/net/wireless/rtl818x/rtl8187/dev.c | 15 ++++++++++-----
> 1 file changed, 10 insertions(+), 5 deletions(-)
>
>diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c
>index f49220e..e83d53c 100644
>--- a/drivers/net/wireless/rtl818x/rtl8187/dev.c
>+++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c
>@@ -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_free_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;
This part looks wrong - you free_urb(entry) then unanchor_urb(entry).
>@@ -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;
> }
>
>@@ -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 |
>--
>1.8.1.2
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH] rtl8187: fix use after free on failure path in rtl8187_init_urbs()
@ 2013-08-31 21:18 Alexey Khoroshilov
0 siblings, 0 replies; 5+ messages in thread
From: Alexey Khoroshilov @ 2013-08-31 21:18 UTC (permalink / raw)
To: Herton Ronaldo Krzesinski, Hin-Tak Leung, Larry Finger
Cc: Alexey Khoroshilov, John W. Linville, linux-wireless, netdev,
linux-kernel, ldv-project
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>
---
drivers/net/wireless/rtl818x/rtl8187/dev.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c
index f49220e..e83d53c 100644
--- a/drivers/net/wireless/rtl818x/rtl8187/dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c
@@ -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_free_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;
@@ -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;
}
@@ -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 |
--
1.8.1.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2013-09-03 20:09 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-09-02 6:34 [PATCH] rtl8187: fix use after free on failure path in rtl8187_init_urbs() Hin-Tak Leung
2013-09-03 20:09 ` Alexey Khoroshilov
-- strict thread matches above, loose matches on Subject: below --
2013-09-01 7:51 Hin-Tak Leung
2013-09-02 4:06 ` Alexey Khoroshilov
2013-08-31 21:18 Alexey Khoroshilov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).