netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] IPV6: Sereral errors on udpv6_connect()
@ 2003-06-04  0:39 YOSHIFUJI Hideaki / 吉藤英明
  2003-06-04  5:46 ` David S. Miller
  2003-06-13 21:07 ` [patch] IPV6: Refcount leaks in udpv6_connect() Ville Nuorvala
  0 siblings, 2 replies; 7+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2003-06-04  0:39 UTC (permalink / raw)
  To: davem; +Cc: Ville Nuorvala, netdev

Hello.

The CONFIG_IPV6_SUBTREE contains multiple fixes and changes.
I'm trying to split them.

This patch fixes multiple errors in udpv6_connect().
 - pointer within an automatic storage class variable fl was illegally cached
   using ip6_dst_store().
 - uninitialized saddr was copied to fl.fl6_src.
 - don't cache if ipv6_saddr_get() failed.
Patch is based on CONFIG_IPV6_SUBTREE patch from Ville Nuorvala 
<vnuorval@tcs.hut.fi>.

Index: linux25-LINUS/net/ipv6/udp.c
===================================================================
RCS file: /cvsroot/usagi/usagi-backport/linux25/net/ipv6/udp.c,v
retrieving revision 1.1.1.18
diff -u -r1.1.1.18 udp.c
--- linux25-LINUS/net/ipv6/udp.c	26 May 2003 08:04:11 -0000	1.1.1.18
+++ linux25-LINUS/net/ipv6/udp.c	4 Jun 2003 00:29:32 -0000
@@ -254,7 +254,6 @@
 	struct inet_opt      	*inet = inet_sk(sk);
 	struct ipv6_pinfo      	*np = inet6_sk(sk);
 	struct in6_addr		*daddr;
-	struct in6_addr		saddr;
 	struct dst_entry	*dst;
 	struct flowi		fl;
 	struct ip6_flowlabel	*flowlabel = NULL;
@@ -355,7 +354,7 @@
 
 	fl.proto = IPPROTO_UDP;
 	ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
-	ipv6_addr_copy(&fl.fl6_src, &saddr);
+	ipv6_addr_copy(&fl.fl6_src, &np->saddr);
 	fl.oif = sk->bound_dev_if;
 	fl.fl_ip_dport = inet->dport;
 	fl.fl_ip_sport = inet->sport;
@@ -381,20 +380,23 @@
 		return err;
 	}
 
-	ip6_dst_store(sk, dst, &fl.fl6_dst);
-
 	/* get the source address used in the appropriate device */
 
-	err = ipv6_get_saddr(dst, daddr, &saddr);
+	err = ipv6_get_saddr(dst, daddr, &fl.fl6_src);
 
 	if (err == 0) {
 		if (ipv6_addr_any(&np->saddr))
-			ipv6_addr_copy(&np->saddr, &saddr);
+			ipv6_addr_copy(&np->saddr, &fl.fl6_src);
 
 		if (ipv6_addr_any(&np->rcv_saddr)) {
-			ipv6_addr_copy(&np->rcv_saddr, &saddr);
+			ipv6_addr_copy(&np->rcv_saddr, &fl.fl6_src);
 			inet->rcv_saddr = LOOPBACK4_IPV6;
 		}
+
+		ip6_dst_store(sk, dst,
+			      !ipv6_addr_cmp(&fl.fl6_dst, &np->daddr) ?
+			      &np->daddr : NULL);
+
 		sk->state = TCP_ESTABLISHED;
 	}
 	fl6_sock_release(flowlabel);

-- 
Hideaki YOSHIFUJI @ USAGI Project <yoshfuji@linux-ipv6.org>
GPG FP: 9022 65EB 1ECF 3AD1 0BDF  80D8 4807 F894 E062 0EEA

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] IPV6: Sereral errors on udpv6_connect()
  2003-06-04  0:39 [PATCH] IPV6: Sereral errors on udpv6_connect() YOSHIFUJI Hideaki / 吉藤英明
