ipv6: discard overlapping fragment
Subsystems (3)
PATCH 1/2 ipv6: discard overlapping fragment
Hi all,
here is a patch to take care of RFC5722 "Handling of Overlapping IPv6 Fragments" in IPv6 stack.
Regards,
Nicolas
Quoted 1 line
From
d3244c5458cb331f635d68dd52511bd507580bcbMon Sep 17 00:00:00 2001
From: Nicolas Dichtel <[email protected]>
Date: Fri, 3 Sep 2010 15:31:14 +0200
Subject: [PATCH] ipv6: discard overlapping fragment
RFC5722 prohibits reassembling fragments when some data overlaps.
Bug spotted by Zhang Zuotao <[email protected]>.
Signed-off-by Nicolas Dichtel <[email protected]>
--- net/ipv6/reassembly.c | 71 ++++++++++-------------------------------------- 1 files changed, 15 insertions(+), 56 deletions(-)
net/ipv6/reassembly.c +15 -56
@@ -149,13 +149,6 @@ int ip6_frag_match(struct inet_frag_queue *q, void *a) }EXPORT_SYMBOL (ip6_frag_match); -/* Memory Tracking Functions. */ -static void frag_kfree_skb (struct netns_frags *nf,struct sk_buff *skb) -{ -atomic_sub (skb->truesize, &nf->mem); -kfree_skb (skb); -} -void ip6_frag_init (struct inet_frag_queue *q,void *a) { struct frag_queue *fq = container_of(q, struct frag_queue, q);
@@ -346,58 +339,22 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, } found: -/* We found where to put this one. Check for overlap with -* preceding fragment, and, if needed, align things so that -* any overlaps are eliminated. +/* RFC5722, Section 4: +* When reassembling an IPv6 datagram, if +* one or more its constituent fragments is determined to be an +* overlapping fragment, the entire datagram (and any constituent +* fragments, including those not yet received) MUST be silently +* discarded. */ -if (prev) { -int i = (FRAG6_CB (prev)->offset + prev->len) - offset; -if (i >0 ) { - offset += i; -if (end <= offset) - goto err; -if (!pskb_pull (skb, i)) - goto err; -if (skb->ip_summed !=CHECKSUM_UNNECESSARY ) - skb->ip_summed =CHECKSUM_NONE ; - } - } +/* Check for overlap with preceding fragment. */ +if (prev && + (FRAG6_CB (prev)->offset + prev->len) - offset >0 ) + goto discard_fq; -/* Look for overlap with succeeding segments. -* If we can merge fragments, do it. -*/ -while (next &&FRAG6_CB (next)->offset < end) { -int i = end -FRAG6_CB (next)->offset;/* overlap is 'i' bytes */ - -if (i < next->len) { -/* Eat head of the next overlapped fragment -* and leave the loop. The next ones cannot overlap. -*/ -if (!pskb_pull (next, i)) - goto err; -FRAG6_CB (next)->offset += i;/* next fragment */ - fq->q.meat -= i; -if (next->ip_summed !=CHECKSUM_UNNECESSARY ) - next->ip_summed =CHECKSUM_NONE ; -break ; - }else { -struct sk_buff *free_it = next; - -/* Old fragment is completely overridden with -* new one drop it. -*/ - next = next->next; - -if (prev) - prev->next = next; -else - fq->q.fragments = next; - - fq->q.meat -= free_it->len; -frag_kfree_skb (fq->q.net, free_it); - } - } +/* Look for overlap with succeeding segment. */ +if (next &&FRAG6_CB (next)->offset < end) + goto discard_fq;FRAG6_CB (skb)->offset = offset;
@@ -436,6 +393,8 @@ found:write_unlock (&ip6_frags.lock);return -1 ; +discard_fq: +fq_kill (fq); err:IP6_INC_STATS (net,ip6_dst_idev (skb_dst (skb)),IPSTATS_MIB_REASMFAILS );
Signature · 1 line
1.5.4.5
From: Nicolas Dichtel <[email protected]>
Date: Fri, 03 Sep 2010 17:13:05 +0200
Quoted 2 lines
here is a patch to take care of RFC5722 "Handling of Overlapping IPv6 Fragments" in IPv6 stack.
Applied to net-2.6