From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org, Martin KaFai Lau <kafai@fb.com>,
"David S. Miller" <davem@davemloft.net>
Subject: [PATCH 4.14 15/22] ipv6: Fix SO_REUSEPORT UDP socket with implicit sk_ipv6only
Date: Fri, 9 Feb 2018 14:40:04 +0100 [thread overview]
Message-ID: <20180209133935.189090931@linuxfoundation.org> (raw)
In-Reply-To: <20180209133934.024795822@linuxfoundation.org>
4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Martin KaFai Lau <kafai@fb.com>
[ Upstream commit 7ece54a60ee2ba7a386308cae73c790bd580589c ]
If a sk_v6_rcv_saddr is !IPV6_ADDR_ANY and !IPV6_ADDR_MAPPED, it
implicitly implies it is an ipv6only socket. However, in inet6_bind(),
this addr_type checking and setting sk->sk_ipv6only to 1 are only done
after sk->sk_prot->get_port(sk, snum) has been completed successfully.
This inconsistency between sk_v6_rcv_saddr and sk_ipv6only confuses
the 'get_port()'.
In particular, when binding SO_REUSEPORT UDP sockets,
udp_reuseport_add_sock(sk,...) is called. udp_reuseport_add_sock()
checks "ipv6_only_sock(sk2) == ipv6_only_sock(sk)" before adding sk to
sk2->sk_reuseport_cb. In this case, ipv6_only_sock(sk2) could be
1 while ipv6_only_sock(sk) is still 0 here. The end result is,
reuseport_alloc(sk) is called instead of adding sk to the existing
sk2->sk_reuseport_cb.
It can be reproduced by binding two SO_REUSEPORT UDP sockets on an
IPv6 address (!ANY and !MAPPED). Only one of the socket will
receive packet.
The fix is to set the implicit sk_ipv6only before calling get_port().
The original sk_ipv6only has to be saved such that it can be restored
in case get_port() failed. The situation is similar to the
inet_reset_saddr(sk) after get_port() has failed.
Thanks to Calvin Owens <calvinowens@fb.com> who created an easy
reproduction which leads to a fix.
Fixes: e32ea7e74727 ("soreuseport: fast reuseport UDP socket selection")
Signed-off-by: Martin KaFai Lau <kafai@fb.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ipv6/af_inet6.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -284,6 +284,7 @@ int inet6_bind(struct socket *sock, stru
struct net *net = sock_net(sk);
__be32 v4addr = 0;
unsigned short snum;
+ bool saved_ipv6only;
int addr_type = 0;
int err = 0;
@@ -389,19 +390,21 @@ int inet6_bind(struct socket *sock, stru
if (!(addr_type & IPV6_ADDR_MULTICAST))
np->saddr = addr->sin6_addr;
+ saved_ipv6only = sk->sk_ipv6only;
+ if (addr_type != IPV6_ADDR_ANY && addr_type != IPV6_ADDR_MAPPED)
+ sk->sk_ipv6only = 1;
+
/* Make sure we are allowed to bind here. */
if ((snum || !inet->bind_address_no_port) &&
sk->sk_prot->get_port(sk, snum)) {
+ sk->sk_ipv6only = saved_ipv6only;
inet_reset_saddr(sk);
err = -EADDRINUSE;
goto out;
}
- if (addr_type != IPV6_ADDR_ANY) {
+ if (addr_type != IPV6_ADDR_ANY)
sk->sk_userlocks |= SOCK_BINDADDR_LOCK;
- if (addr_type != IPV6_ADDR_MAPPED)
- sk->sk_ipv6only = 1;
- }
if (snum)
sk->sk_userlocks |= SOCK_BINDPORT_LOCK;
inet->inet_sport = htons(inet->inet_num);
next prev parent reply other threads:[~2018-02-09 13:45 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-02-09 13:39 [PATCH 4.14 00/22] 4.14.19-stable review Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.14 01/22] .gitignore: sort normal pattern rules alphabetically Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.14 02/22] .gitignore: move *.dtb and *.dtb.S patterns to the top-level .gitignore Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.14 03/22] kbuild: rpm-pkg: keep spec file until make mrproper Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.14 04/22] ip6mr: fix stale iterator Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.14 05/22] net: igmp: add a missing rcu locking section Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.14 06/22] qlcnic: fix deadlock bug Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.14 07/22] qmi_wwan: Add support for Quectel EP06 Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.14 08/22] r8169: fix RTL8168EP take too long to complete driver initialization Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.14 09/22] tcp: release sk_frag.page in tcp_disconnect Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.14 10/22] vhost_net: stop device during reset owner Greg Kroah-Hartman
2018-02-09 13:40 ` [PATCH 4.14 11/22] Revert "defer call to mem_cgroup_sk_alloc()" Greg Kroah-Hartman
2018-02-09 13:40 ` [PATCH 4.14 12/22] net: ipv6: send unsolicited NA after DAD Greg Kroah-Hartman
2018-02-09 13:40 ` [PATCH 4.14 13/22] rocker: fix possible null pointer dereference in rocker_router_fib_event_work Greg Kroah-Hartman
2018-02-09 13:40 ` [PATCH 4.14 14/22] tcp_bbr: fix pacing_gain to always be unity when using lt_bw Greg Kroah-Hartman
2018-02-09 13:40 ` Greg Kroah-Hartman [this message]
2018-02-09 13:40 ` [PATCH 4.14 16/22] soreuseport: fix mem leak in reuseport_add_sock() Greg Kroah-Hartman
2018-02-09 13:40 ` [PATCH 4.14 17/22] media: mtk-vcodec: add missing MODULE_LICENSE/DESCRIPTION Greg Kroah-Hartman
2018-02-09 13:40 ` [PATCH 4.14 18/22] media: soc_camera: soc_scale_crop: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE Greg Kroah-Hartman
2018-02-09 13:40 ` [PATCH 4.14 19/22] crypto: tcrypt - fix S/G table for test_aead_speed() Greg Kroah-Hartman
2018-02-09 13:40 ` [PATCH 4.14 20/22] arch: define weak abort() Greg Kroah-Hartman
2018-02-09 13:40 ` [PATCH 4.14 21/22] kernel/exit.c: export abort() to modules Greg Kroah-Hartman
2018-02-09 13:40 ` [PATCH 4.14 22/22] scsi: storvsc: missing error code in storvsc_probe() Greg Kroah-Hartman
2018-02-09 18:01 ` [PATCH 4.14 00/22] 4.14.19-stable review Timur Tabi
2018-02-09 18:18 ` Greg Kroah-Hartman
2018-02-09 18:20 ` Timur Tabi
2018-02-09 19:36 ` kernelci.org bot
2018-02-09 20:23 ` Kevin Hilman
2018-02-09 20:19 ` Shuah Khan
2018-02-09 21:30 ` Dan Rue
2018-02-10 15:47 ` Guenter Roeck
2018-02-13 9:19 ` Greg Kroah-Hartman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180209133935.189090931@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=davem@davemloft.net \
--cc=kafai@fb.com \
--cc=linux-kernel@vger.kernel.org \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).