[lkml]   [2014]   [Dec]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
Patch in this message
Subject[ 24/25] mac80211: fix fragmentation code, particularly for encryption
2.6.32-longterm review patch.  If anyone has any objections, please let me know.


From: Johannes Berg <>

commit a722a419815ed203b519151f9556859ff256638b upstream

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

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.

Fixes: 2de8e0d999b8 ("mac80211: rewrite fragmentation")
Reported-by: Jouni Malinen <>
Signed-off-by: Johannes Berg <>
(backported from commit 338f977f4eb441e69bb9a46eaa0ac715c931a67f)
Signed-off-by: Luis Henriques <>
Acked-by: Andy Whitcroft <>
Acked-by: Stefan Bader <>
Signed-off-by: Andy Whitcroft <>
Signed-off-by: Willy Tarreau <>
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 b1d7904..687fc8e 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -770,7 +770,7 @@ static int ieee80211_fragment(struct ieee80211_local *local,
pos += fraglen;

- skb->len = hdrlen + per_fragm;
+ skb_trim(skb, hdrlen + per_fragm);
return 0;


 \ /
  Last update: 2014-12-06 19:21    [W:0.436 / U:0.068 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site