]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 22 Mar 2021 09:50:06 +0000 (10:50 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 22 Mar 2021 09:50:06 +0000 (10:50 +0100)
added patches:
ext4-do-not-try-to-set-xattr-into-ea_inode-if-value-is-empty.patch
ext4-find-old-entry-again-if-failed-to-rename-whiteout.patch
ext4-fix-potential-error-in-ext4_do_update_inode.patch

queue-4.14/ext4-do-not-try-to-set-xattr-into-ea_inode-if-value-is-empty.patch [new file with mode: 0644]
queue-4.14/ext4-find-old-entry-again-if-failed-to-rename-whiteout.patch [new file with mode: 0644]
queue-4.14/ext4-fix-potential-error-in-ext4_do_update_inode.patch [new file with mode: 0644]
queue-4.14/series

diff --git a/queue-4.14/ext4-do-not-try-to-set-xattr-into-ea_inode-if-value-is-empty.patch b/queue-4.14/ext4-do-not-try-to-set-xattr-into-ea_inode-if-value-is-empty.patch
new file mode 100644 (file)
index 0000000..66a36e4
--- /dev/null
@@ -0,0 +1,57 @@
+From 6b22489911b726eebbf169caee52fea52013fbdd Mon Sep 17 00:00:00 2001
+From: "zhangyi (F)" <yi.zhang@huawei.com>
+Date: Fri, 5 Mar 2021 20:05:08 +0800
+Subject: ext4: do not try to set xattr into ea_inode if value is empty
+
+From: zhangyi (F) <yi.zhang@huawei.com>
+
+commit 6b22489911b726eebbf169caee52fea52013fbdd upstream.
+
+Syzbot report a warning that ext4 may create an empty ea_inode if set
+an empty extent attribute to a file on the file system which is no free
+blocks left.
+
+  WARNING: CPU: 6 PID: 10667 at fs/ext4/xattr.c:1640 ext4_xattr_set_entry+0x10f8/0x1114 fs/ext4/xattr.c:1640
+  ...
+  Call trace:
+   ext4_xattr_set_entry+0x10f8/0x1114 fs/ext4/xattr.c:1640
+   ext4_xattr_block_set+0x1d0/0x1b1c fs/ext4/xattr.c:1942
+   ext4_xattr_set_handle+0x8a0/0xf1c fs/ext4/xattr.c:2390
+   ext4_xattr_set+0x120/0x1f0 fs/ext4/xattr.c:2491
+   ext4_xattr_trusted_set+0x48/0x5c fs/ext4/xattr_trusted.c:37
+   __vfs_setxattr+0x208/0x23c fs/xattr.c:177
+  ...
+
+Now, ext4 try to store extent attribute into an external inode if
+ext4_xattr_block_set() return -ENOSPC, but for the case of store an
+empty extent attribute, store the extent entry into the extent
+attribute block is enough. A simple reproduce below.
+
+  fallocate test.img -l 1M
+  mkfs.ext4 -F -b 2048 -O ea_inode test.img
+  mount test.img /mnt
+  dd if=/dev/zero of=/mnt/foo bs=2048 count=500
+  setfattr -n "user.test" /mnt/foo
+
+Reported-by: syzbot+98b881fdd8ebf45ab4ae@syzkaller.appspotmail.com
+Fixes: 9c6e7853c531 ("ext4: reserve space for xattr entries/names")
+Cc: stable@kernel.org
+Signed-off-by: zhangyi (F) <yi.zhang@huawei.com>
+Link: https://lore.kernel.org/r/20210305120508.298465-1-yi.zhang@huawei.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/xattr.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -2418,7 +2418,7 @@ retry_inode:
+                                * external inode if possible.
+                                */
+                               if (ext4_has_feature_ea_inode(inode->i_sb) &&
+-                                  !i.in_inode) {
++                                  i.value_len && !i.in_inode) {
+                                       i.in_inode = 1;
+                                       goto retry_inode;
+                               }
diff --git a/queue-4.14/ext4-find-old-entry-again-if-failed-to-rename-whiteout.patch b/queue-4.14/ext4-find-old-entry-again-if-failed-to-rename-whiteout.patch
new file mode 100644 (file)
index 0000000..dddddc5
--- /dev/null
@@ -0,0 +1,73 @@
+From b7ff91fd030dc9d72ed91b1aab36e445a003af4f Mon Sep 17 00:00:00 2001
+From: "zhangyi (F)" <yi.zhang@huawei.com>
+Date: Wed, 3 Mar 2021 21:17:02 +0800
+Subject: ext4: find old entry again if failed to rename whiteout
+
+From: zhangyi (F) <yi.zhang@huawei.com>
+
+commit b7ff91fd030dc9d72ed91b1aab36e445a003af4f upstream.
+
+If we failed to add new entry on rename whiteout, we cannot reset the
+old->de entry directly, because the old->de could have moved from under
+us during make indexed dir. So find the old entry again before reset is
+needed, otherwise it may corrupt the filesystem as below.
+
+  /dev/sda: Entry '00000001' in ??? (12) has deleted/unused inode 15. CLEARED.
+  /dev/sda: Unattached inode 75
+  /dev/sda: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.
+
+Fixes: 6b4b8e6b4ad ("ext4: fix bug for rename with RENAME_WHITEOUT")
+Cc: stable@vger.kernel.org
+Signed-off-by: zhangyi (F) <yi.zhang@huawei.com>
+Link: https://lore.kernel.org/r/20210303131703.330415-1-yi.zhang@huawei.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/namei.c |   29 +++++++++++++++++++++++++++--
+ 1 file changed, 27 insertions(+), 2 deletions(-)
+
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -3445,6 +3445,31 @@ static int ext4_setent(handle_t *handle,
+       return 0;
+ }
++static void ext4_resetent(handle_t *handle, struct ext4_renament *ent,
++                        unsigned ino, unsigned file_type)
++{
++      struct ext4_renament old = *ent;
++      int retval = 0;
++
++      /*
++       * old->de could have moved from under us during make indexed dir,
++       * so the old->de may no longer valid and need to find it again
++       * before reset old inode info.
++       */
++      old.bh = ext4_find_entry(old.dir, &old.dentry->d_name, &old.de, NULL);
++      if (IS_ERR(old.bh))
++              retval = PTR_ERR(old.bh);
++      if (!old.bh)
++              retval = -ENOENT;
++      if (retval) {
++              ext4_std_error(old.dir->i_sb, retval);
++              return;
++      }
++
++      ext4_setent(handle, &old, ino, file_type);
++      brelse(old.bh);
++}
++
+ static int ext4_find_delete_entry(handle_t *handle, struct inode *dir,
+                                 const struct qstr *d_name)
+ {
+@@ -3754,8 +3779,8 @@ static int ext4_rename(struct inode *old
+ end_rename:
+       if (whiteout) {
+               if (retval) {
+-                      ext4_setent(handle, &old,
+-                              old.inode->i_ino, old_file_type);
++                      ext4_resetent(handle, &old,
++                                    old.inode->i_ino, old_file_type);
+                       drop_nlink(whiteout);
+               }
+               unlock_new_inode(whiteout);
diff --git a/queue-4.14/ext4-fix-potential-error-in-ext4_do_update_inode.patch b/queue-4.14/ext4-fix-potential-error-in-ext4_do_update_inode.patch
new file mode 100644 (file)
index 0000000..3ba8cea
--- /dev/null
@@ -0,0 +1,47 @@
+From 7d8bd3c76da1d94b85e6c9b7007e20e980bfcfe6 Mon Sep 17 00:00:00 2001
+From: Shijie Luo <luoshijie1@huawei.com>
+Date: Fri, 12 Mar 2021 01:50:51 -0500
+Subject: ext4: fix potential error in ext4_do_update_inode
+
+From: Shijie Luo <luoshijie1@huawei.com>
+
+commit 7d8bd3c76da1d94b85e6c9b7007e20e980bfcfe6 upstream.
+
+If set_large_file = 1 and errors occur in ext4_handle_dirty_metadata(),
+the error code will be overridden, go to out_brelse to avoid this
+situation.
+
+Signed-off-by: Shijie Luo <luoshijie1@huawei.com>
+Link: https://lore.kernel.org/r/20210312065051.36314-1-luoshijie1@huawei.com
+Cc: stable@kernel.org
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/inode.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -5130,7 +5130,7 @@ static int ext4_do_update_inode(handle_t
+       struct ext4_inode_info *ei = EXT4_I(inode);
+       struct buffer_head *bh = iloc->bh;
+       struct super_block *sb = inode->i_sb;
+-      int err = 0, rc, block;
++      int err = 0, block;
+       int need_datasync = 0, set_large_file = 0;
+       uid_t i_uid;
+       gid_t i_gid;
+@@ -5240,9 +5240,9 @@ static int ext4_do_update_inode(handle_t
+                                             bh->b_data);
+       BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
+-      rc = ext4_handle_dirty_metadata(handle, NULL, bh);
+-      if (!err)
+-              err = rc;
++      err = ext4_handle_dirty_metadata(handle, NULL, bh);
++      if (err)
++              goto out_brelse;
+       ext4_clear_inode_state(inode, EXT4_STATE_NEW);
+       if (set_large_file) {
+               BUFFER_TRACE(EXT4_SB(sb)->s_sbh, "get write access");
index 26fa9b8f6880432b8305a57ccb2756e206bebbac..bc0e4699caa446d7f6ae6fd6ed640a702d2e177c 100644 (file)
@@ -37,3 +37,6 @@ x86-ioapic-ignore-irq2-again.patch
 kernel-fs-introduce-and-use-set_restart_fn-and-arch_set_restart_data.patch
 x86-move-ts_compat-back-to-asm-thread_info.h.patch
 x86-introduce-ts_compat_restart-to-fix-get_nr_restart_syscall.patch
+ext4-find-old-entry-again-if-failed-to-rename-whiteout.patch
+ext4-do-not-try-to-set-xattr-into-ea_inode-if-value-is-empty.patch
+ext4-fix-potential-error-in-ext4_do_update_inode.patch