@ 2003-06-04  5:46 ` David S. Miller
  2003-06-13 21:07 ` [patch] IPV6: Refcount leaks in udpv6_connect() Ville Nuorvala
  1 sibling, 0 replies; 7+ messages in thread
From: David S. Miller @ 2003-06-04  5:46 UTC (permalink / raw)
  To: yoshfuji; +Cc: vnuorval, netdev

   From: YOSHIFUJI Hideaki / 吉藤英明 <yoshfuji@linux-ipv6.org>
   Date: Wed, 04 Jun 2003 09:39:44 +0900 (JST)
   
   This patch fixes multiple errors in udpv6_connect().
    - pointer within an automatic storage class variable fl was illegally cached
      using ip6_dst_store().
    - uninitialized saddr was copied to fl.fl6_src.
    - don't cache if ipv6_saddr_get() failed.

Applied.

All these kinds of things need to be done differently once
routing by saddr is supported, more specifically when
route6 lookups make source address selection.  Look at
ipv4 side to see the kind of thing I'm talking about.

Yoshfuji-san, remember when Alexey wanted you to change your
source address selection so that it occurred at routing layer?
This is exactly what I'm talking about.

In my view, ipv6 routing is merely a SEVERELY crippled version
of ipv4 routing.  Most of ipv6 routing changes needed amount
to merely "porting over" existing ipv4 routing features.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [patch] IPV6: Refcount leaks in udpv6_connect()
  2003-06-04  0:39 [PATCH] IPV6: Sereral errors on udpv6_connect() YOSHIFUJI Hideaki / 吉藤英明
  2003-06-04  5:46 ` David S. Miller
@ 2003-06-13 21:07 ` Ville Nuorvala
  2003-06-14  1:26   ` YOSHIFUJI Hideaki / 吉藤英明
  2003-06-15  7:26   ` David S. Miller
  1 sibling, 2 replies; 7+ messages in thread
From: Ville Nuorvala @ 2003-06-13 21:07 UTC (permalink / raw)
  To: YOSHIFUJI Hideaki / 吉藤英明; +Cc: davem, netdev

Hi!

A dst refcount leak had unfortunately crept into my original
CONFIG_IPV6_SUBTREES patch and your derived udpv6_connect() patch
(changeset 1.1215.68.12).

While fixing this, I also found and fixed some other apparent leaks.

This patch fixes several bugs in udpv6_connect():
- dst refcount leak if ipv6_get_saddr() fails
- several flowlabel refcount leaks

The diff is done against ChangeSet 1.1307.

Thanks,
Ville

diff -Nur --exclude=SCCS --exclude=BitKeeper --exclude=ChangeSet linux-2.5/net/ipv6/udp.c merge-2.5/net/ipv6/udp.c
--- linux-2.5/net/ipv6/udp.c	Fri Jun 13 16:08:00 2003
+++ merge-2.5/net/ipv6/udp.c	Fri Jun 13 16:05:33 2003
@@ -299,9 +299,10 @@
 	if (addr_type == IPV6_ADDR_MAPPED) {
 		struct sockaddr_in sin;

-		if (__ipv6_only_sock(sk))
-			return -ENETUNREACH;
-
+		if (__ipv6_only_sock(sk)) {
+			err = -ENETUNREACH;
+			goto out;
+		}
 		sin.sin_family = AF_INET;
 		sin.sin_addr.s_addr = daddr->s6_addr32[3];
 		sin.sin_port = usin->sin6_port;
@@ -309,8 +310,8 @@
 		err = udp_connect(sk, (struct sockaddr*) &sin, sizeof(sin));

 ipv4_connected:
-		if (err < 0)
-			return err;
+		if (err)
+			goto out;

 		ipv6_addr_set(&np->daddr, 0, 0, htonl(0x0000ffff), inet->daddr);

@@ -323,7 +324,7 @@
 			ipv6_addr_set(&np->rcv_saddr, 0, 0, htonl(0x0000ffff),
 				      inet->rcv_saddr);
 		}
