]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.6-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 12 Jan 2025 12:38:12 +0000 (13:38 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 12 Jan 2025 12:38:12 +0000 (13:38 +0100)
added patches:
dm-verity-fec-fix-rs-fec-repair-for-roots-unaligned-to-block-size-take-2.patch
f2fs-fix-null-ptr-deref-in-f2fs_submit_page_bio.patch

queue-6.6/dm-verity-fec-fix-rs-fec-repair-for-roots-unaligned-to-block-size-take-2.patch [new file with mode: 0644]
queue-6.6/f2fs-fix-null-ptr-deref-in-f2fs_submit_page_bio.patch [new file with mode: 0644]
queue-6.6/series

diff --git a/queue-6.6/dm-verity-fec-fix-rs-fec-repair-for-roots-unaligned-to-block-size-take-2.patch b/queue-6.6/dm-verity-fec-fix-rs-fec-repair-for-roots-unaligned-to-block-size-take-2.patch
new file mode 100644 (file)
index 0000000..bdac21b
--- /dev/null
@@ -0,0 +1,159 @@
+From 6df90c02bae468a3a6110bafbc659884d0c4966c Mon Sep 17 00:00:00 2001
+From: Milan Broz <gmazyland@gmail.com>
+Date: Wed, 18 Dec 2024 13:56:58 +0100
+Subject: dm-verity FEC: Fix RS FEC repair for roots unaligned to block size (take 2)
+
+From: Milan Broz <gmazyland@gmail.com>
+
+commit 6df90c02bae468a3a6110bafbc659884d0c4966c upstream.
+
+This patch fixes an issue that was fixed in the commit
+  df7b59ba9245 ("dm verity: fix FEC for RS roots unaligned to block size")
+but later broken again in the commit
+  8ca7cab82bda ("dm verity fec: fix misaligned RS roots IO")
+
+If the Reed-Solomon roots setting spans multiple blocks, the code does not
+use proper parity bytes and randomly fails to repair even trivial errors.
+
+This bug cannot happen if the sector size is multiple of RS roots
+setting (Android case with roots 2).
+
+The previous solution was to find a dm-bufio block size that is multiple
+of the device sector size and roots size. Unfortunately, the optimization
+in commit 8ca7cab82bda ("dm verity fec: fix misaligned RS roots IO")
+is incorrect and uses data block size for some roots (for example, it uses
+4096 block size for roots = 20).
+
+This patch uses a different approach:
+
+ - It always uses a configured data block size for dm-bufio to avoid
+ possible misaligned IOs.
+
+ - and it caches the processed parity bytes, so it can join it
+ if it spans two blocks.
+
+As the RS calculation is called only if an error is detected and
+the process is computationally intensive, copying a few more bytes
+should not introduce performance issues.
+
+The issue was reported to cryptsetup with trivial reproducer
+  https://gitlab.com/cryptsetup/cryptsetup/-/issues/923
+
+Reproducer (with roots=20):
+
+ # create verity device with RS FEC
+ dd if=/dev/urandom of=data.img bs=4096 count=8 status=none
+ veritysetup format data.img hash.img --fec-device=fec.img --fec-roots=20 | \
+ awk '/^Root hash/{ print $3 }' >roothash
+
+ # create an erasure that should always be repairable with this roots setting
+ dd if=/dev/zero of=data.img conv=notrunc bs=1 count=4 seek=4 status=none
+
+ # try to read it through dm-verity
+ veritysetup open data.img test hash.img --fec-device=fec.img --fec-roots=20 $(cat roothash)
+ dd if=/dev/mapper/test of=/dev/null bs=4096 status=noxfer
+
+ Even now the log says it cannot repair it:
+   : verity-fec: 7:1: FEC 0: failed to correct: -74
+   : device-mapper: verity: 7:1: data block 0 is corrupted
+   ...
+
+With this fix, errors are properly repaired.
+   : verity-fec: 7:1: FEC 0: corrected 4 errors
+
+Signed-off-by: Milan Broz <gmazyland@gmail.com>
+Fixes: 8ca7cab82bda ("dm verity fec: fix misaligned RS roots IO")
+Cc: stable@vger.kernel.org
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Milan Broz <gmazyland@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/md/dm-verity-fec.c |   39 ++++++++++++++++++++++++++-------------
+ 1 file changed, 26 insertions(+), 13 deletions(-)
+
+--- a/drivers/md/dm-verity-fec.c
++++ b/drivers/md/dm-verity-fec.c
+@@ -60,14 +60,19 @@ static int fec_decode_rs8(struct dm_veri
+  * to the data block. Caller is responsible for releasing buf.
+  */
+ static u8 *fec_read_parity(struct dm_verity *v, u64 rsb, int index,
+-                         unsigned int *offset, struct dm_buffer **buf)
++                         unsigned int *offset, unsigned int par_buf_offset,
++                        struct dm_buffer **buf)
+ {
+       u64 position, block, rem;
+       u8 *res;
++      /* We have already part of parity bytes read, skip to the next block */
++      if (par_buf_offset)
++              index++;
++
+       position = (index + rsb) * v->fec->roots;
+       block = div64_u64_rem(position, v->fec->io_size, &rem);
+-      *offset = (unsigned int)rem;
++      *offset = par_buf_offset ? 0 : (unsigned int)rem;
+       res = dm_bufio_read(v->fec->bufio, block, buf);
+       if (IS_ERR(res)) {
+@@ -127,10 +132,11 @@ static int fec_decode_bufs(struct dm_ver
+ {
+       int r, corrected = 0, res;
+       struct dm_buffer *buf;
+-      unsigned int n, i, offset;
+-      u8 *par, *block;
++      unsigned int n, i, offset, par_buf_offset = 0;
++      u8 *par, *block, par_buf[DM_VERITY_FEC_RSM - DM_VERITY_FEC_MIN_RSN];
+-      par = fec_read_parity(v, rsb, block_offset, &offset, &buf);
++      par = fec_read_parity(v, rsb, block_offset, &offset,
++                            par_buf_offset, &buf);
+       if (IS_ERR(par))
+               return PTR_ERR(par);
+@@ -140,7 +146,8 @@ static int fec_decode_bufs(struct dm_ver
+        */
+       fec_for_each_buffer_rs_block(fio, n, i) {
+               block = fec_buffer_rs_block(v, fio, n, i);
+-              res = fec_decode_rs8(v, fio, block, &par[offset], neras);
++              memcpy(&par_buf[par_buf_offset], &par[offset], v->fec->roots - par_buf_offset);
++              res = fec_decode_rs8(v, fio, block, par_buf, neras);
+               if (res < 0) {
+                       r = res;
+                       goto error;
+@@ -153,12 +160,21 @@ static int fec_decode_bufs(struct dm_ver
+               if (block_offset >= 1 << v->data_dev_block_bits)
+                       goto done;
+-              /* read the next block when we run out of parity bytes */
+-              offset += v->fec->roots;
++              /* Read the next block when we run out of parity bytes */
++              offset += (v->fec->roots - par_buf_offset);
++              /* Check if parity bytes are split between blocks */
++              if (offset < v->fec->io_size && (offset + v->fec->roots) > v->fec->io_size) {
++                      par_buf_offset = v->fec->io_size - offset;
++                      memcpy(par_buf, &par[offset], par_buf_offset);
++                      offset += par_buf_offset;
++              } else
++                      par_buf_offset = 0;
++
+               if (offset >= v->fec->io_size) {
+                       dm_bufio_release(buf);
+-                      par = fec_read_parity(v, rsb, block_offset, &offset, &buf);
++                      par = fec_read_parity(v, rsb, block_offset, &offset,
++                                            par_buf_offset, &buf);
+                       if (IS_ERR(par))
+                               return PTR_ERR(par);
+               }
+@@ -743,10 +759,7 @@ int verity_fec_ctr(struct dm_verity *v)
+               return -E2BIG;
+       }
+-      if ((f->roots << SECTOR_SHIFT) & ((1 << v->data_dev_block_bits) - 1))
+-              f->io_size = 1 << v->data_dev_block_bits;
+-      else
+-              f->io_size = v->fec->roots << SECTOR_SHIFT;
++      f->io_size = 1 << v->data_dev_block_bits;
+       f->bufio = dm_bufio_client_create(f->dev->bdev,
+                                         f->io_size,
diff --git a/queue-6.6/f2fs-fix-null-ptr-deref-in-f2fs_submit_page_bio.patch b/queue-6.6/f2fs-fix-null-ptr-deref-in-f2fs_submit_page_bio.patch
new file mode 100644 (file)
index 0000000..4615e19
--- /dev/null
@@ -0,0 +1,96 @@
+From b7d0a97b28083084ebdd8e5c6bccd12e6ec18faa Mon Sep 17 00:00:00 2001
+From: Ye Bin <yebin10@huawei.com>
+Date: Sat, 12 Oct 2024 00:44:50 +0800
+Subject: f2fs: fix null-ptr-deref in f2fs_submit_page_bio()
+
+From: Ye Bin <yebin10@huawei.com>
+
+commit b7d0a97b28083084ebdd8e5c6bccd12e6ec18faa upstream.
+
+There's issue as follows when concurrently installing the f2fs.ko
+module and mounting the f2fs file system:
+KASAN: null-ptr-deref in range [0x0000000000000020-0x0000000000000027]
+RIP: 0010:__bio_alloc+0x2fb/0x6c0 [f2fs]
+Call Trace:
+ <TASK>
+ f2fs_submit_page_bio+0x126/0x8b0 [f2fs]
+ __get_meta_page+0x1d4/0x920 [f2fs]
+ get_checkpoint_version.constprop.0+0x2b/0x3c0 [f2fs]
+ validate_checkpoint+0xac/0x290 [f2fs]
+ f2fs_get_valid_checkpoint+0x207/0x950 [f2fs]
+ f2fs_fill_super+0x1007/0x39b0 [f2fs]
+ mount_bdev+0x183/0x250
+ legacy_get_tree+0xf4/0x1e0
+ vfs_get_tree+0x88/0x340
+ do_new_mount+0x283/0x5e0
+ path_mount+0x2b2/0x15b0
+ __x64_sys_mount+0x1fe/0x270
+ do_syscall_64+0x5f/0x170
+ entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+Above issue happens as the biset of the f2fs file system is not
+initialized before register "f2fs_fs_type".
+To address above issue just register "f2fs_fs_type" at the last in
+init_f2fs_fs(). Ensure that all f2fs file system resources are
+initialized.
+
+Fixes: f543805fcd60 ("f2fs: introduce private bioset")
+Signed-off-by: Ye Bin <yebin10@huawei.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Bin Lan <lanbincn@qq.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/f2fs/super.c |   12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -4931,9 +4931,6 @@ static int __init init_f2fs_fs(void)
+       err = register_shrinker(&f2fs_shrinker_info, "f2fs-shrinker");
+       if (err)
+               goto free_sysfs;
+-      err = register_filesystem(&f2fs_fs_type);
+-      if (err)
+-              goto free_shrinker;
+       f2fs_create_root_stats();
+       err = f2fs_init_post_read_processing();
+       if (err)
+@@ -4956,7 +4953,12 @@ static int __init init_f2fs_fs(void)
+       err = f2fs_create_casefold_cache();
+       if (err)
+               goto free_compress_cache;
++      err = register_filesystem(&f2fs_fs_type);
++      if (err)
++              goto free_casefold_cache;
+       return 0;
++free_casefold_cache:
++      f2fs_destroy_casefold_cache();
+ free_compress_cache:
+       f2fs_destroy_compress_cache();
+ free_compress_mempool:
+@@ -4971,8 +4973,6 @@ free_post_read:
+       f2fs_destroy_post_read_processing();
+ free_root_stats:
+       f2fs_destroy_root_stats();
+-      unregister_filesystem(&f2fs_fs_type);
+-free_shrinker:
+       unregister_shrinker(&f2fs_shrinker_info);
+ free_sysfs:
+       f2fs_exit_sysfs();
+@@ -4996,6 +4996,7 @@ fail:
+ static void __exit exit_f2fs_fs(void)
+ {
++      unregister_filesystem(&f2fs_fs_type);
+       f2fs_destroy_casefold_cache();
+       f2fs_destroy_compress_cache();
+       f2fs_destroy_compress_mempool();
+@@ -5004,7 +5005,6 @@ static void __exit exit_f2fs_fs(void)
+       f2fs_destroy_iostat_processing();
+       f2fs_destroy_post_read_processing();
+       f2fs_destroy_root_stats();
+-      unregister_filesystem(&f2fs_fs_type);
+       unregister_shrinker(&f2fs_shrinker_info);
+       f2fs_exit_sysfs();
+       f2fs_destroy_garbage_collection_cache();
index 883c8ba56a40c0022bc2e515445602494824edb3..bad1c950667c1b5d11600cf923d1b0259ed0971d 100644 (file)
@@ -76,3 +76,5 @@ acpi-resource-add-asus-vivobook-x1504vap-to-irq1_level_low_skip_override.patch
 drm-amdkfd-fixed-page-fault-when-enable-mes-shader-debugger.patch
 drm-amd-display-increase-max_surfaces-to-the-value-supported-by-hw.patch
 io_uring-timeout-fix-multishot-updates.patch
+f2fs-fix-null-ptr-deref-in-f2fs_submit_page_bio.patch
+dm-verity-fec-fix-rs-fec-repair-for-roots-unaligned-to-block-size-take-2.patch