]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 4.19
authorSasha Levin <sashal@kernel.org>
Tue, 30 Mar 2021 20:51:41 +0000 (16:51 -0400)
committerSasha Levin <sashal@kernel.org>
Tue, 30 Mar 2021 20:51:41 +0000 (16:51 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-4.19/ipv6-weaken-the-v4mapped-source-check.patch [new file with mode: 0644]
queue-4.19/selinux-vsock-set-sid-for-socket-returned-by-accept.patch [new file with mode: 0644]
queue-4.19/series [new file with mode: 0644]
queue-4.19/tcp-relookup-sock-for-rst-ack-packets-handled-by-obs.patch [new file with mode: 0644]

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 (file)
index 0000000..9575ee5
--- /dev/null
@@ -0,0 +1,102 @@
+From 1c79a7b82fb8a78065c818d64f63c2e2971d6b2e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Mar 2021 09:55:15 -0700
+Subject: ipv6: weaken the v4mapped source check
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ 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 <sunyishao@fb.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Acked-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..2b49a93
--- /dev/null
@@ -0,0 +1,41 @@
+From 15de7aa6cf96f9ce42b43fee4079572ba572f660 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Mar 2021 18:24:43 +0000
+Subject: selinux: vsock: Set SID for socket returned by accept()
+
+From: David Brazdil <dbrazdil@google.com>
+
+[ 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 <dbrazdil@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..d56069a
--- /dev/null
@@ -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 (file)
index 0000000..bd34b64
--- /dev/null
@@ -0,0 +1,86 @@
+From cc34bcdfa1a0ab1a35bb3c2f8c07ae19767b6472 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <ovov@yandex-team.ru>
+
+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 <ovov@yandex-team.ru>
+Reported-by: Oleg Senin <olegsenin@yandex-team.ru>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+