-		return 0;
+		goto out;
 	}

 	if (addr_type&IPV6_ADDR_LINKLOCAL) {
@@ -331,8 +332,8 @@
 		    usin->sin6_scope_id) {
 			if (sk->sk_bound_dev_if &&
 			    sk->sk_bound_dev_if != usin->sin6_scope_id) {
-				fl6_sock_release(flowlabel);
-				return -EINVAL;
+				err = -EINVAL;
+				goto out;
 			}
 			sk->sk_bound_dev_if = usin->sin6_scope_id;
 			if (!sk->sk_bound_dev_if &&
@@ -341,8 +342,10 @@
 		}

 		/* Connect to link-local address requires an interface */
-		if (!sk->sk_bound_dev_if)
-			return -EINVAL;
+		if (!sk->sk_bound_dev_if) {
+			err = -EINVAL;
+			goto out;
+		}
 	}

 	ipv6_addr_copy(&np->daddr, daddr);
@@ -379,31 +382,33 @@

 	if ((err = dst->error) != 0) {
 		dst_release(dst);
-		fl6_sock_release(flowlabel);
-		return err;
+		goto out;
 	}

 	/* get the source address used in the appropriate device */

 	err = ipv6_get_saddr(dst, daddr, &fl.fl6_src);

-	if (err == 0) {
-		if (ipv6_addr_any(&np->saddr))
-			ipv6_addr_copy(&np->saddr, &fl.fl6_src);
-
-		if (ipv6_addr_any(&np->rcv_saddr)) {
-			ipv6_addr_copy(&np->rcv_saddr, &fl.fl6_src);
-			inet->rcv_saddr = LOOPBACK4_IPV6;
-		}
+	if (err) {
+		dst_release(dst);
+		goto out;
+	}

-		ip6_dst_store(sk, dst,
-			      !ipv6_addr_cmp(&fl.fl6_dst, &np->daddr) ?
-			      &np->daddr : NULL);
+	if (ipv6_addr_any(&np->saddr))
+		ipv6_addr_copy(&np->saddr, &fl.fl6_src);

-		sk->sk_state = TCP_ESTABLISHED;
+	if (ipv6_addr_any(&np->rcv_saddr)) {
+		ipv6_addr_copy(&np->rcv_saddr, &fl.fl6_src);
+		inet->rcv_saddr = LOOPBACK4_IPV6;
 	}
-	fl6_sock_release(flowlabel);

+	ip6_dst_store(sk, dst,
+		      !ipv6_addr_cmp(&fl.fl6_dst, &np->daddr) ?
+		      &np->daddr : NULL);
+
+	sk->sk_state = TCP_ESTABLISHED;
+out:
+	fl6_sock_release(flowlabel);
 	return err;
 }

