]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 22 Jun 2020 18:01:31 +0000 (20:01 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 22 Jun 2020 18:01:31 +0000 (20:01 +0200)
added patches:
ext4-avoid-utf8_strncasecmp-with-unstable-name.patch
ext4-fix-partial-cluster-initialization-when-splitting-extent.patch

queue-5.4/ext4-avoid-utf8_strncasecmp-with-unstable-name.patch [new file with mode: 0644]
queue-5.4/ext4-fix-partial-cluster-initialization-when-splitting-extent.patch [new file with mode: 0644]
queue-5.4/series

diff --git a/queue-5.4/ext4-avoid-utf8_strncasecmp-with-unstable-name.patch b/queue-5.4/ext4-avoid-utf8_strncasecmp-with-unstable-name.patch
new file mode 100644 (file)
index 0000000..e8145f1
--- /dev/null
@@ -0,0 +1,65 @@
+From 2ce3ee931a097e9720310db3f09c01c825a4580c Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Mon, 1 Jun 2020 13:05:43 -0700
+Subject: ext4: avoid utf8_strncasecmp() with unstable name
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit 2ce3ee931a097e9720310db3f09c01c825a4580c upstream.
+
+If the dentry name passed to ->d_compare() fits in dentry::d_iname, then
+it may be concurrently modified by a rename.  This can cause undefined
+behavior (possibly out-of-bounds memory accesses or crashes) in
+utf8_strncasecmp(), since fs/unicode/ isn't written to handle strings
+that may be concurrently modified.
+
+Fix this by first copying the filename to a stack buffer if needed.
+This way we get a stable snapshot of the filename.
+
+Fixes: b886ee3e778e ("ext4: Support case-insensitive file name lookups")
+Cc: <stable@vger.kernel.org> # v5.2+
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Cc: Daniel Rosenberg <drosen@google.com>
+Cc: Gabriel Krisman Bertazi <krisman@collabora.co.uk>
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Reviewed-by: Andreas Dilger <adilger@dilger.ca>
+Link: https://lore.kernel.org/r/20200601200543.59417-1-ebiggers@kernel.org
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/dir.c |   16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+--- a/fs/ext4/dir.c
++++ b/fs/ext4/dir.c
+@@ -677,6 +677,7 @@ static int ext4_d_compare(const struct d
+       struct qstr qstr = {.name = str, .len = len };
+       const struct dentry *parent = READ_ONCE(dentry->d_parent);
+       const struct inode *inode = READ_ONCE(parent->d_inode);
++      char strbuf[DNAME_INLINE_LEN];
+       if (!inode || !IS_CASEFOLDED(inode) ||
+           !EXT4_SB(inode->i_sb)->s_encoding) {
+@@ -685,6 +686,21 @@ static int ext4_d_compare(const struct d
+               return memcmp(str, name->name, len);
+       }
++      /*
++       * If the dentry name is stored in-line, then it may be concurrently
++       * modified by a rename.  If this happens, the VFS will eventually retry
++       * the lookup, so it doesn't matter what ->d_compare() returns.
++       * However, it's unsafe to call utf8_strncasecmp() with an unstable
++       * string.  Therefore, we have to copy the name into a temporary buffer.
++       */
++      if (len <= DNAME_INLINE_LEN - 1) {
++              memcpy(strbuf, str, len);
++              strbuf[len] = 0;
++              qstr.name = strbuf;
++              /* prevent compiler from optimizing out the temporary buffer */
++              barrier();
++      }
++
+       return ext4_ci_compare(inode, name, &qstr, false);
+ }
diff --git a/queue-5.4/ext4-fix-partial-cluster-initialization-when-splitting-extent.patch b/queue-5.4/ext4-fix-partial-cluster-initialization-when-splitting-extent.patch
new file mode 100644 (file)
index 0000000..901b409
--- /dev/null
@@ -0,0 +1,118 @@
+From cfb3c85a600c6aa25a2581b3c1c4db3460f14e46 Mon Sep 17 00:00:00 2001
+From: Jeffle Xu <jefflexu@linux.alibaba.com>
+Date: Fri, 22 May 2020 12:18:44 +0800
+Subject: ext4: fix partial cluster initialization when splitting extent
+
+From: Jeffle Xu <jefflexu@linux.alibaba.com>
+
+commit cfb3c85a600c6aa25a2581b3c1c4db3460f14e46 upstream.
+
+Fix the bug when calculating the physical block number of the first
+block in the split extent.
+
+This bug will cause xfstests shared/298 failure on ext4 with bigalloc
+enabled occasionally. Ext4 error messages indicate that previously freed
+blocks are being freed again, and the following fsck will fail due to
+the inconsistency of block bitmap and bg descriptor.
+
+The following is an example case:
+
+1. First, Initialize a ext4 filesystem with cluster size '16K', block size
+'4K', in which case, one cluster contains four blocks.
+
+2. Create one file (e.g., xxx.img) on this ext4 filesystem. Now the extent
+tree of this file is like:
+
+...
+36864:[0]4:220160
+36868:[0]14332:145408
+51200:[0]2:231424
+...
+
+3. Then execute PUNCH_HOLE fallocate on this file. The hole range is
+like:
+
+..
+ext4_ext_remove_space: dev 254,16 ino 12 since 49506 end 49506 depth 1
+ext4_ext_remove_space: dev 254,16 ino 12 since 49544 end 49546 depth 1
+ext4_ext_remove_space: dev 254,16 ino 12 since 49605 end 49607 depth 1
+...
+
+4. Then the extent tree of this file after punching is like
+
+...
+49507:[0]37:158047
+49547:[0]58:158087
+...
+
+5. Detailed procedure of punching hole [49544, 49546]
+
+5.1. The block address space:
+```
+lblk        ~49505  49506   49507~49543     49544~49546    49547~
+         ---------+------+-------------+----------------+--------
+           extent | hole |   extent    |       hole     | extent
+         ---------+------+-------------+----------------+--------
+pblk       ~158045  158046  158047~158083  158084~158086   158087~
+```
+
+5.2. The detailed layout of cluster 39521:
+```
+               cluster 39521
+       <------------------------------->
+
+               hole              extent
+       <----------------------><--------
+
+lblk      49544   49545   49546   49547
+       +-------+-------+-------+-------+
+       |       |       |       |       |
+       +-------+-------+-------+-------+
+pblk     158084  1580845  158086  158087
+```
+
+5.3. The ftrace output when punching hole [49544, 49546]:
+- ext4_ext_remove_space (start 49544, end 49546)
+  - ext4_ext_rm_leaf (start 49544, end 49546, last_extent [49507(158047), 40], partial [pclu 39522 lblk 0 state 2])
+    - ext4_remove_blocks (extent [49507(158047), 40], from 49544 to 49546, partial [pclu 39522 lblk 0 state 2]
+      - ext4_free_blocks: (block 158084 count 4)
+        - ext4_mballoc_free (extent 1/6753/1)
+
+5.4. Ext4 error message in dmesg:
+EXT4-fs error (device vdb): mb_free_blocks:1457: group 1, block 158084:freeing already freed block (bit 6753); block bitmap corrupt.
+EXT4-fs error (device vdb): ext4_mb_generate_buddy:747: group 1, block bitmap and bg descriptor inconsistent: 19550 vs 19551 free clusters
+
+In this case, the whole cluster 39521 is freed mistakenly when freeing
+pblock 158084~158086 (i.e., the first three blocks of this cluster),
+although pblock 158087 (the last remaining block of this cluster) has
+not been freed yet.
+
+The root cause of this isuue is that, the pclu of the partial cluster is
+calculated mistakenly in ext4_ext_remove_space(). The correct
+partial_cluster.pclu (i.e., the cluster number of the first block in the
+next extent, that is, lblock 49597 (pblock 158086)) should be 39521 rather
+than 39522.
+
+Fixes: f4226d9ea400 ("ext4: fix partial cluster initialization")
+Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
+Reviewed-by: Eric Whitney <enwlinux@gmail.com>
+Cc: stable@kernel.org # v3.19+
+Link: https://lore.kernel.org/r/1590121124-37096-1-git-send-email-jefflexu@linux.alibaba.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/extents.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -3010,7 +3010,7 @@ again:
+                        * in use to avoid freeing it when removing blocks.
+                        */
+                       if (sbi->s_cluster_ratio > 1) {
+-                              pblk = ext4_ext_pblock(ex) + end - ee_block + 2;
++                              pblk = ext4_ext_pblock(ex) + end - ee_block + 1;
+                               partial.pclu = EXT4_B2C(sbi, pblk);
+                               partial.state = nofree;
+                       }
index 8e461851e70ea93bdd87b40a900c964808ff8692..2dfb2256e48215bdcdcd82584bc86d5573cb0e2f 100644 (file)
@@ -280,3 +280,5 @@ mvpp2-remove-module-bugfix.patch
 arm64-hw_breakpoint-don-t-invoke-overflow-handler-on.patch
 libata-use-per-port-sync-for-detach.patch
 drm-encoder_slave-fix-refcouting-error-for-modules.patch
+ext4-fix-partial-cluster-initialization-when-splitting-extent.patch
+ext4-avoid-utf8_strncasecmp-with-unstable-name.patch