]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 26 May 2024 13:53:26 +0000 (15:53 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 26 May 2024 13:53:26 +0000 (15:53 +0200)
added patches:
alsa-core-fix-null-module-pointer-assignment-at-card-init.patch
alsa-timer-set-lower-bound-of-start-tick-time.patch
nilfs2-fix-potential-hang-in-nilfs_detach_log_writer.patch
nilfs2-fix-unexpected-freezing-of-nilfs_segctor_sync.patch

queue-5.10/alsa-core-fix-null-module-pointer-assignment-at-card-init.patch [new file with mode: 0644]
queue-5.10/alsa-timer-set-lower-bound-of-start-tick-time.patch [new file with mode: 0644]
queue-5.10/nilfs2-fix-potential-hang-in-nilfs_detach_log_writer.patch [new file with mode: 0644]
queue-5.10/nilfs2-fix-unexpected-freezing-of-nilfs_segctor_sync.patch [new file with mode: 0644]
queue-5.10/series

diff --git a/queue-5.10/alsa-core-fix-null-module-pointer-assignment-at-card-init.patch b/queue-5.10/alsa-core-fix-null-module-pointer-assignment-at-card-init.patch
new file mode 100644 (file)
index 0000000..01bbfd9
--- /dev/null
@@ -0,0 +1,56 @@
+From 39381fe7394e5eafac76e7e9367e7351138a29c1 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Wed, 22 May 2024 09:04:39 +0200
+Subject: ALSA: core: Fix NULL module pointer assignment at card init
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 39381fe7394e5eafac76e7e9367e7351138a29c1 upstream.
+
+The commit 81033c6b584b ("ALSA: core: Warn on empty module")
+introduced a WARN_ON() for a NULL module pointer passed at snd_card
+object creation, and it also wraps the code around it with '#ifdef
+MODULE'.  This works in most cases, but the devils are always in
+details.  "MODULE" is defined when the target code (i.e. the sound
+core) is built as a module; but this doesn't mean that the caller is
+also built-in or not.  Namely, when only the sound core is built-in
+(CONFIG_SND=y) while the driver is a module (CONFIG_SND_USB_AUDIO=m),
+the passed module pointer is ignored even if it's non-NULL, and
+card->module remains as NULL.  This would result in the missing module
+reference up/down at the device open/close, leading to a race with the
+code execution after the module removal.
+
+For addressing the bug, move the assignment of card->module again out
+of ifdef.  The WARN_ON() is still wrapped with ifdef because the
+module can be really NULL when all sound drivers are built-in.
+
+Note that we keep 'ifdef MODULE' for WARN_ON(), otherwise it would
+lead to a false-positive NULL module check.  Admittedly it won't catch
+perfectly, i.e. no check is performed when CONFIG_SND=y.  But, it's no
+real problem as it's only for debugging, and the condition is pretty
+rare.
+
+Fixes: 81033c6b584b ("ALSA: core: Warn on empty module")
+Reported-by: Xu Yang <xu.yang_2@nxp.com>
+Closes: https://lore.kernel.org/r/20240520170349.2417900-1-xu.yang_2@nxp.com
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Tested-by: Xu Yang <xu.yang_2@nxp.com>
+Link: https://lore.kernel.org/r/20240522070442.17786-1-tiwai@suse.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/core/init.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/sound/core/init.c
++++ b/sound/core/init.c
+@@ -206,8 +206,8 @@ int snd_card_new(struct device *parent,
+       card->number = idx;
+ #ifdef MODULE
+       WARN_ON(!module);
+-      card->module = module;
+ #endif
++      card->module = module;
+       INIT_LIST_HEAD(&card->devices);
+       init_rwsem(&card->controls_rwsem);
+       rwlock_init(&card->ctl_files_rwlock);
diff --git a/queue-5.10/alsa-timer-set-lower-bound-of-start-tick-time.patch b/queue-5.10/alsa-timer-set-lower-bound-of-start-tick-time.patch
new file mode 100644 (file)
index 0000000..b3dd8f1
--- /dev/null
@@ -0,0 +1,47 @@
+From 4a63bd179fa8d3fcc44a0d9d71d941ddd62f0c4e Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Tue, 14 May 2024 20:27:36 +0200
+Subject: ALSA: timer: Set lower bound of start tick time
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 4a63bd179fa8d3fcc44a0d9d71d941ddd62f0c4e upstream.
+
+Currently ALSA timer doesn't have the lower limit of the start tick
+time, and it allows a very small size, e.g. 1 tick with 1ns resolution
+for hrtimer.  Such a situation may lead to an unexpected RCU stall,
+where  the callback repeatedly queuing the expire update, as reported
+by fuzzer.
+
+This patch introduces a sanity check of the timer start tick time, so
+that the system returns an error when a too small start size is set.
+As of this patch, the lower limit is hard-coded to 100us, which is
+small enough but can still work somehow.
+
+Reported-by: syzbot+43120c2af6ca2938cc38@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/r/000000000000fa00a1061740ab6d@google.com
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20240514182745.4015-1-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/core/timer.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/sound/core/timer.c
++++ b/sound/core/timer.c
+@@ -553,6 +553,14 @@ static int snd_timer_start1(struct snd_t
+               goto unlock;
+       }
++      /* check the actual time for the start tick;
++       * bail out as error if it's way too low (< 100us)
++       */
++      if (start) {
++              if ((u64)snd_timer_hw_resolution(timer) * ticks < 100000)
++                      return -EINVAL;
++      }
++
+       if (start)
+               timeri->ticks = timeri->cticks = ticks;
+       else if (!timeri->cticks)
diff --git a/queue-5.10/nilfs2-fix-potential-hang-in-nilfs_detach_log_writer.patch b/queue-5.10/nilfs2-fix-potential-hang-in-nilfs_detach_log_writer.patch
new file mode 100644 (file)
index 0000000..8b552a0
--- /dev/null
@@ -0,0 +1,110 @@
+From eb85dace897c5986bc2f36b3c783c6abb8a4292e Mon Sep 17 00:00:00 2001
+From: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Date: Mon, 20 May 2024 22:26:21 +0900
+Subject: nilfs2: fix potential hang in nilfs_detach_log_writer()
+
+From: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+
+commit eb85dace897c5986bc2f36b3c783c6abb8a4292e upstream.
+
+Syzbot has reported a potential hang in nilfs_detach_log_writer() called
+during nilfs2 unmount.
+
+Analysis revealed that this is because nilfs_segctor_sync(), which
+synchronizes with the log writer thread, can be called after
+nilfs_segctor_destroy() terminates that thread, as shown in the call trace
+below:
+
+nilfs_detach_log_writer
+  nilfs_segctor_destroy
+    nilfs_segctor_kill_thread  --> Shut down log writer thread
+    flush_work
+      nilfs_iput_work_func
+        nilfs_dispose_list
+          iput
+            nilfs_evict_inode
+              nilfs_transaction_commit
+                nilfs_construct_segment (if inode needs sync)
+                  nilfs_segctor_sync  --> Attempt to synchronize with
+                                          log writer thread
+                           *** DEADLOCK ***
+
+Fix this issue by changing nilfs_segctor_sync() so that the log writer
+thread returns normally without synchronizing after it terminates, and by
+forcing tasks that are already waiting to complete once after the thread
+terminates.
+
+The skipped inode metadata flushout will then be processed together in the
+subsequent cleanup work in nilfs_segctor_destroy().
+
+Link: https://lkml.kernel.org/r/20240520132621.4054-4-konishi.ryusuke@gmail.com
+Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Reported-by: syzbot+e3973c409251e136fdd0@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=e3973c409251e136fdd0
+Tested-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Cc: <stable@vger.kernel.org>
+Cc: "Bai, Shuangpeng" <sjb7183@psu.edu>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nilfs2/segment.c |   21 ++++++++++++++++++---
+ 1 file changed, 18 insertions(+), 3 deletions(-)
+
+--- a/fs/nilfs2/segment.c
++++ b/fs/nilfs2/segment.c
+@@ -2234,6 +2234,14 @@ static int nilfs_segctor_sync(struct nil
+       for (;;) {
+               set_current_state(TASK_INTERRUPTIBLE);
++              /*
++               * Synchronize only while the log writer thread is alive.
++               * Leave flushing out after the log writer thread exits to
++               * the cleanup work in nilfs_segctor_destroy().
++               */
++              if (!sci->sc_task)
++                      break;
++
+               if (atomic_read(&wait_req.done)) {
+                       err = wait_req.err;
+                       break;
+@@ -2249,7 +2257,7 @@ static int nilfs_segctor_sync(struct nil
+       return err;
+ }
+-static void nilfs_segctor_wakeup(struct nilfs_sc_info *sci, int err)
++static void nilfs_segctor_wakeup(struct nilfs_sc_info *sci, int err, bool force)
+ {
+       struct nilfs_segctor_wait_request *wrq, *n;
+       unsigned long flags;
+@@ -2257,7 +2265,7 @@ static void nilfs_segctor_wakeup(struct
+       spin_lock_irqsave(&sci->sc_wait_request.lock, flags);
+       list_for_each_entry_safe(wrq, n, &sci->sc_wait_request.head, wq.entry) {
+               if (!atomic_read(&wrq->done) &&
+-                  nilfs_cnt32_ge(sci->sc_seq_done, wrq->seq)) {
++                  (force || nilfs_cnt32_ge(sci->sc_seq_done, wrq->seq))) {
+                       wrq->err = err;
+                       atomic_set(&wrq->done, 1);
+               }
+@@ -2397,7 +2405,7 @@ static void nilfs_segctor_notify(struct
+       if (mode == SC_LSEG_SR) {
+               sci->sc_state &= ~NILFS_SEGCTOR_COMMIT;
+               sci->sc_seq_done = sci->sc_seq_accepted;
+-              nilfs_segctor_wakeup(sci, err);
++              nilfs_segctor_wakeup(sci, err, false);
+               sci->sc_flush_request = 0;
+       } else {
+               if (mode == SC_FLUSH_FILE)
+@@ -2779,6 +2787,13 @@ static void nilfs_segctor_destroy(struct
+               || sci->sc_seq_request != sci->sc_seq_done);
+       spin_unlock(&sci->sc_state_lock);
++      /*
++       * Forcibly wake up tasks waiting in nilfs_segctor_sync(), which can
++       * be called from delayed iput() via nilfs_evict_inode() and can race
++       * with the above log writer thread termination.
++       */
++      nilfs_segctor_wakeup(sci, 0, true);
++
+       if (flush_work(&sci->sc_iput_work))
+               flag = true;
diff --git a/queue-5.10/nilfs2-fix-unexpected-freezing-of-nilfs_segctor_sync.patch b/queue-5.10/nilfs2-fix-unexpected-freezing-of-nilfs_segctor_sync.patch
new file mode 100644 (file)
index 0000000..c1ea0fa
--- /dev/null
@@ -0,0 +1,82 @@
+From 936184eadd82906992ff1f5ab3aada70cce44cee Mon Sep 17 00:00:00 2001
+From: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Date: Mon, 20 May 2024 22:26:20 +0900
+Subject: nilfs2: fix unexpected freezing of nilfs_segctor_sync()
+
+From: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+
+commit 936184eadd82906992ff1f5ab3aada70cce44cee upstream.
+
+A potential and reproducible race issue has been identified where
+nilfs_segctor_sync() would block even after the log writer thread writes a
+checkpoint, unless there is an interrupt or other trigger to resume log
+writing.
+
+This turned out to be because, depending on the execution timing of the
+log writer thread running in parallel, the log writer thread may skip
+responding to nilfs_segctor_sync(), which causes a call to schedule()
+waiting for completion within nilfs_segctor_sync() to lose the opportunity
+to wake up.
+
+The reason why waking up the task waiting in nilfs_segctor_sync() may be
+skipped is that updating the request generation issued using a shared
+sequence counter and adding an wait queue entry to the request wait queue
+to the log writer, are not done atomically.  There is a possibility that
+log writing and request completion notification by nilfs_segctor_wakeup()
+may occur between the two operations, and in that case, the wait queue
+entry is not yet visible to nilfs_segctor_wakeup() and the wake-up of
+nilfs_segctor_sync() will be carried over until the next request occurs.
+
+Fix this issue by performing these two operations simultaneously within
+the lock section of sc_state_lock.  Also, following the memory barrier
+guidelines for event waiting loops, move the call to set_current_state()
+in the same location into the event waiting loop to ensure that a memory
+barrier is inserted just before the event condition determination.
+
+Link: https://lkml.kernel.org/r/20240520132621.4054-3-konishi.ryusuke@gmail.com
+Fixes: 9ff05123e3bf ("nilfs2: segment constructor")
+Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Tested-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Cc: <stable@vger.kernel.org>
+Cc: "Bai, Shuangpeng" <sjb7183@psu.edu>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nilfs2/segment.c |   17 +++++++++++++----
+ 1 file changed, 13 insertions(+), 4 deletions(-)
+
+--- a/fs/nilfs2/segment.c
++++ b/fs/nilfs2/segment.c
+@@ -2212,19 +2212,28 @@ static int nilfs_segctor_sync(struct nil
+       struct nilfs_segctor_wait_request wait_req;
+       int err = 0;
+-      spin_lock(&sci->sc_state_lock);
+       init_wait(&wait_req.wq);
+       wait_req.err = 0;
+       atomic_set(&wait_req.done, 0);
++      init_waitqueue_entry(&wait_req.wq, current);
++
++      /*
++       * To prevent a race issue where completion notifications from the
++       * log writer thread are missed, increment the request sequence count
++       * "sc_seq_request" and insert a wait queue entry using the current
++       * sequence number into the "sc_wait_request" queue at the same time
++       * within the lock section of "sc_state_lock".
++       */
++      spin_lock(&sci->sc_state_lock);
+       wait_req.seq = ++sci->sc_seq_request;
++      add_wait_queue(&sci->sc_wait_request, &wait_req.wq);
+       spin_unlock(&sci->sc_state_lock);
+-      init_waitqueue_entry(&wait_req.wq, current);
+-      add_wait_queue(&sci->sc_wait_request, &wait_req.wq);
+-      set_current_state(TASK_INTERRUPTIBLE);
+       wake_up(&sci->sc_wait_daemon);
+       for (;;) {
++              set_current_state(TASK_INTERRUPTIBLE);
++
+               if (atomic_read(&wait_req.done)) {
+                       err = wait_req.err;
+                       break;
index 17ad29724357abb8f607fd24d4b8804e859c6a5c..e0df361901ede70f499b6f379628038a98b71da4 100644 (file)
@@ -3,3 +3,7 @@ speakup-fix-sizeof-vs-array_size-bug.patch
 r8169-fix-possible-ring-buffer-corruption-on-fragmented-tx-packets.patch
 ring-buffer-fix-a-race-between-readers-and-resize-checks.patch
 net-smc91x-fix-m68k-kernel-compilation-for-coldfire-cpu.patch
+nilfs2-fix-unexpected-freezing-of-nilfs_segctor_sync.patch
+nilfs2-fix-potential-hang-in-nilfs_detach_log_writer.patch
+alsa-core-fix-null-module-pointer-assignment-at-card-init.patch
+alsa-timer-set-lower-bound-of-start-tick-time.patch