All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] compat-wireless:rt2800usb: Added rx packet length validity check
@ 2012-08-20 16:53 Sergei Poselenov
  2012-08-21 11:43 ` [rt2x00-users] " Stanislaw Gruszka
  0 siblings, 1 reply; 15+ messages in thread
From: Sergei Poselenov @ 2012-08-20 16:53 UTC (permalink / raw)
  To: users; +Cc: Luis R. Rodriguez, linux-wireless

On our system (ARM Cortex-M3 SOC running linux-2.6.33 with
compat-wireless-3.4-rc3-1 modules configured for rt2x00) frequent
crashes were observed in rt2800usb module because of the invalid
length of the received packet (3392, 46920...). This patch adds
the sanity check on the packet legth. In case of the bad length,
mark the packet as with CRC error.

The fix was also tested on the latest
compat-wireless-3.5.1-1-snpc.tar.bz2, applies cleanly.

Cc: stable@vger.kernel.org
Signed-off-by: Sergei Poselenov <sposelenov@emcraft.com>
---
 drivers/net/wireless/rt2x00/rt2800usb.c |   10 ++++++++--
 1 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/usbwifi/compat-wireless-3.4-rc3-1/drivers/net/wireless/rt2x00/rt2800usb.c b/usbwifi/compat-wireless-3.4-rc3-1/drivers/net/wireless/rt2x00/rt2800usb.c
index 001735f..6776ec8 100644
--- a/usbwifi/compat-wireless-3.4-rc3-1/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/usbwifi/compat-wireless-3.4-rc3-1/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -662,13 +662,18 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
 	rx_pkt_len = rt2x00_get_field32(word, RXINFO_W0_USB_DMA_RX_PKT_LEN);
 
 	/*
-	 * Remove the RXINFO structure from the sbk.
+	 * Remove the RXINFO structure from the skb.
 	 */
 	skb_pull(entry->skb, RXINFO_DESC_SIZE);
 
 	/*
-	 * FIXME: we need to check for rx_pkt_len validity
+	 * Check for rx_pkt_len validity, mark as failed.
 	 */
+	if (rx_pkt_len > entry->skb->len) {
+		rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
+		goto procrxwi;
+	}
+
 	rxd = (__le32 *)(entry->skb->data + rx_pkt_len);
 
 	/*
@@ -713,6 +718,7 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
 	 */
 	skb_trim(entry->skb, rx_pkt_len);
 
+procrxwi:
 	/*
 	 * Process the RXWI structure.
 	 */

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [rt2x00-users] [PATCH] compat-wireless:rt2800usb: Added rx packet length validity check
  2012-08-20 16:53 [PATCH] compat-wireless:rt2800usb: Added rx packet length validity check Sergei Poselenov
@ 2012-08-21 11:43 ` Stanislaw Gruszka
  2012-08-21 13:39   ` Ivo Van Doorn
                     ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Stanislaw Gruszka @ 2012-08-21 11:43 UTC (permalink / raw)
  To: Sergei Poselenov; +Cc: users, linux-wireless, Luis R. Rodriguez

On Mon, Aug 20, 2012 at 08:53:55PM +0400, Sergei Poselenov wrote:
> On our system (ARM Cortex-M3 SOC running linux-2.6.33 with
> compat-wireless-3.4-rc3-1 modules configured for rt2x00) frequent
Please remove compat-wireless reference here and in the subject.

> crashes were observed in rt2800usb module because of the invalid
> length of the received packet (3392, 46920...). This patch adds
> the sanity check on the packet legth. In case of the bad length,
> mark the packet as with CRC error.
> 
> The fix was also tested on the latest
> compat-wireless-3.5.1-1-snpc.tar.bz2, applies cleanly.
> 
> Cc: stable@vger.kernel.org
> Signed-off-by: Sergei Poselenov <sposelenov@emcraft.com>
> ---
>  drivers/net/wireless/rt2x00/rt2800usb.c |   10 ++++++++--
>  1 files changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/usbwifi/compat-wireless-3.4-rc3-1/drivers/net/wireless/rt2x00/rt2800usb.c b/usbwifi/compat-wireless-3.4-rc3-1/drivers/net/wireless/rt2x00/rt2800usb.c
> index 001735f..6776ec8 100644
> --- a/usbwifi/compat-wireless-3.4-rc3-1/drivers/net/wireless/rt2x00/rt2800usb.c
> +++ b/usbwifi/compat-wireless-3.4-rc3-1/drivers/net/wireless/rt2x00/rt2800usb.c
> @@ -662,13 +662,18 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
>  	rx_pkt_len = rt2x00_get_field32(word, RXINFO_W0_USB_DMA_RX_PKT_LEN);
>  
>  	/*
> -	 * Remove the RXINFO structure from the sbk.
> +	 * Remove the RXINFO structure from the skb.
>  	 */
>  	skb_pull(entry->skb, RXINFO_DESC_SIZE);
Would be great if you could post this as separate patch.

>  	/*
> -	 * FIXME: we need to check for rx_pkt_len validity
> +	 * Check for rx_pkt_len validity, mark as failed.
>  	 */
> +	if (rx_pkt_len > entry->skb->len) {
> +		rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
> +		goto procrxwi;

I would rather prefer something like 

if (unlikely(rx_pkt_len == 0 || rx_pkt_len > entry->queue->data_size)) {
 	/* Process error in rt2x00lib_rxdone() */
	rxdesc->size = rx_pkt_len;
	return;
}

Thanks
Stanislaw


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [rt2x00-users] [PATCH] compat-wireless:rt2800usb: Added rx packet length validity check
  2012-08-21 11:43 ` [rt2x00-users] " Stanislaw Gruszka
