Skip to contentSkip to conversation

Problem with "mac80211: free up 2 bytes in skb->cb"

PATCH In review Johannes Berg 2 participants 4 messages Oct 14, 2008 1 message not in the archive Networking drivers (wireless)

lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

Johannes Berg

author maintainer
#1 lore raw
Quoted 10 lines · On Tue, 2008-10-14 at 16:48 +1300, Stephen Blackheath [to Rt2400-devel] wrote:

Felix & John,

This patch definitely breaks wifi on the rt73usb.

The symptom is that all connection negotiation works, rx works, but transmitted packets are garbage and are not received at the remote end.
Tested in AP mode using hostapd and WPA encryption. Also observed in
managed mode with WEP encryption, but in this case, it wasn't 100% confirmed to be your patch.

Quoted 7 lines

The problem goes away completely with this option:

modprobe rt73usb nohwcrypt=1

...which disables hardware encryption.

I don't know the exact reason, and I perhaps the bug is in rt73usb.

Yeah, the hw_key pointer is used (and obviously NULL) after skb->cb is memset to 0, that is a bug in that patch, Felix will post a fix.

johannes

#2 lore raw

PATCH 1/1 mac80211 fix regression introduced by "mac80211: free up 2 bytes in skb->cb"

The hw_key pointer is used (and obviously NULL) after skb->cb is memset to 0. This patch grabs the iv_len before the memset call.

drivers/net/wireless/rt2x00/rt2x00queue.c +5 -4
index 1676ac4..451d410 100644
@@ -374,7 +374,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
 	struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
 	struct txentry_desc txdesc;
 	struct skb_frame_desc *skbdesc;
-	unsigned int iv_len;
+	unsigned int iv_len = 0;
 
 	if (unlikely(rt2x00queue_full(queue)))
 		return -EINVAL;
@@ -395,6 +395,9 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
 	entry->skb = skb;
 	rt2x00queue_create_tx_descriptor(entry, &txdesc);
 
+	if (IEEE80211_SKB_CB(skb)->control.hw_key != NULL)
+		iv_len = IEEE80211_SKB_CB(skb)->control.hw_key->iv_len;
+
 	/*
 	 * All information is retreived from the skb->cb array,
 	 * now we should claim ownership of the driver part of that
@@ -410,9 +413,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
 	 * the frame so we can provide it to the driver seperately.
 	 */
 	if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) &&
-	    !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags) &&
-		(IEEE80211_SKB_CB(skb)->control.hw_key != NULL)) {
-		iv_len = IEEE80211_SKB_CB(skb)->control.hw_key->iv_len;
+	    !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) {
 		rt2x00crypto_tx_remove_iv(skb, iv_len);
 	}
 
author maintainer Acked-by on v1 1/1
#3 lore raw

Re: [PATCH] mac80211 fix regression introduced by "mac80211: free up 2 bytes in skb->cb"

Quoted 5 lines · Felix Fietkau

The hw_key pointer is used (and obviously NULL) after skb->cb is memset to 0. This patch grabs the iv_len before the memset call.

Subject should be "rt2x00: " instead of "mac80211 ", but

Quoted 36 lines
drivers/net/wireless/rt2x00/rt2x00queue.c +5 -4
index 1676ac4..451d410 100644
@@ -374,7 +374,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
 	struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
 	struct txentry_desc txdesc;
 	struct skb_frame_desc *skbdesc;
-	unsigned int iv_len;
+	unsigned int iv_len = 0;
 
 	if (unlikely(rt2x00queue_full(queue)))
 		return -EINVAL;
@@ -395,6 +395,9 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
 	entry->skb = skb;
 	rt2x00queue_create_tx_descriptor(entry, &txdesc);
 
+	if (IEEE80211_SKB_CB(skb)->control.hw_key != NULL)
+		iv_len = IEEE80211_SKB_CB(skb)->control.hw_key->iv_len;
+
 	/*
 	 * All information is retreived from the skb->cb array,
 	 * now we should claim ownership of the driver part of that
@@ -410,9 +413,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
 	 * the frame so we can provide it to the driver seperately.
 	 */
 	if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) &&
-	    !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags) &&
-		(IEEE80211_SKB_CB(skb)->control.hw_key != NULL)) {
-		iv_len = IEEE80211_SKB_CB(skb)->control.hw_key->iv_len;
+	    !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) {
 		rt2x00crypto_tx_remove_iv(skb, iv_len);
 	}
 
#4 lore raw

Re: [PATCH] mac80211 fix regression introduced by "mac80211: free up 2 bytes in skb->cb"

Quoted 10 lines · Johannes Berg
Quoted 5 lines · Felix Fietkau

The hw_key pointer is used (and obviously NULL) after skb->cb is memset to 0. This patch grabs the iv_len before the memset call.

Subject should be "rt2x00: " instead of "mac80211 ", but

Yeah, sorry about that.
John: please fix that up when merging ;)

- Felix