summaryrefslogtreecommitdiff
path: root/net/lapb/lapb_out.c
diff options
context:
space:
mode:
authorMartin KaFai Lau <kafai@fb.com>2018-01-24 23:15:27 -0800
committerBruno Martins <bgcngm@gmail.com>2022-10-28 15:39:24 +0100
commit1ab50514c430c00855f469893b35f855a9518e99 (patch)
tree6b0bea7d0d97560b28339420d1f6431756d0f168 /net/lapb/lapb_out.c
parentf3dfd61c502d25e8305072d42329a3ac93be8c67 (diff)
ipv6: Fix SO_REUSEPORT UDP socket with implicit sk_ipv6only
[ 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> Change-Id: If8cf2bec6d47a27e0502a8a8392105863c34dab3
Diffstat (limited to 'net/lapb/lapb_out.c')
0 files changed, 0 insertions, 0 deletions