@ 2012-08-21 13:39   ` Ivo Van Doorn
  2012-08-21 14:18     ` Stanislaw Gruszka
  2012-08-26 13:53   ` [rt2x00-users] [PATCH] compat-wireless:rt2800usb: " Sergei Poselenov
  2012-08-26 13:56   ` [rt2x00-users] [PATCH] compat-wireless:rt2800usb: Fixed a typo Sergei Poselenov
  2 siblings, 1 reply; 15+ messages in thread
From: Ivo Van Doorn @ 2012-08-21 13:39 UTC (permalink / raw)
  To: Stanislaw Gruszka
  Cc: Sergei Poselenov, users, linux-wireless, Luis R. Rodriguez

On Tue, Aug 21, 2012 at 1:43 PM, Stanislaw Gruszka <sgruszka@redhat.com> wrote:
> On Mon, Aug 20, 2012 at 08:53:55PM +0400, Sergei Poselenov wrote:
>> On our system (ARM Cortex-M3 SOC running linux-2.6.33 with
>> compat-wireless-3.4-rc3-1 modules configured for rt2x00) frequent
> Please remove compat-wireless reference here and in the subject.
>
>> crashes were observed in rt2800usb module because of the invalid
>> length of the received packet (3392, 46920...). This patch adds
>> the sanity check on the packet legth. In case of the bad length,
>> mark the packet as with CRC error.
>>
>> The fix was also tested on the latest
>> compat-wireless-3.5.1-1-snpc.tar.bz2, applies cleanly.
>>
>> Cc: stable@vger.kernel.org
>> Signed-off-by: Sergei Poselenov <sposelenov@emcraft.com>
>> ---
>>  drivers/net/wireless/rt2x00/rt2800usb.c |   10 ++++++++--
>>  1 files changed, 8 insertions(+), 2 deletions(-)
>>
>> diff --git a/usbwifi/compat-wireless-3.4-rc3-1/drivers/net/wireless/rt2x00/rt2800usb.c b/usbwifi/compat-wireless-3.4-rc3-1/drivers/net/wireless/rt2x00/rt2800usb.c
>> index 001735f..6776ec8 100644
>> --- a/usbwifi/compat-wireless-3.4-rc3-1/drivers/net/wireless/rt2x00/rt2800usb.c
>> +++ b/usbwifi/compat-wireless-3.4-rc3-1/drivers/net/wireless/rt2x00/rt2800usb.c
>> @@ -662,13 +662,18 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
>>       rx_pkt_len = rt2x00_get_field32(word, RXINFO_W0_USB_DMA_RX_PKT_LEN);
>>
>>       /*
>> -      * Remove the RXINFO structure from the sbk.
>> +      * Remove the RXINFO structure from the skb.
>>        */
>>       skb_pull(entry->skb, RXINFO_DESC_SIZE);
> Would be great if you could post this as separate patch.
>
>>       /*
>> -      * FIXME: we need to check for rx_pkt_len validity
>> +      * Check for rx_pkt_len validity, mark as failed.
>>        */
>> +     if (rx_pkt_len > entry->skb->len) {
>> +             rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
>> +             goto procrxwi;
>
> I would rather prefer something like
>
> if (unlikely(rx_pkt_len == 0 || rx_pkt_len > entry->queue->data_size)) {
>         /* Process error in rt2x00lib_rxdone() */
>         rxdesc->size = rx_pkt_len;
>         return;
> }

But how do you know the packet is correct then? Obviously something is wrong,
so just resetting the rxdesc->size wouldn't be a solution right?

Ivo

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [rt2x00-users] [PATCH] compat-wireless:rt2800usb: Added rx packet length validity check
  2012-08-21 13:39   ` Ivo Van Doorn
@ 2012-08-21 14:18     ` Stanislaw Gruszka
  2012-08-21 20:07       ` Gertjan van Wingerde
  0 siblings, 1 reply; 15+ messages in thread
From: Stanislaw Gruszka @ 2012-08-21 14:18 UTC (permalink / raw)
  To: Ivo Van Doorn; +Cc: Sergei Poselenov, users, linux-wireless, Luis R. Rodriguez

On Tue, Aug 21, 2012 at 03:39:41PM +0200, Ivo Van Doorn wrote:
> On Tue, Aug 21, 2012 at 1:43 PM, Stanislaw Gruszka <sgruszka@redhat.com> wrote:
> > On Mon, Aug 20, 2012 at 08:53:55PM +0400, Sergei Poselenov wrote:
> >> On our system (ARM Cortex-M3 SOC running linux-2.6.33 with
> >> compat-wireless-3.4-rc3-1 modules configured for rt2x00) frequent
> > Please remove compat-wireless reference here and in the subject.
> >
> >> crashes were observed in rt2800usb module because of the invalid
> >> length of the received packet (3392, 46920...). This patch adds
> >> the sanity check on the packet legth. In case of the bad length,
> >> mark the packet as with CRC error.
> >>
> >> The fix was also tested on the latest
> >> compat-wireless-3.5.1-1-snpc.tar.bz2, applies cleanly.
> >>
> >> Cc: stable@vger.kernel.org
> >> Signed-off-by: Sergei Poselenov <sposelenov@emcraft.com>
> >> ---
> >>  drivers/net/wireless/rt2x00/rt2800usb.c |   10 ++++++++--
> >>  1 files changed, 8 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/usbwifi/compat-wireless-3.4-rc3-1/drivers/net/wireless/rt2x00/rt2800usb.c b/usbwifi/compat-wireless-3.4-rc3-1/drivers/net/wireless/rt2x00/rt2800usb.c
> >> index 001735f..6776ec8 100644
> >> --- a/usbwifi/compat-wireless-3.4-rc3-1/drivers/net/wireless/rt2x00/rt2800usb.c
> >> +++ b/usbwifi/compat-wireless-3.4-rc3-1/drivers/net/wireless/rt2x00/rt2800usb.c
> >> @@ -662,13 +662,18 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
> >>       rx_pkt_len = rt2x00_get_field32(word, RXINFO_W0_USB_DMA_RX_PKT_LEN);
> >>
> >>       /*
> >> -      * Remove the RXINFO structure from the sbk.
> >> +      * Remove the RXINFO structure from the skb.
> >>        */
> >>       skb_pull(entry->skb, RXINFO_DESC_SIZE);
> > Would be great if you could post this as separate patch.
> >
> >>       /*
> >> -      * FIXME: we need to check for rx_pkt_len validity
> >> +      * Check for rx_pkt_len validity, mark as failed.
> >>        */
> >> +     if (rx_pkt_len > entry->skb->len) {
> >> +             rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
> >> +             goto procrxwi;
> >
> > I would rather prefer something like
> >
> > if (unlikely(rx_pkt_len == 0 || rx_pkt_len > entry->queue->data_size)) {
> >         /* Process error in rt2x00lib_rxdone() */
> >         rxdesc->size = rx_pkt_len;
> >         return;
> > }
> 
> But how do you know the packet is correct then?
Non zero rx_pkt_len smaller than data_size indicate correct package.

> Obviously something is wrong,
> so just resetting the rxdesc->size wouldn't be a solution right?

rt2x00lib_rxdone has rxdesc->size check too, if ->size is bad it 
prints warning, and requeue skb. 

Perhaps this could be coded in some cleaner way (avoid double check),
but basically this should do the job. 

Stanislaw

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [rt2x00-users] [PATCH] compat-wireless:rt2800usb: Added rx packet length validity check
  2012-08-21 14:18     ` Stanislaw Gruszka
@ 2012-08-21 20:07       ` Gertjan van Wingerde
  2012-08-22  9:27         ` Stanislaw Gruszka
  0 siblings, 1 reply; 15+ messages in thread
From: Gertjan van Wingerde @ 2012-08-21 20:07 UTC (permalink / raw)
  To: Stanislaw Gruszka
  Cc: Ivo Van Doorn, Sergei Poselenov, users, linux-wireless,
	Luis R. Rodriguez

On 21 aug. 2012, at 16:18, Stanislaw Gruszka <sgruszka@redhat.com> wrote:

> On Tue, Aug 21, 2012 at 03:39:41PM +0200, Ivo Van Doorn wrote:
>> On Tue, Aug 21, 2012 at 1:43 PM, Stanislaw Gruszka <sgruszka@redhat.com> wrote:
>>> On Mon, Aug 20, 2012 at 08:53:55PM +0400, Sergei Poselenov wrote:
>>>> On our system (ARM Cortex-M3 SOC running linux-2.6.33 with
>>>> compat-wireless-3.4-rc3-1 modules configured for rt2x00) frequent
>>> Please remove compat-wireless reference here and in the subject.
>>> 
>>>> crashes were observed in rt2800usb module because of the invalid
>>>> length of the received packet (3392, 46920...). This patch adds
>>>> the sanity check on the packet legth. In case of the bad length,
>>>> mark the packet as with CRC error.
>>>> 
>>>> The fix was also tested on the latest
>>>> compat-wireless-3.5.1-1-snpc.tar.bz2, applies cleanly.
>>>> 
>>>> Cc: stable@vger.kernel.org
>>>> Signed-off-by: Sergei Poselenov <sposelenov@emcraft.com>
>>>> ---
>>>> drivers/net/wireless/rt2x00/rt2800usb.c |   10 ++++++++--
>>>> 1 files changed, 8 insertions(+), 2 deletions(-)
>>>> 
>>>> diff --git a/usbwifi/compat-wireless-3.4-rc3-1/drivers/net/wireless/rt2x00/rt2800usb.c b/usbwifi/compat-wireless-3.4-rc3-1/drivers/net/wireless/rt2x00/rt2800usb.c
>>>> index 001735f..6776ec8 100644
>>>> --- a/usbwifi/compat-wireless-3.4-rc3-1/drivers/net/wireless/rt2x00/rt2800usb.c
>>>> +++ b/usbwifi/compat-wireless-3.4-rc3-1/drivers/net/wireless/rt2x00/rt2800usb.c
>>>> @@ -662,13 +662,18 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
>>>>      rx_pkt_len = rt2x00_get_field32(word, RXINFO_W0_USB_DMA_RX_PKT_LEN);
>>>> 
>>>>      /*
>>>> -      * Remove the RXINFO structure from the sbk.
>>>> +      * Remove the RXINFO structure from the skb.
>>>>       */
>>>>      skb_pull(entry->skb, RXINFO_DESC_SIZE);
>>> Would be great if you could post this as separate patch.
>>> 
>>>>      /*
>>>> -      * FIXME: we need to check for rx_pkt_len validity
>>>> +      * Check for rx_pkt_len validity, mark as failed.
>>>>       */
>>>> +     if (rx_pkt_len > entry->skb->len) {
>>>> +             rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
>>>> +             goto procrxwi;
>>> 
>>> I would rather prefer something like
>>> 
>>> if (unlikely(rx_pkt_len == 0 || rx_pkt_len > entry->queue->data_size)) {
>>>        /* Process error in rt2x00lib_rxdone() */
>>>        rxdesc->size = rx_pkt_len;
>>>        return;
>>> }
>> 
>> But how do you know the packet is correct then?
> Non zero rx_pkt_len smaller than data_size indicate correct package.

To be honest, I think the original approach of Sergei is better. Not touching rxdesc beyond setting the flag will ensure that rt2x00lib_rxdone will simply bounce the skb without handing an invalid packet over to mac80211. That said, it isn't necessary to set the flag. Just returning from the function is good enough.

However, the check that Sergei does is not correct either. The real check that should be done is checking whether the skb has enough data to hold both rx_pkt_len bytes + the size of the rxd, which is 1 word (4 bytes). If only rx_pkt_len are left we don't have an rxd, and is the usb packet invalid as well.

> 
>> Obviously something is wrong,
>> so just resetting the rxdesc->size wouldn't be a solution right?
> 
> rt2x00lib_rxdone has rxdesc->size check too, if ->size is bad it 
> prints warning, and requeue skb. 
> 
> Perhaps this could be coded in some cleaner way (avoid double check),
> but basically this should do the job. 

As I mentioned above, simply bailing out if rt2800usb_fill_rxdone without doing anything (not even setting a flag) should do the trick and IMHO is the cleanest approach.

---
Gertjan

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [rt2x00-users] [PATCH] compat-wireless:rt2800usb: Added rx packet length validity check
  2012-08-21 20:07       ` Gertjan van Wingerde
@ 2012-08-22  9:27         ` Stanislaw Gruszka
  2012-08-22 20:41           ` Gertjan van Wingerde
  0 siblings, 1 reply; 15+ messages in thread
From: Stanislaw Gruszka @ 2012-08-22  9:27 UTC (permalink / raw)
  To: Gertjan van Wingerde
  Cc: Ivo Van Doorn, Sergei Poselenov, users, linux-wireless,
	Luis R. Rodriguez

On Tue, Aug 21, 2012 at 10:07:03PM +0200, Gertjan van Wingerde wrote:
> >>>> +     if (rx_pkt_len > entry->skb->len) {
> >>>> +             rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
> >>>> +             goto procrxwi;
> >>> 
> >>> I would rather prefer something like
> >>> 
> >>> if (unlikely(rx_pkt_len == 0 || rx_pkt_len > entry->queue->data_size)) {
> >>>        /* Process error in rt2x00lib_rxdone() */
> >>>        rxdesc->size = rx_pkt_len;
> >>>        return;
> >>> }
> >> 
> >> But how do you know the packet is correct then?
> > Non zero rx_pkt_len smaller than data_size indicate correct package.
> 
> To be honest, I think the original approach of Sergei is better. Not touching rxdesc beyond setting the flag will ensure that rt2x00lib_rxdone will simply bounce the skb without handing an invalid packet over to mac80211. That said, it isn't necessary to set the flag. Just returning from the function is good enough.
> 
> However, the check that Sergei does is not correct either. The real check that should be done is checking whether the skb has enough data to hold both rx_pkt_len bytes + the size of the rxd, which is 1 word (4 bytes). If only rx_pkt_len are left we don't have an rxd, and is the usb packet invalid as well.

Yes, but there is also usb alignment on skb->len, so is better to use
queue->data_size to validate rx_pkt (data) length IMHO.

> >> Obviously something is wrong,
> >> so just resetting the rxdesc->size wouldn't be a solution right?
> > 
> > rt2x00lib_rxdone has rxdesc->size check too, if ->size is bad it 
> > prints warning, and requeue skb. 
> > 
> > Perhaps this could be coded in some cleaner way (avoid double check),
> > but basically this should do the job. 
> 
> As I mentioned above, simply bailing out if rt2800usb_fill_rxdone without doing anything (not even setting a flag) should do the trick and IMHO is the cleanest approach.

IIRC this is basically what I proposed, except without setting
rxdesc->size, unlikely() and rx_pkt_len == 0 check. It will work as
rxdesc->size will be 0. But I think it would be better, if WARNING on
rt2x00lib_rxdone() will print actual corrupted size instead of 0.
Having unlikely is good too - this must be unlikely situation.

BTW: would be good to fix reason of that corruption if possible
(as long this is not a H/W or F/W bug). But for now, let just
stop kernel crashing. Printing WARNING on this situation will
help to identify there is something wrong if someone will observe
performance problems or similar.

Thanks
Stanislaw

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [rt2x00-users] [PATCH] compat-wireless:rt2800usb: Added rx packet length validity check
  2012-08-22  9:27         ` Stanislaw Gruszka
@ 2012-08-22 20:41           ` Gertjan van Wingerde
  2012-08-22 21:16             ` Stanislaw Gruszka
                               ` (3 more replies)
  0 siblings, 4 replies; 15+ messages in thread
From: Gertjan van Wingerde @ 2012-08-22 20:41 UTC (permalink / raw)
  To: Stanislaw Gruszka
  Cc: Ivo Van Doorn, Sergei Poselenov, users, linux-wireless,
	Luis R. Rodriguez

Hi Stanislaw,

On 22 aug. 2012, at 11:27, Stanislaw Gruszka <sgruszka@redhat.com> wrote:

> On Tue, Aug 21, 2012 at 10:07:03PM +0200, Gertjan van Wingerde wrote:
>>>>>> +     if (rx_pkt_len > entry->skb->len) {
>>>>>> +             rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
>>>>>> +             goto procrxwi;
>>>>> 
>>>>> I would rather prefer something like
>>>>> 
>>>>> if (unlikely(rx_pkt_len == 0 || rx_pkt_len > entry->queue->data_size)) {
>>>>>       /* Process error in rt2x00lib_rxdone() */
>>>>>       rxdesc->size = rx_pkt_len;
>>>>>       return;
>>>>> }
>>>> 
>>>> But how do you know the packet is correct then?
>>> Non zero rx_pkt_len smaller than data_size indicate correct package.
>> 
>> To be honest, I think the original approach of Sergei is better. Not touching rxdesc beyond setting the flag will ensure that rt2x00lib_rxdone will simply bounce the skb without handing an invalid packet over to mac80211. That said, it isn't necessary to set the flag. Just returning from the function is good enough.
>> 
>> However, the check that Sergei does is not correct either. The real check that should be done is checking whether the skb has enough data to hold both rx_pkt_len bytes + the size of the rxd, which is 1 word (4 bytes). If only rx_pkt_len are left we don't have an rxd, and is the usb packet invalid as well.
> 
> Yes, but there is also usb alignment on skb->len, so is better to use
> queue->data_size to validate rx_pkt (data) length IMHO.

Oh, well it's an (almost) equivalent test anyway, so I guess I don't care.

> 
>>>> Obviously something is wrong,
>>>> so just resetting the rxdesc->size wouldn't be a solution right?
>>> 
>>> rt2x00lib_rxdone has rxdesc->size check too, if ->size is bad it 
>>> prints warning, and requeue skb. 
>>> 
>>> Perhaps this could be coded in some cleaner way (avoid double check),
>>> but basically this should do the job. 
>> 
>> As I mentioned above, simply bailing out if rt2800usb_fill_rxdone without doing anything (not even setting a flag) should do the trick and IMHO is the cleanest approach.
> 
> IIRC this is basically what I proposed, except without setting
> rxdesc->size, unlikely() and rx_pkt_len == 0 check. It will work as
> rxdesc->size will be 0. But I think it would be better, if WARNING on
> rt2x00lib_rxdone() will print actual corrupted size instead of 0.
> Having unlikely is good too - this must be unlikely situation.

OK, I agree with the use of unlikely(). An rx_pkt_len of 0 doesn't seem to happen in practice, so testing for it seems superfluous, but may be providing some extra safety. Don't really care about that. I really don't think we should set rxdesc->size, as we cannot determine it. If we want to print the value, then do it in this function. Adding a hack to having it printed somewhere else doesn't seem right to me.
Also, it should be an error log message, not a WARNING. There's no need to have a stack trace as the buffer is filled by HW, not by some other function. So, the use of WARNING, with its stack dumping functionality is overkill.


> 
> BTW: would be good to fix reason of that corruption if possible
> (as long this is not a H/W or F/W bug). But for now, let just
> stop kernel crashing. Printing WARNING on this situation will
> help to identify there is something wrong if someone will observe
> performance problems or similar.

I think this is a HW issue. As mentioned above, I believe a WARNING here is overkill, as we don't need the stack trace.

Anyway, Sergei, would you be able to modify the patch along the lines of the discussion?

---
Gertjan

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [rt2x00-users] [PATCH] compat-wireless:rt2800usb: Added rx packet length validity check
  2012-08-22 20:41           ` Gertjan van Wingerde
@ 2012-08-22 21:16             ` Stanislaw Gruszka
  2012-08-23  5:46             ` Sergei Poselenov
                               ` (2 subsequent siblings)
  3 siblings, 0 replies; 15+ messages in thread
From: Stanislaw Gruszka @ 2012-08-22 21:16 UTC (permalink / raw)
  To: Gertjan van Wingerde
  Cc: Ivo Van Doorn, Sergei Poselenov, users, linux-wireless,
	Luis R. Rodriguez

Hi Gertjan
 
On Wed, Aug 22, 2012 at 10:41:42PM +0200, Gertjan van Wingerde wrote:
> > IIRC this is basically what I proposed, except without setting
> > rxdesc->size, unlikely() and rx_pkt_len == 0 check. It will work as
> > rxdesc->size will be 0. But I think it would be better, if WARNING on
> > rt2x00lib_rxdone() will print actual corrupted size instead of 0.
> > Having unlikely is good too - this must be unlikely situation.
> 
> OK, I agree with the use of unlikely(). An rx_pkt_len of 0 doesn't seem to happen in practice, so testing for it seems superfluous, but may be providing some extra safety. Don't really care about that. I really don't think we should set rxdesc->size, as we cannot determine it. If we want to print the value, then do it in this function. Adding a hack to having it printed somewhere else doesn't seem right to me.
> Also, it should be an error log message, not a WARNING. There's no need to have a stack trace as the buffer is filled by HW, not by some other function. So, the use of WARNING, with its stack dumping functionality is overkill.
> 
> 
> > 
> > BTW: would be good to fix reason of that corruption if possible
> > (as long this is not a H/W or F/W bug). But for now, let just
> > stop kernel crashing. Printing WARNING on this situation will
> > help to identify there is something wrong if someone will observe
> > performance problems or similar.
> 
> I think this is a HW issue. As mentioned above, I believe a WARNING here is overkill, as we don't need the stack trace.

I was talking about this WARNING in rt2x00lib_rxdone() (which is not
WARN_ON() or WARN() - so no stactrace):

	/*
	 * Check for valid size in case we get corrupted descriptor from
	 * hardware.
	 */
	if (unlikely(rxdesc.size == 0 ||
		     rxdesc.size > entry->queue->data_size)) {
		WARNING(rt2x00dev, "Wrong frame size %d max %d.\n",
			rxdesc.size, entry->queue->data_size);
		dev_kfree_skb(entry->skb);
		goto renew_skb;
	}


I agree that using ERROR is better.
 
> Anyway, Sergei, would you be able to modify the patch along the lines of the discussion?

I hope so :-)

Thanks
Stanislaw

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [rt2x00-users] [PATCH] compat-wireless:rt2800usb: Added rx packet length validity check
  2012-08-22 20:41           ` Gertjan van Wingerde
  2012-08-22 21:16             ` Stanislaw Gruszka
@ 2012-08-23  5:46             ` Sergei Poselenov
  2012-08-26 13:19             ` Sergei Poselenov
  2012-09-02  9:14             ` [rt2x00-users] [PATCH V2]: rt2800usb: " Sergei Poselenov
  3 siblings, 0 replies; 15+ messages in thread
From: Sergei Poselenov @ 2012-08-23  5:46 UTC (permalink / raw)
  To: Gertjan van Wingerde
  Cc: Stanislaw Gruszka, Ivo Van Doorn, users, linux-wireless,
	Luis R. Rodriguez

Hello guys,

On Wed, 2012-08-22 at 22:41 +0200, Gertjan van Wingerde wrote:
> 
> Anyway, Sergei, would you be able to modify the patch along the lines
> of the discussion? 

Yes, I've been watching your discussion. I hope I'll be able to come up
with a new version shortly.

Regards,
Sergei


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [rt2x00-users] [PATCH] compat-wireless:rt2800usb: Added rx packet length validity check
  2012-08-22 20:41           ` Gertjan van Wingerde
  2012-08-22 21:16             ` Stanislaw Gruszka
  2012-08-23  5:46             ` Sergei Poselenov
@ 2012-08-26 13:19             ` Sergei Poselenov
  2012-09-02  9:14             ` [rt2x00-users] [PATCH V2]: rt2800usb: " Sergei Poselenov
  3 siblings, 0 replies; 15+ messages in thread
From: Sergei Poselenov @ 2012-08-26 13:19 UTC (permalink / raw)
  To: Gertjan van Wingerde
  Cc: Stanislaw Gruszka, Ivo Van Doorn, users, linux-wireless,
	Luis R. Rodriguez

All, 

On Wed, 2012-08-22 at 22:41 +0200, Gertjan van Wingerde wrote:
> Hi Stanislaw,
> 
> On 22 aug. 2012, at 11:27, Stanislaw Gruszka <sgruszka@redhat.com> wrote:
> 
> > On Tue, Aug 21, 2012 at 10:07:03PM +0200, Gertjan van Wingerde wrote:
> >>>>>> +     if (rx_pkt_len > entry->skb->len) {
> >>>>>> +             rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
> >>>>>> +             goto procrxwi;
> >>>>> 
> >>>>> I would rather prefer something like
> >>>>> 
> >>>>> if (unlikely(rx_pkt_len == 0 || rx_pkt_len > entry->queue->data_size)) {
> >>>>>       /* Process error in rt2x00lib_rxdone() */
> >>>>>       rxdesc->size = rx_pkt_len;
> >>>>>       return;
> >>>>> }
> >>>> 
> >>>> But how do you know the packet is correct then?
> >>> Non zero rx_pkt_len smaller than data_size indicate correct package.
> >> 
> >> To be honest, I think the original approach of Sergei is better. Not touching rxdesc beyond setting the flag will ensure that rt2x00lib_rxdone will simply bounce the skb without handing an invalid packet over to mac80211. That said, it isn't necessary to set the flag. Just returning from the function is good enough.
> >> 
> >> However, the check that Sergei does is not correct either. The real check that should be done is checking whether the skb has enough data to hold both rx_pkt_len bytes + the size of the rxd, which is 1 word (4 bytes). If only rx_pkt_len are left we don't have an rxd, and is the usb packet invalid as well.
> > 
> > Yes, but there is also usb alignment on skb->len, so is better to use
> > queue->data_size to validate rx_pkt (data) length IMHO.
> 
> Oh, well it's an (almost) equivalent test anyway, so I guess I don't care.
> 
> > 
> >>>> Obviously something is wrong,
> >>>> so just resetting the rxdesc->size wouldn't be a solution right?
> >>> 
> >>> rt2x00lib_rxdone has rxdesc->size check too, if ->size is bad it 
> >>> prints warning, and requeue skb. 
> >>> 
> >>> Perhaps this could be coded in some cleaner way (avoid double check),
> >>> but basically this should do the job. 
> >> 
> >> As I mentioned above, simply bailing out if rt2800usb_fill_rxdone without doing anything (not even setting a flag) should do the trick and IMHO is the cleanest approach.
> > 
> > IIRC this is basically what I proposed, except without setting
> > rxdesc->size, unlikely() and rx_pkt_len == 0 check. It will work as
> > rxdesc->size will be 0. But I think it would be better, if WARNING on
> > rt2x00lib_rxdone() will print actual corrupted size instead of 0.
> > Having unlikely is good too - this must be unlikely situation.
> 
> OK, I agree with the use of unlikely(). An rx_pkt_len of 0 doesn't seem to happen in practice, so testing for it seems superfluous, but may be providing some extra safety. Don't really care about that. I really don't think we should set rxdesc->size, as we cannot determine it. If we want to print the value, then do it in this function. Adding a hack to having it printed somewhere else doesn't seem right to me.

OK, I modified the check and changed WARNING() to ERROR() in
rt2x00lib_rxdone() as Stanislaw suggested.

Now the error messages looks like follows:
...
phy0 -> rt2800usb_fill_rxdone: Error - Bad frame length 12354, forcing to 0
phy0 -> rt2x00lib_rxdone: Error - Wrong frame size 0 max 3840.
...

OK to submit the final patch?

Regards,
Sergei

> Also, it should be an error log message, not a WARNING. There's no need to have a stack trace as the buffer is filled by HW, not by some other function. So, the use of WARNING, with its stack dumping functionality is overkill.
> 
> 
> > 
> > BTW: would be good to fix reason of that corruption if possible
> > (as long this is not a H/W or F/W bug). But for now, let just
> > stop kernel crashing. Printing WARNING on this situation will
> > help to identify there is something wrong if someone will observe
> > performance problems or similar.
> 
> I think this is a HW issue. As mentioned above, I believe a WARNING here is overkill, as we don't need the stack trace.
> 
> Anyway, Sergei, would you be able to modify the patch along the lines of the discussion?
> 
> ---
> Gertjan



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [rt2x00-users] [PATCH] compat-wireless:rt2800usb: Added rx packet length validity check
  2012-08-21 11:43 ` [rt2x00-users] " Stanislaw Gruszka
  2012-08-21 13:39   ` Ivo Van Doorn
@ 2012-08-26 13:53   ` Sergei Poselenov
  2012-08-26 13:56   ` [rt2x00-users] [PATCH] compat-wireless:rt2800usb: Fixed a typo Sergei Poselenov
  2 siblings, 0 replies; 15+ messages in thread
From: Sergei Poselenov @ 2012-08-26 13:53 UTC (permalink / raw)
  To: Stanislaw Gruszka; +Cc: users, linux-wireless, Luis R. Rodriguez

Stanislaw,

On Tue, 2012-08-21 at 13:43 +0200, Stanislaw Gruszka wrote:
> >       /*
> > -      * Remove the RXINFO structure from the sbk.
> > +      * Remove the RXINFO structure from the skb.
> >        */
> >       skb_pull(entry->skb, RXINFO_DESC_SIZE);
> Would be great if you could post this as separate patch.

I'm sending the patch for this typo in the follow-up email.

Regards,
Sergei


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [rt2x00-users] [PATCH] compat-wireless:rt2800usb: Fixed a typo
  2012-08-21 11:43 ` [rt2x00-users] " Stanislaw Gruszka
  2012-08-21 13:39   ` Ivo Van Doorn
  2012-08-26 13:53   ` [rt2x00-users] [PATCH] compat-wireless:rt2800usb: " Sergei Poselenov
@ 2012-08-26 13:56   ` Sergei Poselenov
  2012-08-27  8:23     ` Ivo Van Doorn
  2 siblings, 1 reply; 15+ messages in thread
From: Sergei Poselenov @ 2012-08-26 13:56 UTC (permalink / raw)
  To: Stanislaw Gruszka; +Cc: users, linux-wireless, Luis R. Rodriguez

Fixed a typo in the comment.

Cc: stable@vger.kernel.org
Signed-off-by: Sergei Poselenov <sposelenov@emcraft.com>
---
 drivers/net/wireless/rt2x00/rt2800usb.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 6cf3365..f8085b2 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -662,7 +662,7 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
 	rx_pkt_len = rt2x00_get_field32(word, RXINFO_W0_USB_DMA_RX_PKT_LEN);
 
 	/*
-	 * Remove the RXINFO structure from the sbk.
+	 * Remove the RXINFO structure from the skb.
 	 */
 	skb_pull(entry->skb, RXINFO_DESC_SIZE);
 
-- 
1.7.4.4




^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [rt2x00-users] [PATCH] compat-wireless:rt2800usb: Fixed a typo
  2012-08-26 13:56   ` [rt2x00-users] [PATCH] compat-wireless:rt2800usb: Fixed a typo Sergei Poselenov
@ 2012-08-27  8:23     ` Ivo Van Doorn
  0 siblings, 0 replies; 15+ messages in thread
From: Ivo Van Doorn @ 2012-08-27  8:23 UTC (permalink / raw)
  To: Sergei Poselenov
  Cc: Stanislaw Gruszka, users, linux-wireless, Luis R. Rodriguez

On Sun, Aug 26, 2012 at 3:56 PM, Sergei Poselenov
<sposelenov@emcraft.com> wrote:
> Fixed a typo in the comment.
>
> Cc: stable@vger.kernel.org
> Signed-off-by: Sergei Poselenov <sposelenov@emcraft.com>

Acked-by: Ivo van Doorn <IvDoorn@gmail.com>

> ---
>  drivers/net/wireless/rt2x00/rt2800usb.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
> index 6cf3365..f8085b2 100644
> --- a/drivers/net/wireless/rt2x00/rt2800usb.c
> +++ b/drivers/net/wireless/rt2x00/rt2800usb.c
> @@ -662,7 +662,7 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
>         rx_pkt_len = rt2x00_get_field32(word, RXINFO_W0_USB_DMA_RX_PKT_LEN);
>
>         /*
> -        * Remove the RXINFO structure from the sbk.
> +        * Remove the RXINFO structure from the skb.
>          */
>         skb_pull(entry->skb, RXINFO_DESC_SIZE);
>
> --
> 1.7.4.4
>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [rt2x00-users] [PATCH V2]: rt2800usb: Added rx packet length validity check
  2012-08-22 20:41           ` Gertjan van Wingerde
                               ` (2 preceding siblings ...)
  2012-08-26 13:19             ` Sergei Poselenov
@ 2012-09-02  9:14             ` Sergei Poselenov
  2012-09-02 20:35               ` Ivo Van Doorn
  3 siblings, 1 reply; 15+ messages in thread
From: Sergei Poselenov @ 2012-09-02  9:14 UTC (permalink / raw)
  To: Gertjan van Wingerde
  Cc: Stanislaw Gruszka, Ivo Van Doorn, users, linux-wireless,
	Luis R. Rodriguez

On our system (ARM Cortex-M3 SOC running linux-2.6.33)
frequent crashes were observed in the rt2800usb module
because of the invalid length of the received packet (3392,
46920...). This patch adds the sanity check on the packet
legth. Also, changed WARNING to ERROR in rt2x00lib_rxdone()
so that the bad packet condition would be noticed.

The fix was tested on the latest compat-wireless-3.5.1-1-snpc.

Cc: stable@vger.kernel.org
Signed-off-by: Sergei Poselenov <sposelenov@emcraft.com>
---
 drivers/net/wireless/rt2x00/rt2800usb.c |   10 +++++++++-
 drivers/net/wireless/rt2x00/rt2x00dev.c |    2 +-
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index f8085b2..48df102 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -667,8 +667,16 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
 	skb_pull(entry->skb, RXINFO_DESC_SIZE);
 
 	/*
-	 * FIXME: we need to check for rx_pkt_len validity
+	 * Check for rx_pkt_len validity. Return if invalid, leaving
+	 * rxdesc->size zeroed out by the upper level.
 	 */
+	if (unlikely(rx_pkt_len == 0 ||
+			rx_pkt_len > entry->queue->data_size)) {
+		ERROR(entry->queue->rt2x00dev,
+			"Bad frame size %d, forcing to 0\n", rx_pkt_len);
+		return;
+	}
+
 	rxd = (__le32 *)(entry->skb->data + rx_pkt_len);
 
 	/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index a59048f..10cf672 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -629,7 +629,7 @@ void rt2x00lib_rxdone(struct queue_entry *entry, gfp_t gfp)
 	 */
 	if (unlikely(rxdesc.size == 0 ||
 		     rxdesc.size > entry->queue->data_size)) {
-		WARNING(rt2x00dev, "Wrong frame size %d max %d.\n",
+		ERROR(rt2x00dev, "Wrong frame size %d max %d.\n",
 			rxdesc.size, entry->queue->data_size);
 		dev_kfree_skb(entry->skb);
 		goto renew_skb;
-- 
1.7.4.4




^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [rt2x00-users] [PATCH V2]: rt2800usb: Added rx packet length validity check
  2012-09-02  9:14             ` [rt2x00-users] [PATCH V2]: rt2800usb: " Sergei Poselenov
@ 2012-09-02 20:35               ` Ivo Van Doorn
  0 siblings, 0 replies; 15+ messages in thread
From: Ivo Van Doorn @ 2012-09-02 20:35 UTC (permalink / raw)
  To: Sergei Poselenov
  Cc: Gertjan van Wingerde, Stanislaw Gruszka, users, linux-wireless,
	Luis R. Rodriguez

On Sun, Sep 2, 2012 at 11:14 AM, Sergei Poselenov
<sposelenov@emcraft.com> wrote:
> On our system (ARM Cortex-M3 SOC running linux-2.6.33)
> frequent crashes were observed in the rt2800usb module
> because of the invalid length of the received packet (3392,
> 46920...). This patch adds the sanity check on the packet
> legth. Also, changed WARNING to ERROR in rt2x00lib_rxdone()
> so that the bad packet condition would be noticed.
>
> The fix was tested on the latest compat-wireless-3.5.1-1-snpc.
>
> Cc: stable@vger.kernel.org
> Signed-off-by: Sergei Poselenov <sposelenov@emcraft.com>

Acked-by: Ivo van Doorn <IvDoorn@gmail.com>

> ---
>  drivers/net/wireless/rt2x00/rt2800usb.c |   10 +++++++++-
>  drivers/net/wireless/rt2x00/rt2x00dev.c |    2 +-
>  2 files changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
> index f8085b2..48df102 100644
> --- a/drivers/net/wireless/rt2x00/rt2800usb.c
> +++ b/drivers/net/wireless/rt2x00/rt2800usb.c
> @@ -667,8 +667,16 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
>         skb_pull(entry->skb, RXINFO_DESC_SIZE);
>
>         /*
> -        * FIXME: we need to check for rx_pkt_len validity
> +        * Check for rx_pkt_len validity. Return if invalid, leaving
> +        * rxdesc->size zeroed out by the upper level.
>          */
> +       if (unlikely(rx_pkt_len == 0 ||
> +                       rx_pkt_len > entry->queue->data_size)) {
> +               ERROR(entry->queue->rt2x00dev,
> +                       "Bad frame size %d, forcing to 0\n", rx_pkt_len);
> +               return;
> +       }
> +
>         rxd = (__le32 *)(entry->skb->data + rx_pkt_len);
>
>         /*
> diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
> index a59048f..10cf672 100644
> --- a/drivers/net/wireless/rt2x00/rt2x00dev.c
> +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
> @@ -629,7 +629,7 @@ void rt2x00lib_rxdone(struct queue_entry *entry, gfp_t gfp)
>          */
>         if (unlikely(rxdesc.size == 0 ||
>                      rxdesc.size > entry->queue->data_size)) {
> -               WARNING(rt2x00dev, "Wrong frame size %d max %d.\n",
> +               ERROR(rt2x00dev, "Wrong frame size %d max %d.\n",
>                         rxdesc.size, entry->queue->data_size);
>                 dev_kfree_skb(entry->skb);
>                 goto renew_skb;
> --
> 1.7.4.4
>
>
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2012-09-02 20:35 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-20 16:53 [PATCH] compat-wireless:rt2800usb: Added rx packet length validity check Sergei Poselenov
2012-08-21 11:43 ` [rt2x00-users] " Stanislaw Gruszka
2012-08-21 13:39   ` Ivo Van Doorn
2012-08-21 14:18     ` Stanislaw Gruszka
2012-08-21 20:07       ` Gertjan van Wingerde
2012-08-22  9:27         ` Stanislaw Gruszka
2012-08-22 20:41           ` Gertjan van Wingerde
2012-08-22 21:16             ` Stanislaw Gruszka
2012-08-23  5:46             ` Sergei Poselenov
2012-08-26 13:19             ` Sergei Poselenov
2012-09-02  9:14             ` [rt2x00-users] [PATCH V2]: rt2800usb: " Sergei Poselenov
2012-09-02 20:35               ` Ivo Van Doorn
2012-08-26 13:53   ` [rt2x00-users] [PATCH] compat-wireless:rt2800usb: " Sergei Poselenov
2012-08-26 13:56   ` [rt2x00-users] [PATCH] compat-wireless:rt2800usb: Fixed a typo Sergei Poselenov
2012-08-27  8:23     ` Ivo Van Doorn

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.