lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <1456946361-9889-1-git-send-email-tracywwnj@gmail.com>
Date:	Wed,  2 Mar 2016 11:19:21 -0800
From:	Wei Wang <weiwan@...gle.com>
To:	"David S . Miller" <davem@...emloft.net>
Cc:	netdev@...r.kernel.org, Eric Dumazet <edumazet@...gle.com>,
	Wei Wang <weiwan@...gle.com>
Subject: [PATCH] ipv6: Fix the pmtu path for connected UDP socket

From: Wei Wang <weiwan@...gle.com>

When ICMPV6_PKT_TOOBIG message is received by a connected UDP socket,
the new mtu value is not properly updated in the dst_entry associated
with the socket.
This leads to the issue that the mtu value returned by getsockopt(sockfd,
IPPROTO_IPV6, IPV6_MTU, ...) is wrong.
The fix is to call the corresponding pmtu related function for connected
socket so that the dst_entry associated with the socket will get updated
with the new mtu value.
And before we call the above function to update mtu, we check to make
sure the source IP address, destination IP address, source port and
destination port are matching between the incoming flow and the socket.

Signed-off-by: Wei Wang <weiwan@...gle.com>
---
 net/ipv6/udp.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 0711f8f..5e6ba54 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -49,6 +49,7 @@
 #include <net/inet6_hashtables.h>
 #include <net/busy_poll.h>
 #include <net/sock_reuseport.h>
+#include <net/inet6_connection_sock.h>
 
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
@@ -566,7 +567,16 @@ void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
 	if (type == ICMPV6_PKT_TOOBIG) {
 		if (!ip6_sk_accept_pmtu(sk))
 			goto out;
-		ip6_sk_update_pmtu(skb, sk, info);
+		bh_lock_sock(sk);
+		if (sk->sk_state == TCP_ESTABLISHED &&
+		    !sock_owned_by_user(sk) &&
+		    ipv6_addr_equal(saddr, &sk->sk_v6_rcv_saddr) &&
+		    ipv6_addr_equal(daddr, &sk->sk_v6_daddr) &&
+		    uh->dest == sk->sk_dport)
+			inet6_csk_update_pmtu(sk, ntohl(info));
+		else
+			ip6_sk_update_pmtu(skb, sk, info);
+		bh_unlock_sock(sk);
 		if (np->pmtudisc != IPV6_PMTUDISC_DONT)
 			harderr = 1;
 	}
-- 
2.7.0.rc3.207.g0ac5344

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