* IPV6 loopback bound socket succeeds connecting to remote host @ 2010-11-29 10:55 Albert Pretorius 2010-12-01 8:18 ` Shan Wei 0 siblings, 1 reply; 9+ messages in thread From: Albert Pretorius @ 2010-11-29 10:55 UTC (permalink / raw) To: netdev 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 ----8<---- diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 99157b4..a0de66c 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,32 @@ 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)) { + /* + * If socket is bound to loopback address but interface + * is not then it is invalid... + */ + struct inet6_ifaddr *ifa; + struct inet6_dev *idev = in6_dev_get(dev_out); + err = -EINVAL; + if (idev) { + list_for_each_entry(ifa, &idev->addr_list, if_list) + { + /* + * ... unless the interface has the same address + */ + if (ipv6_addr_equal(&ifa->addr, &fl->fl6_dst)) + err = 0; + } + in6_dev_put(idev); + } + + if (err) + 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, ---->8---- The bindconnect tool is build with just make and run like: ./obj/bindconnect -l ::1 9999 -r nnnn::nnn:nnnn:nnnn:nnnn%eth0 4444 -u ERROR: Error occurred during connect() : Invalid argument without the patch a UDP datagram is sent and TCP sends a SYN. Please CC me personally as I am not subscribed to the mailing list. thanks, Albert Pretorius ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: IPV6 loopback bound socket succeeds connecting to remote host 2010-11-29 10:55 IPV6 loopback bound socket succeeds connecting to remote host Albert Pretorius @ 2010-12-01 8:18 ` Shan Wei 2010-12-02 7:45 ` Albert Pretorius 0 siblings, 1 reply; 9+ messages in thread From: Shan Wei @ 2010-12-01 8:18 UTC (permalink / raw) To: Albert Pretorius Cc: netdev, yoshfuji@linux-ipv6.org >> YOSHIFUJI Hideaki, David Miller, pekkas, jmorris 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 <albertpretorius@yahoo.co.uk> Signed-off-by: Shan Wei <shanwei@cn.fujitsu.com> --- 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, -- 1.6.3.3 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: IPV6 loopback bound socket succeeds connecting to remote host 2010-12-01 8:18 ` Shan Wei @ 2010-12-02 7:45 ` Albert Pretorius 2010-12-02 8:41 ` Shan Wei 0 siblings, 1 reply; 9+ messages in thread From: Albert Pretorius @ 2010-12-02 7:45 UTC (permalink / raw) To: Shan Wei Cc: netdev, yoshfuji@linux-ipv6.org >> YOSHIFUJI Hideaki, David Miller, pekkas, jmorris Hi --- On Wed, 1/12/10, Shan Wei <shanwei@cn.fujitsu.com> wrote: > I think it make nonsense to translate data between loopback > device and other e.g. eth0 device in same machine. I agree, RFC4291 makes it clear for IPV6 that no interface should accept traffic from loopback, I should not have tried to make it behave like IPV4. I can not find an equivalent statement for IPV4 though, all I could find is this from RFC3330: 127.0.0.0/8 - This block is assigned for use as the Internet host loopback address. A datagram sent by a higher level protocol to an address anywhere within this block should loop back inside the host. This is ordinarily implemented using only 127.0.0.1/32 for loopback, but no addresses within this block should ever appear on any network anywhere [RFC1700, page 5]. Do you perhaps know? thank you, Albert Pretorius ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: IPV6 loopback bound socket succeeds connecting to remote host 2010-12-02 7:45 ` Albert Pretorius @ 2010-12-02 8:41 ` Shan Wei 2010-12-16 20:18 ` David Miller 0 siblings, 1 reply; 9+ messages in thread From: Shan Wei @ 2010-12-02 8:41 UTC (permalink / raw) To: Albert Pretorius Cc: netdev, yoshfuji@linux-ipv6.org >> YOSHIFUJI Hideaki, David Miller, pekkas, jmorris Albert Pretorius wrote, at 12/02/2010 03:45 PM: > Hi > > --- On Wed, 1/12/10, Shan Wei <shanwei@cn.fujitsu.com> wrote: >> I think it make nonsense to translate data between loopback >> device and other e.g. eth0 device in same machine. > > I agree, RFC4291 makes it clear for IPV6 that no interface should accept traffic from loopback, I should not have tried to make it behave like IPV4. > I can not find an equivalent statement for IPV4 though, all I could find is this from RFC3330: > > 127.0.0.0/8 - This block is assigned for use as the Internet host > loopback address. A datagram sent by a higher level protocol to an > address anywhere within this block should loop back inside the host. > This is ordinarily implemented using only 127.0.0.1/32 for loopback, > but no addresses within this block should ever appear on any network > anywhere [RFC1700, page 5]. > > Do you perhaps know? There are no same statement for IPv4 loopback address. I have checked RFC1122, RFC1700 and RFC5753 . -- Best Regards ----- Shan Wei > thank you, > Albert Pretorius > > > > ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: IPV6 loopback bound socket succeeds connecting to remote host 2010-12-02 8:41 ` Shan Wei @ 2010-12-16 20:18 ` David Miller 2010-12-20 6:31 ` Shan Wei 0 siblings, 1 reply; 9+ messages in thread From: David Miller @ 2010-12-16 20:18 UTC (permalink / raw) To: shanwei; +Cc: albertpretorius, netdev, yoshfuji, pekkas, jmorris From: Shan Wei <shanwei@cn.fujitsu.com> Date: Thu, 02 Dec 2010 16:41:39 +0800 > Albert Pretorius wrote, at 12/02/2010 03:45 PM: >> Hi >> >> --- On Wed, 1/12/10, Shan Wei <shanwei@cn.fujitsu.com> wrote: >>> I think it make nonsense to translate data between loopback >>> device and other e.g. eth0 device in same machine. >> >> I agree, RFC4291 makes it clear for IPV6 that no interface should accept traffic from loopback, I should not have tried to make it behave like IPV4. >> I can not find an equivalent statement for IPV4 though, all I could find is this from RFC3330: >> >> 127.0.0.0/8 - This block is assigned for use as the Internet host >> loopback address. A datagram sent by a higher level protocol to an >> address anywhere within this block should loop back inside the host. >> This is ordinarily implemented using only 127.0.0.1/32 for loopback, >> but no addresses within this block should ever appear on any network >> anywhere [RFC1700, page 5]. >> >> Do you perhaps know? > > There are no same statement for IPv4 loopback address. I have checked RFC1122, RFC1700 and RFC5753 . Shan, you really need to handle this in the ipv6 routing code. Your approach will only modify socket based route handling, it will not handle the ipv6 forwarding case which as per the quoted RFC sections must be handled too. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: IPV6 loopback bound socket succeeds connecting to remote host 2010-12-16 20:18 ` David Miller @ 2010-12-20 6:31 ` Shan Wei 2010-12-20 6:43 ` David Miller 0 siblings, 1 reply; 9+ messages in thread From: Shan Wei @ 2010-12-20 6:31 UTC (permalink / raw) To: David Miller; +Cc: albertpretorius, netdev, yoshfuji, pekkas, jmorris David Miller wrote, at 12/17/2010 04:18 AM: > Your approach will only modify socket based route handling, it will > not handle the ipv6 forwarding case which as per the quoted RFC > sections must be handled too. For the ipv6 forwarding case, we have done the check in ip6_forward(). 493 int addrtype = ipv6_addr_type(&hdr->saddr); 494 495 /* This check is security critical. */ 496 if (addrtype == IPV6_ADDR_ANY || 497 addrtype & (IPV6_ADDR_MULTICAST | IPV6_ADDR_LOOPBACK)) 498 goto error; -- Best Regards ----- Shan Wei ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: IPV6 loopback bound socket succeeds connecting to remote host 2010-12-20 6:31 ` Shan Wei @ 2010-12-20 6:43 ` David Miller 2010-12-22 7:06 ` Shan Wei 0 siblings, 1 reply; 9+ messages in thread From: David Miller @ 2010-12-20 6:43 UTC (permalink / raw) To: shanwei; +Cc: albertpretorius, netdev, yoshfuji, pekkas, jmorris From: Shan Wei <shanwei@cn.fujitsu.com> Date: Mon, 20 Dec 2010 14:31:28 +0800 > David Miller wrote, at 12/17/2010 04:18 AM: >> Your approach will only modify socket based route handling, it will >> not handle the ipv6 forwarding case which as per the quoted RFC >> sections must be handled too. > > For the ipv6 forwarding case, we have done the check in ip6_forward(). > > 493 int addrtype = ipv6_addr_type(&hdr->saddr); > 494 > 495 /* This check is security critical. */ > 496 if (addrtype == IPV6_ADDR_ANY || > 497 addrtype & (IPV6_ADDR_MULTICAST | IPV6_ADDR_LOOPBACK)) > 498 goto error; Indeed, thanks for pointing this out. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: IPV6 loopback bound socket succeeds connecting to remote host 2010-12-20 6:43 ` David Miller @ 2010-12-22 7:06 ` Shan Wei 2010-12-29 16:53 ` Albert Pretorius 0 siblings, 1 reply; 9+ messages in thread From: Shan Wei @ 2010-12-22 7:06 UTC (permalink / raw) To: David Miller; +Cc: albertpretorius, netdev, yoshfuji, pekkas, jmorris David Miller wrote, at 12/20/2010 02:43 PM: > From: Shan Wei <shanwei@cn.fujitsu.com> > Date: Mon, 20 Dec 2010 14:31:28 +0800 > >> David Miller wrote, at 12/17/2010 04:18 AM: >>> Your approach will only modify socket based route handling, it will >>> not handle the ipv6 forwarding case which as per the quoted RFC >>> sections must be handled too. >> >> For the ipv6 forwarding case, we have done the check in ip6_forward(). >> >> 493 int addrtype = ipv6_addr_type(&hdr->saddr); >> 494 >> 495 /* This check is security critical. */ >> 496 if (addrtype == IPV6_ADDR_ANY || >> 497 addrtype & (IPV6_ADDR_MULTICAST | IPV6_ADDR_LOOPBACK)) >> 498 goto error; > > Indeed, thanks for pointing this out. Notice that the state in patchwork is “Changes Requested”, what should i do now? I have no idead which part of this patch should be changed. -- Best Regards ----- Shan Wei ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: IPV6 loopback bound socket succeeds connecting to remote host 2010-12-22 7:06 ` Shan Wei @ 2010-12-29 16:53 ` Albert Pretorius 0 siblings, 0 replies; 9+ messages in thread From: Albert Pretorius @ 2010-12-29 16:53 UTC (permalink / raw) To: David Miller, Shan Wei; +Cc: netdev, yoshfuji, pekkas, jmorris Hi I tested this on 2.6.37-rc8 but unfortunately that does not address the problem. I suspect the ip_forward.c change only addresses the routing of data when /proc/sys/net/ipv6/conf/all/forwarding is enabled. The original patch is required to prevent the kernel from sending a packet on the network with a source address of loopback. The kernel should not do that regardless of whether the packet will be dropped by the network (not routed). Also from an application point of view I believe the behaviour should be the same for IPV4 and IPV6 when binding to loopback and connecting to remote address (i.e. EINVAL). A further change is required to avoid the kernel acting on the reception of a packet with source address of loopback. Currently it will generate an ICMP6 dest unreachable, or pass the packet to an application listening on that port. This patch (which includes the previous) seems to addresses the above problems: ---8<--- diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index a83e920..a374100 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c @@ -108,7 +108,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt * of loopback must be dropped. */ if (!(dev->flags & IFF_LOOPBACK) && - ipv6_addr_loopback(&hdr->daddr)) + (ipv6_addr_loopback(&hdr->daddr) | ipv6_addr_loopback(&hdr->saddr))) goto err; skb->transport_header = skb->network_header + sizeof(*hdr); diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 94b5bf1..0257998 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -919,6 +919,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); @@ -926,6 +927,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, --->8--- best regards, Albert Pretorius --- On Wed, 22/12/10, Shan Wei <shanwei@cn.fujitsu.com> wrote: > From: Shan Wei <shanwei@cn.fujitsu.com> > Subject: Re: IPV6 loopback bound socket succeeds connecting to remote host > To: "David Miller" <davem@davemloft.net> > Cc: albertpretorius@yahoo.co.uk, netdev@vger.kernel.org, yoshfuji@linux-ipv6.org, pekkas@netcore.fi, jmorris@namei.org > Date: Wednesday, 22 December, 2010, 7:06 > David Miller wrote, at 12/20/2010 > 02:43 PM: > > From: Shan Wei <shanwei@cn.fujitsu.com> > > Date: Mon, 20 Dec 2010 14:31:28 +0800 > > > >> David Miller wrote, at 12/17/2010 04:18 AM: > >>> Your approach will only modify socket based > route handling, it will > >>> not handle the ipv6 forwarding case which as > per the quoted RFC > >>> sections must be handled too. > >> > >> For the ipv6 forwarding case, we have done the > check in ip6_forward(). > >> > >> 493 > int addrtype = > ipv6_addr_type(&hdr->saddr); > >> 494 > >> 495 > /* This check is security critical. > */ > >> 496 > if (addrtype == IPV6_ADDR_ANY || > >> 497 > addrtype & > (IPV6_ADDR_MULTICAST | IPV6_ADDR_LOOPBACK)) > >> 498 > goto > error; > > > > Indeed, thanks for pointing this out. > > Notice that the state in patchwork is “Changes > Requested”, what should i do > now? I have no idead which part of this patch should > be changed. > > -- > Best Regards > ----- > Shan Wei > ^ permalink raw reply related [flat|nested] 9+ messages in thread
end of thread, other threads:[~2010-12-29 16:53 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-11-29 10:55 IPV6 loopback bound socket succeeds connecting to remote host Albert Pretorius 2010-12-01 8:18 ` Shan Wei 2010-12-02 7:45 ` Albert Pretorius 2010-12-02 8:41 ` Shan Wei 2010-12-16 20:18 ` David Miller 2010-12-20 6:31 ` Shan Wei 2010-12-20 6:43 ` David Miller 2010-12-22 7:06 ` Shan Wei 2010-12-29 16:53 ` Albert Pretorius
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).