[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <AANLkTik5=zcsVHwLsFqMvRvoLyPdhK=1dRUny5+jqoxf@mail.gmail.com>
Date: Wed, 23 Mar 2011 19:34:31 +0800
From: Feng Gao <kernel.goter@...il.com>
To: Eric Dumazet <eric.dumazet@...il.com>
Cc: netdev@...r.kernel.org
Subject: Re: [PATCH] ip_fragment:kernel may panic when replay big packet with
RST flag
Sorry, I will google it.
I find this problem in 2.4.35. and then I read the Latest code,maybe
it has the same problem too.
diff -Nur skbuff.h skbuff.h.frag
--- skbuff.h 2008-08-21 02:16:14.000000000 +0800
+++ skbuff.h.frag 2011-03-23 19:30:20.000000000 +0800
@@ -1754,6 +1754,20 @@
__nf_copy(dst, src);
}
+/* This func for ip_fragment deal with RST packet */
+static inline void nf_copy_rst(struct sk_buff *dst, const struct sk_buff *src)
+{
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+ nf_conntrack_put(dst->nfct);
+ nf_conntrack_put_reasm(dst->nfct_reasm);
+#endif
+#ifdef CONFIG_BRIDGE_NETFILTER
+ nf_bridge_put(dst->nf_bridge);
+ dst->nf_bridge = src->nf_bridge;
+ nf_bridge_get(src->nf_bridge);
+#endif
+}
+
#ifdef CONFIG_NETWORK_SECMARK
static inline void skb_copy_secmark(struct sk_buff *to, const struct
sk_buff *from)
{
diff -Nur ip_output.c ip_output.c.frag
--- ip_output.c 2008-08-21 02:16:14.000000000 +0800
+++ ip_output.c.frag 2011-03-23 19:27:57.000000000 +0800
@@ -413,7 +413,14 @@
#ifdef CONFIG_NET_SCHED
to->tc_index = from->tc_index;
#endif
- nf_copy(to, from);
+ struct tcphdr *th = (struct tcphdr *)((char *)iph + (iph->ihl << 2));
+ if(iph->protocol == IPPROTO_TCP && th->rst){
+ /*RST packet*/
+ nf_copy_rst(to, from);
+ }else{
+ /*Other packet*/
+ nf_copy(to, from);
+ }
#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
to->nf_trace = from->nf_trace;
2011/3/23 Eric Dumazet <eric.dumazet@...il.com>:
> Le mercredi 23 mars 2011 à 18:49 +0800, Feng Gao a écrit :
>> Hello everyone:
>>
>> PC(A)-linux(B)-PC(C)
>> computer(linux B) with two net interface,eth0 and eth1.
>> PC(A) send syn to PC(C) though linux B.
>> then PC(C) replay a big packet with RST flag(use tcpsic or other tools).
>>
>> This RST packet(1480) come in from eth0(mtu 1500) and go out from
>> eth1(mtu 700), so this RST packet should fragment.
>>
>> BUT in tcp_packet func: if the connection has no reply packet,and
>> receive the RST packet.ip_conntrack should destroy.
>> if (!test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
>> /* If only reply is a RST, we can consider ourselves not to
>> have an established connection: this is a fairly common
>> problem case, so we can delete the conntrack
>> immediately. --RR */
>> if (th->rst) {
>> nf_ct_kill_acct(ct, ctinfo, skb);
>> return NF_ACCEPT;
>> }
>> }
>>
>> BUT the skb->nfct is not set NULL in func nf_ct_kill_acct.
>> so when this RST packet goto ip_fragment,ip_fragment call nf_copy, in
>> __nf_copy func
>> the fragment skb->nfct point to the destory mem.
>> dst->nfct = src->nfct;
>> nf_conntrack_get(src->nfct);
>>
>> SO finally.kfree_skb call destroy_conntrack again. this may result in
>> LINUX B kernel panic.
>>
>>
>> here is the patch,sorry ,i dont know how to use diff to generate patch.
>> :-D
>>
>
> Hi Feng
>
> Oh well, please learn how to do this. If you are able to make such
> analysis, you sure can learn how to use diff !!!
>
> What is the version of linux you use ?
>
>
>
>
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists