2017-10-31 13:24:35 -04:00
|
|
|
From 338f977f4eb441e69bb9a46eaa0ac715c931a67f Mon Sep 17 00:00:00 2001
|
|
|
|
From: Johannes Berg <johannes.berg@intel.com>
|
|
|
|
Date: Sat, 1 Feb 2014 00:16:23 +0100
|
|
|
|
Subject: mac80211: fix fragmentation code, particularly for encryption
|
|
|
|
|
|
|
|
The "new" fragmentation code (since my rewrite almost 5 years ago)
|
|
|
|
erroneously sets skb->len rather than using skb_trim() to adjust
|
|
|
|
the length of the first fragment after copying out all the others.
|
|
|
|
This leaves the skb tail pointer pointing to after where the data
|
|
|
|
originally ended, and thus causes the encryption MIC to be written
|
|
|
|
at that point, rather than where it belongs: immediately after the
|
|
|
|
data.
|
|
|
|
|
|
|
|
The impact of this is that if software encryption is done, then
|
|
|
|
a) encryption doesn't work for the first fragment, the connection
|
|
|
|
becomes unusable as the first fragment will never be properly
|
|
|
|
verified at the receiver, the MIC is practically guaranteed to
|
|
|
|
be wrong
|
|
|
|
b) we leak up to 8 bytes of plaintext (!) of the packet out into
|
|
|
|
the air
|
|
|
|
|
|
|
|
This is only mitigated by the fact that many devices are capable
|
|
|
|
of doing encryption in hardware, in which case this can't happen
|
|
|
|
as the tail pointer is irrelevant in that case. Additionally,
|
|
|
|
fragmentation is not used very frequently and would normally have
|
|
|
|
to be configured manually.
|
|
|
|
|
|
|
|
Fix this by using skb_trim() properly.
|
|
|
|
|
|
|
|
Cc: stable@vger.kernel.org
|
|
|
|
Fixes: 2de8e0d999b8 ("mac80211: rewrite fragmentation")
|
|
|
|
Reported-by: Jouni Malinen <j@w1.fi>
|
|
|
|
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
|
|
|
---
|
|
|
|
net/mac80211/tx.c | 2 +-
|
|
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
|
|
|
|
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
|
|
|
|
index 27c990b..97a02d3 100644
|
|
|
|
--- a/net/mac80211/tx.c
|
|
|
|
+++ b/net/mac80211/tx.c
|
|
|
|
@@ -878,7 +878,7 @@ static int ieee80211_fragment(struct ieee80211_tx_data *tx,
|
|
|
|
}
|
|
|
|
|
|
|
|
/* adjust first fragment's length */
|
|
|
|
- skb->len = hdrlen + per_fragm;
|
|
|
|
+ skb_trim(skb, hdrlen + per_fragm);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
--
|
|
|
|
cgit v1.1
|
|
|
|
|