Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 2803

kernel-2.6.18-238.el5.src.rpm

From: David S. Miller <davem@redhat.com>
Subject: [RHEL5]: Fix ipv6 OOPS triggerable by any user.
Date: Tue, 20 Mar 2007 01:54:33 -0400 (EDT)
Bugzilla: 233088
Message-Id: <20070320.015433.60806669.davem@redhat.com>
Changelog: [net] ipv6_fl_socklist is inadvertently shared



We accidently copy the ipv6 flow list to child sockets of listening
TCP sockets, but don't bump the reference count, clone the object,
etc.  And the list linkage of this object is not built such that
multiple sockets can point to it anyways.

Therefore if a listening socket has a flow list attached,
when a child connection closes we'll OOPS or double free
the flow list entry.

Any user can trigger this.

Writing a reproducer should be simple:

1) Open listening IPV6 TCP socket
2) Attach a flowlabel with IPV6_FLOWLABEL_MGR socket option,
   freq->flr_action == IPV6_FL_A_GET and appropriate metadata.
3) Connect to that listening socket, and close()

Instant oops.  The fix is to simply not inherit this ipv6
socket option.

This was discovered and merged upstream right before this
past weekend.  See:

	http://marc.info/?l=linux-netdev&m=117406721731891&w=2

Please ACK.

Commit d35690beda1429544d46c8eb34b2e3a8c37ab299
Author: Masayuki Nakagawa <nakagawa.msy@ncos.nec.co.jp>

    [IPV6]: ipv6_fl_socklist is inadvertently shared.
    
    The ipv6_fl_socklist from listening socket is inadvertently shared
    with new socket created for connection.  This leads to a variety of
    interesting, but fatal, bugs. For example, removing one of the
    sockets may lead to the other socket's encountering a page fault
    when the now freed list is referenced.
    
    The fix is to not share the flow label list with the new socket.
    
    Signed-off-by: Masayuki Nakagawa <nakagawa.msy@ncos.nec.co.jp>
    Signed-off-by: David S. Miller <davem@davemloft.net>

diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index f57a9ba..92f9992 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -975,6 +975,7 @@ static struct sock * tcp_v6_syn_recv_soc
 	   First: no IPv4 options.
 	 */
 	newinet->opt = NULL;
+	newnp->ipv6_fl_list = NULL;
 
 	/* Clone RX bits */
 	newnp->rxopt.all = np->rxopt.all;