All of lore.kernel.org
 help / color / mirror / Atom feed
From: <tan.hu@zte.com.cn>
To: ja@ssi.bg
Cc: wensong@linux-vs.org, horms@verge.net.au, pablo@netfilter.org,
	kadlec@blackhole.kfki.hu, fw@strlen.de, davem@davemloft.net,
	netdev@vger.kernel.org, lvs-devel@vger.kernel.org,
	netfilter-devel@vger.kernel.org, coreteam@netfilter.org,
	linux-kernel@vger.kernel.org, zhong.weidong@zte.com.cn,
	jiang.biao2@zte.com.cn
Subject: Re: Re: [PATCH] ipvs: fix race between ip_vs_conn_new() andip_vs_del_dest()
Date: Wed, 25 Jul 2018 10:46:37 +0800 (CST)	[thread overview]
Message-ID: <201807251046372965178@zte.com.cn> (raw)
In-Reply-To: <alpine.LFD.2.20.1807242216100.3314@ja.home.ssi.bg>


[-- Attachment #1.1: Type: text/plain, Size: 2909 bytes --]

Thanks for your reviewing, I have sent patch-v2, please check it.

> Hello,
> 
> On Tue, 24 Jul 2018, Tan Hu wrote:
> 
> > We came across infinite loop in ipvs when using ipvs in docker
> > env.
> >
> > When ipvs receives new packets and cannot find an ipvs connection,
> > it will create a new connection, then if the dest is unavailable
> > (i.e. IP_VS_DEST_F_AVAILABLE), the packet will be dropped sliently.
> >
> > But if the dropped packet is the first packet of this connection,
> > the connection control timer never has a chance to start and the
> > ipvs connection cannot be released. This will lead to memory leak, or
> > infinite loop in cleanup_net() when net namespace is released like
> > this:
> >
> > ip_vs_conn_net_cleanup at ffffffffa0a9f31a [ip_vs]
> > __ip_vs_cleanup at ffffffffa0a9f60a [ip_vs]
> > ops_exit_list at ffffffff81567a49
> > cleanup_net at ffffffff81568b40
> > process_one_work at ffffffff810a851b
> > worker_thread at ffffffff810a9356
> > kthread at ffffffff810b0b6f
> > ret_from_fork at ffffffff81697a18
> >
> > race condition:
> > CPU1 CPU2
> > ip_vs_in()
> > ip_vs_conn_new()
> > ip_vs_del_dest()
> > __ip_vs_unlink_dest()
> > ~IP_VS_DEST_F_AVAILABLE
> > cp->dest && !IP_VS_DEST_F_AVAILABLE
> > __ip_vs_conn_put
> > ...
> > cleanup_net ---> infinite looping
> >
> > Fix this by checking whether the timer already started.
> 
> Looks like an old bug...
> 
> >
> > Signed-off-by: Tan Hu <tan.hu@zte.com.cn>
> > Reviewed-by: Jiang Biao <jiang.biao2@zte.com.cn>
> > ---
> > net/netfilter/ipvs/ip_vs_core.c | 10 +++++++---
> > 1 file changed, 7 insertions(+), 3 deletions(-)
> >
> > diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
> > index 0679dd1..ca9e7cc 100644
> > --- a/net/netfilter/ipvs/ip_vs_core.c
> > +++ b/net/netfilter/ipvs/ip_vs_core.c
> > @@ -1972,13 +1972,17 @@ static int ip_vs_in_icmp_v6(struct netns_ipvs *ipvs, struct sk_buff *skb,
> > if (cp->dest && !(cp->dest->flags & IP_VS_DEST_F_AVAILABLE)) {
> > /* the destination server is not available */
> 
> Add: u32 flags = cp->flags;
> 
> >
> > + /* when timer already started, silently drop the packet.*/
> > + if (timer_pending(&cp->timer))
> > + __ip_vs_conn_put(cp);
> > + else
> > + ip_vs_conn_put(cp);
> 
> When ip_vs_conn_put is called for IP_VS_CONN_F_ONE_PACKET
> it is possible to call ip_vs_conn_expire and to free cp with
> ip_vs_conn_rcu_free immediately. What we can do is to avoid the
> ip_vs_conn_expire_now call in such case by reading the flags
> early (as above) and adding the needed check (as below).
> 
> > +
> > if (sysctl_expire_nodest_conn(ipvs)) {
> 
> Add !(flags & IP_VS_CONN_F_ONE_PACKET) check in above 'if'.
> 
> > /* try to expire the connection immediately */
> > ip_vs_conn_expire_now(cp);
> > }
> > - /* don't restart its timer, and silently
> > - drop the packet. */
> > - __ip_vs_conn_put(cp);
> > +
> > return NF_DROP;
> > }
> >
> 
> Regards

WARNING: multiple messages have this Message-ID (diff)
From: <tan.hu@zte.com.cn>
To: <ja@ssi.bg>
Cc: <wensong@linux-vs.org>, <horms@verge.net.au>,
	<pablo@netfilter.org>, <kadlec@blackhole.kfki.hu>, <fw@strlen.de>,
	<davem@davemloft.net>, <netdev@vger.kernel.org>,
	<lvs-devel@vger.kernel.org>, <netfilter-devel@vger.kernel.org>,
	<coreteam@netfilter.org>, <linux-kernel@vger.kernel.org>,
	<zhong.weidong@zte.com.cn>, <jiang.biao2@zte.com.cn>
Subject: Re: Re: [PATCH] ipvs: fix race between ip_vs_conn_new() andip_vs_del_dest()
Date: Wed, 25 Jul 2018 10:46:37 +0800 (CST)	[thread overview]
Message-ID: <201807251046372965178@zte.com.cn> (raw)
In-Reply-To: <alpine.LFD.2.20.1807242216100.3314@ja.home.ssi.bg>


[-- Attachment #1.1: Type: text/plain, Size: 2909 bytes --]

Thanks for your reviewing, I have sent patch-v2, please check it.

> Hello,
> 
> On Tue, 24 Jul 2018, Tan Hu wrote:
> 
> > We came across infinite loop in ipvs when using ipvs in docker
> > env.
> >
> > When ipvs receives new packets and cannot find an ipvs connection,
> > it will create a new connection, then if the dest is unavailable
> > (i.e. IP_VS_DEST_F_AVAILABLE), the packet will be dropped sliently.
> >
> > But if the dropped packet is the first packet of this connection,
> > the connection control timer never has a chance to start and the
> > ipvs connection cannot be released. This will lead to memory leak, or
> > infinite loop in cleanup_net() when net namespace is released like
> > this:
> >
> > ip_vs_conn_net_cleanup at ffffffffa0a9f31a [ip_vs]
> > __ip_vs_cleanup at ffffffffa0a9f60a [ip_vs]
> > ops_exit_list at ffffffff81567a49
> > cleanup_net at ffffffff81568b40
> > process_one_work at ffffffff810a851b
> > worker_thread at ffffffff810a9356
> > kthread at ffffffff810b0b6f
> > ret_from_fork at ffffffff81697a18
> >
> > race condition:
> > CPU1 CPU2
> > ip_vs_in()
> > ip_vs_conn_new()
> > ip_vs_del_dest()
> > __ip_vs_unlink_dest()
> > ~IP_VS_DEST_F_AVAILABLE
> > cp->dest && !IP_VS_DEST_F_AVAILABLE
> > __ip_vs_conn_put
> > ...
> > cleanup_net ---> infinite looping
> >
> > Fix this by checking whether the timer already started.
> 
> Looks like an old bug...
> 
> >
> > Signed-off-by: Tan Hu <tan.hu@zte.com.cn>
> > Reviewed-by: Jiang Biao <jiang.biao2@zte.com.cn>
> > ---
> > net/netfilter/ipvs/ip_vs_core.c | 10 +++++++---
> > 1 file changed, 7 insertions(+), 3 deletions(-)
> >
> > diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
> > index 0679dd1..ca9e7cc 100644
> > --- a/net/netfilter/ipvs/ip_vs_core.c
> > +++ b/net/netfilter/ipvs/ip_vs_core.c
> > @@ -1972,13 +1972,17 @@ static int ip_vs_in_icmp_v6(struct netns_ipvs *ipvs, struct sk_buff *skb,
> > if (cp->dest && !(cp->dest->flags & IP_VS_DEST_F_AVAILABLE)) {
> > /* the destination server is not available */
> 
> Add: u32 flags = cp->flags;
> 
> >
> > + /* when timer already started, silently drop the packet.*/
> > + if (timer_pending(&cp->timer))
> > + __ip_vs_conn_put(cp);
> > + else
> > + ip_vs_conn_put(cp);
> 
> When ip_vs_conn_put is called for IP_VS_CONN_F_ONE_PACKET
> it is possible to call ip_vs_conn_expire and to free cp with
> ip_vs_conn_rcu_free immediately. What we can do is to avoid the
> ip_vs_conn_expire_now call in such case by reading the flags
> early (as above) and adding the needed check (as below).
> 
> > +
> > if (sysctl_expire_nodest_conn(ipvs)) {
> 
> Add !(flags & IP_VS_CONN_F_ONE_PACKET) check in above 'if'.
> 
> > /* try to expire the connection immediately */
> > ip_vs_conn_expire_now(cp);
> > }
> > - /* don't restart its timer, and silently
> > - drop the packet. */
> > - __ip_vs_conn_put(cp);
> > +
> > return NF_DROP;
> > }
> >
> 
> Regards

  reply	other threads:[~2018-07-25  2:46 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-07-24  8:12 [PATCH] ipvs: fix race between ip_vs_conn_new() and ip_vs_del_dest() Tan Hu
2018-07-24 19:47 ` Julian Anastasov
2018-07-24 19:47   ` Julian Anastasov
2018-07-25  2:46   ` tan.hu [this message]
2018-07-25  2:46     ` Re: [PATCH] ipvs: fix race between ip_vs_conn_new() andip_vs_del_dest() tan.hu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=201807251046372965178@zte.com.cn \
    --to=tan.hu@zte.com.cn \
    --cc=coreteam@netfilter.org \
    --cc=davem@davemloft.net \
    --cc=fw@strlen.de \
    --cc=horms@verge.net.au \
    --cc=ja@ssi.bg \
    --cc=jiang.biao2@zte.com.cn \
    --cc=kadlec@blackhole.kfki.hu \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lvs-devel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=pablo@netfilter.org \
    --cc=wensong@linux-vs.org \
    --cc=zhong.weidong@zte.com.cn \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.