aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/unicast.c
diff options
context:
space:
mode:
authorSven Eckelmann <sven@narfation.org>2011-02-06 23:26:43 +0000
committerSven Eckelmann <sven@narfation.org>2011-02-08 00:54:31 +0100
commit531c9da8c854c5b075383253a57fdd4e0be82e99 (patch)
treead3cd10621d05b18b1b403f28733e0bc11b8eb8f /net/batman-adv/unicast.c
parent1181e1daace88018b2ff66592aa10a4791d705ff (diff)
downloadkernel_samsung_smdk4412-531c9da8c854c5b075383253a57fdd4e0be82e99.zip
kernel_samsung_smdk4412-531c9da8c854c5b075383253a57fdd4e0be82e99.tar.gz
kernel_samsung_smdk4412-531c9da8c854c5b075383253a57fdd4e0be82e99.tar.bz2
batman-adv: Linearize fragment packets before merge
We access the data inside the skbs of two fragments directly using memmove during the merge. The data of the skb could span over multiple skb pages. An direct access without knowledge about the pages would lead to an invalid memory access. Signed-off-by: Sven Eckelmann <sven@narfation.org> [lindner_marek@yahoo.de: Move return from function to the end] Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Diffstat (limited to 'net/batman-adv/unicast.c')
-rw-r--r--net/batman-adv/unicast.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c
index ee41fef..d1a6113 100644
--- a/net/batman-adv/unicast.c
+++ b/net/batman-adv/unicast.c
@@ -50,12 +50,12 @@ static struct sk_buff *frag_merge_packet(struct list_head *head,
skb = tfp->skb;
}
+ if (skb_linearize(skb) < 0 || skb_linearize(tmp_skb) < 0)
+ goto err;
+
skb_pull(tmp_skb, sizeof(struct unicast_frag_packet));
- if (pskb_expand_head(skb, 0, tmp_skb->len, GFP_ATOMIC) < 0) {
- /* free buffered skb, skb will be freed later */
- kfree_skb(tfp->skb);
- return NULL;
- }
+ if (pskb_expand_head(skb, 0, tmp_skb->len, GFP_ATOMIC) < 0)
+ goto err;
/* move free entry to end */
tfp->skb = NULL;
@@ -70,6 +70,11 @@ static struct sk_buff *frag_merge_packet(struct list_head *head,
unicast_packet->packet_type = BAT_UNICAST;
return skb;
+
+err:
+ /* free buffered skb, skb will be freed later */
+ kfree_skb(tfp->skb);
+ return NULL;
}
static void frag_create_entry(struct list_head *head, struct sk_buff *skb)