]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 25 Mar 2019 20:11:11 +0000 (05:11 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 25 Mar 2019 20:11:11 +0000 (05:11 +0900)
added patches:
ext4-brelse-all-indirect-buffer-in-ext4_ind_remove_space.patch
ext4-fix-data-corruption-caused-by-unaligned-direct-aio.patch
ext4-fix-null-pointer-dereference-while-journal-is-aborted.patch
mmc-tmio_mmc_core-don-t-claim-spurious-interrupts.patch

queue-3.18/ext4-brelse-all-indirect-buffer-in-ext4_ind_remove_space.patch [new file with mode: 0644]
queue-3.18/ext4-fix-data-corruption-caused-by-unaligned-direct-aio.patch [new file with mode: 0644]
queue-3.18/ext4-fix-null-pointer-dereference-while-journal-is-aborted.patch [new file with mode: 0644]
queue-3.18/mmc-tmio_mmc_core-don-t-claim-spurious-interrupts.patch [new file with mode: 0644]
queue-3.18/series

diff --git a/queue-3.18/ext4-brelse-all-indirect-buffer-in-ext4_ind_remove_space.patch b/queue-3.18/ext4-brelse-all-indirect-buffer-in-ext4_ind_remove_space.patch
new file mode 100644 (file)
index 0000000..f415cf0
--- /dev/null
@@ -0,0 +1,70 @@
+From 674a2b27234d1b7afcb0a9162e81b2e53aeef217 Mon Sep 17 00:00:00 2001
+From: "zhangyi (F)" <yi.zhang@huawei.com>
+Date: Sat, 23 Mar 2019 11:43:05 -0400
+Subject: ext4: brelse all indirect buffer in ext4_ind_remove_space()
+
+From: zhangyi (F) <yi.zhang@huawei.com>
+
+commit 674a2b27234d1b7afcb0a9162e81b2e53aeef217 upstream.
+
+All indirect buffers get by ext4_find_shared() should be released no
+mater the branch should be freed or not. But now, we forget to release
+the lower depth indirect buffers when removing space from the same
+higher depth indirect block. It will lead to buffer leak and futher
+more, it may lead to quota information corruption when using old quota,
+consider the following case.
+
+ - Create and mount an empty ext4 filesystem without extent and quota
+   features,
+ - quotacheck and enable the user & group quota,
+ - Create some files and write some data to them, and then punch hole
+   to some files of them, it may trigger the buffer leak problem
+   mentioned above.
+ - Disable quota and run quotacheck again, it will create two new
+   aquota files and write the checked quota information to them, which
+   probably may reuse the freed indirect block(the buffer and page
+   cache was not freed) as data block.
+ - Enable quota again, it will invoke
+   vfs_load_quota_inode()->invalidate_bdev() to try to clean unused
+   buffers and pagecache. Unfortunately, because of the buffer of quota
+   data block is still referenced, quota code cannot read the up to date
+   quota info from the device and lead to quota information corruption.
+
+This problem can be reproduced by xfstests generic/231 on ext3 file
+system or ext4 file system without extent and quota features.
+
+This patch fix this problem by releasing the missing indirect buffers,
+in ext4_ind_remove_space().
+
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: zhangyi (F) <yi.zhang@huawei.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/indirect.c |   12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+--- a/fs/ext4/indirect.c
++++ b/fs/ext4/indirect.c
+@@ -1480,10 +1480,14 @@ end_range:
+                                          partial->p + 1,
+                                          partial2->p,
+                                          (chain+n-1) - partial);
+-                      BUFFER_TRACE(partial->bh, "call brelse");
+-                      brelse(partial->bh);
+-                      BUFFER_TRACE(partial2->bh, "call brelse");
+-                      brelse(partial2->bh);
++                      while (partial > chain) {
++                              BUFFER_TRACE(partial->bh, "call brelse");
++                              brelse(partial->bh);
++                      }
++                      while (partial2 > chain2) {
++                              BUFFER_TRACE(partial2->bh, "call brelse");
++                              brelse(partial2->bh);
++                      }
+                       return 0;
+               }
diff --git a/queue-3.18/ext4-fix-data-corruption-caused-by-unaligned-direct-aio.patch b/queue-3.18/ext4-fix-data-corruption-caused-by-unaligned-direct-aio.patch
new file mode 100644 (file)
index 0000000..a989f70
--- /dev/null
@@ -0,0 +1,79 @@
+From 372a03e01853f860560eade508794dd274e9b390 Mon Sep 17 00:00:00 2001
+From: Lukas Czerner <lczerner@redhat.com>
+Date: Thu, 14 Mar 2019 23:20:25 -0400
+Subject: ext4: fix data corruption caused by unaligned direct AIO
+
+From: Lukas Czerner <lczerner@redhat.com>
+
+commit 372a03e01853f860560eade508794dd274e9b390 upstream.
+
+Ext4 needs to serialize unaligned direct AIO because the zeroing of
+partial blocks of two competing unaligned AIOs can result in data
+corruption.
+
+However it decides not to serialize if the potentially unaligned aio is
+past i_size with the rationale that no pending writes are possible past
+i_size. Unfortunately if the i_size is not block aligned and the second
+unaligned write lands past i_size, but still into the same block, it has
+the potential of corrupting the previous unaligned write to the same
+block.
+
+This is (very simplified) reproducer from Frank
+
+    // 41472 = (10 * 4096) + 512
+    // 37376 = 41472 - 4096
+
+    ftruncate(fd, 41472);
+    io_prep_pwrite(iocbs[0], fd, buf[0], 4096, 37376);
+    io_prep_pwrite(iocbs[1], fd, buf[1], 4096, 41472);
+
+    io_submit(io_ctx, 1, &iocbs[1]);
+    io_submit(io_ctx, 1, &iocbs[2]);
+
+    io_getevents(io_ctx, 2, 2, events, NULL);
+
+Without this patch the 512B range from 40960 up to the start of the
+second unaligned write (41472) is going to be zeroed overwriting the data
+written by the first write. This is a data corruption.
+
+00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
+*
+00009200  30 30 30 30 30 30 30 30  30 30 30 30 30 30 30 30
+*
+0000a000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
+*
+0000a200  31 31 31 31 31 31 31 31  31 31 31 31 31 31 31 31
+
+With this patch the data corruption is avoided because we will recognize
+the unaligned_aio and wait for the unwritten extent conversion.
+
+00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
+*
+00009200  30 30 30 30 30 30 30 30  30 30 30 30 30 30 30 30
+*
+0000a200  31 31 31 31 31 31 31 31  31 31 31 31 31 31 31 31
+*
+0000b200
+
+Reported-by: Frank Sorenson <fsorenso@redhat.com>
+Signed-off-by: Lukas Czerner <lczerner@redhat.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Fixes: e9e3bcecf44c ("ext4: serialize unaligned asynchronous DIO")
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/file.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/ext4/file.c
++++ b/fs/ext4/file.c
+@@ -79,7 +79,7 @@ ext4_unaligned_aio(struct inode *inode,
+       struct super_block *sb = inode->i_sb;
+       int blockmask = sb->s_blocksize - 1;
+-      if (pos >= i_size_read(inode))
++      if (pos >= ALIGN(i_size_read(inode), sb->s_blocksize))
+               return 0;
+       if ((pos | iov_iter_alignment(from)) & blockmask)
diff --git a/queue-3.18/ext4-fix-null-pointer-dereference-while-journal-is-aborted.patch b/queue-3.18/ext4-fix-null-pointer-dereference-while-journal-is-aborted.patch
new file mode 100644 (file)
index 0000000..8723771
--- /dev/null
@@ -0,0 +1,59 @@
+From fa30dde38aa8628c73a6dded7cb0bba38c27b576 Mon Sep 17 00:00:00 2001
+From: Jiufei Xue <jiufei.xue@linux.alibaba.com>
+Date: Thu, 14 Mar 2019 23:19:22 -0400
+Subject: ext4: fix NULL pointer dereference while journal is aborted
+
+From: Jiufei Xue <jiufei.xue@linux.alibaba.com>
+
+commit fa30dde38aa8628c73a6dded7cb0bba38c27b576 upstream.
+
+We see the following NULL pointer dereference while running xfstests
+generic/475:
+BUG: unable to handle kernel NULL pointer dereference at 0000000000000008
+PGD 8000000c84bad067 P4D 8000000c84bad067 PUD c84e62067 PMD 0
+Oops: 0000 [#1] SMP PTI
+CPU: 7 PID: 9886 Comm: fsstress Kdump: loaded Not tainted 5.0.0-rc8 #10
+RIP: 0010:ext4_do_update_inode+0x4ec/0x760
+...
+Call Trace:
+? jbd2_journal_get_write_access+0x42/0x50
+? __ext4_journal_get_write_access+0x2c/0x70
+? ext4_truncate+0x186/0x3f0
+ext4_mark_iloc_dirty+0x61/0x80
+ext4_mark_inode_dirty+0x62/0x1b0
+ext4_truncate+0x186/0x3f0
+? unmap_mapping_pages+0x56/0x100
+ext4_setattr+0x817/0x8b0
+notify_change+0x1df/0x430
+do_truncate+0x5e/0x90
+? generic_permission+0x12b/0x1a0
+
+This is triggered because the NULL pointer handle->h_transaction was
+dereferenced in function ext4_update_inode_fsync_trans().
+I found that the h_transaction was set to NULL in jbd2__journal_restart
+but failed to attached to a new transaction while the journal is aborted.
+
+Fix this by checking the handle before updating the inode.
+
+Fixes: b436b9bef84d ("ext4: Wait for proper transaction commit on fsync")
+Signed-off-by: Jiufei Xue <jiufei.xue@linux.alibaba.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/ext4_jbd2.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/ext4/ext4_jbd2.h
++++ b/fs/ext4/ext4_jbd2.h
+@@ -374,7 +374,7 @@ static inline void ext4_update_inode_fsy
+ {
+       struct ext4_inode_info *ei = EXT4_I(inode);
+-      if (ext4_handle_valid(handle)) {
++      if (ext4_handle_valid(handle) && !is_handle_aborted(handle)) {
+               ei->i_sync_tid = handle->h_transaction->t_tid;
+               if (datasync)
+                       ei->i_datasync_tid = handle->h_transaction->t_tid;
diff --git a/queue-3.18/mmc-tmio_mmc_core-don-t-claim-spurious-interrupts.patch b/queue-3.18/mmc-tmio_mmc_core-don-t-claim-spurious-interrupts.patch
new file mode 100644 (file)
index 0000000..5181d3f
--- /dev/null
@@ -0,0 +1,62 @@
+From 5c27ff5db1491a947264d6d4e4cbe43ae6535bae Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Mon, 18 Feb 2019 20:45:40 +0300
+Subject: mmc: tmio_mmc_core: don't claim spurious interrupts
+
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+
+commit 5c27ff5db1491a947264d6d4e4cbe43ae6535bae upstream.
+
+I have encountered an interrupt storm during the eMMC chip probing (and
+the chip finally didn't get detected).  It turned out that U-Boot left
+the DMAC interrupts enabled while the Linux driver  didn't use those.
+The SDHI driver's interrupt handler somehow assumes that, even if an
+SDIO interrupt didn't happen, it should return IRQ_HANDLED.  I think
+that if none of the enabled interrupts happened and got handled, we
+should return IRQ_NONE -- that way the kernel IRQ code recoginizes
+a spurious interrupt and masks it off pretty quickly...
+
+Fixes: 7729c7a232a9 ("mmc: tmio: Provide separate interrupt handlers")
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
+Cc: stable@vger.kernel.org
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mmc/host/tmio_mmc_pio.c |    8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+--- a/drivers/mmc/host/tmio_mmc_pio.c
++++ b/drivers/mmc/host/tmio_mmc_pio.c
+@@ -714,7 +714,7 @@ irqreturn_t tmio_mmc_sdio_irq(int irq, v
+       unsigned int sdio_status;
+       if (!(pdata->flags & TMIO_MMC_SDIO_IRQ))
+-              return IRQ_HANDLED;
++              return IRQ_NONE;
+       status = sd_ctrl_read16(host, CTL_SDIO_STATUS);
+       ireg = status & TMIO_SDIO_MASK_ALL & ~host->sdcard_irq_mask;
+@@ -728,7 +728,7 @@ irqreturn_t tmio_mmc_sdio_irq(int irq, v
+       if (mmc->caps & MMC_CAP_SDIO_IRQ && ireg & TMIO_SDIO_STAT_IOIRQ)
+               mmc_signal_sdio_irq(mmc);
+-      return IRQ_HANDLED;
++      return IRQ_RETVAL(ireg);
+ }
+ EXPORT_SYMBOL(tmio_mmc_sdio_irq);
+@@ -745,9 +745,7 @@ irqreturn_t tmio_mmc_irq(int irq, void *
+       if (__tmio_mmc_sdcard_irq(host, ireg, status))
+               return IRQ_HANDLED;
+-      tmio_mmc_sdio_irq(irq, devid);
+-
+-      return IRQ_HANDLED;
++      return tmio_mmc_sdio_irq(irq, devid);
+ }
+ EXPORT_SYMBOL(tmio_mmc_irq);
index 0e73f67d9a2d6e61d9c6e5f0d0fda8dd12db4993..6e649ae56427393d76dfe7b5b06419f36d0e66a4 100644 (file)
@@ -1,2 +1,6 @@
 udf-fix-crash-on-io-error-during-truncate.patch
 futex-ensure-that-futex-address-is-aligned-in-handle_futex_death.patch
+ext4-fix-null-pointer-dereference-while-journal-is-aborted.patch
+ext4-fix-data-corruption-caused-by-unaligned-direct-aio.patch
+ext4-brelse-all-indirect-buffer-in-ext4_ind_remove_space.patch
+mmc-tmio_mmc_core-don-t-claim-spurious-interrupts.patch