diff options
author | John W. Linville <linville@tuxdriver.com> | 2007-10-02 00:03:54 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2007-10-02 00:03:54 -0400 |
commit | 04045f98e0457aba7d4e6736f37eed189c48a5f7 (patch) | |
tree | c7b927f223e6648885ef6fc3a60d073df883ef82 /net/ieee80211/ieee80211_rx.c | |
parent | 9b42c336d06411e6463949d2dac63949f66ff70b (diff) |
[IEEE80211]: avoid integer underflow for runt rx frames
Reported by Chris Evans <scarybeasts@gmail.com>:
> The summary is that an evil 80211 frame can crash out a victim's
> machine. It only applies to drivers using the 80211 wireless code, and
> only then to certain drivers (and even then depends on a card's
> firmware not dropping a dubious packet). I must confess I'm not
> keeping track of Linux wireless support, and the different protocol
> stacks etc.
>
> Details are as follows:
>
> ieee80211_rx() does not explicitly check that "skb->len >= hdrlen".
> There are other skb->len checks, but not enough to prevent a subtle
> off-by-two error if the frame has the IEEE80211_STYPE_QOS_DATA flag
> set.
>
> This leads to integer underflow and crash here:
>
> if (frag != 0)
> flen -= hdrlen;
>
> (flen is subsequently used as a memcpy length parameter).
How about this?
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ieee80211/ieee80211_rx.c')
-rw-r--r-- | net/ieee80211/ieee80211_rx.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c index f2de2e48b021..6284c99b456e 100644 --- a/net/ieee80211/ieee80211_rx.c +++ b/net/ieee80211/ieee80211_rx.c | |||
@@ -366,6 +366,12 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, | |||
366 | frag = WLAN_GET_SEQ_FRAG(sc); | 366 | frag = WLAN_GET_SEQ_FRAG(sc); |
367 | hdrlen = ieee80211_get_hdrlen(fc); | 367 | hdrlen = ieee80211_get_hdrlen(fc); |
368 | 368 | ||
369 | if (skb->len < hdrlen) { | ||
370 | printk(KERN_INFO "%s: invalid SKB length %d\n", | ||
371 | dev->name, skb->len); | ||
372 | goto rx_dropped; | ||
373 | } | ||
374 | |||
369 | /* Put this code here so that we avoid duplicating it in all | 375 | /* Put this code here so that we avoid duplicating it in all |
370 | * Rx paths. - Jean II */ | 376 | * Rx paths. - Jean II */ |
371 | #ifdef CONFIG_WIRELESS_EXT | 377 | #ifdef CONFIG_WIRELESS_EXT |