From 271c15fb73f403c7caaef3b3a13dbb500a2cb4ea Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Tue, 30 Mar 2021 16:51:41 -0400 Subject: [PATCH] Fixes for 4.19 Signed-off-by: Sasha Levin --- ...pv6-weaken-the-v4mapped-source-check.patch | 102 ++++++++++++++++++ ...et-sid-for-socket-returned-by-accept.patch | 41 +++++++ queue-4.19/series | 3 + ...k-for-rst-ack-packets-handled-by-obs.patch | 86 +++++++++++++++ 4 files changed, 232 insertions(+) create mode 100644 queue-4.19/ipv6-weaken-the-v4mapped-source-check.patch create mode 100644 queue-4.19/selinux-vsock-set-sid-for-socket-returned-by-accept.patch create mode 100644 queue-4.19/series create mode 100644 queue-4.19/tcp-relookup-sock-for-rst-ack-packets-handled-by-obs.patch diff --git a/queue-4.19/ipv6-weaken-the-v4mapped-source-check.patch b/queue-4.19/ipv6-weaken-the-v4mapped-source-check.patch new file mode 100644 index 00000000000..9575ee53405 --- /dev/null +++ b/queue-4.19/ipv6-weaken-the-v4mapped-source-check.patch @@ -0,0 +1,102 @@ +From 1c79a7b82fb8a78065c818d64f63c2e2971d6b2e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 17 Mar 2021 09:55:15 -0700 +Subject: ipv6: weaken the v4mapped source check + +From: Jakub Kicinski + +[ Upstream commit dcc32f4f183ab8479041b23a1525d48233df1d43 ] + +This reverts commit 6af1799aaf3f1bc8defedddfa00df3192445bbf3. + +Commit 6af1799aaf3f ("ipv6: drop incoming packets having a v4mapped +source address") introduced an input check against v4mapped addresses. +Use of such addresses on the wire is indeed questionable and not +allowed on public Internet. As the commit pointed out + + https://tools.ietf.org/html/draft-itojun-v6ops-v4mapped-harmful-02 + +lists potential issues. + +Unfortunately there are applications which use v4mapped addresses, +and breaking them is a clear regression. For example v4mapped +addresses (or any semi-valid addresses, really) may be used +for uni-direction event streams or packet export. + +Since the issue which sparked the addition of the check was with +TCP and request_socks in particular push the check down to TCPv6 +and DCCP. This restores the ability to receive UDPv6 packets with +v4mapped address as the source. + +Keep using the IPSTATS_MIB_INHDRERRORS statistic to minimize the +user-visible changes. + +Fixes: 6af1799aaf3f ("ipv6: drop incoming packets having a v4mapped source address") +Reported-by: Sunyi Shao +Signed-off-by: Jakub Kicinski +Acked-by: Mat Martineau +Reviewed-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/dccp/ipv6.c | 5 +++++ + net/ipv6/ip6_input.c | 10 ---------- + net/ipv6/tcp_ipv6.c | 5 +++++ + 3 files changed, 10 insertions(+), 10 deletions(-) + +diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c +index b438bed6749d..2cd3508a3786 100644 +--- a/net/dccp/ipv6.c ++++ b/net/dccp/ipv6.c +@@ -319,6 +319,11 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb) + if (!ipv6_unicast_destination(skb)) + return 0; /* discard, don't send a reset here */ + ++ if (ipv6_addr_v4mapped(&ipv6_hdr(skb)->saddr)) { ++ __IP6_INC_STATS(sock_net(sk), NULL, IPSTATS_MIB_INHDRERRORS); ++ return 0; ++ } ++ + if (dccp_bad_service_code(sk, service)) { + dcb->dccpd_reset_code = DCCP_RESET_CODE_BAD_SERVICE_CODE; + goto drop; +diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c +index acf0749ee5bb..57d84accbf1e 100644 +--- a/net/ipv6/ip6_input.c ++++ b/net/ipv6/ip6_input.c +@@ -222,16 +222,6 @@ static struct sk_buff *ip6_rcv_core(struct sk_buff *skb, struct net_device *dev, + if (ipv6_addr_is_multicast(&hdr->saddr)) + goto err; + +- /* While RFC4291 is not explicit about v4mapped addresses +- * in IPv6 headers, it seems clear linux dual-stack +- * model can not deal properly with these. +- * Security models could be fooled by ::ffff:127.0.0.1 for example. +- * +- * https://tools.ietf.org/html/draft-itojun-v6ops-v4mapped-harmful-02 +- */ +- if (ipv6_addr_v4mapped(&hdr->saddr)) +- goto err; +- + skb->transport_header = skb->network_header + sizeof(*hdr); + IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr); + +diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c +index 6e84f2eb08d6..8d822df83b08 100644 +--- a/net/ipv6/tcp_ipv6.c ++++ b/net/ipv6/tcp_ipv6.c +@@ -1039,6 +1039,11 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) + if (!ipv6_unicast_destination(skb)) + goto drop; + ++ if (ipv6_addr_v4mapped(&ipv6_hdr(skb)->saddr)) { ++ __IP6_INC_STATS(sock_net(sk), NULL, IPSTATS_MIB_INHDRERRORS); ++ return 0; ++ } ++ + return tcp_conn_request(&tcp6_request_sock_ops, + &tcp_request_sock_ipv6_ops, sk, skb); + +-- +2.30.1 + diff --git a/queue-4.19/selinux-vsock-set-sid-for-socket-returned-by-accept.patch b/queue-4.19/selinux-vsock-set-sid-for-socket-returned-by-accept.patch new file mode 100644 index 00000000000..2b49a93b0ea --- /dev/null +++ b/queue-4.19/selinux-vsock-set-sid-for-socket-returned-by-accept.patch @@ -0,0 +1,41 @@ +From 15de7aa6cf96f9ce42b43fee4079572ba572f660 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Mar 2021 18:24:43 +0000 +Subject: selinux: vsock: Set SID for socket returned by accept() + +From: David Brazdil + +[ Upstream commit 1f935e8e72ec28dddb2dc0650b3b6626a293d94b ] + +For AF_VSOCK, accept() currently returns sockets that are unlabelled. +Other socket families derive the child's SID from the SID of the parent +and the SID of the incoming packet. This is typically done as the +connected socket is placed in the queue that accept() removes from. + +Reuse the existing 'security_sk_clone' hook to copy the SID from the +parent (server) socket to the child. There is no packet SID in this +case. + +Fixes: d021c344051a ("VSOCK: Introduce VM Sockets") +Signed-off-by: David Brazdil +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/vmw_vsock/af_vsock.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c +index 4b65db13e1bb..aceafec612a8 100644 +--- a/net/vmw_vsock/af_vsock.c ++++ b/net/vmw_vsock/af_vsock.c +@@ -628,6 +628,7 @@ struct sock *__vsock_create(struct net *net, + vsk->trusted = psk->trusted; + vsk->owner = get_cred(psk->owner); + vsk->connect_timeout = psk->connect_timeout; ++ security_sk_clone(parent, sk); + } else { + vsk->trusted = ns_capable_noaudit(&init_user_ns, CAP_NET_ADMIN); + vsk->owner = get_current_cred(); +-- +2.30.1 + diff --git a/queue-4.19/series b/queue-4.19/series new file mode 100644 index 00000000000..d56069a539a --- /dev/null +++ b/queue-4.19/series @@ -0,0 +1,3 @@ +selinux-vsock-set-sid-for-socket-returned-by-accept.patch +tcp-relookup-sock-for-rst-ack-packets-handled-by-obs.patch +ipv6-weaken-the-v4mapped-source-check.patch diff --git a/queue-4.19/tcp-relookup-sock-for-rst-ack-packets-handled-by-obs.patch b/queue-4.19/tcp-relookup-sock-for-rst-ack-packets-handled-by-obs.patch new file mode 100644 index 00000000000..bd34b645021 --- /dev/null +++ b/queue-4.19/tcp-relookup-sock-for-rst-ack-packets-handled-by-obs.patch @@ -0,0 +1,86 @@ +From cc34bcdfa1a0ab1a35bb3c2f8c07ae19767b6472 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Mar 2021 20:55:41 +0300 +Subject: tcp: relookup sock for RST+ACK packets handled by obsolete req sock + +From: Alexander Ovechkin + +commit 7233da86697efef41288f8b713c10c2499cffe85 upstream. + +Currently tcp_check_req can be called with obsolete req socket for which big +socket have been already created (because of CPU race or early demux +assigning req socket to multiple packets in gro batch). + +Commit e0f9759f530bf789e984 ("tcp: try to keep packet if SYN_RCV race +is lost") added retry in case when tcp_check_req is called for PSH|ACK packet. +But if client sends RST+ACK immediatly after connection being +established (it is performing healthcheck, for example) retry does not +occur. In that case tcp_check_req tries to close req socket, +leaving big socket active. + +Fixes: e0f9759f530b ("tcp: try to keep packet if SYN_RCV race is lost") +Signed-off-by: Alexander Ovechkin +Reported-by: Oleg Senin +Signed-off-by: Sasha Levin +--- + include/net/inet_connection_sock.h | 2 +- + net/ipv4/inet_connection_sock.c | 7 +++++-- + net/ipv4/tcp_minisocks.c | 7 +++++-- + 3 files changed, 11 insertions(+), 5 deletions(-) + +diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h +index fc9d6e37552d..da8a582ab032 100644 +--- a/include/net/inet_connection_sock.h ++++ b/include/net/inet_connection_sock.h +@@ -288,7 +288,7 @@ static inline int inet_csk_reqsk_queue_is_full(const struct sock *sk) + return inet_csk_reqsk_queue_len(sk) >= sk->sk_max_ack_backlog; + } + +-void inet_csk_reqsk_queue_drop(struct sock *sk, struct request_sock *req); ++bool inet_csk_reqsk_queue_drop(struct sock *sk, struct request_sock *req); + void inet_csk_reqsk_queue_drop_and_put(struct sock *sk, struct request_sock *req); + + void inet_csk_destroy_sock(struct sock *sk); +diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c +index 534e2598981d..439a55d1aa99 100644 +--- a/net/ipv4/inet_connection_sock.c ++++ b/net/ipv4/inet_connection_sock.c +@@ -698,12 +698,15 @@ static bool reqsk_queue_unlink(struct request_sock_queue *queue, + return found; + } + +-void inet_csk_reqsk_queue_drop(struct sock *sk, struct request_sock *req) ++bool inet_csk_reqsk_queue_drop(struct sock *sk, struct request_sock *req) + { +- if (reqsk_queue_unlink(&inet_csk(sk)->icsk_accept_queue, req)) { ++ bool unlinked = reqsk_queue_unlink(&inet_csk(sk)->icsk_accept_queue, req); ++ ++ if (unlinked) { + reqsk_queue_removed(&inet_csk(sk)->icsk_accept_queue, req); + reqsk_put(req); + } ++ return unlinked; + } + EXPORT_SYMBOL(inet_csk_reqsk_queue_drop); + +diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c +index 9436fb9b6a3d..a20b393b4501 100644 +--- a/net/ipv4/tcp_minisocks.c ++++ b/net/ipv4/tcp_minisocks.c +@@ -815,8 +815,11 @@ embryonic_reset: + tcp_reset(sk); + } + if (!fastopen) { +- inet_csk_reqsk_queue_drop(sk, req); +- __NET_INC_STATS(sock_net(sk), LINUX_MIB_EMBRYONICRSTS); ++ bool unlinked = inet_csk_reqsk_queue_drop(sk, req); ++ ++ if (unlinked) ++ __NET_INC_STATS(sock_net(sk), LINUX_MIB_EMBRYONICRSTS); ++ *req_stolen = !unlinked; + } + return NULL; + } +-- +2.30.1 + -- 2.47.3