]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.2-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 6 Mar 2023 13:43:36 +0000 (14:43 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 6 Mar 2023 13:43:36 +0000 (14:43 +0100)
added patches:
exfat-fix-inode-i_blocks-for-non-512-byte-sector-size-device.patch
exfat-fix-reporting-fs-error-when-reading-dir-beyond-eof.patch
exfat-fix-unexpected-eof-while-reading-dir.patch
exfat-redefine-dir_deleted-as-the-bad-cluster-number.patch
f2fs-fix-cgroup-writeback-accounting-with-fs-layer-encryption.patch
f2fs-fix-information-leak-in-f2fs_move_inline_dirents.patch
f2fs-fix-kernel-crash-due-to-null-io-bio.patch
f2fs-retry-to-update-the-inode-page-given-data-corruption.patch
f2fs-revert-f2fs-truncate-blocks-in-batch-in-__complete_revoke_list.patch
fs-cramfs-inode.c-initialize-file_ra_state.patch
fs-dlm-be-sure-to-call-dlm_send_queue_flush.patch
fs-dlm-don-t-set-stop-rx-flag-after-node-reset.patch
fs-dlm-fix-race-setting-stop-tx-flag.patch
fs-dlm-fix-use-after-free-in-midcomms-commit.patch
fs-dlm-move-sending-fin-message-into-state-change-handling.patch
fs-dlm-send-fin-ack-back-in-right-cases.patch
fs-dlm-start-midcomms-before-scand.patch
fs-hfsplus-fix-uaf-issue-in-hfsplus_put_super.patch
hfs-fix-missing-hfs_bnode_get-in-__hfs_bnode_create.patch
md-don-t-update-recovery_cp-when-curr_resync-is-active.patch
ocfs2-fix-defrag-path-triggering-jbd2-assert.patch
ocfs2-fix-non-auto-defrag-path-not-working-issue.patch
selftests-landlock-skip-overlayfs-tests-when-not-supported.patch
selftests-landlock-test-ptrace-as-much-as-possible-with-yama.patch
udf-detect-system-inodes-linked-into-directory-hierarchy.patch
udf-do-not-bother-merging-very-long-extents.patch
udf-do-not-update-file-length-for-failed-writes-to-inline-files.patch
udf-fix-file-corruption-when-appending-just-after-end-of-preallocated-extent.patch
udf-preserve-link-count-of-system-files.patch
udf-truncate-added-extents-on-failed-expansion.patch

31 files changed:
queue-6.2/exfat-fix-inode-i_blocks-for-non-512-byte-sector-size-device.patch [new file with mode: 0644]
queue-6.2/exfat-fix-reporting-fs-error-when-reading-dir-beyond-eof.patch [new file with mode: 0644]
queue-6.2/exfat-fix-unexpected-eof-while-reading-dir.patch [new file with mode: 0644]
queue-6.2/exfat-redefine-dir_deleted-as-the-bad-cluster-number.patch [new file with mode: 0644]
queue-6.2/f2fs-fix-cgroup-writeback-accounting-with-fs-layer-encryption.patch [new file with mode: 0644]
queue-6.2/f2fs-fix-information-leak-in-f2fs_move_inline_dirents.patch [new file with mode: 0644]
queue-6.2/f2fs-fix-kernel-crash-due-to-null-io-bio.patch [new file with mode: 0644]
queue-6.2/f2fs-retry-to-update-the-inode-page-given-data-corruption.patch [new file with mode: 0644]
queue-6.2/f2fs-revert-f2fs-truncate-blocks-in-batch-in-__complete_revoke_list.patch [new file with mode: 0644]
queue-6.2/fs-cramfs-inode.c-initialize-file_ra_state.patch [new file with mode: 0644]
queue-6.2/fs-dlm-be-sure-to-call-dlm_send_queue_flush.patch [new file with mode: 0644]
queue-6.2/fs-dlm-don-t-set-stop-rx-flag-after-node-reset.patch [new file with mode: 0644]
queue-6.2/fs-dlm-fix-race-setting-stop-tx-flag.patch [new file with mode: 0644]
queue-6.2/fs-dlm-fix-use-after-free-in-midcomms-commit.patch [new file with mode: 0644]
queue-6.2/fs-dlm-move-sending-fin-message-into-state-change-handling.patch [new file with mode: 0644]
queue-6.2/fs-dlm-send-fin-ack-back-in-right-cases.patch [new file with mode: 0644]
queue-6.2/fs-dlm-start-midcomms-before-scand.patch [new file with mode: 0644]
queue-6.2/fs-hfsplus-fix-uaf-issue-in-hfsplus_put_super.patch [new file with mode: 0644]
queue-6.2/hfs-fix-missing-hfs_bnode_get-in-__hfs_bnode_create.patch [new file with mode: 0644]
queue-6.2/md-don-t-update-recovery_cp-when-curr_resync-is-active.patch [new file with mode: 0644]
queue-6.2/ocfs2-fix-defrag-path-triggering-jbd2-assert.patch [new file with mode: 0644]
queue-6.2/ocfs2-fix-non-auto-defrag-path-not-working-issue.patch [new file with mode: 0644]
queue-6.2/selftests-landlock-skip-overlayfs-tests-when-not-supported.patch [new file with mode: 0644]
queue-6.2/selftests-landlock-test-ptrace-as-much-as-possible-with-yama.patch [new file with mode: 0644]
queue-6.2/series
queue-6.2/udf-detect-system-inodes-linked-into-directory-hierarchy.patch [new file with mode: 0644]
queue-6.2/udf-do-not-bother-merging-very-long-extents.patch [new file with mode: 0644]
queue-6.2/udf-do-not-update-file-length-for-failed-writes-to-inline-files.patch [new file with mode: 0644]
queue-6.2/udf-fix-file-corruption-when-appending-just-after-end-of-preallocated-extent.patch [new file with mode: 0644]
queue-6.2/udf-preserve-link-count-of-system-files.patch [new file with mode: 0644]
queue-6.2/udf-truncate-added-extents-on-failed-expansion.patch [new file with mode: 0644]

diff --git a/queue-6.2/exfat-fix-inode-i_blocks-for-non-512-byte-sector-size-device.patch b/queue-6.2/exfat-fix-inode-i_blocks-for-non-512-byte-sector-size-device.patch
new file mode 100644 (file)
index 0000000..3ef8c3b
--- /dev/null
@@ -0,0 +1,83 @@
+From 39c1ce8eafc0ff64fb9e28536ccc7df6a8e2999d Mon Sep 17 00:00:00 2001
+From: Yuezhang Mo <Yuezhang.Mo@sony.com>
+Date: Wed, 4 Jan 2023 14:37:47 +0800
+Subject: exfat: fix inode->i_blocks for non-512 byte sector size device
+
+From: Yuezhang Mo <Yuezhang.Mo@sony.com>
+
+commit 39c1ce8eafc0ff64fb9e28536ccc7df6a8e2999d upstream.
+
+inode->i_blocks is not real number of blocks, but 512 byte ones.
+
+Fixes: 98d917047e8b ("exfat: add file operations")
+Cc: stable@vger.kernel.org # v5.7+
+Reported-by: Wang Yugui <wangyugui@e16-tech.com>
+Tested-by: Wang Yugui <wangyugui@e16-tech.com>
+Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
+Reviewed-by: Andy Wu <Andy.Wu@sony.com>
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/exfat/file.c  |    3 +--
+ fs/exfat/inode.c |    6 ++----
+ fs/exfat/namei.c |    2 +-
+ fs/exfat/super.c |    3 +--
+ 4 files changed, 5 insertions(+), 9 deletions(-)
+
+--- a/fs/exfat/file.c
++++ b/fs/exfat/file.c
+@@ -209,8 +209,7 @@ void exfat_truncate(struct inode *inode)
+       if (err)
+               goto write_size;
+-      inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >>
+-                              inode->i_blkbits;
++      inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >> 9;
+ write_size:
+       aligned_size = i_size_read(inode);
+       if (aligned_size & (blocksize - 1)) {
+--- a/fs/exfat/inode.c
++++ b/fs/exfat/inode.c
+@@ -220,8 +220,7 @@ static int exfat_map_cluster(struct inod
+               num_clusters += num_to_be_allocated;
+               *clu = new_clu.dir;
+-              inode->i_blocks +=
+-                      num_to_be_allocated << sbi->sect_per_clus_bits;
++              inode->i_blocks += EXFAT_CLU_TO_B(num_to_be_allocated, sbi) >> 9;
+               /*
+                * Move *clu pointer along FAT chains (hole care) because the
+@@ -576,8 +575,7 @@ static int exfat_fill_inode(struct inode
+       exfat_save_attr(inode, info->attr);
+-      inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >>
+-                              inode->i_blkbits;
++      inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >> 9;
+       inode->i_mtime = info->mtime;
+       inode->i_ctime = info->mtime;
+       ei->i_crtime = info->crtime;
+--- a/fs/exfat/namei.c
++++ b/fs/exfat/namei.c
+@@ -396,7 +396,7 @@ static int exfat_find_empty_entry(struct
+               ei->i_size_ondisk += sbi->cluster_size;
+               ei->i_size_aligned += sbi->cluster_size;
+               ei->flags = p_dir->flags;
+-              inode->i_blocks += 1 << sbi->sect_per_clus_bits;
++              inode->i_blocks += sbi->cluster_size >> 9;
+       }
+       return dentry;
+--- a/fs/exfat/super.c
++++ b/fs/exfat/super.c
+@@ -373,8 +373,7 @@ static int exfat_read_root(struct inode
+       inode->i_op = &exfat_dir_inode_operations;
+       inode->i_fop = &exfat_dir_operations;
+-      inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >>
+-                              inode->i_blkbits;
++      inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >> 9;
+       ei->i_pos = ((loff_t)sbi->root_dir << 32) | 0xffffffff;
+       ei->i_size_aligned = i_size_read(inode);
+       ei->i_size_ondisk = i_size_read(inode);
diff --git a/queue-6.2/exfat-fix-reporting-fs-error-when-reading-dir-beyond-eof.patch b/queue-6.2/exfat-fix-reporting-fs-error-when-reading-dir-beyond-eof.patch
new file mode 100644 (file)
index 0000000..bd137d4
--- /dev/null
@@ -0,0 +1,49 @@
+From 706fdcac002316893434d753be8cfb549fe1d40d Mon Sep 17 00:00:00 2001
+From: Yuezhang Mo <Yuezhang.Mo@sony.com>
+Date: Thu, 20 Oct 2022 14:27:37 +0800
+Subject: exfat: fix reporting fs error when reading dir beyond EOF
+
+From: Yuezhang Mo <Yuezhang.Mo@sony.com>
+
+commit 706fdcac002316893434d753be8cfb549fe1d40d upstream.
+
+Since seekdir() does not check whether the position is valid, the
+position may exceed the size of the directory. We found that for
+a directory with discontinuous clusters, if the position exceeds
+the size of the directory and the excess size is greater than or
+equal to the cluster size, exfat_readdir() will return -EIO,
+causing a file system error and making the file system unavailable.
+
+Reproduce this bug by:
+
+seekdir(dir, dir_size + cluster_size);
+dirent = readdir(dir);
+
+The following log will be printed if mount with 'errors=remount-ro'.
+
+[11166.712896] exFAT-fs (sdb1): error, invalid access to FAT (entry 0xffffffff)
+[11166.712905] exFAT-fs (sdb1): Filesystem has been set read-only
+
+Fixes: 1e5654de0f51 ("exfat: handle wrong stream entry size in exfat_readdir()")
+Cc: stable@vger.kernel.org # v5.7+
+Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
+Reviewed-by: Andy Wu <Andy.Wu@sony.com>
+Reviewed-by: Aoyama Wataru <wataru.aoyama@sony.com>
+Reviewed-by: Sungjong Seo <sj1557.seo@samsung.com>
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/exfat/dir.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/exfat/dir.c
++++ b/fs/exfat/dir.c
+@@ -100,7 +100,7 @@ static int exfat_readdir(struct inode *i
+                       clu.dir = ei->hint_bmap.clu;
+               }
+-              while (clu_offset > 0) {
++              while (clu_offset > 0 && clu.dir != EXFAT_EOF_CLUSTER) {
+                       if (exfat_get_next_cluster(sb, &(clu.dir)))
+                               return -EIO;
diff --git a/queue-6.2/exfat-fix-unexpected-eof-while-reading-dir.patch b/queue-6.2/exfat-fix-unexpected-eof-while-reading-dir.patch
new file mode 100644 (file)
index 0000000..d346ea3
--- /dev/null
@@ -0,0 +1,49 @@
+From 6cb5d1a16a51d080fbc1649a5144cbc5ca7d6f88 Mon Sep 17 00:00:00 2001
+From: Yuezhang Mo <Yuezhang.Mo@sony.com>
+Date: Thu, 22 Sep 2022 14:43:47 +0800
+Subject: exfat: fix unexpected EOF while reading dir
+
+From: Yuezhang Mo <Yuezhang.Mo@sony.com>
+
+commit 6cb5d1a16a51d080fbc1649a5144cbc5ca7d6f88 upstream.
+
+If the position is not aligned with the dentry size, the return
+value of readdir() will be NULL and errno is 0, which means the
+end of the directory stream is reached.
+
+If the position is aligned with dentry size, but there is no file
+or directory at the position, exfat_readdir() will continue to
+get dentry from the next dentry. So the dentry gotten by readdir()
+may not be at the position.
+
+After this commit, if the position is not aligned with the dentry
+size, round the position up to the dentry size and continue to get
+the dentry.
+
+Fixes: ca06197382bd ("exfat: add directory operations")
+Cc: stable@vger.kernel.org # v5.7+
+Reported-by: Wang Yugui <wangyugui@e16-tech.com>
+Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
+Reviewed-by: Andy Wu <Andy.Wu@sony.com>
+Reviewed-by: Aoyama Wataru <wataru.aoyama@sony.com>
+Reviewed-by: Sungjong Seo <sj1557.seo@samsung.com>
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/exfat/dir.c |    5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+--- a/fs/exfat/dir.c
++++ b/fs/exfat/dir.c
+@@ -234,10 +234,7 @@ static int exfat_iterate(struct file *fi
+               fake_offset = 1;
+       }
+-      if (cpos & (DENTRY_SIZE - 1)) {
+-              err = -ENOENT;
+-              goto unlock;
+-      }
++      cpos = round_up(cpos, DENTRY_SIZE);
+       /* name buffer should be allocated before use */
+       err = exfat_alloc_namebuf(nb);
diff --git a/queue-6.2/exfat-redefine-dir_deleted-as-the-bad-cluster-number.patch b/queue-6.2/exfat-redefine-dir_deleted-as-the-bad-cluster-number.patch
new file mode 100644 (file)
index 0000000..f0c2147
--- /dev/null
@@ -0,0 +1,38 @@
+From bdaadfd343e3cba49ad0b009ff4b148dad0fa404 Mon Sep 17 00:00:00 2001
+From: Sungjong Seo <sj1557.seo@samsung.com>
+Date: Thu, 29 Dec 2022 20:52:38 +0900
+Subject: exfat: redefine DIR_DELETED as the bad cluster number
+
+From: Sungjong Seo <sj1557.seo@samsung.com>
+
+commit bdaadfd343e3cba49ad0b009ff4b148dad0fa404 upstream.
+
+When a file or a directory is deleted, the hint for the cluster of
+its parent directory in its in-memory inode is set as DIR_DELETED.
+Therefore, DIR_DELETED must be one of invalid cluster numbers. According
+to the exFAT specification, a volume can have at most 2^32-11 clusters.
+However, DIR_DELETED is wrongly defined as 0xFFFF0321, which could be
+a valid cluster number. To fix it, let's redefine DIR_DELETED as
+0xFFFFFFF7, the bad cluster number.
+
+Fixes: 1acf1a564b60 ("exfat: add in-memory and on-disk structures and headers")
+Cc: stable@vger.kernel.org # v5.7+
+Reported-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
+Signed-off-by: Sungjong Seo <sj1557.seo@samsung.com>
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/exfat/exfat_fs.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/exfat/exfat_fs.h
++++ b/fs/exfat/exfat_fs.h
+@@ -50,7 +50,7 @@ enum {
+ #define ES_IDX_LAST_FILENAME(name_len)        \
+       (ES_IDX_FIRST_FILENAME + EXFAT_FILENAME_ENTRY_NUM(name_len) - 1)
+-#define DIR_DELETED           0xFFFF0321
++#define DIR_DELETED           0xFFFFFFF7
+ /* type values */
+ #define TYPE_UNUSED           0x0000
diff --git a/queue-6.2/f2fs-fix-cgroup-writeback-accounting-with-fs-layer-encryption.patch b/queue-6.2/f2fs-fix-cgroup-writeback-accounting-with-fs-layer-encryption.patch
new file mode 100644 (file)
index 0000000..5281c90
--- /dev/null
@@ -0,0 +1,63 @@
+From 844545c51a5b2a524b22a2fe9d0b353b827d24b4 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Thu, 2 Feb 2023 17:02:39 -0800
+Subject: f2fs: fix cgroup writeback accounting with fs-layer encryption
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit 844545c51a5b2a524b22a2fe9d0b353b827d24b4 upstream.
+
+When writing a page from an encrypted file that is using
+filesystem-layer encryption (not inline encryption), f2fs encrypts the
+pagecache page into a bounce page, then writes the bounce page.
+
+It also passes the bounce page to wbc_account_cgroup_owner().  That's
+incorrect, because the bounce page is a newly allocated temporary page
+that doesn't have the memory cgroup of the original pagecache page.
+This makes wbc_account_cgroup_owner() not account the I/O to the owner
+of the pagecache page as it should.
+
+Fix this by always passing the pagecache page to
+wbc_account_cgroup_owner().
+
+Fixes: 578c647879f7 ("f2fs: implement cgroup writeback support")
+Cc: stable@vger.kernel.org
+Reported-by: Matthew Wilcox (Oracle) <willy@infradead.org>
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Acked-by: Tejun Heo <tj@kernel.org>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/f2fs/data.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -741,7 +741,7 @@ int f2fs_submit_page_bio(struct f2fs_io_
+       }
+       if (fio->io_wbc && !is_read_io(fio->op))
+-              wbc_account_cgroup_owner(fio->io_wbc, page, PAGE_SIZE);
++              wbc_account_cgroup_owner(fio->io_wbc, fio->page, PAGE_SIZE);
+       inc_page_count(fio->sbi, is_read_io(fio->op) ?
+                       __read_io_type(page) : WB_DATA_TYPE(fio->page));
+@@ -948,7 +948,7 @@ alloc_new:
+       }
+       if (fio->io_wbc)
+-              wbc_account_cgroup_owner(fio->io_wbc, page, PAGE_SIZE);
++              wbc_account_cgroup_owner(fio->io_wbc, fio->page, PAGE_SIZE);
+       inc_page_count(fio->sbi, WB_DATA_TYPE(page));
+@@ -1022,7 +1022,7 @@ alloc_new:
+       }
+       if (fio->io_wbc)
+-              wbc_account_cgroup_owner(fio->io_wbc, bio_page, PAGE_SIZE);
++              wbc_account_cgroup_owner(fio->io_wbc, fio->page, PAGE_SIZE);
+       io->last_block_in_bio = fio->new_blkaddr;
diff --git a/queue-6.2/f2fs-fix-information-leak-in-f2fs_move_inline_dirents.patch b/queue-6.2/f2fs-fix-information-leak-in-f2fs_move_inline_dirents.patch
new file mode 100644 (file)
index 0000000..4e1f9a4
--- /dev/null
@@ -0,0 +1,56 @@
+From 9a5571cff4ffcfc24847df9fd545cc5799ac0ee5 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Sun, 22 Jan 2023 23:04:14 -0800
+Subject: f2fs: fix information leak in f2fs_move_inline_dirents()
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit 9a5571cff4ffcfc24847df9fd545cc5799ac0ee5 upstream.
+
+When converting an inline directory to a regular one, f2fs is leaking
+uninitialized memory to disk because it doesn't initialize the entire
+directory block.  Fix this by zero-initializing the block.
+
+This bug was introduced by commit 4ec17d688d74 ("f2fs: avoid unneeded
+initializing when converting inline dentry"), which didn't consider the
+security implications of leaking uninitialized memory to disk.
+
+This was found by running xfstest generic/435 on a KMSAN-enabled kernel.
+
+Fixes: 4ec17d688d74 ("f2fs: avoid unneeded initializing when converting inline dentry")
+Cc: <stable@vger.kernel.org> # v4.3+
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/f2fs/inline.c |   13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+--- a/fs/f2fs/inline.c
++++ b/fs/f2fs/inline.c
+@@ -422,18 +422,17 @@ static int f2fs_move_inline_dirents(stru
+       dentry_blk = page_address(page);
++      /*
++       * Start by zeroing the full block, to ensure that all unused space is
++       * zeroed and no uninitialized memory is leaked to disk.
++       */
++      memset(dentry_blk, 0, F2FS_BLKSIZE);
++
+       make_dentry_ptr_inline(dir, &src, inline_dentry);
+       make_dentry_ptr_block(dir, &dst, dentry_blk);
+       /* copy data from inline dentry block to new dentry block */
+       memcpy(dst.bitmap, src.bitmap, src.nr_bitmap);
+-      memset(dst.bitmap + src.nr_bitmap, 0, dst.nr_bitmap - src.nr_bitmap);
+-      /*
+-       * we do not need to zero out remainder part of dentry and filename
+-       * field, since we have used bitmap for marking the usage status of
+-       * them, besides, we can also ignore copying/zeroing reserved space
+-       * of dentry block, because them haven't been used so far.
+-       */
+       memcpy(dst.dentry, src.dentry, SIZE_OF_DIR_ENTRY * src.max);
+       memcpy(dst.filename, src.filename, src.max * F2FS_SLOT_LEN);
diff --git a/queue-6.2/f2fs-fix-kernel-crash-due-to-null-io-bio.patch b/queue-6.2/f2fs-fix-kernel-crash-due-to-null-io-bio.patch
new file mode 100644 (file)
index 0000000..6842fa1
--- /dev/null
@@ -0,0 +1,58 @@
+From 267c159f9c7bcb7009dae16889b880c5ed8759a8 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk@kernel.org>
+Date: Sun, 5 Feb 2023 19:13:39 -0800
+Subject: f2fs: fix kernel crash due to null io->bio
+
+From: Jaegeuk Kim <jaegeuk@kernel.org>
+
+commit 267c159f9c7bcb7009dae16889b880c5ed8759a8 upstream.
+
+We should return when io->bio is null before doing anything. Otherwise, panic.
+
+BUG: kernel NULL pointer dereference, address: 0000000000000010
+RIP: 0010:__submit_merged_write_cond+0x164/0x240 [f2fs]
+Call Trace:
+ <TASK>
+ f2fs_submit_merged_write+0x1d/0x30 [f2fs]
+ commit_checkpoint+0x110/0x1e0 [f2fs]
+ f2fs_write_checkpoint+0x9f7/0xf00 [f2fs]
+ ? __pfx_issue_checkpoint_thread+0x10/0x10 [f2fs]
+ __checkpoint_and_complete_reqs+0x84/0x190 [f2fs]
+ ? preempt_count_add+0x82/0xc0
+ ? __pfx_issue_checkpoint_thread+0x10/0x10 [f2fs]
+ issue_checkpoint_thread+0x4c/0xf0 [f2fs]
+ ? __pfx_autoremove_wake_function+0x10/0x10
+ kthread+0xff/0x130
+ ? __pfx_kthread+0x10/0x10
+ ret_from_fork+0x2c/0x50
+ </TASK>
+
+Cc: stable@vger.kernel.org # v5.18+
+Fixes: 64bf0eef0171 ("f2fs: pass the bio operation to bio_alloc_bioset")
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/f2fs/data.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -655,6 +655,9 @@ static void __f2fs_submit_merged_write(s
+       f2fs_down_write(&io->io_rwsem);
++      if (!io->bio)
++              goto unlock_out;
++
+       /* change META to META_FLUSH in the checkpoint procedure */
+       if (type >= META_FLUSH) {
+               io->fio.type = META_FLUSH;
+@@ -663,6 +666,7 @@ static void __f2fs_submit_merged_write(s
+                       io->bio->bi_opf |= REQ_PREFLUSH | REQ_FUA;
+       }
+       __submit_merged_bio(io);
++unlock_out:
+       f2fs_up_write(&io->io_rwsem);
+ }
diff --git a/queue-6.2/f2fs-retry-to-update-the-inode-page-given-data-corruption.patch b/queue-6.2/f2fs-retry-to-update-the-inode-page-given-data-corruption.patch
new file mode 100644 (file)
index 0000000..140444a
--- /dev/null
@@ -0,0 +1,53 @@
+From 3aa51c61cb4a4dcb40df51ac61171e9ac5a35321 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk@kernel.org>
+Date: Mon, 30 Jan 2023 15:20:09 -0800
+Subject: f2fs: retry to update the inode page given data corruption
+
+From: Jaegeuk Kim <jaegeuk@kernel.org>
+
+commit 3aa51c61cb4a4dcb40df51ac61171e9ac5a35321 upstream.
+
+If the storage gives a corrupted node block due to short power failure and
+reset, f2fs stops the entire operations by setting the checkpoint failure flag.
+
+Let's give more chances to live by re-issuing IOs for a while in such critical
+path.
+
+Cc: stable@vger.kernel.org
+Suggested-by: Randall Huang <huangrandall@google.com>
+Suggested-by: Chao Yu <chao@kernel.org>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/f2fs/inode.c |   13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+--- a/fs/f2fs/inode.c
++++ b/fs/f2fs/inode.c
+@@ -714,18 +714,19 @@ void f2fs_update_inode_page(struct inode
+ {
+       struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+       struct page *node_page;
++      int count = 0;
+ retry:
+       node_page = f2fs_get_node_page(sbi, inode->i_ino);
+       if (IS_ERR(node_page)) {
+               int err = PTR_ERR(node_page);
+-              if (err == -ENOMEM) {
+-                      cond_resched();
++              /* The node block was truncated. */
++              if (err == -ENOENT)
++                      return;
++
++              if (err == -ENOMEM || ++count <= DEFAULT_RETRY_IO_COUNT)
+                       goto retry;
+-              } else if (err != -ENOENT) {
+-                      f2fs_stop_checkpoint(sbi, false,
+-                                      STOP_CP_REASON_UPDATE_INODE);
+-              }
++              f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_UPDATE_INODE);
+               return;
+       }
+       f2fs_update_inode(inode, node_page);
diff --git a/queue-6.2/f2fs-revert-f2fs-truncate-blocks-in-batch-in-__complete_revoke_list.patch b/queue-6.2/f2fs-revert-f2fs-truncate-blocks-in-batch-in-__complete_revoke_list.patch
new file mode 100644 (file)
index 0000000..ff0e9fc
--- /dev/null
@@ -0,0 +1,51 @@
+From c7dbc06688292db34c1bb9c715e29ac4935af994 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk@kernel.org>
+Date: Tue, 14 Feb 2023 15:53:52 -0800
+Subject: f2fs: Revert "f2fs: truncate blocks in batch in __complete_revoke_list()"
+
+From: Jaegeuk Kim <jaegeuk@kernel.org>
+
+commit c7dbc06688292db34c1bb9c715e29ac4935af994 upstream.
+
+We should not truncate replaced blocks, and were supposed to truncate the first
+part as well.
+
+This reverts commit 78a99fe6254cad4be310cd84af39f6c46b668c72.
+
+Cc: stable@vger.kernel.org
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/f2fs/segment.c |    9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -262,19 +262,24 @@ static void __complete_revoke_list(struc
+                                       bool revoke)
+ {
+       struct revoke_entry *cur, *tmp;
++      pgoff_t start_index = 0;
+       bool truncate = is_inode_flag_set(inode, FI_ATOMIC_REPLACE);
+       list_for_each_entry_safe(cur, tmp, head, list) {
+-              if (revoke)
++              if (revoke) {
+                       __replace_atomic_write_block(inode, cur->index,
+                                               cur->old_addr, NULL, true);
++              } else if (truncate) {
++                      f2fs_truncate_hole(inode, start_index, cur->index);
++                      start_index = cur->index + 1;
++              }
+               list_del(&cur->list);
+               kmem_cache_free(revoke_entry_slab, cur);
+       }
+       if (!revoke && truncate)
+-              f2fs_do_truncate_blocks(inode, 0, false);
++              f2fs_do_truncate_blocks(inode, start_index * PAGE_SIZE, false);
+ }
+ static int __f2fs_commit_atomic_write(struct inode *inode)
diff --git a/queue-6.2/fs-cramfs-inode.c-initialize-file_ra_state.patch b/queue-6.2/fs-cramfs-inode.c-initialize-file_ra_state.patch
new file mode 100644 (file)
index 0000000..4e30946
--- /dev/null
@@ -0,0 +1,35 @@
+From 3e35102666f873a135d31a726ac1ec8af4905206 Mon Sep 17 00:00:00 2001
+From: Andrew Morton <akpm@linux-foundation.org>
+Date: Sun, 26 Feb 2023 12:31:11 -0800
+Subject: fs/cramfs/inode.c: initialize file_ra_state
+
+From: Andrew Morton <akpm@linux-foundation.org>
+
+commit 3e35102666f873a135d31a726ac1ec8af4905206 upstream.
+
+file_ra_state_init() assumes that the file_ra_state has been zeroed out.
+Fixes a KMSAN used-unintialized issue (at least).
+
+Fixes: cf948cbc35e80 ("cramfs: read_mapping_page() is synchronous")
+Reported-by: syzbot <syzbot+8ce7f8308d91e6b8bbe2@syzkaller.appspotmail.com>
+  Link: https://lkml.kernel.org/r/0000000000008f74e905f56df987@google.com
+Cc: Matthew Wilcox <willy@infradead.org>
+Cc: Nicolas Pitre <nico@fluxnic.net>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cramfs/inode.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/cramfs/inode.c
++++ b/fs/cramfs/inode.c
+@@ -183,7 +183,7 @@ static void *cramfs_blkdev_read(struct s
+                               unsigned int len)
+ {
+       struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping;
+-      struct file_ra_state ra;
++      struct file_ra_state ra = {};
+       struct page *pages[BLKS_PER_BUF];
+       unsigned i, blocknr, buffer;
+       unsigned long devsize;
diff --git a/queue-6.2/fs-dlm-be-sure-to-call-dlm_send_queue_flush.patch b/queue-6.2/fs-dlm-be-sure-to-call-dlm_send_queue_flush.patch
new file mode 100644 (file)
index 0000000..971757c
--- /dev/null
@@ -0,0 +1,34 @@
+From 7354fa4ef697191effedc2ae9a8293427708bbf5 Mon Sep 17 00:00:00 2001
+From: Alexander Aring <aahringo@redhat.com>
+Date: Thu, 12 Jan 2023 17:10:33 -0500
+Subject: fs: dlm: be sure to call dlm_send_queue_flush()
+
+From: Alexander Aring <aahringo@redhat.com>
+
+commit 7354fa4ef697191effedc2ae9a8293427708bbf5 upstream.
+
+If we release a midcomms node structure, there should be nothing left
+inside the dlm midcomms send queue. However, sometimes this is not true
+because I believe some DLM_FIN message was not acked... if we run
+into a shutdown timeout, then we should be sure there is no pending send
+dlm message inside this queue when releasing midcomms node structure.
+
+Cc: stable@vger.kernel.org
+Fixes: 489d8e559c65 ("fs: dlm: add reliable connection if reconnect")
+Signed-off-by: Alexander Aring <aahringo@redhat.com>
+Signed-off-by: David Teigland <teigland@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/dlm/midcomms.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/dlm/midcomms.c
++++ b/fs/dlm/midcomms.c
+@@ -1402,6 +1402,7 @@ static void midcomms_node_release(struct
+       struct midcomms_node *node = container_of(rcu, struct midcomms_node, rcu);
+       WARN_ON_ONCE(atomic_read(&node->send_queue_cnt));
++      dlm_send_queue_flush(node);
+       kfree(node);
+ }
diff --git a/queue-6.2/fs-dlm-don-t-set-stop-rx-flag-after-node-reset.patch b/queue-6.2/fs-dlm-don-t-set-stop-rx-flag-after-node-reset.patch
new file mode 100644 (file)
index 0000000..926bbb7
--- /dev/null
@@ -0,0 +1,47 @@
+From 15c63db8e86a72e0d5cfb9bf0cd1870e39a3e5fe Mon Sep 17 00:00:00 2001
+From: Alexander Aring <aahringo@redhat.com>
+Date: Thu, 12 Jan 2023 17:10:35 -0500
+Subject: fs: dlm: don't set stop rx flag after node reset
+
+From: Alexander Aring <aahringo@redhat.com>
+
+commit 15c63db8e86a72e0d5cfb9bf0cd1870e39a3e5fe upstream.
+
+Similar to the stop tx flag, the rx flag should warn about a dlm message
+being received at DLM_FIN state change, when we are assuming no other
+dlm application messages. If we receive a FIN message and we are in the
+state DLM_FIN_WAIT2 we call midcomms_node_reset() which puts the
+midcomms node into DLM_CLOSED state. Afterwards we should not set the
+DLM_NODE_FLAG_STOP_RX flag any more.  This patch changes the setting
+DLM_NODE_FLAG_STOP_RX in those state changes when we receive a FIN
+message and we assume there will be no other dlm application messages
+received until we hit DLM_CLOSED state.
+
+Cc: stable@vger.kernel.org
+Fixes: 489d8e559c65 ("fs: dlm: add reliable connection if reconnect")
+Signed-off-by: Alexander Aring <aahringo@redhat.com>
+Signed-off-by: David Teigland <teigland@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/dlm/midcomms.c |    3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/fs/dlm/midcomms.c
++++ b/fs/dlm/midcomms.c
+@@ -524,6 +524,7 @@ static void dlm_midcomms_receive_buffer(
+                               break;
+                       case DLM_FIN_WAIT1:
+                               node->state = DLM_CLOSING;
++                              set_bit(DLM_NODE_FLAG_STOP_RX, &node->flags);
+                               pr_debug("switch node %d to state %s\n",
+                                        node->nodeid, dlm_state_str(node->state));
+                               break;
+@@ -544,8 +545,6 @@ static void dlm_midcomms_receive_buffer(
+                               return;
+                       }
+                       spin_unlock(&node->state_lock);
+-
+-                      set_bit(DLM_NODE_FLAG_STOP_RX, &node->flags);
+                       break;
+               default:
+                       WARN_ON_ONCE(test_bit(DLM_NODE_FLAG_STOP_RX, &node->flags));
diff --git a/queue-6.2/fs-dlm-fix-race-setting-stop-tx-flag.patch b/queue-6.2/fs-dlm-fix-race-setting-stop-tx-flag.patch
new file mode 100644 (file)
index 0000000..37f3edd
--- /dev/null
@@ -0,0 +1,45 @@
+From 164272113b685927126c938b4a9cbd2075eb15ee Mon Sep 17 00:00:00 2001
+From: Alexander Aring <aahringo@redhat.com>
+Date: Thu, 12 Jan 2023 17:10:34 -0500
+Subject: fs: dlm: fix race setting stop tx flag
+
+From: Alexander Aring <aahringo@redhat.com>
+
+commit 164272113b685927126c938b4a9cbd2075eb15ee upstream.
+
+This patch sets the stop tx flag before we commit the dlm message.
+This flag will report about unexpected transmissions after we
+send the DLM_FIN message out, which should be the last message sent.
+When we commit the dlm fin message, it could be that we already
+got an ack back and the CLOSED state change already happened.
+We should not set this flag when we are in CLOSED state. To avoid this
+race we simply set the tx flag before the state change can be in
+progress by moving it before dlm_midcomms_commit_mhandle().
+
+Cc: stable@vger.kernel.org
+Fixes: 489d8e559c65 ("fs: dlm: add reliable connection if reconnect")
+Signed-off-by: Alexander Aring <aahringo@redhat.com>
+Signed-off-by: David Teigland <teigland@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/dlm/midcomms.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/dlm/midcomms.c
++++ b/fs/dlm/midcomms.c
+@@ -406,6 +406,7 @@ static int dlm_send_fin(struct midcomms_
+       if (!mh)
+               return -ENOMEM;
++      set_bit(DLM_NODE_FLAG_STOP_TX, &node->flags);
+       mh->ack_rcv = ack_rcv;
+       m_header = (struct dlm_header *)ppc;
+@@ -417,7 +418,6 @@ static int dlm_send_fin(struct midcomms_
+       pr_debug("sending fin msg to node %d\n", node->nodeid);
+       dlm_midcomms_commit_mhandle(mh, NULL, 0);
+-      set_bit(DLM_NODE_FLAG_STOP_TX, &node->flags);
+       return 0;
+ }
diff --git a/queue-6.2/fs-dlm-fix-use-after-free-in-midcomms-commit.patch b/queue-6.2/fs-dlm-fix-use-after-free-in-midcomms-commit.patch
new file mode 100644 (file)
index 0000000..93eb519
--- /dev/null
@@ -0,0 +1,178 @@
+From 724b6bab0d75f1dc01fdfbf7fe8d4217a5cb90ba Mon Sep 17 00:00:00 2001
+From: Alexander Aring <aahringo@redhat.com>
+Date: Thu, 12 Jan 2023 17:10:32 -0500
+Subject: fs: dlm: fix use after free in midcomms commit
+
+From: Alexander Aring <aahringo@redhat.com>
+
+commit 724b6bab0d75f1dc01fdfbf7fe8d4217a5cb90ba upstream.
+
+While working on processing dlm message in softirq context I experienced
+the following KASAN use-after-free warning:
+
+[  151.760477] ==================================================================
+[  151.761803] BUG: KASAN: use-after-free in dlm_midcomms_commit_mhandle+0x19d/0x4b0
+[  151.763414] Read of size 4 at addr ffff88811a980c60 by task lock_torture/1347
+
+[  151.765284] CPU: 7 PID: 1347 Comm: lock_torture Not tainted 6.1.0-rc4+ #2828
+[  151.766778] Hardware name: Red Hat KVM/RHEL-AV, BIOS 1.16.0-3.module+el8.7.0+16134+e5908aa2 04/01/2014
+[  151.768726] Call Trace:
+[  151.769277]  <TASK>
+[  151.769748]  dump_stack_lvl+0x5b/0x86
+[  151.770556]  print_report+0x180/0x4c8
+[  151.771378]  ? kasan_complete_mode_report_info+0x7c/0x1e0
+[  151.772241]  ? dlm_midcomms_commit_mhandle+0x19d/0x4b0
+[  151.773069]  kasan_report+0x93/0x1a0
+[  151.773668]  ? dlm_midcomms_commit_mhandle+0x19d/0x4b0
+[  151.774514]  __asan_load4+0x7e/0xa0
+[  151.775089]  dlm_midcomms_commit_mhandle+0x19d/0x4b0
+[  151.775890]  ? create_message.isra.29.constprop.64+0x57/0xc0
+[  151.776770]  send_common+0x19f/0x1b0
+[  151.777342]  ? remove_from_waiters+0x60/0x60
+[  151.778017]  ? lock_downgrade+0x410/0x410
+[  151.778648]  ? __this_cpu_preempt_check+0x13/0x20
+[  151.779421]  ? rcu_lockdep_current_cpu_online+0x88/0xc0
+[  151.780292]  _convert_lock+0x46/0x150
+[  151.780893]  convert_lock+0x7b/0xc0
+[  151.781459]  dlm_lock+0x3ac/0x580
+[  151.781993]  ? 0xffffffffc0540000
+[  151.782522]  ? torture_stop+0x120/0x120 [dlm_locktorture]
+[  151.783379]  ? dlm_scan_rsbs+0xa70/0xa70
+[  151.784003]  ? preempt_count_sub+0xd6/0x130
+[  151.784661]  ? is_module_address+0x47/0x70
+[  151.785309]  ? torture_stop+0x120/0x120 [dlm_locktorture]
+[  151.786166]  ? 0xffffffffc0540000
+[  151.786693]  ? lockdep_init_map_type+0xc3/0x360
+[  151.787414]  ? 0xffffffffc0540000
+[  151.787947]  torture_dlm_lock_sync.isra.3+0xe9/0x150 [dlm_locktorture]
+[  151.789004]  ? torture_stop+0x120/0x120 [dlm_locktorture]
+[  151.789858]  ? 0xffffffffc0540000
+[  151.790392]  ? lock_torture_cleanup+0x20/0x20 [dlm_locktorture]
+[  151.791347]  ? delay_tsc+0x94/0xc0
+[  151.791898]  torture_ex_iter+0xc3/0xea [dlm_locktorture]
+[  151.792735]  ? torture_start+0x30/0x30 [dlm_locktorture]
+[  151.793606]  lock_torture+0x177/0x270 [dlm_locktorture]
+[  151.794448]  ? torture_dlm_lock_sync.isra.3+0x150/0x150 [dlm_locktorture]
+[  151.795539]  ? lock_torture_stats+0x80/0x80 [dlm_locktorture]
+[  151.796476]  ? do_raw_spin_lock+0x11e/0x1e0
+[  151.797152]  ? mark_held_locks+0x34/0xb0
+[  151.797784]  ? _raw_spin_unlock_irqrestore+0x30/0x70
+[  151.798581]  ? __kthread_parkme+0x79/0x110
+[  151.799246]  ? trace_preempt_on+0x2a/0xf0
+[  151.799902]  ? __kthread_parkme+0x79/0x110
+[  151.800579]  ? preempt_count_sub+0xd6/0x130
+[  151.801271]  ? __kasan_check_read+0x11/0x20
+[  151.801963]  ? __kthread_parkme+0xec/0x110
+[  151.802630]  ? lock_torture_stats+0x80/0x80 [dlm_locktorture]
+[  151.803569]  kthread+0x192/0x1d0
+[  151.804104]  ? kthread_complete_and_exit+0x30/0x30
+[  151.804881]  ret_from_fork+0x1f/0x30
+[  151.805480]  </TASK>
+
+[  151.806111] Allocated by task 1347:
+[  151.806681]  kasan_save_stack+0x26/0x50
+[  151.807308]  kasan_set_track+0x25/0x30
+[  151.807920]  kasan_save_alloc_info+0x1e/0x30
+[  151.808609]  __kasan_slab_alloc+0x63/0x80
+[  151.809263]  kmem_cache_alloc+0x1ad/0x830
+[  151.809916]  dlm_allocate_mhandle+0x17/0x20
+[  151.810590]  dlm_midcomms_get_mhandle+0x96/0x260
+[  151.811344]  _create_message+0x95/0x180
+[  151.811994]  create_message.isra.29.constprop.64+0x57/0xc0
+[  151.812880]  send_common+0x129/0x1b0
+[  151.813467]  _convert_lock+0x46/0x150
+[  151.814074]  convert_lock+0x7b/0xc0
+[  151.814648]  dlm_lock+0x3ac/0x580
+[  151.815199]  torture_dlm_lock_sync.isra.3+0xe9/0x150 [dlm_locktorture]
+[  151.816258]  torture_ex_iter+0xc3/0xea [dlm_locktorture]
+[  151.817129]  lock_torture+0x177/0x270 [dlm_locktorture]
+[  151.817986]  kthread+0x192/0x1d0
+[  151.818518]  ret_from_fork+0x1f/0x30
+
+[  151.819369] Freed by task 1336:
+[  151.819890]  kasan_save_stack+0x26/0x50
+[  151.820514]  kasan_set_track+0x25/0x30
+[  151.821128]  kasan_save_free_info+0x2e/0x50
+[  151.821812]  __kasan_slab_free+0x107/0x1a0
+[  151.822483]  kmem_cache_free+0x204/0x5e0
+[  151.823152]  dlm_free_mhandle+0x18/0x20
+[  151.823781]  dlm_mhandle_release+0x2e/0x40
+[  151.824454]  rcu_core+0x583/0x1330
+[  151.825047]  rcu_core_si+0xe/0x20
+[  151.825594]  __do_softirq+0xf4/0x5c2
+
+[  151.826450] Last potentially related work creation:
+[  151.827238]  kasan_save_stack+0x26/0x50
+[  151.827870]  __kasan_record_aux_stack+0xa2/0xc0
+[  151.828609]  kasan_record_aux_stack_noalloc+0xb/0x20
+[  151.829415]  call_rcu+0x4c/0x760
+[  151.829954]  dlm_mhandle_delete+0x97/0xb0
+[  151.830718]  dlm_process_incoming_buffer+0x2fc/0xb30
+[  151.831524]  process_dlm_messages+0x16e/0x470
+[  151.832245]  process_one_work+0x505/0xa10
+[  151.832905]  worker_thread+0x67/0x650
+[  151.833507]  kthread+0x192/0x1d0
+[  151.834046]  ret_from_fork+0x1f/0x30
+
+[  151.834900] The buggy address belongs to the object at ffff88811a980c30
+                which belongs to the cache dlm_mhandle of size 88
+[  151.836894] The buggy address is located 48 bytes inside of
+                88-byte region [ffff88811a980c30, ffff88811a980c88)
+
+[  151.839007] The buggy address belongs to the physical page:
+[  151.839904] page:0000000076cf5d62 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x11a980
+[  151.841378] flags: 0x8000000000000200(slab|zone=2)
+[  151.842141] raw: 8000000000000200 0000000000000000 dead000000000122 ffff8881089b43c0
+[  151.843401] raw: 0000000000000000 0000000000220022 00000001ffffffff 0000000000000000
+[  151.844640] page dumped because: kasan: bad access detected
+
+[  151.845822] Memory state around the buggy address:
+[  151.846602]  ffff88811a980b00: fb fb fb fb fc fc fc fc fa fb fb fb fb fb fb fb
+[  151.847761]  ffff88811a980b80: fb fb fb fc fc fc fc fa fb fb fb fb fb fb fb fb
+[  151.848921] >ffff88811a980c00: fb fb fc fc fc fc fa fb fb fb fb fb fb fb fb fb
+[  151.850076]                                                        ^
+[  151.851085]  ffff88811a980c80: fb fc fc fc fc fa fb fb fb fb fb fb fb fb fb fb
+[  151.852269]  ffff88811a980d00: fc fc fc fc fa fb fb fb fb fb fb fb fb fb fb fc
+[  151.853428] ==================================================================
+[  151.855618] Disabling lock debugging due to kernel taint
+
+It is accessing a mhandle in dlm_midcomms_commit_mhandle() and the mhandle
+was freed by a call_rcu() call in dlm_process_incoming_buffer(),
+dlm_mhandle_delete(). It looks like it was freed because an ack of
+this message was received. There is a short race between committing the
+dlm message to be transmitted and getting an ack back. If the ack is
+faster than returning from dlm_midcomms_commit_msg_3_2(), then we run
+into a use-after free because we still need to reference the mhandle when
+calling srcu_read_unlock().
+
+To avoid that, we don't allow that mhandle to be freed between
+dlm_midcomms_commit_msg_3_2() and srcu_read_unlock() by using rcu read
+lock. We can do that because mhandle is protected by rcu handling.
+
+Cc: stable@vger.kernel.org
+Fixes: 489d8e559c65 ("fs: dlm: add reliable connection if reconnect")
+Signed-off-by: Alexander Aring <aahringo@redhat.com>
+Signed-off-by: David Teigland <teigland@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/dlm/midcomms.c |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/fs/dlm/midcomms.c
++++ b/fs/dlm/midcomms.c
+@@ -1214,8 +1214,15 @@ void dlm_midcomms_commit_mhandle(struct
+               dlm_free_mhandle(mh);
+               break;
+       case DLM_VERSION_3_2:
++              /* held rcu read lock here, because we sending the
++               * dlm message out, when we do that we could receive
++               * an ack back which releases the mhandle and we
++               * get a use after free.
++               */
++              rcu_read_lock();
+               dlm_midcomms_commit_msg_3_2(mh, name, namelen);
+               srcu_read_unlock(&nodes_srcu, mh->idx);
++              rcu_read_unlock();
+               break;
+       default:
+               srcu_read_unlock(&nodes_srcu, mh->idx);
diff --git a/queue-6.2/fs-dlm-move-sending-fin-message-into-state-change-handling.patch b/queue-6.2/fs-dlm-move-sending-fin-message-into-state-change-handling.patch
new file mode 100644 (file)
index 0000000..495ba5c
--- /dev/null
@@ -0,0 +1,109 @@
+From a58496361802070996f9bd76e941d109c4a85ebd Mon Sep 17 00:00:00 2001
+From: Alexander Aring <aahringo@redhat.com>
+Date: Thu, 12 Jan 2023 17:10:36 -0500
+Subject: fs: dlm: move sending fin message into state change handling
+
+From: Alexander Aring <aahringo@redhat.com>
+
+commit a58496361802070996f9bd76e941d109c4a85ebd upstream.
+
+This patch moves the send fin handling, which should appear in a specific
+state change, into the state change handling while the per node
+state_lock is held. I experienced issues with other messages because
+we changed the state and a fin message was sent out in a different state.
+
+Cc: stable@vger.kernel.org
+Fixes: 489d8e559c65 ("fs: dlm: add reliable connection if reconnect")
+Signed-off-by: Alexander Aring <aahringo@redhat.com>
+Signed-off-by: David Teigland <teigland@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/dlm/midcomms.c |   33 +++++++++------------------------
+ 1 file changed, 9 insertions(+), 24 deletions(-)
+
+--- a/fs/dlm/midcomms.c
++++ b/fs/dlm/midcomms.c
+@@ -402,7 +402,7 @@ static int dlm_send_fin(struct midcomms_
+       struct dlm_mhandle *mh;
+       char *ppc;
+-      mh = dlm_midcomms_get_mhandle(node->nodeid, mb_len, GFP_NOFS, &ppc);
++      mh = dlm_midcomms_get_mhandle(node->nodeid, mb_len, GFP_ATOMIC, &ppc);
+       if (!mh)
+               return -ENOMEM;
+@@ -518,8 +518,8 @@ static void dlm_midcomms_receive_buffer(
+                                       node->state = DLM_LAST_ACK;
+                                       pr_debug("switch node %d to state %s case 1\n",
+                                                node->nodeid, dlm_state_str(node->state));
+-                                      spin_unlock(&node->state_lock);
+-                                      goto send_fin;
++                                      set_bit(DLM_NODE_FLAG_STOP_RX, &node->flags);
++                                      dlm_send_fin(node, dlm_pas_fin_ack_rcv);
+                               }
+                               break;
+                       case DLM_FIN_WAIT1:
+@@ -563,12 +563,6 @@ static void dlm_midcomms_receive_buffer(
+               log_print_ratelimited("ignore dlm msg because seq mismatch, seq: %u, expected: %u, nodeid: %d",
+                                     seq, node->seq_next, node->nodeid);
+       }
+-
+-      return;
+-
+-send_fin:
+-      set_bit(DLM_NODE_FLAG_STOP_RX, &node->flags);
+-      dlm_send_fin(node, dlm_pas_fin_ack_rcv);
+ }
+ static struct midcomms_node *
+@@ -1368,11 +1362,11 @@ void dlm_midcomms_remove_member(int node
+               case DLM_CLOSE_WAIT:
+                       /* passive shutdown DLM_LAST_ACK case 2 */
+                       node->state = DLM_LAST_ACK;
+-                      spin_unlock(&node->state_lock);
+-
+                       pr_debug("switch node %d to state %s case 2\n",
+                                node->nodeid, dlm_state_str(node->state));
+-                      goto send_fin;
++                      set_bit(DLM_NODE_FLAG_STOP_RX, &node->flags);
++                      dlm_send_fin(node, dlm_pas_fin_ack_rcv);
++                      break;
+               case DLM_LAST_ACK:
+                       /* probably receive fin caught it, do nothing */
+                       break;
+@@ -1388,12 +1382,6 @@ void dlm_midcomms_remove_member(int node
+       spin_unlock(&node->state_lock);
+       srcu_read_unlock(&nodes_srcu, idx);
+-      return;
+-
+-send_fin:
+-      set_bit(DLM_NODE_FLAG_STOP_RX, &node->flags);
+-      dlm_send_fin(node, dlm_pas_fin_ack_rcv);
+-      srcu_read_unlock(&nodes_srcu, idx);
+ }
+ static void midcomms_node_release(struct rcu_head *rcu)
+@@ -1425,6 +1413,7 @@ static void midcomms_shutdown(struct mid
+               node->state = DLM_FIN_WAIT1;
+               pr_debug("switch node %d to state %s case 2\n",
+                        node->nodeid, dlm_state_str(node->state));
++              dlm_send_fin(node, dlm_act_fin_ack_rcv);
+               break;
+       case DLM_CLOSED:
+               /* we have what we want */
+@@ -1438,12 +1427,8 @@ static void midcomms_shutdown(struct mid
+       }
+       spin_unlock(&node->state_lock);
+-      if (node->state == DLM_FIN_WAIT1) {
+-              dlm_send_fin(node, dlm_act_fin_ack_rcv);
+-
+-              if (DLM_DEBUG_FENCE_TERMINATION)
+-                      msleep(5000);
+-      }
++      if (DLM_DEBUG_FENCE_TERMINATION)
++              msleep(5000);
+       /* wait for other side dlm + fin */
+       ret = wait_event_timeout(node->shutdown_wait,
diff --git a/queue-6.2/fs-dlm-send-fin-ack-back-in-right-cases.patch b/queue-6.2/fs-dlm-send-fin-ack-back-in-right-cases.patch
new file mode 100644 (file)
index 0000000..1bffd85
--- /dev/null
@@ -0,0 +1,70 @@
+From 00908b3388255fc1d3782b744d07f327712f401f Mon Sep 17 00:00:00 2001
+From: Alexander Aring <aahringo@redhat.com>
+Date: Thu, 12 Jan 2023 17:10:37 -0500
+Subject: fs: dlm: send FIN ack back in right cases
+
+From: Alexander Aring <aahringo@redhat.com>
+
+commit 00908b3388255fc1d3782b744d07f327712f401f upstream.
+
+This patch moves to send a ack back for receiving a FIN message only
+when we are in valid states. In other cases and there might be a sender
+waiting for a ack we just let it timeout at the senders time and
+hopefully all other cleanups will remove the FIN message on their
+sending queue. As an example we should never send out an ACK being in
+LAST_ACK state or we cannot assume a working socket communication when
+we are in CLOSED state.
+
+Cc: stable@vger.kernel.org
+Fixes: 489d8e559c65 ("fs: dlm: add reliable connection if reconnect")
+Signed-off-by: Alexander Aring <aahringo@redhat.com>
+Signed-off-by: David Teigland <teigland@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/dlm/midcomms.c |    9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+--- a/fs/dlm/midcomms.c
++++ b/fs/dlm/midcomms.c
+@@ -375,7 +375,7 @@ static int dlm_send_ack(int nodeid, uint
+       struct dlm_msg *msg;
+       char *ppc;
+-      msg = dlm_lowcomms_new_msg(nodeid, mb_len, GFP_NOFS, &ppc,
++      msg = dlm_lowcomms_new_msg(nodeid, mb_len, GFP_ATOMIC, &ppc,
+                                  NULL, NULL);
+       if (!msg)
+               return -ENOMEM;
+@@ -498,15 +498,14 @@ static void dlm_midcomms_receive_buffer(
+               switch (p->header.h_cmd) {
+               case DLM_FIN:
+-                      /* send ack before fin */
+-                      dlm_send_ack(node->nodeid, node->seq_next);
+-
+                       spin_lock(&node->state_lock);
+                       pr_debug("receive fin msg from node %d with state %s\n",
+                                node->nodeid, dlm_state_str(node->state));
+                       switch (node->state) {
+                       case DLM_ESTABLISHED:
++                              dlm_send_ack(node->nodeid, node->seq_next);
++
+                               node->state = DLM_CLOSE_WAIT;
+                               pr_debug("switch node %d to state %s\n",
+                                        node->nodeid, dlm_state_str(node->state));
+@@ -523,12 +522,14 @@ static void dlm_midcomms_receive_buffer(
+                               }
+                               break;
+                       case DLM_FIN_WAIT1:
++                              dlm_send_ack(node->nodeid, node->seq_next);
+                               node->state = DLM_CLOSING;
+                               set_bit(DLM_NODE_FLAG_STOP_RX, &node->flags);
+                               pr_debug("switch node %d to state %s\n",
+                                        node->nodeid, dlm_state_str(node->state));
+                               break;
+                       case DLM_FIN_WAIT2:
++                              dlm_send_ack(node->nodeid, node->seq_next);
+                               midcomms_node_reset(node);
+                               pr_debug("switch node %d to state %s\n",
+                                        node->nodeid, dlm_state_str(node->state));
diff --git a/queue-6.2/fs-dlm-start-midcomms-before-scand.patch b/queue-6.2/fs-dlm-start-midcomms-before-scand.patch
new file mode 100644 (file)
index 0000000..0b9f327
--- /dev/null
@@ -0,0 +1,57 @@
+From aad633dc0cf90093998b1ae0ba9f19b5f1dab644 Mon Sep 17 00:00:00 2001
+From: Alexander Aring <aahringo@redhat.com>
+Date: Thu, 12 Jan 2023 17:10:31 -0500
+Subject: fs: dlm: start midcomms before scand
+
+From: Alexander Aring <aahringo@redhat.com>
+
+commit aad633dc0cf90093998b1ae0ba9f19b5f1dab644 upstream.
+
+The scand kthread can send dlm messages out, especially dlm remove
+messages to free memory for unused rsb on other nodes. To send out dlm
+messages, midcomms must be initialized. This patch moves the midcomms
+start before scand is started.
+
+Cc: stable@vger.kernel.org
+Fixes: e7fd41792fc0 ("[DLM] The core of the DLM for GFS2/CLVM")
+Signed-off-by: Alexander Aring <aahringo@redhat.com>
+Signed-off-by: David Teigland <teigland@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/dlm/lockspace.c |   16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/fs/dlm/lockspace.c
++++ b/fs/dlm/lockspace.c
+@@ -381,23 +381,23 @@ static int threads_start(void)
+ {
+       int error;
+-      error = dlm_scand_start();
++      /* Thread for sending/receiving messages for all lockspace's */
++      error = dlm_midcomms_start();
+       if (error) {
+-              log_print("cannot start dlm_scand thread %d", error);
++              log_print("cannot start dlm midcomms %d", error);
+               goto fail;
+       }
+-      /* Thread for sending/receiving messages for all lockspace's */
+-      error = dlm_midcomms_start();
++      error = dlm_scand_start();
+       if (error) {
+-              log_print("cannot start dlm midcomms %d", error);
+-              goto scand_fail;
++              log_print("cannot start dlm_scand thread %d", error);
++              goto midcomms_fail;
+       }
+       return 0;
+- scand_fail:
+-      dlm_scand_stop();
++ midcomms_fail:
++      dlm_midcomms_stop();
+  fail:
+       return error;
+ }
diff --git a/queue-6.2/fs-hfsplus-fix-uaf-issue-in-hfsplus_put_super.patch b/queue-6.2/fs-hfsplus-fix-uaf-issue-in-hfsplus_put_super.patch
new file mode 100644 (file)
index 0000000..cf6cd55
--- /dev/null
@@ -0,0 +1,52 @@
+From 07db5e247ab5858439b14dd7cc1fe538b9efcf32 Mon Sep 17 00:00:00 2001
+From: Dongliang Mu <mudongliangabcd@gmail.com>
+Date: Sun, 26 Feb 2023 20:49:47 +0800
+Subject: fs: hfsplus: fix UAF issue in hfsplus_put_super
+
+From: Dongliang Mu <mudongliangabcd@gmail.com>
+
+commit 07db5e247ab5858439b14dd7cc1fe538b9efcf32 upstream.
+
+The current hfsplus_put_super first calls hfs_btree_close on
+sbi->ext_tree, then invokes iput on sbi->hidden_dir, resulting in an
+use-after-free issue in hfsplus_release_folio.
+
+As shown in hfsplus_fill_super, the error handling code also calls iput
+before hfs_btree_close.
+
+To fix this error, we move all iput calls before hfsplus_btree_close.
+
+Note that this patch is tested on Syzbot.
+
+Link: https://lkml.kernel.org/r/20230226124948.3175736-1-mudongliangabcd@gmail.com
+Reported-by: syzbot+57e3e98f7e3b80f64d56@syzkaller.appspotmail.com
+Tested-by: Dongliang Mu <mudongliangabcd@gmail.com>
+Signed-off-by: Dongliang Mu <mudongliangabcd@gmail.com>
+Cc: Bart Van Assche <bvanassche@acm.org>
+Cc: Jens Axboe <axboe@kernel.dk>
+Cc: Muchun Song <songmuchun@bytedance.com>
+Cc: Roman Gushchin <roman.gushchin@linux.dev>
+Cc: "Theodore Ts'o" <tytso@mit.edu>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/hfsplus/super.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/fs/hfsplus/super.c
++++ b/fs/hfsplus/super.c
+@@ -295,11 +295,11 @@ static void hfsplus_put_super(struct sup
+               hfsplus_sync_fs(sb, 1);
+       }
++      iput(sbi->alloc_file);
++      iput(sbi->hidden_dir);
+       hfs_btree_close(sbi->attr_tree);
+       hfs_btree_close(sbi->cat_tree);
+       hfs_btree_close(sbi->ext_tree);
+-      iput(sbi->alloc_file);
+-      iput(sbi->hidden_dir);
+       kfree(sbi->s_vhdr_buf);
+       kfree(sbi->s_backup_vhdr_buf);
+       unload_nls(sbi->nls);
diff --git a/queue-6.2/hfs-fix-missing-hfs_bnode_get-in-__hfs_bnode_create.patch b/queue-6.2/hfs-fix-missing-hfs_bnode_get-in-__hfs_bnode_create.patch
new file mode 100644 (file)
index 0000000..8be488d
--- /dev/null
@@ -0,0 +1,98 @@
+From a9dc087fd3c484fd1ed18c5efb290efaaf44ce03 Mon Sep 17 00:00:00 2001
+From: Liu Shixin <liushixin2@huawei.com>
+Date: Mon, 12 Dec 2022 10:16:27 +0800
+Subject: hfs: fix missing hfs_bnode_get() in __hfs_bnode_create
+
+From: Liu Shixin <liushixin2@huawei.com>
+
+commit a9dc087fd3c484fd1ed18c5efb290efaaf44ce03 upstream.
+
+Syzbot found a kernel BUG in hfs_bnode_put():
+
+ kernel BUG at fs/hfs/bnode.c:466!
+ invalid opcode: 0000 [#1] PREEMPT SMP KASAN
+ CPU: 0 PID: 3634 Comm: kworker/u4:5 Not tainted 6.1.0-rc7-syzkaller-00190-g97ee9d1c1696 #0
+ Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022
+ Workqueue: writeback wb_workfn (flush-7:0)
+ RIP: 0010:hfs_bnode_put+0x46f/0x480 fs/hfs/bnode.c:466
+ Code: 8a 80 ff e9 73 fe ff ff 89 d9 80 e1 07 80 c1 03 38 c1 0f 8c a0 fe ff ff 48 89 df e8 db 8a 80 ff e9 93 fe ff ff e8 a1 68 2c ff <0f> 0b e8 9a 68 2c ff 0f 0b 0f 1f 84 00 00 00 00 00 55 41 57 41 56
+ RSP: 0018:ffffc90003b4f258 EFLAGS: 00010293
+ RAX: ffffffff825e318f RBX: 0000000000000000 RCX: ffff8880739dd7c0
+ RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
+ RBP: ffffc90003b4f430 R08: ffffffff825e2d9b R09: ffffed10045157d1
+ R10: ffffed10045157d1 R11: 1ffff110045157d0 R12: ffff8880228abe80
+ R13: ffff88807016c000 R14: dffffc0000000000 R15: ffff8880228abe00
+ FS:  0000000000000000(0000) GS:ffff8880b9800000(0000) knlGS:0000000000000000
+ CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 00007fa6ebe88718 CR3: 000000001e93d000 CR4: 00000000003506f0
+ DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+ DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+ Call Trace:
+  <TASK>
+  hfs_write_inode+0x1bc/0xb40
+  write_inode fs/fs-writeback.c:1440 [inline]
+  __writeback_single_inode+0x4d6/0x670 fs/fs-writeback.c:1652
+  writeback_sb_inodes+0xb3b/0x18f0 fs/fs-writeback.c:1878
+  __writeback_inodes_wb+0x125/0x420 fs/fs-writeback.c:1949
+  wb_writeback+0x440/0x7b0 fs/fs-writeback.c:2054
+  wb_check_start_all fs/fs-writeback.c:2176 [inline]
+  wb_do_writeback fs/fs-writeback.c:2202 [inline]
+  wb_workfn+0x827/0xef0 fs/fs-writeback.c:2235
+  process_one_work+0x877/0xdb0 kernel/workqueue.c:2289
+  worker_thread+0xb14/0x1330 kernel/workqueue.c:2436
+  kthread+0x266/0x300 kernel/kthread.c:376
+  ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:306
+  </TASK>
+
+The BUG_ON() is triggered at here:
+
+/* Dispose of resources used by a node */
+void hfs_bnode_put(struct hfs_bnode *node)
+{
+       if (node) {
+               <skipped>
+               BUG_ON(!atomic_read(&node->refcnt)); <- we have issue here!!!!
+               <skipped>
+       }
+}
+
+By tracing the refcnt, I found the node is created by hfs_bmap_alloc()
+with refcnt 1.  Then the node is used by hfs_btree_write().  There is a
+missing of hfs_bnode_get() after find the node.  The issue happened in
+following path:
+
+<alloc>
+ hfs_bmap_alloc
+   hfs_bnode_find
+     __hfs_bnode_create   <- allocate a new node with refcnt 1.
+   hfs_bnode_put          <- decrease the refcnt
+
+<write>
+ hfs_btree_write
+   hfs_bnode_find
+     __hfs_bnode_create
+       hfs_bnode_findhash <- find the node without refcnt increased.
+   hfs_bnode_put         <- trigger the BUG_ON() since refcnt is 0.
+
+Link: https://lkml.kernel.org/r/20221212021627.3766829-1-liushixin2@huawei.com
+Reported-by: syzbot+5b04b49a7ec7226c7426@syzkaller.appspotmail.com
+Signed-off-by: Liu Shixin <liushixin2@huawei.com>
+Cc: Fabio M. De Francesco <fmdefrancesco@gmail.com>
+Cc: Viacheslav Dubeyko <slava@dubeyko.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/hfs/bnode.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/hfs/bnode.c
++++ b/fs/hfs/bnode.c
+@@ -274,6 +274,7 @@ static struct hfs_bnode *__hfs_bnode_cre
+               tree->node_hash[hash] = node;
+               tree->node_hash_cnt++;
+       } else {
++              hfs_bnode_get(node2);
+               spin_unlock(&tree->hash_lock);
+               kfree(node);
+               wait_event(node2->lock_wq, !test_bit(HFS_BNODE_NEW, &node2->flags));
diff --git a/queue-6.2/md-don-t-update-recovery_cp-when-curr_resync-is-active.patch b/queue-6.2/md-don-t-update-recovery_cp-when-curr_resync-is-active.patch
new file mode 100644 (file)
index 0000000..2c8f692
--- /dev/null
@@ -0,0 +1,51 @@
+From 1d1f25bfda432a6b61bd0205d426226bbbd73504 Mon Sep 17 00:00:00 2001
+From: Hou Tao <houtao1@huawei.com>
+Date: Tue, 31 Jan 2023 15:07:19 +0800
+Subject: md: don't update recovery_cp when curr_resync is ACTIVE
+
+From: Hou Tao <houtao1@huawei.com>
+
+commit 1d1f25bfda432a6b61bd0205d426226bbbd73504 upstream.
+
+Don't update recovery_cp when curr_resync is MD_RESYNC_ACTIVE, otherwise
+md may skip the resync of the first 3 sectors if the resync procedure is
+interrupted before the first calling of ->sync_request() as shown below:
+
+md_do_sync thread          control thread
+  // setup resync
+  mddev->recovery_cp = 0
+  j = 0
+  mddev->curr_resync = MD_RESYNC_ACTIVE
+
+                             // e.g., set array as idle
+                             set_bit(MD_RECOVERY_INTR, &&mddev_recovery)
+  // resync loop
+  // check INTR before calling sync_request
+  !test_bit(MD_RECOVERY_INTR, &mddev->recovery
+
+  // resync interrupted
+  // update recovery_cp from 0 to 3
+  // the resync of three 3 sectors will be skipped
+  mddev->recovery_cp = 3
+
+Fixes: eac58d08d493 ("md: Use enum for overloaded magic numbers used by mddev->curr_resync")
+Cc: stable@vger.kernel.org # 6.0+
+Signed-off-by: Hou Tao <houtao1@huawei.com>
+Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
+Signed-off-by: Song Liu <song@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/md/md.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -9030,7 +9030,7 @@ void md_do_sync(struct md_thread *thread
+       mddev->pers->sync_request(mddev, max_sectors, &skipped);
+       if (!test_bit(MD_RECOVERY_CHECK, &mddev->recovery) &&
+-          mddev->curr_resync >= MD_RESYNC_ACTIVE) {
++          mddev->curr_resync > MD_RESYNC_ACTIVE) {
+               if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
+                       if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) {
+                               if (mddev->curr_resync >= mddev->recovery_cp) {
diff --git a/queue-6.2/ocfs2-fix-defrag-path-triggering-jbd2-assert.patch b/queue-6.2/ocfs2-fix-defrag-path-triggering-jbd2-assert.patch
new file mode 100644 (file)
index 0000000..00f9791
--- /dev/null
@@ -0,0 +1,100 @@
+From 60eed1e3d45045623e46944ebc7c42c30a4350f0 Mon Sep 17 00:00:00 2001
+From: Heming Zhao via Ocfs2-devel <ocfs2-devel@oss.oracle.com>
+Date: Fri, 17 Feb 2023 08:37:17 +0800
+Subject: ocfs2: fix defrag path triggering jbd2 ASSERT
+
+From: Heming Zhao via Ocfs2-devel <ocfs2-devel@oss.oracle.com>
+
+commit 60eed1e3d45045623e46944ebc7c42c30a4350f0 upstream.
+
+code path:
+
+ocfs2_ioctl_move_extents
+ ocfs2_move_extents
+  ocfs2_defrag_extent
+   __ocfs2_move_extent
+    + ocfs2_journal_access_di
+    + ocfs2_split_extent  //sub-paths call jbd2_journal_restart
+    + ocfs2_journal_dirty //crash by jbs2 ASSERT
+
+crash stacks:
+
+PID: 11297  TASK: ffff974a676dcd00  CPU: 67  COMMAND: "defragfs.ocfs2"
+ #0 [ffffb25d8dad3900] machine_kexec at ffffffff8386fe01
+ #1 [ffffb25d8dad3958] __crash_kexec at ffffffff8395959d
+ #2 [ffffb25d8dad3a20] crash_kexec at ffffffff8395a45d
+ #3 [ffffb25d8dad3a38] oops_end at ffffffff83836d3f
+ #4 [ffffb25d8dad3a58] do_trap at ffffffff83833205
+ #5 [ffffb25d8dad3aa0] do_invalid_op at ffffffff83833aa6
+ #6 [ffffb25d8dad3ac0] invalid_op at ffffffff84200d18
+    [exception RIP: jbd2_journal_dirty_metadata+0x2ba]
+    RIP: ffffffffc09ca54a  RSP: ffffb25d8dad3b70  RFLAGS: 00010207
+    RAX: 0000000000000000  RBX: ffff9706eedc5248  RCX: 0000000000000000
+    RDX: 0000000000000001  RSI: ffff97337029ea28  RDI: ffff9706eedc5250
+    RBP: ffff9703c3520200   R8: 000000000f46b0b2   R9: 0000000000000000
+    R10: 0000000000000001  R11: 00000001000000fe  R12: ffff97337029ea28
+    R13: 0000000000000000  R14: ffff9703de59bf60  R15: ffff9706eedc5250
+    ORIG_RAX: ffffffffffffffff  CS: 0010  SS: 0018
+ #7 [ffffb25d8dad3ba8] ocfs2_journal_dirty at ffffffffc137fb95 [ocfs2]
+ #8 [ffffb25d8dad3be8] __ocfs2_move_extent at ffffffffc139a950 [ocfs2]
+ #9 [ffffb25d8dad3c80] ocfs2_defrag_extent at ffffffffc139b2d2 [ocfs2]
+
+Analysis
+
+This bug has the same root cause of 'commit 7f27ec978b0e ("ocfs2: call
+ocfs2_journal_access_di() before ocfs2_journal_dirty() in
+ocfs2_write_end_nolock()")'.  For this bug, jbd2_journal_restart() is
+called by ocfs2_split_extent() during defragmenting.
+
+How to fix
+
+For ocfs2_split_extent() can handle journal operations totally by itself.
+Caller doesn't need to call journal access/dirty pair, and caller only
+needs to call journal start/stop pair.  The fix method is to remove
+journal access/dirty from __ocfs2_move_extent().
+
+The discussion for this patch:
+https://oss.oracle.com/pipermail/ocfs2-devel/2023-February/000647.html
+
+Link: https://lkml.kernel.org/r/20230217003717.32469-1-heming.zhao@suse.com
+Signed-off-by: Heming Zhao <heming.zhao@suse.com>
+Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Gang He <ghe@suse.com>
+Cc: Jun Piao <piaojun@huawei.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ocfs2/move_extents.c |   10 ----------
+ 1 file changed, 10 deletions(-)
+
+--- a/fs/ocfs2/move_extents.c
++++ b/fs/ocfs2/move_extents.c
+@@ -105,14 +105,6 @@ static int __ocfs2_move_extent(handle_t
+        */
+       replace_rec.e_flags = ext_flags & ~OCFS2_EXT_REFCOUNTED;
+-      ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode),
+-                                    context->et.et_root_bh,
+-                                    OCFS2_JOURNAL_ACCESS_WRITE);
+-      if (ret) {
+-              mlog_errno(ret);
+-              goto out;
+-      }
+-
+       ret = ocfs2_split_extent(handle, &context->et, path, index,
+                                &replace_rec, context->meta_ac,
+                                &context->dealloc);
+@@ -121,8 +113,6 @@ static int __ocfs2_move_extent(handle_t
+               goto out;
+       }
+-      ocfs2_journal_dirty(handle, context->et.et_root_bh);
+-
+       context->new_phys_cpos = new_p_cpos;
+       /*
diff --git a/queue-6.2/ocfs2-fix-non-auto-defrag-path-not-working-issue.patch b/queue-6.2/ocfs2-fix-non-auto-defrag-path-not-working-issue.patch
new file mode 100644 (file)
index 0000000..4a1c807
--- /dev/null
@@ -0,0 +1,91 @@
+From 236b9254f8d1edc273ad88b420aa85fbd84f492d Mon Sep 17 00:00:00 2001
+From: Heming Zhao via Ocfs2-devel <ocfs2-devel@oss.oracle.com>
+Date: Mon, 20 Feb 2023 13:05:26 +0800
+Subject: ocfs2: fix non-auto defrag path not working issue
+
+From: Heming Zhao via Ocfs2-devel <ocfs2-devel@oss.oracle.com>
+
+commit 236b9254f8d1edc273ad88b420aa85fbd84f492d upstream.
+
+This fixes three issues on move extents ioctl without auto defrag:
+
+a) In ocfs2_find_victim_alloc_group(), we have to convert bits to block
+   first in case of global bitmap.
+
+b) In ocfs2_probe_alloc_group(), when finding enough bits in block
+   group bitmap, we have to back off move_len to start pos as well,
+   otherwise it may corrupt filesystem.
+
+c) In ocfs2_ioctl_move_extents(), set me_threshold both for non-auto
+   and auto defrag paths.  Otherwise it will set move_max_hop to 0 and
+   finally cause unexpectedly ENOSPC error.
+
+Currently there are no tools triggering the above issues since
+defragfs.ocfs2 enables auto defrag by default.  Tested with manually
+changing defragfs.ocfs2 to run non auto defrag path.
+
+Link: https://lkml.kernel.org/r/20230220050526.22020-1-heming.zhao@suse.com
+Signed-off-by: Heming Zhao <heming.zhao@suse.com>
+Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Gang He <ghe@suse.com>
+Cc: Jun Piao <piaojun@huawei.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ocfs2/move_extents.c |   24 +++++++++++++-----------
+ 1 file changed, 13 insertions(+), 11 deletions(-)
+
+--- a/fs/ocfs2/move_extents.c
++++ b/fs/ocfs2/move_extents.c
+@@ -434,7 +434,7 @@ static int ocfs2_find_victim_alloc_group
+                       bg = (struct ocfs2_group_desc *)gd_bh->b_data;
+                       if (vict_blkno < (le64_to_cpu(bg->bg_blkno) +
+-                                              le16_to_cpu(bg->bg_bits))) {
++                                              (le16_to_cpu(bg->bg_bits) << bits_per_unit))) {
+                               *ret_bh = gd_bh;
+                               *vict_bit = (vict_blkno - blkno) >>
+@@ -549,6 +549,7 @@ static void ocfs2_probe_alloc_group(stru
+                       last_free_bits++;
+               if (last_free_bits == move_len) {
++                      i -= move_len;
+                       *goal_bit = i;
+                       *phys_cpos = base_cpos + i;
+                       break;
+@@ -1020,18 +1021,19 @@ int ocfs2_ioctl_move_extents(struct file
+       context->range = &range;
++      /*
++       * ok, the default theshold for the defragmentation
++       * is 1M, since our maximum clustersize was 1M also.
++       * any thought?
++       */
++      if (!range.me_threshold)
++              range.me_threshold = 1024 * 1024;
++
++      if (range.me_threshold > i_size_read(inode))
++              range.me_threshold = i_size_read(inode);
++
+       if (range.me_flags & OCFS2_MOVE_EXT_FL_AUTO_DEFRAG) {
+               context->auto_defrag = 1;
+-              /*
+-               * ok, the default theshold for the defragmentation
+-               * is 1M, since our maximum clustersize was 1M also.
+-               * any thought?
+-               */
+-              if (!range.me_threshold)
+-                      range.me_threshold = 1024 * 1024;
+-
+-              if (range.me_threshold > i_size_read(inode))
+-                      range.me_threshold = i_size_read(inode);
+               if (range.me_flags & OCFS2_MOVE_EXT_FL_PART_DEFRAG)
+                       context->partial = 1;
diff --git a/queue-6.2/selftests-landlock-skip-overlayfs-tests-when-not-supported.patch b/queue-6.2/selftests-landlock-skip-overlayfs-tests-when-not-supported.patch
new file mode 100644 (file)
index 0000000..659e2bc
--- /dev/null
@@ -0,0 +1,118 @@
+From 366617a69e60610912836570546f118006ebc7cb Mon Sep 17 00:00:00 2001
+From: Jeff Xu <jeffxu@google.com>
+Date: Fri, 13 Jan 2023 05:32:29 +0000
+Subject: selftests/landlock: Skip overlayfs tests when not supported
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jeff Xu <jeffxu@google.com>
+
+commit 366617a69e60610912836570546f118006ebc7cb upstream.
+
+overlayfs may be disabled in the kernel configuration, causing related
+tests to fail.  Check that overlayfs is supported at runtime, so we can
+skip layout2_overlay.* accordingly.
+
+Signed-off-by: Jeff Xu <jeffxu@google.com>
+Reviewed-by: Guenter Roeck <groeck@chromium.org>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20230113053229.1281774-2-jeffxu@google.com
+[mic: Reword comments and constify variables]
+Signed-off-by: Mickaël Salaün <mic@digikod.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/landlock/fs_test.c |   47 +++++++++++++++++++++++++++++
+ 1 file changed, 47 insertions(+)
+
+--- a/tools/testing/selftests/landlock/fs_test.c
++++ b/tools/testing/selftests/landlock/fs_test.c
+@@ -11,6 +11,7 @@
+ #include <fcntl.h>
+ #include <linux/landlock.h>
+ #include <sched.h>
++#include <stdio.h>
+ #include <string.h>
+ #include <sys/capability.h>
+ #include <sys/mount.h>
+@@ -89,6 +90,40 @@ static const char dir_s3d3[] = TMP_DIR "
+  *         â””── s3d3
+  */
++static bool fgrep(FILE *const inf, const char *const str)
++{
++      char line[32];
++      const int slen = strlen(str);
++
++      while (!feof(inf)) {
++              if (!fgets(line, sizeof(line), inf))
++                      break;
++              if (strncmp(line, str, slen))
++                      continue;
++
++              return true;
++      }
++
++      return false;
++}
++
++static bool supports_overlayfs(void)
++{
++      bool res;
++      FILE *const inf = fopen("/proc/filesystems", "r");
++
++      /*
++       * Consider that the filesystem is supported if we cannot get the
++       * supported ones.
++       */
++      if (!inf)
++              return true;
++
++      res = fgrep(inf, "nodev\toverlay\n");
++      fclose(inf);
++      return res;
++}
++
+ static void mkdir_parents(struct __test_metadata *const _metadata,
+                         const char *const path)
+ {
+@@ -4001,6 +4036,9 @@ FIXTURE(layout2_overlay) {};
+ FIXTURE_SETUP(layout2_overlay)
+ {
++      if (!supports_overlayfs())
++              SKIP(return, "overlayfs is not supported");
++
+       prepare_layout(_metadata);
+       create_directory(_metadata, LOWER_BASE);
+@@ -4037,6 +4075,9 @@ FIXTURE_SETUP(layout2_overlay)
+ FIXTURE_TEARDOWN(layout2_overlay)
+ {
++      if (!supports_overlayfs())
++              SKIP(return, "overlayfs is not supported");
++
+       EXPECT_EQ(0, remove_path(lower_do1_fl3));
+       EXPECT_EQ(0, remove_path(lower_dl1_fl2));
+       EXPECT_EQ(0, remove_path(lower_fl1));
+@@ -4068,6 +4109,9 @@ FIXTURE_TEARDOWN(layout2_overlay)
+ TEST_F_FORK(layout2_overlay, no_restriction)
+ {
++      if (!supports_overlayfs())
++              SKIP(return, "overlayfs is not supported");
++
+       ASSERT_EQ(0, test_open(lower_fl1, O_RDONLY));
+       ASSERT_EQ(0, test_open(lower_dl1, O_RDONLY));
+       ASSERT_EQ(0, test_open(lower_dl1_fl2, O_RDONLY));
+@@ -4231,6 +4275,9 @@ TEST_F_FORK(layout2_overlay, same_conten
+       size_t i;
+       const char *path_entry;
++      if (!supports_overlayfs())
++              SKIP(return, "overlayfs is not supported");
++
+       /* Sets rules on base directories (i.e. outside overlay scope). */
+       ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer1_base);
+       ASSERT_LE(0, ruleset_fd);
diff --git a/queue-6.2/selftests-landlock-test-ptrace-as-much-as-possible-with-yama.patch b/queue-6.2/selftests-landlock-test-ptrace-as-much-as-possible-with-yama.patch
new file mode 100644 (file)
index 0000000..f985eed
--- /dev/null
@@ -0,0 +1,215 @@
+From 8677e555f17f51321d0730b945aeb7d4b95f998f Mon Sep 17 00:00:00 2001
+From: Jeff Xu <jeffxu@google.com>
+Date: Sat, 14 Jan 2023 02:03:06 +0000
+Subject: selftests/landlock: Test ptrace as much as possible with Yama
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jeff Xu <jeffxu@google.com>
+
+commit 8677e555f17f51321d0730b945aeb7d4b95f998f upstream.
+
+Update ptrace tests according to all potential Yama security policies.
+This is required to make such tests pass even if Yama is enabled.
+
+Tests are not skipped but they now check both Landlock and Yama boundary
+restrictions at run time to keep a maximum test coverage (i.e. positive
+and negative testing).
+
+Signed-off-by: Jeff Xu <jeffxu@google.com>
+Link: https://lore.kernel.org/r/20230114020306.1407195-2-jeffxu@google.com
+Cc: stable@vger.kernel.org
+[mic: Add curly braces around EXPECT_EQ() to make it build, and improve
+commit message]
+Co-developed-by: Mickaël Salaün <mic@digikod.net>
+Signed-off-by: Mickaël Salaün <mic@digikod.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/landlock/ptrace_test.c |  113 +++++++++++++++++++++----
+ 1 file changed, 96 insertions(+), 17 deletions(-)
+
+--- a/tools/testing/selftests/landlock/ptrace_test.c
++++ b/tools/testing/selftests/landlock/ptrace_test.c
+@@ -19,6 +19,12 @@
+ #include "common.h"
++/* Copied from security/yama/yama_lsm.c */
++#define YAMA_SCOPE_DISABLED 0
++#define YAMA_SCOPE_RELATIONAL 1
++#define YAMA_SCOPE_CAPABILITY 2
++#define YAMA_SCOPE_NO_ATTACH 3
++
+ static void create_domain(struct __test_metadata *const _metadata)
+ {
+       int ruleset_fd;
+@@ -60,6 +66,25 @@ static int test_ptrace_read(const pid_t
+       return 0;
+ }
++static int get_yama_ptrace_scope(void)
++{
++      int ret;
++      char buf[2] = {};
++      const int fd = open("/proc/sys/kernel/yama/ptrace_scope", O_RDONLY);
++
++      if (fd < 0)
++              return 0;
++
++      if (read(fd, buf, 1) < 0) {
++              close(fd);
++              return -1;
++      }
++
++      ret = atoi(buf);
++      close(fd);
++      return ret;
++}
++
+ /* clang-format off */
+ FIXTURE(hierarchy) {};
+ /* clang-format on */
+@@ -232,8 +257,51 @@ TEST_F(hierarchy, trace)
+       pid_t child, parent;
+       int status, err_proc_read;
+       int pipe_child[2], pipe_parent[2];
++      int yama_ptrace_scope;
+       char buf_parent;
+       long ret;
++      bool can_read_child, can_trace_child, can_read_parent, can_trace_parent;
++
++      yama_ptrace_scope = get_yama_ptrace_scope();
++      ASSERT_LE(0, yama_ptrace_scope);
++
++      if (yama_ptrace_scope > YAMA_SCOPE_DISABLED)
++              TH_LOG("Incomplete tests due to Yama restrictions (scope %d)",
++                     yama_ptrace_scope);
++
++      /*
++       * can_read_child is true if a parent process can read its child
++       * process, which is only the case when the parent process is not
++       * isolated from the child with a dedicated Landlock domain.
++       */
++      can_read_child = !variant->domain_parent;
++
++      /*
++       * can_trace_child is true if a parent process can trace its child
++       * process.  This depends on two conditions:
++       * - The parent process is not isolated from the child with a dedicated
++       *   Landlock domain.
++       * - Yama allows tracing children (up to YAMA_SCOPE_RELATIONAL).
++       */
++      can_trace_child = can_read_child &&
++                        yama_ptrace_scope <= YAMA_SCOPE_RELATIONAL;
++
++      /*
++       * can_read_parent is true if a child process can read its parent
++       * process, which is only the case when the child process is not
++       * isolated from the parent with a dedicated Landlock domain.
++       */
++      can_read_parent = !variant->domain_child;
++
++      /*
++       * can_trace_parent is true if a child process can trace its parent
++       * process.  This depends on two conditions:
++       * - The child process is not isolated from the parent with a dedicated
++       *   Landlock domain.
++       * - Yama is disabled (YAMA_SCOPE_DISABLED).
++       */
++      can_trace_parent = can_read_parent &&
++                         yama_ptrace_scope <= YAMA_SCOPE_DISABLED;
+       /*
+        * Removes all effective and permitted capabilities to not interfere
+@@ -264,16 +332,21 @@ TEST_F(hierarchy, trace)
+               /* Waits for the parent to be in a domain, if any. */
+               ASSERT_EQ(1, read(pipe_parent[0], &buf_child, 1));
+-              /* Tests PTRACE_ATTACH and PTRACE_MODE_READ on the parent. */
++              /* Tests PTRACE_MODE_READ on the parent. */
+               err_proc_read = test_ptrace_read(parent);
++              if (can_read_parent) {
++                      EXPECT_EQ(0, err_proc_read);
++              } else {
++                      EXPECT_EQ(EACCES, err_proc_read);
++              }
++
++              /* Tests PTRACE_ATTACH on the parent. */
+               ret = ptrace(PTRACE_ATTACH, parent, NULL, 0);
+-              if (variant->domain_child) {
++              if (can_trace_parent) {
++                      EXPECT_EQ(0, ret);
++              } else {
+                       EXPECT_EQ(-1, ret);
+                       EXPECT_EQ(EPERM, errno);
+-                      EXPECT_EQ(EACCES, err_proc_read);
+-              } else {
+-                      EXPECT_EQ(0, ret);
+-                      EXPECT_EQ(0, err_proc_read);
+               }
+               if (ret == 0) {
+                       ASSERT_EQ(parent, waitpid(parent, &status, 0));
+@@ -283,11 +356,11 @@ TEST_F(hierarchy, trace)
+               /* Tests child PTRACE_TRACEME. */
+               ret = ptrace(PTRACE_TRACEME);
+-              if (variant->domain_parent) {
++              if (can_trace_child) {
++                      EXPECT_EQ(0, ret);
++              } else {
+                       EXPECT_EQ(-1, ret);
+                       EXPECT_EQ(EPERM, errno);
+-              } else {
+-                      EXPECT_EQ(0, ret);
+               }
+               /*
+@@ -296,7 +369,7 @@ TEST_F(hierarchy, trace)
+                */
+               ASSERT_EQ(1, write(pipe_child[1], ".", 1));
+-              if (!variant->domain_parent) {
++              if (can_trace_child) {
+                       ASSERT_EQ(0, raise(SIGSTOP));
+               }
+@@ -321,7 +394,7 @@ TEST_F(hierarchy, trace)
+       ASSERT_EQ(1, read(pipe_child[0], &buf_parent, 1));
+       /* Tests child PTRACE_TRACEME. */
+-      if (!variant->domain_parent) {
++      if (can_trace_child) {
+               ASSERT_EQ(child, waitpid(child, &status, 0));
+               ASSERT_EQ(1, WIFSTOPPED(status));
+               ASSERT_EQ(0, ptrace(PTRACE_DETACH, child, NULL, 0));
+@@ -331,17 +404,23 @@ TEST_F(hierarchy, trace)
+               EXPECT_EQ(ESRCH, errno);
+       }
+-      /* Tests PTRACE_ATTACH and PTRACE_MODE_READ on the child. */
++      /* Tests PTRACE_MODE_READ on the child. */
+       err_proc_read = test_ptrace_read(child);
++      if (can_read_child) {
++              EXPECT_EQ(0, err_proc_read);
++      } else {
++              EXPECT_EQ(EACCES, err_proc_read);
++      }
++
++      /* Tests PTRACE_ATTACH on the child. */
+       ret = ptrace(PTRACE_ATTACH, child, NULL, 0);
+-      if (variant->domain_parent) {
++      if (can_trace_child) {
++              EXPECT_EQ(0, ret);
++      } else {
+               EXPECT_EQ(-1, ret);
+               EXPECT_EQ(EPERM, errno);
+-              EXPECT_EQ(EACCES, err_proc_read);
+-      } else {
+-              EXPECT_EQ(0, ret);
+-              EXPECT_EQ(0, err_proc_read);
+       }
++
+       if (ret == 0) {
+               ASSERT_EQ(child, waitpid(child, &status, 0));
+               ASSERT_EQ(1, WIFSTOPPED(status));
index e870c957fad35cffcb4d0b21671799b878de85c2..e15545fc322232f79b88793dcf877e26a9817dfe 100644 (file)
@@ -789,3 +789,33 @@ ksmbd-fix-possible-memory-leak-in-smb2_lock.patch
 torture-fix-hang-during-kthread-shutdown-phase.patch
 arm-dts-exynos-correct-hdmi-phy-compatible-in-exynos4.patch
 io_uring-mark-task-task_running-before-handling-resume-task-work.patch
+hfs-fix-missing-hfs_bnode_get-in-__hfs_bnode_create.patch
+fs-hfsplus-fix-uaf-issue-in-hfsplus_put_super.patch
+exfat-fix-reporting-fs-error-when-reading-dir-beyond-eof.patch
+exfat-fix-unexpected-eof-while-reading-dir.patch
+exfat-redefine-dir_deleted-as-the-bad-cluster-number.patch
+exfat-fix-inode-i_blocks-for-non-512-byte-sector-size-device.patch
+fs-dlm-start-midcomms-before-scand.patch
+fs-dlm-fix-use-after-free-in-midcomms-commit.patch
+fs-dlm-be-sure-to-call-dlm_send_queue_flush.patch
+fs-dlm-fix-race-setting-stop-tx-flag.patch
+fs-dlm-don-t-set-stop-rx-flag-after-node-reset.patch
+fs-dlm-move-sending-fin-message-into-state-change-handling.patch
+fs-dlm-send-fin-ack-back-in-right-cases.patch
+f2fs-fix-information-leak-in-f2fs_move_inline_dirents.patch
+f2fs-retry-to-update-the-inode-page-given-data-corruption.patch
+f2fs-fix-cgroup-writeback-accounting-with-fs-layer-encryption.patch
+f2fs-fix-kernel-crash-due-to-null-io-bio.patch
+f2fs-revert-f2fs-truncate-blocks-in-batch-in-__complete_revoke_list.patch
+ocfs2-fix-defrag-path-triggering-jbd2-assert.patch
+ocfs2-fix-non-auto-defrag-path-not-working-issue.patch
+fs-cramfs-inode.c-initialize-file_ra_state.patch
+selftests-landlock-skip-overlayfs-tests-when-not-supported.patch
+selftests-landlock-test-ptrace-as-much-as-possible-with-yama.patch
+udf-truncate-added-extents-on-failed-expansion.patch
+udf-do-not-bother-merging-very-long-extents.patch
+udf-do-not-update-file-length-for-failed-writes-to-inline-files.patch
+udf-preserve-link-count-of-system-files.patch
+udf-detect-system-inodes-linked-into-directory-hierarchy.patch
+udf-fix-file-corruption-when-appending-just-after-end-of-preallocated-extent.patch
+md-don-t-update-recovery_cp-when-curr_resync-is-active.patch
diff --git a/queue-6.2/udf-detect-system-inodes-linked-into-directory-hierarchy.patch b/queue-6.2/udf-detect-system-inodes-linked-into-directory-hierarchy.patch
new file mode 100644 (file)
index 0000000..b224a72
--- /dev/null
@@ -0,0 +1,40 @@
+From 85a37983ec69cc9fcd188bc37c4de15ee326355a Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Tue, 3 Jan 2023 10:03:35 +0100
+Subject: udf: Detect system inodes linked into directory hierarchy
+
+From: Jan Kara <jack@suse.cz>
+
+commit 85a37983ec69cc9fcd188bc37c4de15ee326355a upstream.
+
+When UDF filesystem is corrupted, hidden system inodes can be linked
+into directory hierarchy which is an avenue for further serious
+corruption of the filesystem and kernel confusion as noticed by syzbot
+fuzzed images. Refuse to access system inodes linked into directory
+hierarchy and vice versa.
+
+CC: stable@vger.kernel.org
+Reported-by: syzbot+38695a20b8addcbc1084@syzkaller.appspotmail.com
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/udf/inode.c |    7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/fs/udf/inode.c
++++ b/fs/udf/inode.c
+@@ -1885,8 +1885,13 @@ struct inode *__udf_iget(struct super_bl
+       if (!inode)
+               return ERR_PTR(-ENOMEM);
+-      if (!(inode->i_state & I_NEW))
++      if (!(inode->i_state & I_NEW)) {
++              if (UDF_I(inode)->i_hidden != hidden_inode) {
++                      iput(inode);
++                      return ERR_PTR(-EFSCORRUPTED);
++              }
+               return inode;
++      }
+       memcpy(&UDF_I(inode)->i_location, ino, sizeof(struct kernel_lb_addr));
+       err = udf_read_inode(inode, hidden_inode);
diff --git a/queue-6.2/udf-do-not-bother-merging-very-long-extents.patch b/queue-6.2/udf-do-not-bother-merging-very-long-extents.patch
new file mode 100644 (file)
index 0000000..33cbe60
--- /dev/null
@@ -0,0 +1,52 @@
+From 53cafe1d6d8ef9f93318e5bfccc0d24f27d41ced Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Fri, 16 Dec 2022 12:37:51 +0100
+Subject: udf: Do not bother merging very long extents
+
+From: Jan Kara <jack@suse.cz>
+
+commit 53cafe1d6d8ef9f93318e5bfccc0d24f27d41ced upstream.
+
+When merging very long extents we try to push as much length as possible
+to the first extent. However this is unnecessarily complicated and not
+really worth the trouble. Furthermore there was a bug in the logic
+resulting in corrupting extents in the file as syzbot reproducer shows.
+So just don't bother with the merging of extents that are too long
+together.
+
+CC: stable@vger.kernel.org
+Reported-by: syzbot+60f291a24acecb3c2bd5@syzkaller.appspotmail.com
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/udf/inode.c |   19 ++-----------------
+ 1 file changed, 2 insertions(+), 17 deletions(-)
+
+--- a/fs/udf/inode.c
++++ b/fs/udf/inode.c
+@@ -1087,23 +1087,8 @@ static void udf_merge_extents(struct ino
+                       blocksize - 1) >> blocksize_bits)))) {
+                       if (((li->extLength & UDF_EXTENT_LENGTH_MASK) +
+-                              (lip1->extLength & UDF_EXTENT_LENGTH_MASK) +
+-                              blocksize - 1) & ~UDF_EXTENT_LENGTH_MASK) {
+-                              lip1->extLength = (lip1->extLength -
+-                                                (li->extLength &
+-                                                 UDF_EXTENT_LENGTH_MASK) +
+-                                                 UDF_EXTENT_LENGTH_MASK) &
+-                                                      ~(blocksize - 1);
+-                              li->extLength = (li->extLength &
+-                                               UDF_EXTENT_FLAG_MASK) +
+-                                              (UDF_EXTENT_LENGTH_MASK + 1) -
+-                                              blocksize;
+-                              lip1->extLocation.logicalBlockNum =
+-                                      li->extLocation.logicalBlockNum +
+-                                      ((li->extLength &
+-                                              UDF_EXTENT_LENGTH_MASK) >>
+-                                              blocksize_bits);
+-                      } else {
++                           (lip1->extLength & UDF_EXTENT_LENGTH_MASK) +
++                           blocksize - 1) <= UDF_EXTENT_LENGTH_MASK) {
+                               li->extLength = lip1->extLength +
+                                       (((li->extLength &
+                                               UDF_EXTENT_LENGTH_MASK) +
diff --git a/queue-6.2/udf-do-not-update-file-length-for-failed-writes-to-inline-files.patch b/queue-6.2/udf-do-not-update-file-length-for-failed-writes-to-inline-files.patch
new file mode 100644 (file)
index 0000000..5478bcd
--- /dev/null
@@ -0,0 +1,62 @@
+From 256fe4162f8b5a1625b8603ca5f7ff79725bfb47 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Mon, 2 Jan 2023 20:14:47 +0100
+Subject: udf: Do not update file length for failed writes to inline files
+
+From: Jan Kara <jack@suse.cz>
+
+commit 256fe4162f8b5a1625b8603ca5f7ff79725bfb47 upstream.
+
+When write to inline file fails (or happens only partly), we still
+updated length of inline data as if the whole write succeeded. Fix the
+update of length of inline data to happen only if the write succeeds.
+
+Reported-by: syzbot+0937935b993956ba28ab@syzkaller.appspotmail.com
+CC: stable@vger.kernel.org
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/udf/file.c |   26 ++++++++++++--------------
+ 1 file changed, 12 insertions(+), 14 deletions(-)
+
+--- a/fs/udf/file.c
++++ b/fs/udf/file.c
+@@ -149,26 +149,24 @@ static ssize_t udf_file_write_iter(struc
+               goto out;
+       down_write(&iinfo->i_data_sem);
+-      if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
+-              loff_t end = iocb->ki_pos + iov_iter_count(from);
+-
+-              if (inode->i_sb->s_blocksize <
+-                              (udf_file_entry_alloc_offset(inode) + end)) {
+-                      err = udf_expand_file_adinicb(inode);
+-                      if (err) {
+-                              inode_unlock(inode);
+-                              udf_debug("udf_expand_adinicb: err=%d\n", err);
+-                              return err;
+-                      }
+-              } else {
+-                      iinfo->i_lenAlloc = max(end, inode->i_size);
+-                      up_write(&iinfo->i_data_sem);
++      if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB &&
++          inode->i_sb->s_blocksize < (udf_file_entry_alloc_offset(inode) +
++                               iocb->ki_pos + iov_iter_count(from))) {
++              err = udf_expand_file_adinicb(inode);
++              if (err) {
++                      inode_unlock(inode);
++                      udf_debug("udf_expand_adinicb: err=%d\n", err);
++                      return err;
+               }
+       } else
+               up_write(&iinfo->i_data_sem);
+       retval = __generic_file_write_iter(iocb, from);
+ out:
++      down_write(&iinfo->i_data_sem);
++      if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB && retval > 0)
++              iinfo->i_lenAlloc = inode->i_size;
++      up_write(&iinfo->i_data_sem);
+       inode_unlock(inode);
+       if (retval > 0) {
diff --git a/queue-6.2/udf-fix-file-corruption-when-appending-just-after-end-of-preallocated-extent.patch b/queue-6.2/udf-fix-file-corruption-when-appending-just-after-end-of-preallocated-extent.patch
new file mode 100644 (file)
index 0000000..26c5ad6
--- /dev/null
@@ -0,0 +1,63 @@
+From 36ec52ea038b18a53e198116ef7d7e70c87db046 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Mon, 23 Jan 2023 14:18:47 +0100
+Subject: udf: Fix file corruption when appending just after end of preallocated extent
+
+From: Jan Kara <jack@suse.cz>
+
+commit 36ec52ea038b18a53e198116ef7d7e70c87db046 upstream.
+
+When we append new block just after the end of preallocated extent, the
+code in inode_getblk() wrongly determined we're going to use the
+preallocated extent which resulted in adding block into a wrong logical
+offset in the file. Sequence like this manifests it:
+
+xfs_io -f -c "pwrite 0x2cacf 0xd122" -c "truncate 0x2dd6f" \
+  -c "pwrite 0x27fd9 0x69a9" -c "pwrite 0x32981 0x7244" <file>
+
+The code that determined the use of preallocated extent is actually
+stale because udf_do_extend_file() does not create preallocation anymore
+so after calling that function we are sure there's no usable
+preallocation. Just remove the faulty condition.
+
+CC: stable@vger.kernel.org
+Fixes: 16d055656814 ("udf: Discard preallocation before extending file with a hole")
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/udf/inode.c |   24 +++++++++++-------------
+ 1 file changed, 11 insertions(+), 13 deletions(-)
+
+--- a/fs/udf/inode.c
++++ b/fs/udf/inode.c
+@@ -799,19 +799,17 @@ static sector_t inode_getblk(struct inod
+               c = 0;
+               offset = 0;
+               count += ret;
+-              /* We are not covered by a preallocated extent? */
+-              if ((laarr[0].extLength & UDF_EXTENT_FLAG_MASK) !=
+-                                              EXT_NOT_RECORDED_ALLOCATED) {
+-                      /* Is there any real extent? - otherwise we overwrite
+-                       * the fake one... */
+-                      if (count)
+-                              c = !c;
+-                      laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
+-                              inode->i_sb->s_blocksize;
+-                      memset(&laarr[c].extLocation, 0x00,
+-                              sizeof(struct kernel_lb_addr));
+-                      count++;
+-              }
++              /*
++               * Is there any real extent? - otherwise we overwrite the fake
++               * one...
++               */
++              if (count)
++                      c = !c;
++              laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
++                      inode->i_sb->s_blocksize;
++              memset(&laarr[c].extLocation, 0x00,
++                      sizeof(struct kernel_lb_addr));
++              count++;
+               endnum = c + 1;
+               lastblock = 1;
+       } else {
diff --git a/queue-6.2/udf-preserve-link-count-of-system-files.patch b/queue-6.2/udf-preserve-link-count-of-system-files.patch
new file mode 100644 (file)
index 0000000..68ea922
--- /dev/null
@@ -0,0 +1,69 @@
+From fc8033a34a3ca7d23353e645e6dde5d364ac5f12 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Tue, 3 Jan 2023 09:56:56 +0100
+Subject: udf: Preserve link count of system files
+
+From: Jan Kara <jack@suse.cz>
+
+commit fc8033a34a3ca7d23353e645e6dde5d364ac5f12 upstream.
+
+System files in UDF filesystem have link count 0. To not confuse VFS we
+fudge the link count to be 1 when reading such inodes however we forget
+to restore the link count of 0 when writing such inodes. Fix that.
+
+CC: stable@vger.kernel.org
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/udf/inode.c |    9 +++++++--
+ fs/udf/super.c |    1 +
+ fs/udf/udf_i.h |    3 ++-
+ 3 files changed, 10 insertions(+), 3 deletions(-)
+
+--- a/fs/udf/inode.c
++++ b/fs/udf/inode.c
+@@ -1373,6 +1373,7 @@ reread:
+               ret = -EIO;
+               goto out;
+       }
++      iinfo->i_hidden = hidden_inode;
+       iinfo->i_unique = 0;
+       iinfo->i_lenEAttr = 0;
+       iinfo->i_lenExtents = 0;
+@@ -1708,8 +1709,12 @@ static int udf_update_inode(struct inode
+       if (S_ISDIR(inode->i_mode) && inode->i_nlink > 0)
+               fe->fileLinkCount = cpu_to_le16(inode->i_nlink - 1);
+-      else
+-              fe->fileLinkCount = cpu_to_le16(inode->i_nlink);
++      else {
++              if (iinfo->i_hidden)
++                      fe->fileLinkCount = cpu_to_le16(0);
++              else
++                      fe->fileLinkCount = cpu_to_le16(inode->i_nlink);
++      }
+       fe->informationLength = cpu_to_le64(inode->i_size);
+--- a/fs/udf/super.c
++++ b/fs/udf/super.c
+@@ -147,6 +147,7 @@ static struct inode *udf_alloc_inode(str
+       ei->i_next_alloc_goal = 0;
+       ei->i_strat4096 = 0;
+       ei->i_streamdir = 0;
++      ei->i_hidden = 0;
+       init_rwsem(&ei->i_data_sem);
+       ei->cached_extent.lstart = -1;
+       spin_lock_init(&ei->i_extent_cache_lock);
+--- a/fs/udf/udf_i.h
++++ b/fs/udf/udf_i.h
+@@ -44,7 +44,8 @@ struct udf_inode_info {
+       unsigned                i_use : 1;      /* unallocSpaceEntry */
+       unsigned                i_strat4096 : 1;
+       unsigned                i_streamdir : 1;
+-      unsigned                reserved : 25;
++      unsigned                i_hidden : 1;   /* hidden system inode */
++      unsigned                reserved : 24;
+       __u8                    *i_data;
+       struct kernel_lb_addr   i_locStreamdir;
+       __u64                   i_lenStreams;
diff --git a/queue-6.2/udf-truncate-added-extents-on-failed-expansion.patch b/queue-6.2/udf-truncate-added-extents-on-failed-expansion.patch
new file mode 100644 (file)
index 0000000..0225928
--- /dev/null
@@ -0,0 +1,65 @@
+From 70bfb3a8d661d4fdc742afc061b88a7f3fc9f500 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Thu, 15 Dec 2022 14:24:03 +0100
+Subject: udf: Truncate added extents on failed expansion
+
+From: Jan Kara <jack@suse.cz>
+
+commit 70bfb3a8d661d4fdc742afc061b88a7f3fc9f500 upstream.
+
+When a file expansion failed because we didn't have enough space for
+indirect extents make sure we truncate extents created so far so that we
+don't leave extents beyond EOF.
+
+CC: stable@vger.kernel.org
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/udf/inode.c |   15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+--- a/fs/udf/inode.c
++++ b/fs/udf/inode.c
+@@ -521,8 +521,10 @@ static int udf_do_extend_file(struct ino
+       }
+       if (fake) {
+-              udf_add_aext(inode, last_pos, &last_ext->extLocation,
+-                           last_ext->extLength, 1);
++              err = udf_add_aext(inode, last_pos, &last_ext->extLocation,
++                                 last_ext->extLength, 1);
++              if (err < 0)
++                      goto out_err;
+               count++;
+       } else {
+               struct kernel_lb_addr tmploc;
+@@ -556,7 +558,7 @@ static int udf_do_extend_file(struct ino
+               err = udf_add_aext(inode, last_pos, &last_ext->extLocation,
+                                  last_ext->extLength, 1);
+               if (err)
+-                      return err;
++                      goto out_err;
+               count++;
+       }
+       if (new_block_bytes) {
+@@ -565,7 +567,7 @@ static int udf_do_extend_file(struct ino
+               err = udf_add_aext(inode, last_pos, &last_ext->extLocation,
+                                  last_ext->extLength, 1);
+               if (err)
+-                      return err;
++                      goto out_err;
+               count++;
+       }
+@@ -579,6 +581,11 @@ out:
+               return -EIO;
+       return count;
++out_err:
++      /* Remove extents we've created so far */
++      udf_clear_extent_cache(inode);
++      udf_truncate_extents(inode);
++      return err;
+ }
+ /* Extend the final block of the file to final_block_len bytes */