From patchwork Wed Dec 1 08:18:35 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shan Wei X-Patchwork-Id: 73761 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 9667EB70A5 for ; Wed, 1 Dec 2010 19:20:24 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752796Ab0LAIUR (ORCPT ); Wed, 1 Dec 2010 03:20:17 -0500 Received: from cn.fujitsu.com ([222.73.24.84]:64517 "EHLO song.cn.fujitsu.com" rhost-flags-OK-FAIL-OK-OK) by vger.kernel.org with ESMTP id S1751971Ab0LAIUQ (ORCPT ); Wed, 1 Dec 2010 03:20:16 -0500 Received: from tang.cn.fujitsu.com (tang.cn.fujitsu.com [10.167.250.3]) by song.cn.fujitsu.com (Postfix) with ESMTP id 5FE8517011E; Wed, 1 Dec 2010 16:20:14 +0800 (CST) Received: from mailserver.fnst.cn.fujitus.com (tang.cn.fujitsu.com [127.0.0.1]) by tang.cn.fujitsu.com (8.14.3/8.13.1) with ESMTP id oB18FbIt017713; Wed, 1 Dec 2010 16:15:37 +0800 Received: from [10.167.225.31] ([10.167.225.31]) by mailserver.fnst.cn.fujitus.com (Lotus Domino Release 8.5.1FP4) with ESMTP id 2010120116202513-136049 ; Wed, 1 Dec 2010 16:20:25 +0800 Message-ID: <4CF604DB.8000302@cn.fujitsu.com> Date: Wed, 01 Dec 2010 16:18:35 +0800 From: Shan Wei User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.13pre) Gecko/20101113 Shredder/3.1.7pre MIME-Version: 1.0 To: Albert Pretorius CC: netdev@vger.kernel.org, "yoshfuji@linux-ipv6.org >> YOSHIFUJI Hideaki" , David Miller , pekkas@netcore.fi, jmorris@namei.org Subject: Re: IPV6 loopback bound socket succeeds connecting to remote host References: <328335.88387.qm@web29006.mail.ird.yahoo.com> In-Reply-To: <328335.88387.qm@web29006.mail.ird.yahoo.com> X-MIMETrack: Itemize by SMTP Server on mailserver/fnst(Release 8.5.1FP4|July 25, 2010) at 2010-12-01 16:20:25, Serialize by Router on mailserver/fnst(Release 8.5.1FP4|July 25, 2010) at 2010-12-01 16:20:25, Serialize complete at 2010-12-01 16:20:25 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Albert Pretorius wrote, at 11/29/2010 06:55 PM: > Hi > I found a problem with ipv6 when a UDP socket is bound to loopback (::1) and connecting to a remote address. The same applies to TCP. > Any data sent ends up on the remote host with a source address of loopback. The expected result of the connect should be EINVAL just like it is for ipv4. > Here is a possible patch that fixes this problem below. I tested it on 2.6.37-rc3 using a tool I put on http://www.gitorious.org/bindconnect Indeed, there is an guide in RFC4291 for us to use IPv6 loopback address. See RFC4291 2.5.3 section: The loopback address must not be used as the source address in IPv6 packets that are sent outside of a single node. An IPv6 packet with a destination address of loopback must never be sent outside of a single node and must never be forwarded by an IPv6 router. A packet received on an interface with a destination address of loopback must be dropped. I think it make nonsense to translate data between loopback device and other e.g. eth0 device in same machine. With your patch, also can't establish a tcp connection from loopback device to other device in same host. ===== [PATCH] ipv6: forbid to send ipv6 packet from loopback to other device in same host According to 2.5.3 section of RFC4291, commit f630e43 dropped the received packet with loopback as destination address. Now forbid to send packet from loopback to other device. Original patch is provided by Albert Pretorius. Reported-by: Albert Pretorius Signed-off-by: Shan Wei --- net/ipv6/ip6_output.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 99157b4..6b6cf84 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -927,6 +927,7 @@ static int ip6_dst_lookup_tail(struct sock *sk, { int err; struct net *net = sock_net(sk); + struct net_device *dev_out; if (*dst == NULL) *dst = ip6_route_output(net, sk, fl); @@ -934,6 +935,13 @@ static int ip6_dst_lookup_tail(struct sock *sk, if ((err = (*dst)->error)) goto out_err_release; + dev_out = ip6_dst_idev(*dst)->dev; + if (dev_out && ipv6_addr_loopback(&fl->fl6_src) && + !(dev_out->flags & IFF_LOOPBACK)) { + err = -EINVAL; + goto out_err_release; + } + if (ipv6_addr_any(&fl->fl6_src)) { err = ipv6_dev_get_saddr(net, ip6_dst_idev(*dst)->dev, &fl->fl6_dst,