[PATCH] Fix small information leak in SO_ORIGINAL_DST and getname()

Linux Kernel Mailing List <[email protected]> Wed, 15 Mar 2006 16:59:47 GMT
Newsgroups gmane.linux.kernel.commits.2-4
Message-ID <[email protected]>
commit 09d3b3dcfa80c9094f1748c1be064b9326c9ef2b
tree eb749783fc02a0a5035299485980e4ff9151cc0c
parent 5dceef59f2919d7396853e4264636e3bd55f85e7
author Pavel Kankovsky <[email protected]> Sat, 04 Mar 2006 14:53:16 +0100
committer Marcelo Tosatti <[email protected]> Thu, 16 Mar 2006 01:44:45 -0600

[PATCH] Fix small information leak in SO_ORIGINAL_DST and getname()

It appears sockaddr_in.sin_zero is not zeroed during certain operations
returning IPv4 socket names, namely:

- getsockopt(...SO_ORIGINAL_DST...) (2.4 and 2.6)
  see getorigdst() in net/ipv4/netfilter/ip_conntrack_core.c

- getsockname() and getpeername()
  see inet_getname() in net/ipv4/af_inet.c

A small patch for 2.4 fixing the problem is enclosed. Its first part
(fixing net/ipv4/af_inet.c) is identical to the change made in 2.6.

 net/ipv4/af_inet.c                     |    1 +
 net/ipv4/netfilter/ip_conntrack_core.c |    1 +
 2 files changed, 2 insertions(+)

diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index a5ccdff..b125514 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -724,6 +724,7 @@ int inet_getname(struct socket *sock, st
 		sin->sin_port = sk->sport;
 		sin->sin_addr.s_addr = addr;
 	}
+	memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
 	*uaddr_len = sizeof(*sin);
 	return(0);
 }
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
index e32dc17..afbb6cb 100644
--- a/net/ipv4/netfilter/ip_conntrack_core.c
+++ b/net/ipv4/netfilter/ip_conntrack_core.c
@@ -1349,6 +1349,7 @@ getorigdst(struct sock *sk, int optval, 
 			.tuple.dst.u.tcp.port;
 		sin.sin_addr.s_addr = h->ctrack->tuplehash[IP_CT_DIR_ORIGINAL]
 			.tuple.dst.ip;
+		memset(sin.sin_zero, 0, sizeof(sin.sin_zero));
 
 		DEBUGP("SO_ORIGINAL_DST: %u.%u.%u.%u %u\n",
 		       NIPQUAD(sin.sin_addr.s_addr), ntohs(sin.sin_port));