--
Ville Nuorvala
Research Assistant, Institute of Digital Communications,
Helsinki University of Technology
email: vnuorval@tcs.hut.fi, phone: +358 (0)9 451 5257

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [patch] IPV6: Refcount leaks in udpv6_connect()
  2003-06-13 21:07 ` [patch] IPV6: Refcount leaks in udpv6_connect() Ville Nuorvala
@ 2003-06-14  1:26   ` YOSHIFUJI Hideaki / 吉藤英明
  2003-06-15  7:26   ` David S. Miller
  1 sibling, 0 replies; 7+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2003-06-14  1:26 UTC (permalink / raw)
  To: vnuorval, davem; +Cc: netdev, yoshfuji

In article <Pine.LNX.4.44.0306132149290.4922-100000@rhea.tcs.hut.fi> (at Sat, 14 Jun 2003 00:07:25 +0300 (EEST)), Ville Nuorvala <vnuorval@tcs.hut.fi> says:

> A dst refcount leak had unfortunately crept into my original
> CONFIG_IPV6_SUBTREES patch and your derived udpv6_connect() patch
> (changeset 1.1215.68.12).

patch looks fine to me.

-- 
Hideaki YOSHIFUJI @ USAGI Project <yoshfuji@linux-ipv6.org>
GPG FP: 9022 65EB 1ECF 3AD1 0BDF  80D8 4807 F894 E062 0EEA

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [patch] IPV6: Refcount leaks in udpv6_connect()
  2003-06-13 21:07 ` [patch] IPV6: Refcount leaks in udpv6_connect() Ville Nuorvala
  2003-06-14  1:26   ` YOSHIFUJI Hideaki / 吉藤英明
@ 2003-06-15  7:26   ` David S. Miller
  2003-06-16  9:22     ` Ville Nuorvala
  1 sibling, 1 reply; 7+ messages in thread
From: David S. Miller @ 2003-06-15  7:26 UTC (permalink / raw)
  To: vnuorval; +Cc: yoshfuji, netdev

   From: Ville Nuorvala <vnuorval@tcs.hut.fi>
   Date: Sat, 14 Jun 2003 00:07:25 +0300 (EEST)
   
   The diff is done against ChangeSet 1.1307.

Your patch does not apply without rejects.
Please regenerate.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [patch] IPV6: Refcount leaks in udpv6_connect()
  2003-06-15  7:26   ` David S. Miller
@ 2003-06-16  9:22     ` Ville Nuorvala
  2003-06-16 12:02       ` David S. Miller
  0 siblings, 1 reply; 7+ messages in thread
From: Ville Nuorvala @ 2003-06-16  9:22 UTC (permalink / raw)
  To: David S. Miller; +Cc: yoshfuji, netdev

[-- Attachment #1: Type: TEXT/PLAIN, Size: 441 bytes --]

On Sun, 15 Jun 2003, David S. Miller wrote:

> Your patch does not apply without rejects.
> Please regenerate.

Hmm, odd. Perhaps the inlining of the patch mangled it somehow. Anyhow,
here's a bk treediff against CS 1.1318 as an attachment.

Hope this applies :)

Thanks,
Ville
--
Ville Nuorvala
Research Assistant, Institute of Digital Communications,
Helsinki University of Technology
email: vnuorval@tcs.hut.fi, phone: +358 (0)9 451 5257

[-- Attachment #2: Type: TEXT/PLAIN, Size: 2772 bytes --]

diff -Nur --exclude=SCCS --exclude=BitKeeper --exclude=ChangeSet linux-2.5.OLD/net/ipv6/udp.c linux-2.5/net/ipv6/udp.c
--- linux-2.5.OLD/net/ipv6/udp.c	Mon Jun 16 12:02:08 2003
+++ linux-2.5/net/ipv6/udp.c	Sun Jun 15 23:10:03 2003
@@ -299,9 +299,10 @@
 	if (addr_type == IPV6_ADDR_MAPPED) {
 		struct sockaddr_in sin;
 
-		if (__ipv6_only_sock(sk))
-			return -ENETUNREACH;
-
+		if (__ipv6_only_sock(sk)) {
+			err = -ENETUNREACH;
+			goto out;
+		}
 		sin.sin_family = AF_INET;
 		sin.sin_addr.s_addr = daddr->s6_addr32[3];
 		sin.sin_port = usin->sin6_port;
@@ -309,8 +310,8 @@
 		err = udp_connect(sk, (struct sockaddr*) &sin, sizeof(sin));
 
 ipv4_connected:
-		if (err < 0)
-			return err;
+		if (err)
+			goto out;
 		
 		ipv6_addr_set(&np->daddr, 0, 0, htonl(0x0000ffff), inet->daddr);
 
@@ -323,7 +324,7 @@
 			ipv6_addr_set(&np->rcv_saddr, 0, 0, htonl(0x0000ffff),
 				      inet->rcv_saddr);
 		}
-		return 0;
+		goto out;
 	}
 
 	if (addr_type&IPV6_ADDR_LINKLOCAL) {
@@ -331,8 +332,8 @@
 		    usin->sin6_scope_id) {
 			if (sk->sk_bound_dev_if &&
 			    sk->sk_bound_dev_if != usin->sin6_scope_id) {
-				fl6_sock_release(flowlabel);
-				return -EINVAL;
+				err = -EINVAL;
+				goto out;
 			}
 			sk->sk_bound_dev_if = usin->sin6_scope_id;
 			if (!sk->sk_bound_dev_if &&
@@ -341,8 +342,10 @@
 		}
 
 		/* Connect to link-local address requires an interface */
-		if (!sk->sk_bound_dev_if)
-			return -EINVAL;
+		if (!sk->sk_bound_dev_if) {
+			err = -EINVAL;
+			goto out;
+		}
 	}
 
 	ipv6_addr_copy(&np->daddr, daddr);
