]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 4.14
authorSasha Levin <sashal@kernel.org>
Mon, 30 Jan 2023 03:56:05 +0000 (22:56 -0500)
committerSasha Levin <sashal@kernel.org>
Mon, 30 Jan 2023 03:56:05 +0000 (22:56 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-4.14/net-ravb-fix-possible-hang-if-ris2_qff1-happen.patch [new file with mode: 0644]
queue-4.14/net-tg3-resolve-deadlock-in-tg3_reset_task-during-ee.patch [new file with mode: 0644]
queue-4.14/netfilter-conntrack-fix-bug-in-for_each_sctp_chunk.patch [new file with mode: 0644]
queue-4.14/netfilter-conntrack-fix-vtag-checks-for-abort-shutdo.patch [new file with mode: 0644]
queue-4.14/netlink-annotate-data-races-around-dst_portid-and-ds.patch [new file with mode: 0644]
queue-4.14/netlink-annotate-data-races-around-sk_state.patch [new file with mode: 0644]
queue-4.14/netrom-fix-use-after-free-of-a-listening-socket.patch [new file with mode: 0644]
queue-4.14/sctp-fail-if-no-bound-addresses-can-be-used-for-a-gi.patch [new file with mode: 0644]
queue-4.14/series

diff --git a/queue-4.14/net-ravb-fix-possible-hang-if-ris2_qff1-happen.patch b/queue-4.14/net-ravb-fix-possible-hang-if-ris2_qff1-happen.patch
new file mode 100644 (file)
index 0000000..61d9051
--- /dev/null
@@ -0,0 +1,49 @@
+From 6b33ee6e31560a1f11e2deaeb6616ed731da3825 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Jan 2023 09:02:11 +0900
+Subject: net: ravb: Fix possible hang if RIS2_QFF1 happen
+
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+
+[ Upstream commit f3c07758c9007a6bfff5290d9e19d3c41930c897 ]
+
+Since this driver enables the interrupt by RIC2_QFE1, this driver
+should clear the interrupt flag if it happens. Otherwise, the interrupt
+causes to hang the system.
+
+Note that this also fix a minor coding style (a comment indentation)
+around the fixed code.
+
+Fixes: c156633f1353 ("Renesas Ethernet AVB driver proper")
+Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Reviewed-by: Sergey Shtylyov <s.shtylyov@omp.ru>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/renesas/ravb_main.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
+index 4c8a4e6efb9f..4acea1ab6000 100644
+--- a/drivers/net/ethernet/renesas/ravb_main.c
++++ b/drivers/net/ethernet/renesas/ravb_main.c
+@@ -727,14 +727,14 @@ static void ravb_error_interrupt(struct net_device *ndev)
+       ravb_write(ndev, ~(EIS_QFS | EIS_RESERVED), EIS);
+       if (eis & EIS_QFS) {
+               ris2 = ravb_read(ndev, RIS2);
+-              ravb_write(ndev, ~(RIS2_QFF0 | RIS2_RFFF | RIS2_RESERVED),
++              ravb_write(ndev, ~(RIS2_QFF0 | RIS2_QFF1 | RIS2_RFFF | RIS2_RESERVED),
+                          RIS2);
+               /* Receive Descriptor Empty int */
+               if (ris2 & RIS2_QFF0)
+                       priv->stats[RAVB_BE].rx_over_errors++;
+-                  /* Receive Descriptor Empty int */
++              /* Receive Descriptor Empty int */
+               if (ris2 & RIS2_QFF1)
+                       priv->stats[RAVB_NC].rx_over_errors++;
+-- 
+2.39.0
+
diff --git a/queue-4.14/net-tg3-resolve-deadlock-in-tg3_reset_task-during-ee.patch b/queue-4.14/net-tg3-resolve-deadlock-in-tg3_reset_task-during-ee.patch
new file mode 100644 (file)
index 0000000..cdcc738
--- /dev/null
@@ -0,0 +1,119 @@
+From 413df5f732aecdd7da275dac8d7bde1fee7b5871 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Jan 2023 13:53:39 -0500
+Subject: net/tg3: resolve deadlock in tg3_reset_task() during EEH
+
+From: David Christensen <drc@linux.vnet.ibm.com>
+
+[ Upstream commit 6c4ca03bd890566d873e3593b32d034bf2f5a087 ]
+
+During EEH error injection testing, a deadlock was encountered in the tg3
+driver when tg3_io_error_detected() was attempting to cancel outstanding
+reset tasks:
+
+crash> foreach UN bt
+...
+PID: 159    TASK: c0000000067c6000  CPU: 8   COMMAND: "eehd"
+...
+ #5 [c00000000681f990] __cancel_work_timer at c00000000019fd18
+ #6 [c00000000681fa30] tg3_io_error_detected at c00800000295f098 [tg3]
+ #7 [c00000000681faf0] eeh_report_error at c00000000004e25c
+...
+
+PID: 290    TASK: c000000036e5f800  CPU: 6   COMMAND: "kworker/6:1"
+...
+ #4 [c00000003721fbc0] rtnl_lock at c000000000c940d8
+ #5 [c00000003721fbe0] tg3_reset_task at c008000002969358 [tg3]
+ #6 [c00000003721fc60] process_one_work at c00000000019e5c4
+...
+
+PID: 296    TASK: c000000037a65800  CPU: 21  COMMAND: "kworker/21:1"
+...
+ #4 [c000000037247bc0] rtnl_lock at c000000000c940d8
+ #5 [c000000037247be0] tg3_reset_task at c008000002969358 [tg3]
+ #6 [c000000037247c60] process_one_work at c00000000019e5c4
+...
+
+PID: 655    TASK: c000000036f49000  CPU: 16  COMMAND: "kworker/16:2"
+...:1
+
+ #4 [c0000000373ebbc0] rtnl_lock at c000000000c940d8
+ #5 [c0000000373ebbe0] tg3_reset_task at c008000002969358 [tg3]
+ #6 [c0000000373ebc60] process_one_work at c00000000019e5c4
+...
+
+Code inspection shows that both tg3_io_error_detected() and
+tg3_reset_task() attempt to acquire the RTNL lock at the beginning of
+their code blocks.  If tg3_reset_task() should happen to execute between
+the times when tg3_io_error_deteced() acquires the RTNL lock and
+tg3_reset_task_cancel() is called, a deadlock will occur.
+
+Moving tg3_reset_task_cancel() call earlier within the code block, prior
+to acquiring RTNL, prevents this from happening, but also exposes another
+deadlock issue where tg3_reset_task() may execute AFTER
+tg3_io_error_detected() has executed:
+
+crash> foreach UN bt
+PID: 159    TASK: c0000000067d2000  CPU: 9   COMMAND: "eehd"
+...
+ #4 [c000000006867a60] rtnl_lock at c000000000c940d8
+ #5 [c000000006867a80] tg3_io_slot_reset at c0080000026c2ea8 [tg3]
+ #6 [c000000006867b00] eeh_report_reset at c00000000004de88
+...
+PID: 363    TASK: c000000037564000  CPU: 6   COMMAND: "kworker/6:1"
+...
+ #3 [c000000036c1bb70] msleep at c000000000259e6c
+ #4 [c000000036c1bba0] napi_disable at c000000000c6b848
+ #5 [c000000036c1bbe0] tg3_reset_task at c0080000026d942c [tg3]
+ #6 [c000000036c1bc60] process_one_work at c00000000019e5c4
+...
+
+This issue can be avoided by aborting tg3_reset_task() if EEH error
+recovery is already in progress.
+
+Fixes: db84bf43ef23 ("tg3: tg3_reset_task() needs to use rtnl_lock to synchronize")
+Signed-off-by: David Christensen <drc@linux.vnet.ibm.com>
+Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
+Link: https://lore.kernel.org/r/20230124185339.225806-1-drc@linux.vnet.ibm.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/tg3.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
+index 3279a6e48f3b..e0eacfc46dd4 100644
+--- a/drivers/net/ethernet/broadcom/tg3.c
++++ b/drivers/net/ethernet/broadcom/tg3.c
+@@ -11158,7 +11158,7 @@ static void tg3_reset_task(struct work_struct *work)
+       rtnl_lock();
+       tg3_full_lock(tp, 0);
+-      if (!netif_running(tp->dev)) {
++      if (tp->pcierr_recovery || !netif_running(tp->dev)) {
+               tg3_flag_clear(tp, RESET_TASK_PENDING);
+               tg3_full_unlock(tp);
+               rtnl_unlock();
+@@ -18190,6 +18190,9 @@ static pci_ers_result_t tg3_io_error_detected(struct pci_dev *pdev,
+       netdev_info(netdev, "PCI I/O error detected\n");
++      /* Want to make sure that the reset task doesn't run */
++      tg3_reset_task_cancel(tp);
++
+       rtnl_lock();
+       /* Could be second call or maybe we don't have netdev yet */
+@@ -18206,9 +18209,6 @@ static pci_ers_result_t tg3_io_error_detected(struct pci_dev *pdev,
+       tg3_timer_stop(tp);
+-      /* Want to make sure that the reset task doesn't run */
+-      tg3_reset_task_cancel(tp);
+-
+       netif_device_detach(netdev);
+       /* Clean up software state, even if MMIO is blocked */
+-- 
+2.39.0
+
diff --git a/queue-4.14/netfilter-conntrack-fix-bug-in-for_each_sctp_chunk.patch b/queue-4.14/netfilter-conntrack-fix-bug-in-for_each_sctp_chunk.patch
new file mode 100644 (file)
index 0000000..b8e50c6
--- /dev/null
@@ -0,0 +1,42 @@
+From 56b843f0a75f0c950cc23e642e8789bec27b949c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Jan 2023 02:47:19 +0100
+Subject: netfilter: conntrack: fix bug in for_each_sctp_chunk
+
+From: Sriram Yagnaraman <sriram.yagnaraman@est.tech>
+
+[ Upstream commit 98ee0077452527f971567db01386de3c3d97ce13 ]
+
+skb_header_pointer() will return NULL if offset + sizeof(_sch) exceeds
+skb->len, so this offset < skb->len test is redundant.
+
+if sch->length == 0, this will end up in an infinite loop, add a check
+for sch->length > 0
+
+Fixes: 9fb9cbb1082d ("[NETFILTER]: Add nf_conntrack subsystem.")
+Suggested-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sriram Yagnaraman <sriram.yagnaraman@est.tech>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_conntrack_proto_sctp.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
+index 1278b27c625a..cffd37f56c5c 100644
+--- a/net/netfilter/nf_conntrack_proto_sctp.c
++++ b/net/netfilter/nf_conntrack_proto_sctp.c
+@@ -184,8 +184,8 @@ static void sctp_print_conntrack(struct seq_file *s, struct nf_conn *ct)
+ #define for_each_sctp_chunk(skb, sch, _sch, offset, dataoff, count)   \
+ for ((offset) = (dataoff) + sizeof(struct sctphdr), (count) = 0;      \
+-      (offset) < (skb)->len &&                                        \
+-      ((sch) = skb_header_pointer((skb), (offset), sizeof(_sch), &(_sch)));   \
++      ((sch) = skb_header_pointer((skb), (offset), sizeof(_sch), &(_sch))) && \
++      (sch)->length;  \
+       (offset) += (ntohs((sch)->length) + 3) & ~3, (count)++)
+ /* Some validity checks to make sure the chunks are fine */
+-- 
+2.39.0
+
diff --git a/queue-4.14/netfilter-conntrack-fix-vtag-checks-for-abort-shutdo.patch b/queue-4.14/netfilter-conntrack-fix-vtag-checks-for-abort-shutdo.patch
new file mode 100644 (file)
index 0000000..18cde0a
--- /dev/null
@@ -0,0 +1,71 @@
+From bca2267a86a571907d4c0682d1eb243a460e65e7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Jan 2023 02:47:18 +0100
+Subject: netfilter: conntrack: fix vtag checks for ABORT/SHUTDOWN_COMPLETE
+
+From: Sriram Yagnaraman <sriram.yagnaraman@est.tech>
+
+[ Upstream commit a9993591fa94246b16b444eea55d84c54608282a ]
+
+RFC 9260, Sec 8.5.1 states that for ABORT/SHUTDOWN_COMPLETE, the chunk
+MUST be accepted if the vtag of the packet matches its own tag and the
+T bit is not set OR if it is set to its peer's vtag and the T bit is set
+in chunk flags. Otherwise the packet MUST be silently dropped.
+
+Update vtag verification for ABORT/SHUTDOWN_COMPLETE based on the above
+description.
+
+Fixes: 9fb9cbb1082d ("[NETFILTER]: Add nf_conntrack subsystem.")
+Signed-off-by: Sriram Yagnaraman <sriram.yagnaraman@est.tech>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_conntrack_proto_sctp.c | 25 ++++++++++++++++---------
+ 1 file changed, 16 insertions(+), 9 deletions(-)
+
+diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
+index 6303a88af12b..1278b27c625a 100644
+--- a/net/netfilter/nf_conntrack_proto_sctp.c
++++ b/net/netfilter/nf_conntrack_proto_sctp.c
+@@ -343,22 +343,29 @@ static int sctp_packet(struct nf_conn *ct,
+       for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
+               /* Special cases of Verification tag check (Sec 8.5.1) */
+               if (sch->type == SCTP_CID_INIT) {
+-                      /* Sec 8.5.1 (A) */
++                      /* (A) vtag MUST be zero */
+                       if (sh->vtag != 0)
+                               goto out_unlock;
+               } else if (sch->type == SCTP_CID_ABORT) {
+-                      /* Sec 8.5.1 (B) */
+-                      if (sh->vtag != ct->proto.sctp.vtag[dir] &&
+-                          sh->vtag != ct->proto.sctp.vtag[!dir])
++                      /* (B) vtag MUST match own vtag if T flag is unset OR
++                       * MUST match peer's vtag if T flag is set
++                       */
++                      if ((!(sch->flags & SCTP_CHUNK_FLAG_T) &&
++                           sh->vtag != ct->proto.sctp.vtag[dir]) ||
++                          ((sch->flags & SCTP_CHUNK_FLAG_T) &&
++                           sh->vtag != ct->proto.sctp.vtag[!dir]))
+                               goto out_unlock;
+               } else if (sch->type == SCTP_CID_SHUTDOWN_COMPLETE) {
+-                      /* Sec 8.5.1 (C) */
+-                      if (sh->vtag != ct->proto.sctp.vtag[dir] &&
+-                          sh->vtag != ct->proto.sctp.vtag[!dir] &&
+-                          sch->flags & SCTP_CHUNK_FLAG_T)
++                      /* (C) vtag MUST match own vtag if T flag is unset OR
++                       * MUST match peer's vtag if T flag is set
++                       */
++                      if ((!(sch->flags & SCTP_CHUNK_FLAG_T) &&
++                           sh->vtag != ct->proto.sctp.vtag[dir]) ||
++                          ((sch->flags & SCTP_CHUNK_FLAG_T) &&
++                           sh->vtag != ct->proto.sctp.vtag[!dir]))
+                               goto out_unlock;
+               } else if (sch->type == SCTP_CID_COOKIE_ECHO) {
+-                      /* Sec 8.5.1 (D) */
++                      /* (D) vtag must be same as init_vtag as found in INIT_ACK */
+                       if (sh->vtag != ct->proto.sctp.vtag[dir])
+                               goto out_unlock;
+               } else if (sch->type == SCTP_CID_HEARTBEAT ||
+-- 
+2.39.0
+
diff --git a/queue-4.14/netlink-annotate-data-races-around-dst_portid-and-ds.patch b/queue-4.14/netlink-annotate-data-races-around-dst_portid-and-ds.patch
new file mode 100644 (file)
index 0000000..886c7f8
--- /dev/null
@@ -0,0 +1,87 @@
+From 52d4b18c876c92d6903288be94e3022f77b37d0f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Jan 2023 12:59:54 +0000
+Subject: netlink: annotate data races around dst_portid and dst_group
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 004db64d185a5f23dfb891d7701e23713b2420ee ]
+
+netlink_getname(), netlink_sendmsg() and netlink_getsockbyportid()
+can read nlk->dst_portid and nlk->dst_group while another
+thread is changing them.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netlink/af_netlink.c | 23 ++++++++++++++---------
+ 1 file changed, 14 insertions(+), 9 deletions(-)
+
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index 1b2e99ce54e5..1547d0825668 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -1062,8 +1062,9 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
+       if (addr->sa_family == AF_UNSPEC) {
+               sk->sk_state    = NETLINK_UNCONNECTED;
+-              nlk->dst_portid = 0;
+-              nlk->dst_group  = 0;
++              /* dst_portid and dst_group can be read locklessly */
++              WRITE_ONCE(nlk->dst_portid, 0);
++              WRITE_ONCE(nlk->dst_group, 0);
+               return 0;
+       }
+       if (addr->sa_family != AF_NETLINK)
+@@ -1085,8 +1086,9 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
+       if (err == 0) {
+               sk->sk_state    = NETLINK_CONNECTED;
+-              nlk->dst_portid = nladdr->nl_pid;
+-              nlk->dst_group  = ffs(nladdr->nl_groups);
++              /* dst_portid and dst_group can be read locklessly */
++              WRITE_ONCE(nlk->dst_portid, nladdr->nl_pid);
++              WRITE_ONCE(nlk->dst_group, ffs(nladdr->nl_groups));
+       }
+       return err;
+@@ -1104,8 +1106,9 @@ static int netlink_getname(struct socket *sock, struct sockaddr *addr,
+       *addr_len = sizeof(*nladdr);
+       if (peer) {
+-              nladdr->nl_pid = nlk->dst_portid;
+-              nladdr->nl_groups = netlink_group_mask(nlk->dst_group);
++              /* Paired with WRITE_ONCE() in netlink_connect() */
++              nladdr->nl_pid = READ_ONCE(nlk->dst_portid);
++              nladdr->nl_groups = netlink_group_mask(READ_ONCE(nlk->dst_group));
+       } else {
+               nladdr->nl_pid = nlk->portid;
+               netlink_lock_table();
+@@ -1134,8 +1137,9 @@ static struct sock *netlink_getsockbyportid(struct sock *ssk, u32 portid)
+       /* Don't bother queuing skb if kernel socket has no input function */
+       nlk = nlk_sk(sock);
++      /* dst_portid can be changed in netlink_connect() */
+       if (sock->sk_state == NETLINK_CONNECTED &&
+-          nlk->dst_portid != nlk_sk(ssk)->portid) {
++          READ_ONCE(nlk->dst_portid) != nlk_sk(ssk)->portid) {
+               sock_put(sock);
+               return ERR_PTR(-ECONNREFUSED);
+       }
+@@ -1847,8 +1851,9 @@ static int netlink_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
+                       goto out;
+               netlink_skb_flags |= NETLINK_SKB_DST;
+       } else {
+-              dst_portid = nlk->dst_portid;
+-              dst_group = nlk->dst_group;
++              /* Paired with WRITE_ONCE() in netlink_connect() */
++              dst_portid = READ_ONCE(nlk->dst_portid);
++              dst_group = READ_ONCE(nlk->dst_group);
+       }
+       /* Paired with WRITE_ONCE() in netlink_insert() */
+-- 
+2.39.0
+
diff --git a/queue-4.14/netlink-annotate-data-races-around-sk_state.patch b/queue-4.14/netlink-annotate-data-races-around-sk_state.patch
new file mode 100644 (file)
index 0000000..3ef46a9
--- /dev/null
@@ -0,0 +1,58 @@
+From db7824a2f9fd4444acb678f28b4fd4a42798a474 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Jan 2023 12:59:55 +0000
+Subject: netlink: annotate data races around sk_state
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 9b663b5cbb15b494ef132a3c937641c90646eb73 ]
+
+netlink_getsockbyportid() reads sk_state while a concurrent
+netlink_connect() can change its value.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netlink/af_netlink.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index 1547d0825668..d7b0a7aa29a8 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -1061,7 +1061,8 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
+               return -EINVAL;
+       if (addr->sa_family == AF_UNSPEC) {
+-              sk->sk_state    = NETLINK_UNCONNECTED;
++              /* paired with READ_ONCE() in netlink_getsockbyportid() */
++              WRITE_ONCE(sk->sk_state, NETLINK_UNCONNECTED);
+               /* dst_portid and dst_group can be read locklessly */
+               WRITE_ONCE(nlk->dst_portid, 0);
+               WRITE_ONCE(nlk->dst_group, 0);
+@@ -1085,7 +1086,8 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
+               err = netlink_autobind(sock);
+       if (err == 0) {
+-              sk->sk_state    = NETLINK_CONNECTED;
++              /* paired with READ_ONCE() in netlink_getsockbyportid() */
++              WRITE_ONCE(sk->sk_state, NETLINK_CONNECTED);
+               /* dst_portid and dst_group can be read locklessly */
+               WRITE_ONCE(nlk->dst_portid, nladdr->nl_pid);
+               WRITE_ONCE(nlk->dst_group, ffs(nladdr->nl_groups));
+@@ -1137,8 +1139,8 @@ static struct sock *netlink_getsockbyportid(struct sock *ssk, u32 portid)
+       /* Don't bother queuing skb if kernel socket has no input function */
+       nlk = nlk_sk(sock);
+-      /* dst_portid can be changed in netlink_connect() */
+-      if (sock->sk_state == NETLINK_CONNECTED &&
++      /* dst_portid and sk_state can be changed in netlink_connect() */
++      if (READ_ONCE(sock->sk_state) == NETLINK_CONNECTED &&
+           READ_ONCE(nlk->dst_portid) != nlk_sk(ssk)->portid) {
+               sock_put(sock);
+               return ERR_PTR(-ECONNREFUSED);
+-- 
+2.39.0
+
diff --git a/queue-4.14/netrom-fix-use-after-free-of-a-listening-socket.patch b/queue-4.14/netrom-fix-use-after-free-of-a-listening-socket.patch
new file mode 100644 (file)
index 0000000..1f07b55
--- /dev/null
@@ -0,0 +1,161 @@
+From 96ca801331cf11abc556d0312836ccab7dbff7ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Jan 2023 15:19:27 -0800
+Subject: netrom: Fix use-after-free of a listening socket.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 409db27e3a2eb5e8ef7226ca33be33361b3ed1c9 ]
+
+syzbot reported a use-after-free in do_accept(), precisely nr_accept()
+as sk_prot_alloc() allocated the memory and sock_put() frees it. [0]
+
+The issue could happen if the heartbeat timer is fired and
+nr_heartbeat_expiry() calls nr_destroy_socket(), where a socket
+has SOCK_DESTROY or a listening socket has SOCK_DEAD.
+
+In this case, the first condition cannot be true.  SOCK_DESTROY is
+flagged in nr_release() only when the file descriptor is close()d,
+but accept() is being called for the listening socket, so the second
+condition must be true.
+
+Usually, the AF_NETROM listener neither starts timers nor sets
+SOCK_DEAD.  However, the condition is met if connect() fails before
+listen().  connect() starts the t1 timer and heartbeat timer, and
+t1timer calls nr_disconnect() when timeout happens.  Then, SOCK_DEAD
+is set, and if we call listen(), the heartbeat timer calls
+nr_destroy_socket().
+
+  nr_connect
+    nr_establish_data_link(sk)
+      nr_start_t1timer(sk)
+    nr_start_heartbeat(sk)
+                                    nr_t1timer_expiry
+                                      nr_disconnect(sk, ETIMEDOUT)
+                                        nr_sk(sk)->state = NR_STATE_0
+                                        sk->sk_state = TCP_CLOSE
+                                        sock_set_flag(sk, SOCK_DEAD)
+nr_listen
+  if (sk->sk_state != TCP_LISTEN)
+    sk->sk_state = TCP_LISTEN
+                                    nr_heartbeat_expiry
+                                      switch (nr->state)
+                                      case NR_STATE_0
+                                        if (sk->sk_state == TCP_LISTEN &&
+                                            sock_flag(sk, SOCK_DEAD))
+                                          nr_destroy_socket(sk)
+
+This path seems expected, and nr_destroy_socket() is called to clean
+up resources.  Initially, there was sock_hold() before nr_destroy_socket()
+so that the socket would not be freed, but the commit 517a16b1a88b
+("netrom: Decrease sock refcount when sock timers expire") accidentally
+removed it.
+
+To fix use-after-free, let's add sock_hold().
+
+[0]:
+BUG: KASAN: use-after-free in do_accept+0x483/0x510 net/socket.c:1848
+Read of size 8 at addr ffff88807978d398 by task syz-executor.3/5315
+
+CPU: 0 PID: 5315 Comm: syz-executor.3 Not tainted 6.2.0-rc3-syzkaller-00165-gd9fc1511728c #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022
+Call Trace:
+ <TASK>
+ __dump_stack lib/dump_stack.c:88 [inline]
+ dump_stack_lvl+0xd1/0x138 lib/dump_stack.c:106
+ print_address_description mm/kasan/report.c:306 [inline]
+ print_report+0x15e/0x461 mm/kasan/report.c:417
+ kasan_report+0xbf/0x1f0 mm/kasan/report.c:517
+ do_accept+0x483/0x510 net/socket.c:1848
+ __sys_accept4_file net/socket.c:1897 [inline]
+ __sys_accept4+0x9a/0x120 net/socket.c:1927
+ __do_sys_accept net/socket.c:1944 [inline]
+ __se_sys_accept net/socket.c:1941 [inline]
+ __x64_sys_accept+0x75/0xb0 net/socket.c:1941
+ do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+ do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+RIP: 0033:0x7fa436a8c0c9
+Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 f1 19 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48
+RSP: 002b:00007fa437784168 EFLAGS: 00000246 ORIG_RAX: 000000000000002b
+RAX: ffffffffffffffda RBX: 00007fa436bac050 RCX: 00007fa436a8c0c9
+RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000005
+RBP: 00007fa436ae7ae9 R08: 0000000000000000 R09: 0000000000000000
+R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
+R13: 00007ffebc6700df R14: 00007fa437784300 R15: 0000000000022000
+ </TASK>
+
+Allocated by task 5294:
+ kasan_save_stack+0x22/0x40 mm/kasan/common.c:45
+ kasan_set_track+0x25/0x30 mm/kasan/common.c:52
+ ____kasan_kmalloc mm/kasan/common.c:371 [inline]
+ ____kasan_kmalloc mm/kasan/common.c:330 [inline]
+ __kasan_kmalloc+0xa3/0xb0 mm/kasan/common.c:380
+ kasan_kmalloc include/linux/kasan.h:211 [inline]
+ __do_kmalloc_node mm/slab_common.c:968 [inline]
+ __kmalloc+0x5a/0xd0 mm/slab_common.c:981
+ kmalloc include/linux/slab.h:584 [inline]
+ sk_prot_alloc+0x140/0x290 net/core/sock.c:2038
+ sk_alloc+0x3a/0x7a0 net/core/sock.c:2091
+ nr_create+0xb6/0x5f0 net/netrom/af_netrom.c:433
+ __sock_create+0x359/0x790 net/socket.c:1515
+ sock_create net/socket.c:1566 [inline]
+ __sys_socket_create net/socket.c:1603 [inline]
+ __sys_socket_create net/socket.c:1588 [inline]
+ __sys_socket+0x133/0x250 net/socket.c:1636
+ __do_sys_socket net/socket.c:1649 [inline]
+ __se_sys_socket net/socket.c:1647 [inline]
+ __x64_sys_socket+0x73/0xb0 net/socket.c:1647
+ do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+ do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+Freed by task 14:
+ kasan_save_stack+0x22/0x40 mm/kasan/common.c:45
+ kasan_set_track+0x25/0x30 mm/kasan/common.c:52
+ kasan_save_free_info+0x2b/0x40 mm/kasan/generic.c:518
+ ____kasan_slab_free mm/kasan/common.c:236 [inline]
+ ____kasan_slab_free+0x13b/0x1a0 mm/kasan/common.c:200
+ kasan_slab_free include/linux/kasan.h:177 [inline]
+ __cache_free mm/slab.c:3394 [inline]
+ __do_kmem_cache_free mm/slab.c:3580 [inline]
+ __kmem_cache_free+0xcd/0x3b0 mm/slab.c:3587
+ sk_prot_free net/core/sock.c:2074 [inline]
+ __sk_destruct+0x5df/0x750 net/core/sock.c:2166
+ sk_destruct net/core/sock.c:2181 [inline]
+ __sk_free+0x175/0x460 net/core/sock.c:2192
+ sk_free+0x7c/0xa0 net/core/sock.c:2203
+ sock_put include/net/sock.h:1991 [inline]
+ nr_heartbeat_expiry+0x1d7/0x460 net/netrom/nr_timer.c:148
+ call_timer_fn+0x1da/0x7c0 kernel/time/timer.c:1700
+ expire_timers+0x2c6/0x5c0 kernel/time/timer.c:1751
+ __run_timers kernel/time/timer.c:2022 [inline]
+ __run_timers kernel/time/timer.c:1995 [inline]
+ run_timer_softirq+0x326/0x910 kernel/time/timer.c:2035
+ __do_softirq+0x1fb/0xadc kernel/softirq.c:571
+
+Fixes: 517a16b1a88b ("netrom: Decrease sock refcount when sock timers expire")
+Reported-by: syzbot+5fafd5cfe1fc91f6b352@syzkaller.appspotmail.com
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Link: https://lore.kernel.org/r/20230120231927.51711-1-kuniyu@amazon.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netrom/nr_timer.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/netrom/nr_timer.c b/net/netrom/nr_timer.c
+index d1a0b7056743..1fb9084bb937 100644
+--- a/net/netrom/nr_timer.c
++++ b/net/netrom/nr_timer.c
+@@ -125,6 +125,7 @@ static void nr_heartbeat_expiry(unsigned long param)
+                  is accepted() it isn't 'dead' so doesn't get removed. */
+               if (sock_flag(sk, SOCK_DESTROY) ||
+                   (sk->sk_state == TCP_LISTEN && sock_flag(sk, SOCK_DEAD))) {
++                      sock_hold(sk);
+                       bh_unlock_sock(sk);
+                       nr_destroy_socket(sk);
+                       goto out;
+-- 
+2.39.0
+
diff --git a/queue-4.14/sctp-fail-if-no-bound-addresses-can-be-used-for-a-gi.patch b/queue-4.14/sctp-fail-if-no-bound-addresses-can-be-used-for-a-gi.patch
new file mode 100644 (file)
index 0000000..d78d1d4
--- /dev/null
@@ -0,0 +1,68 @@
+From d45add1b34312c906fcb3f50f7970ced33e8f038 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 Jan 2023 14:59:33 -0300
+Subject: sctp: fail if no bound addresses can be used for a given scope
+
+From: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+
+[ Upstream commit 458e279f861d3f61796894cd158b780765a1569f ]
+
+Currently, if you bind the socket to something like:
+        servaddr.sin6_family = AF_INET6;
+        servaddr.sin6_port = htons(0);
+        servaddr.sin6_scope_id = 0;
+        inet_pton(AF_INET6, "::1", &servaddr.sin6_addr);
+
+And then request a connect to:
+        connaddr.sin6_family = AF_INET6;
+        connaddr.sin6_port = htons(20000);
+        connaddr.sin6_scope_id = if_nametoindex("lo");
+        inet_pton(AF_INET6, "fe88::1", &connaddr.sin6_addr);
+
+What the stack does is:
+ - bind the socket
+ - create a new asoc
+ - to handle the connect
+   - copy the addresses that can be used for the given scope
+   - try to connect
+
+But the copy returns 0 addresses, and the effect is that it ends up
+trying to connect as if the socket wasn't bound, which is not the
+desired behavior. This unexpected behavior also allows KASLR leaks
+through SCTP diag interface.
+
+The fix here then is, if when trying to copy the addresses that can
+be used for the scope used in connect() it returns 0 addresses, bail
+out. This is what TCP does with a similar reproducer.
+
+Reported-by: Pietro Borrello <borrello@diag.uniroma1.it>
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Reviewed-by: Xin Long <lucien.xin@gmail.com>
+Link: https://lore.kernel.org/r/9fcd182f1099f86c6661f3717f63712ddd1c676c.1674496737.git.marcelo.leitner@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/bind_addr.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c
+index f8a283245672..d723942e5e65 100644
+--- a/net/sctp/bind_addr.c
++++ b/net/sctp/bind_addr.c
+@@ -88,6 +88,12 @@ int sctp_bind_addr_copy(struct net *net, struct sctp_bind_addr *dest,
+               }
+       }
++      /* If somehow no addresses were found that can be used with this
++       * scope, it's an error.
++       */
++      if (list_empty(&dest->address_list))
++              error = -ENETUNREACH;
++
+ out:
+       if (error)
+               sctp_bind_addr_clean(dest);
+-- 
+2.39.0
+
index 8e5403d26efaaed7713c3c05cc1ba0656814433d..5b3fef754a8106cf9f04f7b6f779b73ed89e12fd 100644 (file)
@@ -27,3 +27,11 @@ module-don-t-wait-for-going-modules.patch
 tracing-make-sure-trace_printk-can-output-as-soon-as-it-can-be-used.patch
 arm-9280-1-mm-fix-warning-on-phys_addr_t-to-void-pointer-assignment.patch
 edac-device-respect-any-driver-supplied-workqueue-polling-value.patch
+netlink-annotate-data-races-around-dst_portid-and-ds.patch
+netlink-annotate-data-races-around-sk_state.patch
+netfilter-conntrack-fix-vtag-checks-for-abort-shutdo.patch
+netfilter-conntrack-fix-bug-in-for_each_sctp_chunk.patch
+netrom-fix-use-after-free-of-a-listening-socket.patch
+sctp-fail-if-no-bound-addresses-can-be-used-for-a-gi.patch
+net-ravb-fix-possible-hang-if-ris2_qff1-happen.patch
+net-tg3-resolve-deadlock-in-tg3_reset_task-during-ee.patch