d994f31
From: Sven Eckelmann <sven@narfation.org>
d994f31
Date: Sat, 20 Dec 2014 13:48:55 +0100
d994f31
Subject: [PATCH] batman-adv: Calculate extra tail size based on queued
d994f31
 fragments
d994f31
MIME-Version: 1.0
d994f31
Content-Type: text/plain; charset=UTF-8
d994f31
Content-Transfer-Encoding: 8bit
d994f31
d994f31
The fragmentation code was replaced in 610bfc6bc99bc83680d190ebc69359a05fc7f605
d994f31
("batman-adv: Receive fragmented packets and merge"). The new code provided a
d994f31
mostly unused parameter skb for the merging function. It is used inside the
d994f31
function to calculate the additionally needed skb tailroom. But instead of
d994f31
increasing its own tailroom, it is only increasing the tailroom of the first
d994f31
queued skb. This is not correct in some situations because the first queued
d994f31
entry can be a different one than the parameter.
d994f31
d994f31
An observed problem was:
d994f31
d994f31
1. packet with size 104, total_size 1464, fragno 1 was received
d994f31
   - packet is queued
d994f31
2. packet with size 1400, total_size 1464, fragno 0 was received
d994f31
   - packet is queued at the end of the list
d994f31
3. enough data was received and can be given to the merge function
d994f31
   (1464 == (1400 - 20) + (104 - 20))
d994f31
   - merge functions gets 1400 byte large packet as skb argument
d994f31
4. merge function gets first entry in queue (104 byte)
d994f31
   - stored as skb_out
d994f31
5. merge function calculates the required extra tail as total_size - skb->len
d994f31
   - pskb_expand_head tail of skb_out with 64 bytes
d994f31
6. merge function tries to squeeze the extra 1380 bytes from the second queued
d994f31
   skb (1400 byte aka skb parameter) in the 64 extra tail bytes of skb_out
d994f31
d994f31
Instead calculate the extra required tail bytes for skb_out also using skb_out
d994f31
instead of using the parameter skb. The skb parameter is only used to get the
d994f31
total_size from the last received packet. This is also the total_size used to
d994f31
decide that all fragments were received.
d994f31
d994f31
Reported-by: Philipp Psurek <philipp.psurek@gmail.com>
d994f31
Signed-off-by: Sven Eckelmann <sven@narfation.org>
d994f31
Acked-by: Martin Hundebøll <martin@hundeboll.net>
d994f31
Signed-off-by: David S. Miller <davem@davemloft.net>
d994f31
---
d994f31
 net/batman-adv/fragmentation.c | 2 +-
d994f31
 1 file changed, 1 insertion(+), 1 deletion(-)
d994f31
d994f31
diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c
d994f31
index fc1835c6bb40..8af3461d18d2 100644
d994f31
--- a/net/batman-adv/fragmentation.c
d994f31
+++ b/net/batman-adv/fragmentation.c
d994f31
@@ -251,7 +251,7 @@ batadv_frag_merge_packets(struct hlist_head *chain, struct sk_buff *skb)
d994f31
 	kfree(entry);
d994f31
 
d994f31
 	/* Make room for the rest of the fragments. */
d994f31
-	if (pskb_expand_head(skb_out, 0, size - skb->len, GFP_ATOMIC) < 0) {
d994f31
+	if (pskb_expand_head(skb_out, 0, size - skb_out->len, GFP_ATOMIC) < 0) {
d994f31
 		kfree_skb(skb_out);
d994f31
 		skb_out = NULL;
d994f31
 		goto free;
d994f31
-- 
d994f31
2.1.0
d994f31