@@ -379,31 +382,33 @@
 
 	if ((err = dst->error) != 0) {
 		dst_release(dst);
-		fl6_sock_release(flowlabel);
-		return err;
+		goto out;
 	}
 
 	/* get the source address used in the appropriate device */
 
 	err = ipv6_get_saddr(dst, daddr, &fl.fl6_src);
 
-	if (err == 0) {
-		if (ipv6_addr_any(&np->saddr))
-			ipv6_addr_copy(&np->saddr, &fl.fl6_src);
-
-		if (ipv6_addr_any(&np->rcv_saddr)) {
-			ipv6_addr_copy(&np->rcv_saddr, &fl.fl6_src);
-			inet->rcv_saddr = LOOPBACK4_IPV6;
-		}
+	if (err) {
+		dst_release(dst);
+		goto out;
+	}
 
-		ip6_dst_store(sk, dst,
-			      !ipv6_addr_cmp(&fl.fl6_dst, &np->daddr) ?
-			      &np->daddr : NULL);
+	if (ipv6_addr_any(&np->saddr))
+		ipv6_addr_copy(&np->saddr, &fl.fl6_src);
 
-		sk->sk_state = TCP_ESTABLISHED;
+	if (ipv6_addr_any(&np->rcv_saddr)) {
+		ipv6_addr_copy(&np->rcv_saddr, &fl.fl6_src);
+		inet->rcv_saddr = LOOPBACK4_IPV6;
 	}
-	fl6_sock_release(flowlabel);
 
+	ip6_dst_store(sk, dst,
+		      !ipv6_addr_cmp(&fl.fl6_dst, &np->daddr) ?
+		      &np->daddr : NULL);
+
+	sk->sk_state = TCP_ESTABLISHED;
+out:
+	fl6_sock_release(flowlabel);
 	return err;
 }
 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [patch] IPV6: Refcount leaks in udpv6_connect()
  2003-06-16  9:22     ` Ville Nuorvala
@ 2003-06-16 12:02       ` David S. Miller
  0 siblings, 0 replies; 7+ messages in thread
From: David S. Miller @ 2003-06-16 12:02 UTC (permalink / raw)
  To: vnuorval; +Cc: yoshfuji, netdev

   From: Ville Nuorvala <vnuorval@tcs.hut.fi>
   Date: Mon, 16 Jun 2003 12:22:57 +0300 (EEST)
   
   Hmm, odd. Perhaps the inlining of the patch mangled it somehow. Anyhow,
   here's a bk treediff against CS 1.1318 as an attachment.

Thanks, I've applied your fix.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2003-06-16 12:02 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-06-04  0:39 [PATCH] IPV6: Sereral errors on udpv6_connect() YOSHIFUJI Hideaki / 吉藤英明
2003-06-04  5:46 ` David S. Miller
2003-06-13 21:07 ` [patch] IPV6: Refcount leaks in udpv6_connect() Ville Nuorvala
2003-06-14  1:26   ` YOSHIFUJI Hideaki / 吉藤英明
2003-06-15  7:26   ` David S. Miller
2003-06-16  9:22     ` Ville Nuorvala
2003-06-16 12:02       ` David S. Miller

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).