]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 16 Jan 2023 15:21:40 +0000 (16:21 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 16 Jan 2023 15:21:40 +0000 (16:21 +0100)
added patches:
ocfs2-fix-freeing-uninitialized-resource-on-ocfs2_dlm_shutdown.patch
pseries-eeh-fix-the-kdump-kernel-crash-during-eeh_pseries_init.patch
tipc-call-tipc_lxc_xmit-without-holding-node_read_lock.patch

queue-5.4/ocfs2-fix-freeing-uninitialized-resource-on-ocfs2_dlm_shutdown.patch [new file with mode: 0644]
queue-5.4/pseries-eeh-fix-the-kdump-kernel-crash-during-eeh_pseries_init.patch [new file with mode: 0644]
queue-5.4/series
queue-5.4/tipc-call-tipc_lxc_xmit-without-holding-node_read_lock.patch [new file with mode: 0644]

diff --git a/queue-5.4/ocfs2-fix-freeing-uninitialized-resource-on-ocfs2_dlm_shutdown.patch b/queue-5.4/ocfs2-fix-freeing-uninitialized-resource-on-ocfs2_dlm_shutdown.patch
new file mode 100644 (file)
index 0000000..e71dafe
--- /dev/null
@@ -0,0 +1,69 @@
+From 550842cc60987b269e31b222283ade3e1b6c7fc8 Mon Sep 17 00:00:00 2001
+From: Heming Zhao <ocfs2-devel@oss.oracle.com>
+Date: Mon, 15 Aug 2022 16:57:54 +0800
+Subject: ocfs2: fix freeing uninitialized resource on ocfs2_dlm_shutdown
+
+From: Heming Zhao <ocfs2-devel@oss.oracle.com>
+
+commit 550842cc60987b269e31b222283ade3e1b6c7fc8 upstream.
+
+After commit 0737e01de9c4 ("ocfs2: ocfs2_mount_volume does cleanup job
+before return error"), any procedure after ocfs2_dlm_init() fails will
+trigger crash when calling ocfs2_dlm_shutdown().
+
+ie: On local mount mode, no dlm resource is initialized.  If
+ocfs2_mount_volume() fails in ocfs2_find_slot(), error handling will call
+ocfs2_dlm_shutdown(), then does dlm resource cleanup job, which will
+trigger kernel crash.
+
+This solution should bypass uninitialized resources in
+ocfs2_dlm_shutdown().
+
+Link: https://lkml.kernel.org/r/20220815085754.20417-1-heming.zhao@suse.com
+Fixes: 0737e01de9c4 ("ocfs2: ocfs2_mount_volume does cleanup job before return error")
+Signed-off-by: Heming Zhao <heming.zhao@suse.com>
+Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Gang He <ghe@suse.com>
+Cc: Jun Piao <piaojun@huawei.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ocfs2/dlmglue.c |    8 +++++---
+ fs/ocfs2/super.c   |    3 +--
+ 2 files changed, 6 insertions(+), 5 deletions(-)
+
+--- a/fs/ocfs2/dlmglue.c
++++ b/fs/ocfs2/dlmglue.c
+@@ -3396,10 +3396,12 @@ void ocfs2_dlm_shutdown(struct ocfs2_sup
+       ocfs2_lock_res_free(&osb->osb_nfs_sync_lockres);
+       ocfs2_lock_res_free(&osb->osb_orphan_scan.os_lockres);
+-      ocfs2_cluster_disconnect(osb->cconn, hangup_pending);
+-      osb->cconn = NULL;
++      if (osb->cconn) {
++              ocfs2_cluster_disconnect(osb->cconn, hangup_pending);
++              osb->cconn = NULL;
+-      ocfs2_dlm_shutdown_debug(osb);
++              ocfs2_dlm_shutdown_debug(osb);
++      }
+ }
+ static int ocfs2_drop_lock(struct ocfs2_super *osb,
+--- a/fs/ocfs2/super.c
++++ b/fs/ocfs2/super.c
+@@ -1922,8 +1922,7 @@ static void ocfs2_dismount_volume(struct
+           !ocfs2_is_hard_readonly(osb))
+               hangup_needed = 1;
+-      if (osb->cconn)
+-              ocfs2_dlm_shutdown(osb, hangup_needed);
++      ocfs2_dlm_shutdown(osb, hangup_needed);
+       ocfs2_blockcheck_stats_debugfs_remove(&osb->osb_ecc_stats);
+       debugfs_remove_recursive(osb->osb_debug_root);
diff --git a/queue-5.4/pseries-eeh-fix-the-kdump-kernel-crash-during-eeh_pseries_init.patch b/queue-5.4/pseries-eeh-fix-the-kdump-kernel-crash-during-eeh_pseries_init.patch
new file mode 100644 (file)
index 0000000..1eeb5b9
--- /dev/null
@@ -0,0 +1,73 @@
+From eb8257a12192f43ffd41bd90932c39dade958042 Mon Sep 17 00:00:00 2001
+From: Mahesh Salgaonkar <mahesh@linux.ibm.com>
+Date: Mon, 20 Sep 2021 22:03:26 +0530
+Subject: pseries/eeh: Fix the kdump kernel crash during eeh_pseries_init
+
+From: Mahesh Salgaonkar <mahesh@linux.ibm.com>
+
+commit eb8257a12192f43ffd41bd90932c39dade958042 upstream.
+
+On pseries LPAR when an empty slot is assigned to partition OR in single
+LPAR mode, kdump kernel crashes during issuing PHB reset.
+
+In the kdump scenario, we traverse all PHBs and issue reset using the
+pe_config_addr of the first child device present under each PHB. However
+the code assumes that none of the PHB slots can be empty and uses
+list_first_entry() to get the first child device under the PHB. Since
+list_first_entry() expects the list to be non-empty, it returns an
+invalid pci_dn entry and ends up accessing NULL phb pointer under
+pci_dn->phb causing kdump kernel crash.
+
+This patch fixes the below kdump kernel crash by skipping empty slots:
+
+  audit: initializing netlink subsys (disabled)
+  thermal_sys: Registered thermal governor 'fair_share'
+  thermal_sys: Registered thermal governor 'step_wise'
+  cpuidle: using governor menu
+  pstore: Registered nvram as persistent store backend
+  Issue PHB reset ...
+  audit: type=2000 audit(1631267818.000:1): state=initialized audit_enabled=0 res=1
+  BUG: Kernel NULL pointer dereference on read at 0x00000268
+  Faulting instruction address: 0xc000000008101fb0
+  Oops: Kernel access of bad area, sig: 7 [#1]
+  LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=2048 NUMA pSeries
+  Modules linked in:
+  CPU: 7 PID: 1 Comm: swapper/7 Not tainted 5.14.0 #1
+  NIP:  c000000008101fb0 LR: c000000009284ccc CTR: c000000008029d70
+  REGS: c00000001161b840 TRAP: 0300   Not tainted  (5.14.0)
+  MSR:  8000000002009033 <SF,VEC,EE,ME,IR,DR,RI,LE>  CR: 28000224  XER: 20040002
+  CFAR: c000000008101f0c DAR: 0000000000000268 DSISR: 00080000 IRQMASK: 0
+  ...
+  NIP pseries_eeh_get_pe_config_addr+0x100/0x1b0
+  LR  __machine_initcall_pseries_eeh_pseries_init+0x2cc/0x350
+  Call Trace:
+    0xc00000001161bb80 (unreliable)
+    __machine_initcall_pseries_eeh_pseries_init+0x2cc/0x350
+    do_one_initcall+0x60/0x2d0
+    kernel_init_freeable+0x350/0x3f8
+    kernel_init+0x3c/0x17c
+    ret_from_kernel_thread+0x5c/0x64
+
+Fixes: 5a090f7c363fd ("powerpc/pseries: PCIE PHB reset")
+Signed-off-by: Mahesh Salgaonkar <mahesh@linux.ibm.com>
+[mpe: Tweak wording and trim oops]
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/163215558252.413351.8600189949820258982.stgit@jupiter
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/powerpc/platforms/pseries/eeh_pseries.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/arch/powerpc/platforms/pseries/eeh_pseries.c
++++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
+@@ -879,6 +879,10 @@ static int __init eeh_pseries_init(void)
+       if (is_kdump_kernel() || reset_devices) {
+               pr_info("Issue PHB reset ...\n");
+               list_for_each_entry(phb, &hose_list, list_node) {
++                      // Skip if the slot is empty
++                      if (list_empty(&PCI_DN(phb->dn)->child_list))
++                              continue;
++
+                       pdn = list_first_entry(&PCI_DN(phb->dn)->child_list, struct pci_dn, list);
+                       addr = (pdn->busno << 16) | (pdn->devfn << 8);
+                       config_addr = pseries_eeh_get_config_addr(phb, addr);
index 7f445decc5f8d44e8d63ec4b9b1fd564148245ac..d076b46154aa83d95593053479c6c373ec58ea35 100644 (file)
@@ -654,3 +654,6 @@ revert-usb-ulpi-defer-ulpi_register-on-ulpi_read_id-timeout.patch
 tipc-fix-use-after-free-in-tipc_disc_rcv.patch
 tty-serial-tegra-handle-rx-transfer-in-pio-mode-if-dma-wasn-t-started.patch
 tipc-add-a-missing-case-of-tipc_direct_msg-type.patch
+pseries-eeh-fix-the-kdump-kernel-crash-during-eeh_pseries_init.patch
+ocfs2-fix-freeing-uninitialized-resource-on-ocfs2_dlm_shutdown.patch
+tipc-call-tipc_lxc_xmit-without-holding-node_read_lock.patch
diff --git a/queue-5.4/tipc-call-tipc_lxc_xmit-without-holding-node_read_lock.patch b/queue-5.4/tipc-call-tipc_lxc_xmit-without-holding-node_read_lock.patch
new file mode 100644 (file)
index 0000000..4133ba0
--- /dev/null
@@ -0,0 +1,140 @@
+From 88956177db179e4eba7cd590971961857d1565b8 Mon Sep 17 00:00:00 2001
+From: Xin Long <lucien.xin@gmail.com>
+Date: Sat, 3 Dec 2022 18:37:21 -0500
+Subject: tipc: call tipc_lxc_xmit without holding node_read_lock
+
+From: Xin Long <lucien.xin@gmail.com>
+
+commit 88956177db179e4eba7cd590971961857d1565b8 upstream.
+
+When sending packets between nodes in netns, it calls tipc_lxc_xmit() for
+peer node to receive the packets where tipc_sk_mcast_rcv()/tipc_sk_rcv()
+might be called, and it's pretty much like in tipc_rcv().
+
+Currently the local 'node rw lock' is held during calling tipc_lxc_xmit()
+to protect the peer_net not being freed by another thread. However, when
+receiving these packets, tipc_node_add_conn() might be called where the
+peer 'node rw lock' is acquired. Then a dead lock warning is triggered by
+lockdep detector, although it is not a real dead lock:
+
+    WARNING: possible recursive locking detected
+    --------------------------------------------
+    conn_server/1086 is trying to acquire lock:
+    ffff8880065cb020 (&n->lock#2){++--}-{2:2}, \
+                     at: tipc_node_add_conn.cold.76+0xaa/0x211 [tipc]
+
+    but task is already holding lock:
+    ffff8880065cd020 (&n->lock#2){++--}-{2:2}, \
+                     at: tipc_node_xmit+0x285/0xb30 [tipc]
+
+    other info that might help us debug this:
+     Possible unsafe locking scenario:
+
+           CPU0
+           ----
+      lock(&n->lock#2);
+      lock(&n->lock#2);
+
+     *** DEADLOCK ***
+
+     May be due to missing lock nesting notation
+
+    4 locks held by conn_server/1086:
+     #0: ffff8880036d1e40 (sk_lock-AF_TIPC){+.+.}-{0:0}, \
+                          at: tipc_accept+0x9c0/0x10b0 [tipc]
+     #1: ffff8880036d5f80 (sk_lock-AF_TIPC/1){+.+.}-{0:0}, \
+                          at: tipc_accept+0x363/0x10b0 [tipc]
+     #2: ffff8880065cd020 (&n->lock#2){++--}-{2:2}, \
+                          at: tipc_node_xmit+0x285/0xb30 [tipc]
+     #3: ffff888012e13370 (slock-AF_TIPC){+...}-{2:2}, \
+                          at: tipc_sk_rcv+0x2da/0x1b40 [tipc]
+
+    Call Trace:
+     <TASK>
+     dump_stack_lvl+0x44/0x5b
+     __lock_acquire.cold.77+0x1f2/0x3d7
+     lock_acquire+0x1d2/0x610
+     _raw_write_lock_bh+0x38/0x80
+     tipc_node_add_conn.cold.76+0xaa/0x211 [tipc]
+     tipc_sk_finish_conn+0x21e/0x640 [tipc]
+     tipc_sk_filter_rcv+0x147b/0x3030 [tipc]
+     tipc_sk_rcv+0xbb4/0x1b40 [tipc]
+     tipc_lxc_xmit+0x225/0x26b [tipc]
+     tipc_node_xmit.cold.82+0x4a/0x102 [tipc]
+     __tipc_sendstream+0x879/0xff0 [tipc]
+     tipc_accept+0x966/0x10b0 [tipc]
+     do_accept+0x37d/0x590
+
+This patch avoids this warning by not holding the 'node rw lock' before
+calling tipc_lxc_xmit(). As to protect the 'peer_net', rcu_read_lock()
+should be enough, as in cleanup_net() when freeing the netns, it calls
+synchronize_rcu() before the free is continued.
+
+Also since tipc_lxc_xmit() is like the RX path in tipc_rcv(), it makes
+sense to call it under rcu_read_lock(). Note that the right lock order
+must be:
+
+   rcu_read_lock();
+   tipc_node_read_lock(n);
+   tipc_node_read_unlock(n);
+   tipc_lxc_xmit();
+   rcu_read_unlock();
+
+instead of:
+
+   tipc_node_read_lock(n);
+   rcu_read_lock();
+   tipc_node_read_unlock(n);
+   tipc_lxc_xmit();
+   rcu_read_unlock();
+
+and we have to call tipc_node_read_lock/unlock() twice in
+tipc_node_xmit().
+
+Fixes: f73b12812a3d ("tipc: improve throughput between nodes in netns")
+Reported-by: Shuang Li <shuali@redhat.com>
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Link: https://lore.kernel.org/r/5bdd1f8fee9db695cfff4528a48c9b9d0523fb00.1670110641.git.lucien.xin@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/tipc/node.c |   12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+--- a/net/tipc/node.c
++++ b/net/tipc/node.c
+@@ -1546,6 +1546,7 @@ int tipc_node_xmit(struct net *net, stru
+       struct tipc_node *n;
+       struct sk_buff_head xmitq;
+       bool node_up = false;
++      struct net *peer_net;
+       int bearer_id;
+       int rc;
+@@ -1562,18 +1563,23 @@ int tipc_node_xmit(struct net *net, stru
+               return -EHOSTUNREACH;
+       }
++      rcu_read_lock();
+       tipc_node_read_lock(n);
+       node_up = node_is_up(n);
+-      if (node_up && n->peer_net && check_net(n->peer_net)) {
++      peer_net = n->peer_net;
++      tipc_node_read_unlock(n);
++      if (node_up && peer_net && check_net(peer_net)) {
+               /* xmit inner linux container */
+-              tipc_lxc_xmit(n->peer_net, list);
++              tipc_lxc_xmit(peer_net, list);
+               if (likely(skb_queue_empty(list))) {
+-                      tipc_node_read_unlock(n);
++                      rcu_read_unlock();
+                       tipc_node_put(n);
+                       return 0;
+               }
+       }
++      rcu_read_unlock();
++      tipc_node_read_lock(n);
+       bearer_id = n->active_links[selector & 1];
+       if (unlikely(bearer_id == INVALID_BEARER_ID)) {
+               tipc_node_read_unlock(n);