From b6daa25d653f23252b340cbd7d2153d0b338e44c Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Thu, 19 Jan 2006 16:20:42 +0800 Subject: [PATCH] ieee80211: Fix problem with not decrypting broadcast packets The code for pulling the key to use for decrypt was correctly using the host_mc_decrypt flag. The code that actually decrypted, however, was based on host_decrypt. This patch changes this behavior. Signed-off-by: Etay Bogner Signed-off-by: James Ketrenos Signed-off-by: Zhu Yi Signed-off-by: John W. Linville --- net/ieee80211/ieee80211_rx.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'net/ieee80211') diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c index 7a121802faa..695d0478fd1 100644 --- a/net/ieee80211/ieee80211_rx.c +++ b/net/ieee80211/ieee80211_rx.c @@ -350,6 +350,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, u8 src[ETH_ALEN]; struct ieee80211_crypt_data *crypt = NULL; int keyidx = 0; + int can_be_decrypted = 0; hdr = (struct ieee80211_hdr_4addr *)skb->data; stats = &ieee->stats; @@ -410,12 +411,23 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, return 1; } - if (is_multicast_ether_addr(hdr->addr1) - ? ieee->host_mc_decrypt : ieee->host_decrypt) { + can_be_decrypted = (is_multicast_ether_addr(hdr->addr1) || + is_broadcast_ether_addr(hdr->addr2)) ? + ieee->host_mc_decrypt : ieee->host_decrypt; + + if (can_be_decrypted) { int idx = 0; - if (skb->len >= hdrlen + 3) + if (skb->len >= hdrlen + 3) { + /* Top two-bits of byte 3 are the key index */ idx = skb->data[hdrlen + 3] >> 6; + } + + /* ieee->crypt[] is WEP_KEY (4) in length. Given that idx + * is only allowed 2-bits of storage, no value of idx can + * be provided via above code that would result in idx + * being out of range */ crypt = ieee->crypt[idx]; + #ifdef NOT_YET sta = NULL; @@ -553,7 +565,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, /* skb: hdr + (possibly fragmented, possibly encrypted) payload */ - if (ieee->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) && + if ((fc & IEEE80211_FCTL_PROTECTED) && can_be_decrypted && (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0) goto rx_dropped; @@ -617,7 +629,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, /* skb: hdr + (possible reassembled) full MSDU payload; possibly still * encrypted/authenticated */ - if (ieee->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) && + if ((fc & IEEE80211_FCTL_PROTECTED) && can_be_decrypted && ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt)) goto rx_dropped; -- cgit v1.2.3