]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 11 Sep 2025 12:26:49 +0000 (14:26 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 11 Sep 2025 12:26:49 +0000 (14:26 +0200)
added patches:
net-fix-null-ptr-deref-by-sock_lock_init_class_and_name-and-rmmod.patch
series
usb-hub-fix-flushing-of-delayed-work-used-for-post-resume-purposes.patch

queue-5.4/net-fix-null-ptr-deref-by-sock_lock_init_class_and_name-and-rmmod.patch [new file with mode: 0644]
queue-5.4/series [new file with mode: 0644]
queue-5.4/usb-hub-fix-flushing-of-delayed-work-used-for-post-resume-purposes.patch [new file with mode: 0644]

diff --git a/queue-5.4/net-fix-null-ptr-deref-by-sock_lock_init_class_and_name-and-rmmod.patch b/queue-5.4/net-fix-null-ptr-deref-by-sock_lock_init_class_and_name-and-rmmod.patch
new file mode 100644 (file)
index 0000000..613902b
--- /dev/null
@@ -0,0 +1,272 @@
+From 0bb2f7a1ad1f11d861f58e5ee5051c8974ff9569 Mon Sep 17 00:00:00 2001
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+Date: Mon, 7 Apr 2025 09:33:11 -0700
+Subject: net: Fix null-ptr-deref by sock_lock_init_class_and_name() and rmmod.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+commit 0bb2f7a1ad1f11d861f58e5ee5051c8974ff9569 upstream.
+
+When I ran the repro [0] and waited a few seconds, I observed two
+LOCKDEP splats: a warning immediately followed by a null-ptr-deref. [1]
+
+Reproduction Steps:
+
+  1) Mount CIFS
+  2) Add an iptables rule to drop incoming FIN packets for CIFS
+  3) Unmount CIFS
+  4) Unload the CIFS module
+  5) Remove the iptables rule
+
+At step 3), the CIFS module calls sock_release() for the underlying
+TCP socket, and it returns quickly.  However, the socket remains in
+FIN_WAIT_1 because incoming FIN packets are dropped.
+
+At this point, the module's refcnt is 0 while the socket is still
+alive, so the following rmmod command succeeds.
+
+  # ss -tan
+  State      Recv-Q Send-Q Local Address:Port  Peer Address:Port
+  FIN-WAIT-1 0      477        10.0.2.15:51062   10.0.0.137:445
+
+  # lsmod | grep cifs
+  cifs                 1159168  0
+
+This highlights a discrepancy between the lifetime of the CIFS module
+and the underlying TCP socket.  Even after CIFS calls sock_release()
+and it returns, the TCP socket does not die immediately in order to
+close the connection gracefully.
+
+While this is generally fine, it causes an issue with LOCKDEP because
+CIFS assigns a different lock class to the TCP socket's sk->sk_lock
+using sock_lock_init_class_and_name().
+
+Once an incoming packet is processed for the socket or a timer fires,
+sk->sk_lock is acquired.
+
+Then, LOCKDEP checks the lock context in check_wait_context(), where
+hlock_class() is called to retrieve the lock class.  However, since
+the module has already been unloaded, hlock_class() logs a warning
+and returns NULL, triggering the null-ptr-deref.
+
+If LOCKDEP is enabled, we must ensure that a module calling
+sock_lock_init_class_and_name() (CIFS, NFS, etc) cannot be unloaded
+while such a socket is still alive to prevent this issue.
+
+Let's hold the module reference in sock_lock_init_class_and_name()
+and release it when the socket is freed in sk_prot_free().
+
+Note that sock_lock_init() clears sk->sk_owner for svc_create_socket()
+that calls sock_lock_init_class_and_name() for a listening socket,
+which clones a socket by sk_clone_lock() without GFP_ZERO.
+
+[0]:
+CIFS_SERVER="10.0.0.137"
+CIFS_PATH="//${CIFS_SERVER}/Users/Administrator/Desktop/CIFS_TEST"
+DEV="enp0s3"
+CRED="/root/WindowsCredential.txt"
+
+MNT=$(mktemp -d /tmp/XXXXXX)
+mount -t cifs ${CIFS_PATH} ${MNT} -o vers=3.0,credentials=${CRED},cache=none,echo_interval=1
+
+iptables -A INPUT -s ${CIFS_SERVER} -j DROP
+
+for i in $(seq 10);
+do
+    umount ${MNT}
+    rmmod cifs
+    sleep 1
+done
+
+rm -r ${MNT}
+
+iptables -D INPUT -s ${CIFS_SERVER} -j DROP
+
+[1]:
+DEBUG_LOCKS_WARN_ON(1)
+WARNING: CPU: 10 PID: 0 at kernel/locking/lockdep.c:234 hlock_class (kernel/locking/lockdep.c:234 kernel/locking/lockdep.c:223)
+Modules linked in: cifs_arc4 nls_ucs2_utils cifs_md4 [last unloaded: cifs]
+CPU: 10 UID: 0 PID: 0 Comm: swapper/10 Not tainted 6.14.0 #36
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014
+RIP: 0010:hlock_class (kernel/locking/lockdep.c:234 kernel/locking/lockdep.c:223)
+...
+Call Trace:
+ <IRQ>
+ __lock_acquire (kernel/locking/lockdep.c:4853 kernel/locking/lockdep.c:5178)
+ lock_acquire (kernel/locking/lockdep.c:469 kernel/locking/lockdep.c:5853 kernel/locking/lockdep.c:5816)
+ _raw_spin_lock_nested (kernel/locking/spinlock.c:379)
+ tcp_v4_rcv (./include/linux/skbuff.h:1678 ./include/net/tcp.h:2547 net/ipv4/tcp_ipv4.c:2350)
+...
+
+BUG: kernel NULL pointer dereference, address: 00000000000000c4
+ PF: supervisor read access in kernel mode
+ PF: error_code(0x0000) - not-present page
+PGD 0
+Oops: Oops: 0000 [#1] PREEMPT SMP NOPTI
+CPU: 10 UID: 0 PID: 0 Comm: swapper/10 Tainted: G        W          6.14.0 #36
+Tainted: [W]=WARN
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014
+RIP: 0010:__lock_acquire (kernel/locking/lockdep.c:4852 kernel/locking/lockdep.c:5178)
+Code: 15 41 09 c7 41 8b 44 24 20 25 ff 1f 00 00 41 09 c7 8b 84 24 a0 00 00 00 45 89 7c 24 20 41 89 44 24 24 e8 e1 bc ff ff 4c 89 e7 <44> 0f b6 b8 c4 00 00 00 e8 d1 bc ff ff 0f b6 80 c5 00 00 00 88 44
+RSP: 0018:ffa0000000468a10 EFLAGS: 00010046
+RAX: 0000000000000000 RBX: ff1100010091cc38 RCX: 0000000000000027
+RDX: ff1100081f09ca48 RSI: 0000000000000001 RDI: ff1100010091cc88
+RBP: ff1100010091c200 R08: ff1100083fe6e228 R09: 00000000ffffbfff
+R10: ff1100081eca0000 R11: ff1100083fe10dc0 R12: ff1100010091cc88
+R13: 0000000000000001 R14: 0000000000000000 R15: 00000000000424b1
+FS:  0000000000000000(0000) GS:ff1100081f080000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00000000000000c4 CR3: 0000000002c4a003 CR4: 0000000000771ef0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe07f0 DR7: 0000000000000400
+PKRU: 55555554
+Call Trace:
+ <IRQ>
+ lock_acquire (kernel/locking/lockdep.c:469 kernel/locking/lockdep.c:5853 kernel/locking/lockdep.c:5816)
+ _raw_spin_lock_nested (kernel/locking/spinlock.c:379)
+ tcp_v4_rcv (./include/linux/skbuff.h:1678 ./include/net/tcp.h:2547 net/ipv4/tcp_ipv4.c:2350)
+ ip_protocol_deliver_rcu (net/ipv4/ip_input.c:205 (discriminator 1))
+ ip_local_deliver_finish (./include/linux/rcupdate.h:878 net/ipv4/ip_input.c:234)
+ ip_sublist_rcv_finish (net/ipv4/ip_input.c:576)
+ ip_list_rcv_finish (net/ipv4/ip_input.c:628)
+ ip_list_rcv (net/ipv4/ip_input.c:670)
+ __netif_receive_skb_list_core (net/core/dev.c:5939 net/core/dev.c:5986)
+ netif_receive_skb_list_internal (net/core/dev.c:6040 net/core/dev.c:6129)
+ napi_complete_done (./include/linux/list.h:37 ./include/net/gro.h:519 ./include/net/gro.h:514 net/core/dev.c:6496)
+ e1000_clean (drivers/net/ethernet/intel/e1000/e1000_main.c:3815)
+ __napi_poll.constprop.0 (net/core/dev.c:7191)
+ net_rx_action (net/core/dev.c:7262 net/core/dev.c:7382)
+ handle_softirqs (kernel/softirq.c:561)
+ __irq_exit_rcu (kernel/softirq.c:596 kernel/softirq.c:435 kernel/softirq.c:662)
+ irq_exit_rcu (kernel/softirq.c:680)
+ common_interrupt (arch/x86/kernel/irq.c:280 (discriminator 14))
+  </IRQ>
+ <TASK>
+ asm_common_interrupt (./arch/x86/include/asm/idtentry.h:693)
+RIP: 0010:default_idle (./arch/x86/include/asm/irqflags.h:37 ./arch/x86/include/asm/irqflags.h:92 arch/x86/kernel/process.c:744)
+Code: 4c 01 c7 4c 29 c2 e9 72 ff ff ff 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa eb 07 0f 00 2d c3 2b 15 00 fb f4 <fa> c3 cc cc cc cc 66 66 2e 0f 1f 84 00 00 00 00 00 90 90 90 90 90
+RSP: 0018:ffa00000000ffee8 EFLAGS: 00000202
+RAX: 000000000000640b RBX: ff1100010091c200 RCX: 0000000000061aa4
+RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffffffff812f30c5
+RBP: 000000000000000a R08: 0000000000000001 R09: 0000000000000000
+R10: 0000000000000001 R11: 0000000000000002 R12: 0000000000000000
+R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
+ ? do_idle (kernel/sched/idle.c:186 kernel/sched/idle.c:325)
+ default_idle_call (./include/linux/cpuidle.h:143 kernel/sched/idle.c:118)
+ do_idle (kernel/sched/idle.c:186 kernel/sched/idle.c:325)
+ cpu_startup_entry (kernel/sched/idle.c:422 (discriminator 1))
+ start_secondary (arch/x86/kernel/smpboot.c:315)
+ common_startup_64 (arch/x86/kernel/head_64.S:421)
+ </TASK>
+Modules linked in: cifs_arc4 nls_ucs2_utils cifs_md4 [last unloaded: cifs]
+CR2: 00000000000000c4
+
+Fixes: ed07536ed673 ("[PATCH] lockdep: annotate nfs/nfsd in-kernel sockets")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/20250407163313.22682-1-kuniyu@amazon.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ no ns_tracker and sk_user_frags fields ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/sock.h |   40 ++++++++++++++++++++++++++++++++++++++--
+ net/core/sock.c    |    5 +++++
+ 2 files changed, 43 insertions(+), 2 deletions(-)
+
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -321,6 +321,8 @@ struct bpf_sk_storage;
+   *   @sk_clockid: clockid used by time-based scheduling (SO_TXTIME)
+   *   @sk_txtime_deadline_mode: set deadline mode for SO_TXTIME
+   *   @sk_txtime_unused: unused txtime flags
++  *   @sk_owner: reference to the real owner of the socket that calls
++  *              sock_lock_init_class_and_name().
+   */
+ struct sock {
+       /*
+@@ -515,6 +517,10 @@ struct sock {
+       struct bpf_sk_storage __rcu     *sk_bpf_storage;
+ #endif
+       struct rcu_head         sk_rcu;
++
++#if IS_ENABLED(CONFIG_PROVE_LOCKING) && IS_ENABLED(CONFIG_MODULES)
++      struct module           *sk_owner;
++#endif
+ };
+ enum sk_pacing {
+@@ -1525,6 +1531,35 @@ static inline void sock_release_ownershi
+       }
+ }
++#if IS_ENABLED(CONFIG_PROVE_LOCKING) && IS_ENABLED(CONFIG_MODULES)
++static inline void sk_owner_set(struct sock *sk, struct module *owner)
++{
++      __module_get(owner);
++      sk->sk_owner = owner;
++}
++
++static inline void sk_owner_clear(struct sock *sk)
++{
++      sk->sk_owner = NULL;
++}
++
++static inline void sk_owner_put(struct sock *sk)
++{
++      module_put(sk->sk_owner);
++}
++#else
++static inline void sk_owner_set(struct sock *sk, struct module *owner)
++{
++}
++
++static inline void sk_owner_clear(struct sock *sk)
++{
++}
++
++static inline void sk_owner_put(struct sock *sk)
++{
++}
++#endif
+ /*
+  * Macro so as to not evaluate some arguments when
+  * lockdep is not enabled.
+@@ -1534,13 +1569,14 @@ static inline void sock_release_ownershi
+  */
+ #define sock_lock_init_class_and_name(sk, sname, skey, name, key)     \
+ do {                                                                  \
++      sk_owner_set(sk, THIS_MODULE);                                  \
+       sk->sk_lock.owned = 0;                                          \
+       init_waitqueue_head(&sk->sk_lock.wq);                           \
+       spin_lock_init(&(sk)->sk_lock.slock);                           \
+       debug_check_no_locks_freed((void *)&(sk)->sk_lock,              \
+-                      sizeof((sk)->sk_lock));                         \
++                                 sizeof((sk)->sk_lock));              \
+       lockdep_set_class_and_name(&(sk)->sk_lock.slock,                \
+-                              (skey), (sname));                               \
++                                 (skey), (sname));                    \
+       lockdep_init_map(&(sk)->sk_lock.dep_map, (name), (key), 0);     \
+ } while (0)
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -1567,6 +1567,8 @@ lenout:
+  */
+ static inline void sock_lock_init(struct sock *sk)
+ {
++      sk_owner_clear(sk);
++
+       if (sk->sk_kern_sock)
+               sock_lock_init_class_and_name(
+                       sk,
+@@ -1652,6 +1654,9 @@ static void sk_prot_free(struct proto *p
+       cgroup_sk_free(&sk->sk_cgrp_data);
+       mem_cgroup_sk_free(sk);
+       security_sk_free(sk);
++
++      sk_owner_put(sk);
++
+       if (slab != NULL)
+               kmem_cache_free(slab, sk);
+       else
diff --git a/queue-5.4/series b/queue-5.4/series
new file mode 100644 (file)
index 0000000..b17c4b4
--- /dev/null
@@ -0,0 +1,2 @@
+usb-hub-fix-flushing-of-delayed-work-used-for-post-resume-purposes.patch
+net-fix-null-ptr-deref-by-sock_lock_init_class_and_name-and-rmmod.patch
diff --git a/queue-5.4/usb-hub-fix-flushing-of-delayed-work-used-for-post-resume-purposes.patch b/queue-5.4/usb-hub-fix-flushing-of-delayed-work-used-for-post-resume-purposes.patch
new file mode 100644 (file)
index 0000000..6ed6c34
--- /dev/null
@@ -0,0 +1,119 @@
+From 9bd9c8026341f75f25c53104eb7e656e357ca1a2 Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Fri, 27 Jun 2025 19:43:48 +0300
+Subject: usb: hub: Fix flushing of delayed work used for post resume purposes
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit 9bd9c8026341f75f25c53104eb7e656e357ca1a2 upstream.
+
+Delayed work that prevents USB3 hubs from runtime-suspending too early
+needed to be flushed in hub_quiesce() to resolve issues detected on
+QC SC8280XP CRD board during suspend resume testing.
+
+This flushing did however trigger new issues on Raspberry Pi 3B+, which
+doesn't have USB3 ports, and doesn't queue any post resume delayed work.
+
+The flushed 'hub->init_work' item is used for several purposes, and
+is originally initialized with a 'NULL' work function. The work function
+is also changed on the fly, which may contribute to the issue.
+
+Solve this by creating a dedicated delayed work item for post resume work,
+and flush that delayed work in hub_quiesce()
+
+Cc: stable <stable@kernel.org>
+Fixes: a49e1e2e785f ("usb: hub: Fix flushing and scheduling of delayed work that tunes runtime pm")
+Reported-by: Mark Brown <broonie@kernel.org>
+Closes: https://lore.kernel.org/linux-usb/aF5rNp1l0LWITnEB@finisterre.sirena.org.uk
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Tested-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com> # SC8280XP CRD
+Tested-by: Mark Brown <broonie@kernel.org>
+Link: https://lore.kernel.org/r/20250627164348.3982628-2-mathias.nyman@linux.intel.com
+[florian: adjust for lack of hub_{get,put} and timer_delete_sync]
+Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/core/hub.c |   21 ++++++++-------------
+ drivers/usb/core/hub.h |    1 +
+ 2 files changed, 9 insertions(+), 13 deletions(-)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -1030,12 +1030,11 @@ int usb_remove_device(struct usb_device
+ enum hub_activation_type {
+       HUB_INIT, HUB_INIT2, HUB_INIT3,         /* INITs must come first */
+-      HUB_POST_RESET, HUB_RESUME, HUB_RESET_RESUME, HUB_POST_RESUME,
++      HUB_POST_RESET, HUB_RESUME, HUB_RESET_RESUME,
+ };
+ static void hub_init_func2(struct work_struct *ws);
+ static void hub_init_func3(struct work_struct *ws);
+-static void hub_post_resume(struct work_struct *ws);
+ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
+ {
+@@ -1059,12 +1058,6 @@ static void hub_activate(struct usb_hub
+               goto init3;
+       }
+-      if (type == HUB_POST_RESUME) {
+-              usb_autopm_put_interface_async(to_usb_interface(hub->intfdev));
+-              kref_put(&hub->kref, hub_release);
+-              return;
+-      }
+-
+       kref_get(&hub->kref);
+       /* The superspeed hub except for root hub has to use Hub Depth
+@@ -1318,8 +1311,8 @@ static void hub_activate(struct usb_hub
+               usb_autopm_get_interface_no_resume(
+                       to_usb_interface(hub->intfdev));
+-              INIT_DELAYED_WORK(&hub->init_work, hub_post_resume);
+-              queue_delayed_work(system_power_efficient_wq, &hub->init_work,
++              queue_delayed_work(system_power_efficient_wq,
++                                 &hub->post_resume_work,
+                                  msecs_to_jiffies(USB_SS_PORT_U0_WAKE_TIME));
+               return;
+       }
+@@ -1344,9 +1337,10 @@ static void hub_init_func3(struct work_s
+ static void hub_post_resume(struct work_struct *ws)
+ {
+-      struct usb_hub *hub = container_of(ws, struct usb_hub, init_work.work);
++      struct usb_hub *hub = container_of(ws, struct usb_hub, post_resume_work.work);
+-      hub_activate(hub, HUB_POST_RESUME);
++      usb_autopm_put_interface_async(to_usb_interface(hub->intfdev));
++      kref_put(&hub->kref, hub_release);
+ }
+ enum hub_quiescing_type {
+@@ -1374,7 +1368,7 @@ static void hub_quiesce(struct usb_hub *
+       /* Stop hub_wq and related activity */
+       del_timer_sync(&hub->irq_urb_retry);
+-      flush_delayed_work(&hub->init_work);
++      flush_delayed_work(&hub->post_resume_work);
+       usb_kill_urb(hub->urb);
+       if (hub->has_indicators)
+               cancel_delayed_work_sync(&hub->leds);
+@@ -1921,6 +1915,7 @@ static int hub_probe(struct usb_interfac
+       hub->hdev = hdev;
+       INIT_DELAYED_WORK(&hub->leds, led_work);
+       INIT_DELAYED_WORK(&hub->init_work, NULL);
++      INIT_DELAYED_WORK(&hub->post_resume_work, hub_post_resume);
+       INIT_WORK(&hub->events, hub_event);
+       spin_lock_init(&hub->irq_urb_lock);
+       timer_setup(&hub->irq_urb_retry, hub_retry_irq_urb, 0);
+--- a/drivers/usb/core/hub.h
++++ b/drivers/usb/core/hub.h
+@@ -69,6 +69,7 @@ struct usb_hub {
+       u8                      indicator[USB_MAXCHILDREN];
+       struct delayed_work     leds;
+       struct delayed_work     init_work;
++      struct delayed_work     post_resume_work;
+       struct work_struct      events;
+       spinlock_t              irq_urb_lock;
+       struct timer_list       irq_urb_retry;