]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 27 Sep 2024 08:25:13 +0000 (10:25 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 27 Sep 2024 08:25:13 +0000 (10:25 +0200)
added patches:
mptcp-export-lookup_anno_list_by_saddr.patch
mptcp-pm-fix-uaf-in-__timer_delete_sync.patch
mptcp-validate-id-when-stopping-the-add_addr-retransmit-timer.patch

queue-5.10/mptcp-export-lookup_anno_list_by_saddr.patch [new file with mode: 0644]
queue-5.10/mptcp-pm-fix-uaf-in-__timer_delete_sync.patch [new file with mode: 0644]
queue-5.10/mptcp-validate-id-when-stopping-the-add_addr-retransmit-timer.patch [new file with mode: 0644]
queue-5.10/series

diff --git a/queue-5.10/mptcp-export-lookup_anno_list_by_saddr.patch b/queue-5.10/mptcp-export-lookup_anno_list_by_saddr.patch
new file mode 100644 (file)
index 0000000..b0a301d
--- /dev/null
@@ -0,0 +1,71 @@
+From stable+bounces-76548-greg=kroah.com@vger.kernel.org Tue Sep 17 09:26:33 2024
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+Date: Tue, 17 Sep 2024 09:26:09 +0200
+Subject: mptcp: export lookup_anno_list_by_saddr
+To: mptcp@lists.linux.dev, stable@vger.kernel.org, gregkh@linuxfoundation.org
+Cc: Geliang Tang <geliangtang@gmail.com>, Mat Martineau <mathew.j.martineau@linux.intel.com>, "David S . Miller" <davem@davemloft.net>, Matthieu Baerts <matttbe@kernel.org>
+Message-ID: <20240917072607.799536-6-matttbe@kernel.org>
+
+From: Geliang Tang <geliangtang@gmail.com>
+
+commit d88c476f4a7dd69a2588470f6c4f8b663efa16c6 upstream.
+
+This patch exported the static function lookup_anno_list_by_saddr, and
+renamed it to mptcp_lookup_anno_list_by_saddr.
+
+Signed-off-by: Geliang Tang <geliangtang@gmail.com>
+Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: b4cd80b03389 ("mptcp: pm: Fix uaf in __timer_delete_sync")
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/pm_netlink.c |   10 +++++-----
+ net/mptcp/protocol.h   |    3 +++
+ 2 files changed, 8 insertions(+), 5 deletions(-)
+
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -194,9 +194,9 @@ static void check_work_pending(struct mp
+               WRITE_ONCE(msk->pm.work_pending, false);
+ }
+-static struct mptcp_pm_add_entry *
+-lookup_anno_list_by_saddr(struct mptcp_sock *msk,
+-                        struct mptcp_addr_info *addr)
++struct mptcp_pm_add_entry *
++mptcp_lookup_anno_list_by_saddr(struct mptcp_sock *msk,
++                              struct mptcp_addr_info *addr)
+ {
+       struct mptcp_pm_add_entry *entry;
+@@ -255,7 +255,7 @@ mptcp_pm_del_add_timer(struct mptcp_sock
+       struct sock *sk = (struct sock *)msk;
+       spin_lock_bh(&msk->pm.lock);
+-      entry = lookup_anno_list_by_saddr(msk, addr);
++      entry = mptcp_lookup_anno_list_by_saddr(msk, addr);
+       if (entry)
+               entry->retrans_times = ADD_ADDR_RETRANS_MAX;
+       spin_unlock_bh(&msk->pm.lock);
+@@ -272,7 +272,7 @@ static bool mptcp_pm_alloc_anno_list(str
+       struct mptcp_pm_add_entry *add_entry = NULL;
+       struct sock *sk = (struct sock *)msk;
+-      if (lookup_anno_list_by_saddr(msk, &entry->addr))
++      if (mptcp_lookup_anno_list_by_saddr(msk, &entry->addr))
+               return false;
+       add_entry = kmalloc(sizeof(*add_entry), GFP_ATOMIC);
+--- a/net/mptcp/protocol.h
++++ b/net/mptcp/protocol.h
+@@ -451,6 +451,9 @@ void mptcp_pm_free_anno_list(struct mptc
+ struct mptcp_pm_add_entry *
+ mptcp_pm_del_add_timer(struct mptcp_sock *msk,
+                      struct mptcp_addr_info *addr);
++struct mptcp_pm_add_entry *
++mptcp_lookup_anno_list_by_saddr(struct mptcp_sock *msk,
++                              struct mptcp_addr_info *addr);
+ int mptcp_pm_announce_addr(struct mptcp_sock *msk,
+                          const struct mptcp_addr_info *addr,
diff --git a/queue-5.10/mptcp-pm-fix-uaf-in-__timer_delete_sync.patch b/queue-5.10/mptcp-pm-fix-uaf-in-__timer_delete_sync.patch
new file mode 100644 (file)
index 0000000..d61340a
--- /dev/null
@@ -0,0 +1,93 @@
+From stable+bounces-76550-greg=kroah.com@vger.kernel.org Tue Sep 17 09:26:39 2024
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+Date: Tue, 17 Sep 2024 09:26:11 +0200
+Subject: mptcp: pm: Fix uaf in __timer_delete_sync
+To: mptcp@lists.linux.dev, stable@vger.kernel.org, gregkh@linuxfoundation.org
+Cc: Edward Adam Davis <eadavis@qq.com>, syzbot+f3a31fb909db9b2a5c4d@syzkaller.appspotmail.com, Matthieu Baerts <matttbe@kernel.org>, Paolo Abeni <pabeni@redhat.com>, Jakub Kicinski <kuba@kernel.org>
+Message-ID: <20240917072607.799536-8-matttbe@kernel.org>
+
+From: Edward Adam Davis <eadavis@qq.com>
+
+There are two paths to access mptcp_pm_del_add_timer, result in a race
+condition:
+
+     CPU1                              CPU2
+     ====                               ====
+     net_rx_action
+     napi_poll                          netlink_sendmsg
+     __napi_poll                        netlink_unicast
+     process_backlog                    netlink_unicast_kernel
+     __netif_receive_skb                genl_rcv
+     __netif_receive_skb_one_core       netlink_rcv_skb
+     NF_HOOK                            genl_rcv_msg
+     ip_local_deliver_finish            genl_family_rcv_msg
+     ip_protocol_deliver_rcu            genl_family_rcv_msg_doit
+     tcp_v4_rcv                         mptcp_pm_nl_flush_addrs_doit
+     tcp_v4_do_rcv                      mptcp_nl_remove_addrs_list
+     tcp_rcv_established                mptcp_pm_remove_addrs_and_subflows
+     tcp_data_queue                     remove_anno_list_by_saddr
+     mptcp_incoming_options             mptcp_pm_del_add_timer
+     mptcp_pm_del_add_timer             kfree(entry)
+
+In remove_anno_list_by_saddr(running on CPU2), after leaving the critical
+zone protected by "pm.lock", the entry will be released, which leads to the
+occurrence of uaf in the mptcp_pm_del_add_timer(running on CPU1).
+
+Keeping a reference to add_timer inside the lock, and calling
+sk_stop_timer_sync() with this reference, instead of "entry->add_timer".
+
+Move list_del(&entry->list) to mptcp_pm_del_add_timer and inside the pm lock,
+do not directly access any members of the entry outside the pm lock, which
+can avoid similar "entry->x" uaf.
+
+Fixes: 00cfd77b9063 ("mptcp: retransmit ADD_ADDR when timeout")
+Cc: stable@vger.kernel.org
+Reported-and-tested-by: syzbot+f3a31fb909db9b2a5c4d@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=f3a31fb909db9b2a5c4d
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Edward Adam Davis <eadavis@qq.com>
+Acked-by: Paolo Abeni <pabeni@redhat.com>
+Link: https://patch.msgid.link/tencent_7142963A37944B4A74EF76CD66EA3C253609@qq.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+(cherry picked from commit b4cd80b0338945a94972ac3ed54f8338d2da2076)
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/pm_netlink.c |   13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -253,15 +253,21 @@ mptcp_pm_del_add_timer(struct mptcp_sock
+ {
+       struct mptcp_pm_add_entry *entry;
+       struct sock *sk = (struct sock *)msk;
++      struct timer_list *add_timer = NULL;
+       spin_lock_bh(&msk->pm.lock);
+       entry = mptcp_lookup_anno_list_by_saddr(msk, addr);
+-      if (entry && (!check_id || entry->addr.id == addr->id))
++      if (entry && (!check_id || entry->addr.id == addr->id)) {
+               entry->retrans_times = ADD_ADDR_RETRANS_MAX;
++              add_timer = &entry->add_timer;
++      }
++      if (!check_id && entry)
++              list_del(&entry->list);
+       spin_unlock_bh(&msk->pm.lock);
+-      if (entry && (!check_id || entry->addr.id == addr->id))
+-              sk_stop_timer_sync(sk, &entry->add_timer);
++      /* no lock, because sk_stop_timer_sync() is calling del_timer_sync() */
++      if (add_timer)
++              sk_stop_timer_sync(sk, add_timer);
+       return entry;
+ }
+@@ -766,7 +772,6 @@ static bool remove_anno_list_by_saddr(st
+       entry = mptcp_pm_del_add_timer(msk, addr, false);
+       if (entry) {
+-              list_del(&entry->list);
+               kfree(entry);
+               return true;
+       }
diff --git a/queue-5.10/mptcp-validate-id-when-stopping-the-add_addr-retransmit-timer.patch b/queue-5.10/mptcp-validate-id-when-stopping-the-add_addr-retransmit-timer.patch
new file mode 100644 (file)
index 0000000..fd120d6
--- /dev/null
@@ -0,0 +1,110 @@
+From stable+bounces-76549-greg=kroah.com@vger.kernel.org Tue Sep 17 09:26:36 2024
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+Date: Tue, 17 Sep 2024 09:26:10 +0200
+Subject: mptcp: validate 'id' when stopping the ADD_ADDR retransmit timer
+To: mptcp@lists.linux.dev, stable@vger.kernel.org, gregkh@linuxfoundation.org
+Cc: Davide Caratti <dcaratti@redhat.com>, Mat Martineau <mathew.j.martineau@linux.intel.com>, "David S . Miller" <davem@davemloft.net>, Matthieu Baerts <matttbe@kernel.org>
+Message-ID: <20240917072607.799536-7-matttbe@kernel.org>
+
+From: Davide Caratti <dcaratti@redhat.com>
+
+commit d58300c3185b78ab910092488126b97f0abe3ae2 upstream.
+
+when Linux receives an echo-ed ADD_ADDR, it checks the IP address against
+the list of "announced" addresses. In case of a positive match, the timer
+that handles retransmissions is stopped regardless of the 'Address Id' in
+the received packet: this behaviour does not comply with RFC8684 3.4.1.
+
+Fix it by validating the 'Address Id' in received echo-ed ADD_ADDRs.
+Tested using packetdrill, with the following captured output:
+
+ unpatched kernel:
+
+ Out <...> Flags [.], ack 1, win 256, options [mptcp add-addr v1 id 1 198.51.100.2 hmac 0xfd2e62517888fe29,mptcp dss ack 3007449509], length 0
+ In  <...> Flags [.], ack 1, win 257, options [mptcp add-addr v1-echo id 1 1.2.3.4,mptcp dss ack 3013740213], length 0
+ Out <...> Flags [.], ack 1, win 256, options [mptcp add-addr v1 id 1 198.51.100.2 hmac 0xfd2e62517888fe29,mptcp dss ack 3007449509], length 0
+ In  <...> Flags [.], ack 1, win 257, options [mptcp add-addr v1-echo id 90 198.51.100.2,mptcp dss ack 3013740213], length 0
+        ^^^ retransmission is stopped here, but 'Address Id' is 90
+
+ patched kernel:
+
+ Out <...> Flags [.], ack 1, win 256, options [mptcp add-addr v1 id 1 198.51.100.2 hmac 0x1cf372d59e05f4b8,mptcp dss ack 3007449509], length 0
+ In  <...> Flags [.], ack 1, win 257, options [mptcp add-addr v1-echo id 1 1.2.3.4,mptcp dss ack 1672384568], length 0
+ Out <...> Flags [.], ack 1, win 256, options [mptcp add-addr v1 id 1 198.51.100.2 hmac 0x1cf372d59e05f4b8,mptcp dss ack 3007449509], length 0
+ In  <...> Flags [.], ack 1, win 257, options [mptcp add-addr v1-echo id 90 198.51.100.2,mptcp dss ack 1672384568], length 0
+ Out <...> Flags [.], ack 1, win 256, options [mptcp add-addr v1 id 1 198.51.100.2 hmac 0x1cf372d59e05f4b8,mptcp dss ack 3007449509], length 0
+ In  <...> Flags [.], ack 1, win 257, options [mptcp add-addr v1-echo id 1 198.51.100.2,mptcp dss ack 1672384568], length 0
+        ^^^ retransmission is stopped here, only when both 'Address Id' and 'IP Address' match
+
+Fixes: 00cfd77b9063 ("mptcp: retransmit ADD_ADDR when timeout")
+Signed-off-by: Davide Caratti <dcaratti@redhat.com>
+Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: b4cd80b03389 ("mptcp: pm: Fix uaf in __timer_delete_sync")
+[ Conflicts in options.c, because some features are missing in this
+  version, e.g. commit 557963c383e8 ("mptcp: move to next addr when
+  subflow creation fail") and commit f7dafee18538 ("mptcp: use
+  mptcp_addr_info in mptcp_options_received"). ]
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/options.c    |    2 +-
+ net/mptcp/pm_netlink.c |    8 ++++----
+ net/mptcp/protocol.h   |    2 +-
+ 3 files changed, 6 insertions(+), 6 deletions(-)
+
+--- a/net/mptcp/options.c
++++ b/net/mptcp/options.c
+@@ -915,7 +915,7 @@ void mptcp_incoming_options(struct sock
+                       mptcp_pm_add_addr_received(msk, &addr);
+                       MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_ADDADDR);
+               } else {
+-                      mptcp_pm_del_add_timer(msk, &addr);
++                      mptcp_pm_del_add_timer(msk, &addr, true);
+                       MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_ECHOADD);
+               }
+               mp_opt.add_addr = 0;
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -249,18 +249,18 @@ out:
+ struct mptcp_pm_add_entry *
+ mptcp_pm_del_add_timer(struct mptcp_sock *msk,
+-                     struct mptcp_addr_info *addr)
++                     struct mptcp_addr_info *addr, bool check_id)
+ {
+       struct mptcp_pm_add_entry *entry;
+       struct sock *sk = (struct sock *)msk;
+       spin_lock_bh(&msk->pm.lock);
+       entry = mptcp_lookup_anno_list_by_saddr(msk, addr);
+-      if (entry)
++      if (entry && (!check_id || entry->addr.id == addr->id))
+               entry->retrans_times = ADD_ADDR_RETRANS_MAX;
+       spin_unlock_bh(&msk->pm.lock);
+-      if (entry)
++      if (entry && (!check_id || entry->addr.id == addr->id))
+               sk_stop_timer_sync(sk, &entry->add_timer);
+       return entry;
+@@ -764,7 +764,7 @@ static bool remove_anno_list_by_saddr(st
+ {
+       struct mptcp_pm_add_entry *entry;
+-      entry = mptcp_pm_del_add_timer(msk, addr);
++      entry = mptcp_pm_del_add_timer(msk, addr, false);
+       if (entry) {
+               list_del(&entry->list);
+               kfree(entry);
+--- a/net/mptcp/protocol.h
++++ b/net/mptcp/protocol.h
+@@ -450,7 +450,7 @@ void mptcp_pm_rm_addr_received(struct mp
+ void mptcp_pm_free_anno_list(struct mptcp_sock *msk);
+ struct mptcp_pm_add_entry *
+ mptcp_pm_del_add_timer(struct mptcp_sock *msk,
+-                     struct mptcp_addr_info *addr);
++                     struct mptcp_addr_info *addr, bool check_id);
+ struct mptcp_pm_add_entry *
+ mptcp_lookup_anno_list_by_saddr(struct mptcp_sock *msk,
+                               struct mptcp_addr_info *addr);
index 5f5f24645804d1020004b4c42564306cbed354be..b88075c6406be418ec6a94bbac14c4fc0482c36c 100644 (file)
@@ -45,3 +45,6 @@ cgroup-make-operations-on-the-cgroup-root_list-rcu-s.patch
 netfilter-nft_set_pipapo-walk-over-current-view-on-netlink-dump.patch
 netfilter-nf_tables-missing-iterator-type-in-lookup-walk.patch
 gpio-prevent-potential-speculation-leaks-in-gpio_device_get_desc.patch
+mptcp-export-lookup_anno_list_by_saddr.patch
+mptcp-validate-id-when-stopping-the-add_addr-retransmit-timer.patch
+mptcp-pm-fix-uaf-in-__timer_delete_sync.patch