]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 12 Aug 2023 06:20:04 +0000 (08:20 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 12 Aug 2023 06:20:04 +0000 (08:20 +0200)
added patches:
dmaengine-pl330-return-dma_paused-when-transaction-is-paused.patch
nilfs2-fix-use-after-free-of-nilfs_root-in-dirtying-inodes-via-iput.patch
radix-tree-test-suite-fix-incorrect-allocation-size-for-pthreads.patch

queue-4.14/dmaengine-pl330-return-dma_paused-when-transaction-is-paused.patch [new file with mode: 0644]
queue-4.14/nilfs2-fix-use-after-free-of-nilfs_root-in-dirtying-inodes-via-iput.patch [new file with mode: 0644]
queue-4.14/radix-tree-test-suite-fix-incorrect-allocation-size-for-pthreads.patch [new file with mode: 0644]
queue-4.14/series

diff --git a/queue-4.14/dmaengine-pl330-return-dma_paused-when-transaction-is-paused.patch b/queue-4.14/dmaengine-pl330-return-dma_paused-when-transaction-is-paused.patch
new file mode 100644 (file)
index 0000000..407f5ab
--- /dev/null
@@ -0,0 +1,98 @@
+From 8cda3ececf07d374774f6a13e5a94bc2dc04c26c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= <ilpo.jarvinen@linux.intel.com>
+Date: Fri, 26 May 2023 13:54:34 +0300
+Subject: dmaengine: pl330: Return DMA_PAUSED when transaction is paused
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+commit 8cda3ececf07d374774f6a13e5a94bc2dc04c26c upstream.
+
+pl330_pause() does not set anything to indicate paused condition which
+causes pl330_tx_status() to return DMA_IN_PROGRESS. This breaks 8250
+DMA flush after the fix in commit 57e9af7831dc ("serial: 8250_dma: Fix
+DMA Rx rearm race"). The function comment for pl330_pause() claims
+pause is supported but resume is not which is enough for 8250 DMA flush
+to work as long as DMA status reports DMA_PAUSED when appropriate.
+
+Add PAUSED state for descriptor and mark BUSY descriptors with PAUSED
+in pl330_pause(). Return DMA_PAUSED from pl330_tx_status() when the
+descriptor is PAUSED.
+
+Reported-by: Richard Tresidder <rtresidd@electromag.com.au>
+Tested-by: Richard Tresidder <rtresidd@electromag.com.au>
+Fixes: 88987d2c7534 ("dmaengine: pl330: add DMA_PAUSE feature")
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/linux-serial/f8a86ecd-64b1-573f-c2fa-59f541083f1a@electromag.com.au/
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Link: https://lore.kernel.org/r/20230526105434.14959-1-ilpo.jarvinen@linux.intel.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma/pl330.c |   18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+--- a/drivers/dma/pl330.c
++++ b/drivers/dma/pl330.c
+@@ -404,6 +404,12 @@ enum desc_status {
+        */
+       BUSY,
+       /*
++       * Pause was called while descriptor was BUSY. Due to hardware
++       * limitations, only termination is possible for descriptors
++       * that have been paused.
++       */
++      PAUSED,
++      /*
+        * Sitting on the channel work_list but xfer done
+        * by PL330 core
+        */
+@@ -1926,7 +1932,7 @@ static inline void fill_queue(struct dma
+       list_for_each_entry(desc, &pch->work_list, node) {
+               /* If already submitted */
+-              if (desc->status == BUSY)
++              if (desc->status == BUSY || desc->status == PAUSED)
+                       continue;
+               ret = pl330_submit_req(pch->thread, desc);
+@@ -2191,6 +2197,7 @@ static int pl330_pause(struct dma_chan *
+ {
+       struct dma_pl330_chan *pch = to_pchan(chan);
+       struct pl330_dmac *pl330 = pch->dmac;
++      struct dma_pl330_desc *desc;
+       unsigned long flags;
+       pm_runtime_get_sync(pl330->ddma.dev);
+@@ -2200,6 +2207,10 @@ static int pl330_pause(struct dma_chan *
+       _stop(pch->thread);
+       spin_unlock(&pl330->lock);
++      list_for_each_entry(desc, &pch->work_list, node) {
++              if (desc->status == BUSY)
++                      desc->status = PAUSED;
++      }
+       spin_unlock_irqrestore(&pch->lock, flags);
+       pm_runtime_mark_last_busy(pl330->ddma.dev);
+       pm_runtime_put_autosuspend(pl330->ddma.dev);
+@@ -2290,7 +2301,7 @@ pl330_tx_status(struct dma_chan *chan, d
+               else if (running && desc == running)
+                       transferred =
+                               pl330_get_current_xferred_count(pch, desc);
+-              else if (desc->status == BUSY)
++              else if (desc->status == BUSY || desc->status == PAUSED)
+                       /*
+                        * Busy but not running means either just enqueued,
+                        * or finished and not yet marked done
+@@ -2307,6 +2318,9 @@ pl330_tx_status(struct dma_chan *chan, d
+                       case DONE:
+                               ret = DMA_COMPLETE;
+                               break;
++                      case PAUSED:
++                              ret = DMA_PAUSED;
++                              break;
+                       case PREP:
+                       case BUSY:
+                               ret = DMA_IN_PROGRESS;
diff --git a/queue-4.14/nilfs2-fix-use-after-free-of-nilfs_root-in-dirtying-inodes-via-iput.patch b/queue-4.14/nilfs2-fix-use-after-free-of-nilfs_root-in-dirtying-inodes-via-iput.patch
new file mode 100644 (file)
index 0000000..dd9b9aa
--- /dev/null
@@ -0,0 +1,120 @@
+From f8654743a0e6909dc634cbfad6db6816f10f3399 Mon Sep 17 00:00:00 2001
+From: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Date: Sat, 29 Jul 2023 04:13:18 +0900
+Subject: nilfs2: fix use-after-free of nilfs_root in dirtying inodes via iput
+
+From: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+
+commit f8654743a0e6909dc634cbfad6db6816f10f3399 upstream.
+
+During unmount process of nilfs2, nothing holds nilfs_root structure after
+nilfs2 detaches its writer in nilfs_detach_log_writer().  Previously,
+nilfs_evict_inode() could cause use-after-free read for nilfs_root if
+inodes are left in "garbage_list" and released by nilfs_dispose_list at
+the end of nilfs_detach_log_writer(), and this bug was fixed by commit
+9b5a04ac3ad9 ("nilfs2: fix use-after-free bug of nilfs_root in
+nilfs_evict_inode()").
+
+However, it turned out that there is another possibility of UAF in the
+call path where mark_inode_dirty_sync() is called from iput():
+
+nilfs_detach_log_writer()
+  nilfs_dispose_list()
+    iput()
+      mark_inode_dirty_sync()
+        __mark_inode_dirty()
+          nilfs_dirty_inode()
+            __nilfs_mark_inode_dirty()
+              nilfs_load_inode_block() --> causes UAF of nilfs_root struct
+
+This can happen after commit 0ae45f63d4ef ("vfs: add support for a
+lazytime mount option"), which changed iput() to call
+mark_inode_dirty_sync() on its final reference if i_state has I_DIRTY_TIME
+flag and i_nlink is non-zero.
+
+This issue appears after commit 28a65b49eb53 ("nilfs2: do not write dirty
+data after degenerating to read-only") when using the syzbot reproducer,
+but the issue has potentially existed before.
+
+Fix this issue by adding a "purging flag" to the nilfs structure, setting
+that flag while disposing the "garbage_list" and checking it in
+__nilfs_mark_inode_dirty().
+
+Unlike commit 9b5a04ac3ad9 ("nilfs2: fix use-after-free bug of nilfs_root
+in nilfs_evict_inode()"), this patch does not rely on ns_writer to
+determine whether to skip operations, so as not to break recovery on
+mount.  The nilfs_salvage_orphan_logs routine dirties the buffer of
+salvaged data before attaching the log writer, so changing
+__nilfs_mark_inode_dirty() to skip the operation when ns_writer is NULL
+will cause recovery write to fail.  The purpose of using the cleanup-only
+flag is to allow for narrowing of such conditions.
+
+Link: https://lkml.kernel.org/r/20230728191318.33047-1-konishi.ryusuke@gmail.com
+Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Reported-by: syzbot+74db8b3087f293d3a13a@syzkaller.appspotmail.com
+Closes: https://lkml.kernel.org/r/000000000000b4e906060113fd63@google.com
+Fixes: 0ae45f63d4ef ("vfs: add support for a lazytime mount option")
+Tested-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Cc: <stable@vger.kernel.org> # 4.0+
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nilfs2/inode.c     |    8 ++++++++
+ fs/nilfs2/segment.c   |    2 ++
+ fs/nilfs2/the_nilfs.h |    2 ++
+ 3 files changed, 12 insertions(+)
+
+--- a/fs/nilfs2/inode.c
++++ b/fs/nilfs2/inode.c
+@@ -1121,9 +1121,17 @@ int nilfs_set_file_dirty(struct inode *i
+ int __nilfs_mark_inode_dirty(struct inode *inode, int flags)
+ {
++      struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
+       struct buffer_head *ibh;
+       int err;
++      /*
++       * Do not dirty inodes after the log writer has been detached
++       * and its nilfs_root struct has been freed.
++       */
++      if (unlikely(nilfs_purging(nilfs)))
++              return 0;
++
+       err = nilfs_load_inode_block(inode, &ibh);
+       if (unlikely(err)) {
+               nilfs_msg(inode->i_sb, KERN_WARNING,
+--- a/fs/nilfs2/segment.c
++++ b/fs/nilfs2/segment.c
+@@ -2859,6 +2859,7 @@ void nilfs_detach_log_writer(struct supe
+               nilfs_segctor_destroy(nilfs->ns_writer);
+               nilfs->ns_writer = NULL;
+       }
++      set_nilfs_purging(nilfs);
+       /* Force to free the list of dirty files */
+       spin_lock(&nilfs->ns_inode_lock);
+@@ -2871,4 +2872,5 @@ void nilfs_detach_log_writer(struct supe
+       up_write(&nilfs->ns_segctor_sem);
+       nilfs_dispose_list(nilfs, &garbage_list, 1);
++      clear_nilfs_purging(nilfs);
+ }
+--- a/fs/nilfs2/the_nilfs.h
++++ b/fs/nilfs2/the_nilfs.h
+@@ -37,6 +37,7 @@ enum {
+       THE_NILFS_DISCONTINUED, /* 'next' pointer chain has broken */
+       THE_NILFS_GC_RUNNING,   /* gc process is running */
+       THE_NILFS_SB_DIRTY,     /* super block is dirty */
++      THE_NILFS_PURGING,      /* disposing dirty files for cleanup */
+ };
+ /**
+@@ -216,6 +217,7 @@ THE_NILFS_FNS(INIT, init)
+ THE_NILFS_FNS(DISCONTINUED, discontinued)
+ THE_NILFS_FNS(GC_RUNNING, gc_running)
+ THE_NILFS_FNS(SB_DIRTY, sb_dirty)
++THE_NILFS_FNS(PURGING, purging)
+ /*
+  * Mount option operations
diff --git a/queue-4.14/radix-tree-test-suite-fix-incorrect-allocation-size-for-pthreads.patch b/queue-4.14/radix-tree-test-suite-fix-incorrect-allocation-size-for-pthreads.patch
new file mode 100644 (file)
index 0000000..4428735
--- /dev/null
@@ -0,0 +1,41 @@
+From cac7ea57a06016e4914848b707477fb07ee4ae1c Mon Sep 17 00:00:00 2001
+From: Colin Ian King <colin.i.king@gmail.com>
+Date: Thu, 27 Jul 2023 17:09:30 +0100
+Subject: radix tree test suite: fix incorrect allocation size for pthreads
+
+From: Colin Ian King <colin.i.king@gmail.com>
+
+commit cac7ea57a06016e4914848b707477fb07ee4ae1c upstream.
+
+Currently the pthread allocation for each array item is based on the size
+of a pthread_t pointer and should be the size of the pthread_t structure,
+so the allocation is under-allocating the correct size.  Fix this by using
+the size of each element in the pthreads array.
+
+Static analysis cppcheck reported:
+tools/testing/radix-tree/regression1.c:180:2: warning: Size of pointer
+'threads' used instead of size of its data. [pointerSize]
+
+Link: https://lkml.kernel.org/r/20230727160930.632674-1-colin.i.king@gmail.com
+Fixes: 1366c37ed84b ("radix tree test harness")
+Signed-off-by: Colin Ian King <colin.i.king@gmail.com>
+Cc: Konstantin Khlebnikov <koct9i@gmail.com>
+Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/radix-tree/regression1.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/tools/testing/radix-tree/regression1.c
++++ b/tools/testing/radix-tree/regression1.c
+@@ -198,7 +198,7 @@ void regression1_test(void)
+       nr_threads = 2;
+       pthread_barrier_init(&worker_barrier, NULL, nr_threads);
+-      threads = malloc(nr_threads * sizeof(pthread_t *));
++      threads = malloc(nr_threads * sizeof(*threads));
+       for (i = 0; i < nr_threads; i++) {
+               arg = i;
index 434d3f46546d514bc4cd436f895495ff212df9cb..c3a3f19836e9898d675c896bd08fb8ebbb12e307 100644 (file)
@@ -1,3 +1,6 @@
 sparc-fix-up-arch_cpu_finalize_init-build-breakage.patch
 mmc-moxart-read-scr-register-without-changing-byte-order.patch
 ipv6-adjust-ndisc_is_useropt-to-also-return-true-for-pio.patch
+dmaengine-pl330-return-dma_paused-when-transaction-is-paused.patch
+radix-tree-test-suite-fix-incorrect-allocation-size-for-pthreads.patch
+nilfs2-fix-use-after-free-of-nilfs_root-in-dirtying-inodes-via-iput.patch