[PATCH] hostap_80211_tx.c needs to allocate more tailroom (was: kernel encryption error)

Brandon Craig Rhodes brandon at rhodesmill.org
Wed Jan 17 12:14:54 EST 2007


I was having problems with hostap in WPA mode, and I wrote:

> Jan  9 12:54:25 asaph kernel: Invalid packet for Michael MIC add (tailroom=6 hdr_len=24 skb->len=92)
> Jan  9 12:54:25 asaph kernel: wifi0_rename: TX - encryption failed
>
> What causes this message, and how can I prevent this error?

I have discovered the solution to my own problem.

Jouni Malinen, please let me know whether the patch below is in good
enough shape to be applied to the official code; if not, I'm perfectly
willing to work on it some more.

When hostap_tx_encrypt() tries to allocate enough headroom and
tailroom for ieee80211 encryption, it only makes enough room for the
"mpdu" phase of the operation, but forgets about the "msdu" phase.
(For TKIP, these two phases require, respectively, 4 and 8 bytes of
tailroom, per the "ieee80211_crypt_tkip" structure at the bottom of
net/ieee80211/ieee80211_crypt_tkip.c.)  For the 2.6.18 kernel, this
can be corrected through the following patch.

In case it's helpful on this mailing list:
Signed-off-by: Brandon Craig Rhodes <brandon at rhodesmill.org>

--- a/drivers/net/wireless/hostap/hostap_80211_tx.c	2007-01-10 19:00:41.000000000 -0500
+++ b/drivers/net/wireless/hostap/hostap_80211_tx.c	2007-01-17 11:23:05.000000000 -0500
@@ -306,7 +306,7 @@
 	local_info_t *local;
 	struct ieee80211_hdr_4addr *hdr;
 	u16 fc;
-	int hdr_len, res;
+	int prefix_len, postfix_len, hdr_len, res;
 
 	iface = netdev_priv(skb->dev);
 	local = iface->local;
@@ -332,10 +332,13 @@
 	if (skb == NULL)
 		return NULL;
 
-	if ((skb_headroom(skb) < crypt->ops->extra_mpdu_prefix_len ||
-	     skb_tailroom(skb) < crypt->ops->extra_mpdu_postfix_len) &&
-	    pskb_expand_head(skb, crypt->ops->extra_mpdu_prefix_len,
-			     crypt->ops->extra_mpdu_postfix_len, GFP_ATOMIC)) {
+	prefix_len = crypt->ops->extra_mpdu_prefix_len
+		+ crypt->ops->extra_msdu_prefix_len;
+	postfix_len = crypt->ops->extra_mpdu_postfix_len
+		+ crypt->ops->extra_msdu_postfix_len;
+	if ((skb_headroom(skb) < prefix_len ||
+	     skb_tailroom(skb) < postfix_len) &&
+	    pskb_expand_head(skb, prefix_len, postfix_len, GFP_ATOMIC)) {
 		kfree_skb(skb);
 		return NULL;
 	}




More information about the HostAP mailing list