[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <AANLkTinLD8A1RVXUn7bF8zSdjUsCNBbF=RA6kvr2zrfi@mail.gmail.com>
Date: Wed, 23 Mar 2011 19:37:06 +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
This patch is for 2.6.25.16.
2011/3/23 Feng Gao <kernel.goter@...il.com>:
> 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