]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 15 Jul 2026 10:20:17 +0000 (12:20 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 15 Jul 2026 10:20:17 +0000 (12:20 +0200)
added patches:
block-partitions-fix-of_node-refcount-leak-in-of_partition.patch
btrfs-check-and-set-extent_delalloc_new-before-clearing-extent_delalloc.patch
btrfs-do-not-trim-a-device-which-is-not-writeable.patch
crypto-af_alg-remove-zero-copy-support-from-skcipher-and-aead.patch
crypto-atmel-sha204a-drop-hwrng-quality-reduction-for-atsha204a.patch
crypto-caam-use-print_hex_dump_devel-to-guard-key-hex-dumps-again.patch
crypto-caam-use-print_hex_dump_devel-to-guard-key-hex-dumps.patch
crypto-ccp-do-not-initialize-snp-for-ioctl-snp_commit.patch
crypto-ccp-do-not-initialize-snp-for-ioctl-snp_config.patch
crypto-ccp-do-not-initialize-snp-for-ioctl-snp_vlek_load.patch
crypto-ccp-do-not-initialize-snp-for-sev-ioctls.patch
crypto-chacha20poly1305-validate-poly1305-template-argument.patch
crypto-crypto4xx-remove-insecure-and-unused-rng_alg.patch
crypto-drbg-fix-drbg_max_addtl-on-64-bit-kernels.patch
crypto-drbg-fix-returning-success-on-failure-in-ctr_drbg.patch
crypto-drbg-fix-the-fips_enabled-priority-boost.patch
crypto-ecc-fix-carry-overflow-in-vli-multiplication.patch
crypto-hisi-trng-remove-crypto_rng-interface.patch
crypto-loongson-remove-broken-and-unused-loongson-rng.patch
crypto-loongson-select-crypto_rng.patch
crypto-pcrypt-restore-callback-for-non-parallel-fallback.patch
crypto-tegra-fix-refcount-leak-in-tegra_se_host1x_submit.patch
dm-ioctl-report-an-error-if-a-device-has-no-table.patch
hwrng-jh7110-fix-refcount-leak-in-starfive_trng_read.patch
isofs-bound-rock-ridge-symlink-components-to-the-sl-record.patch
nvme-multipath-set-bio_remapped-on-bios-remapped-to-per-path-namespace-disks.patch
nvme-target-rdma-fix-ndev-refcount-leak-on-queue-connect.patch
nvmet-auth-validate-reply-message-payload-bounds-against-transfer-length.patch
nvmet-fix-pre-auth-out-of-bounds-heap-read-in-discovery-get-log-page.patch
partitions-aix-bound-the-pp_count-scan-to-the-ppe-array.patch
udf-validate-free-block-extents-against-the-partition-length.patch
udf-validate-sparing-table-length-as-an-entry-count-not-a-byte-count.patch
udf-validate-vat-header-length-against-the-vat-inode-size.patch

34 files changed:
queue-6.18/block-partitions-fix-of_node-refcount-leak-in-of_partition.patch [new file with mode: 0644]
queue-6.18/btrfs-check-and-set-extent_delalloc_new-before-clearing-extent_delalloc.patch [new file with mode: 0644]
queue-6.18/btrfs-do-not-trim-a-device-which-is-not-writeable.patch [new file with mode: 0644]
queue-6.18/crypto-af_alg-remove-zero-copy-support-from-skcipher-and-aead.patch [new file with mode: 0644]
queue-6.18/crypto-atmel-sha204a-drop-hwrng-quality-reduction-for-atsha204a.patch [new file with mode: 0644]
queue-6.18/crypto-caam-use-print_hex_dump_devel-to-guard-key-hex-dumps-again.patch [new file with mode: 0644]
queue-6.18/crypto-caam-use-print_hex_dump_devel-to-guard-key-hex-dumps.patch [new file with mode: 0644]
queue-6.18/crypto-ccp-do-not-initialize-snp-for-ioctl-snp_commit.patch [new file with mode: 0644]
queue-6.18/crypto-ccp-do-not-initialize-snp-for-ioctl-snp_config.patch [new file with mode: 0644]
queue-6.18/crypto-ccp-do-not-initialize-snp-for-ioctl-snp_vlek_load.patch [new file with mode: 0644]
queue-6.18/crypto-ccp-do-not-initialize-snp-for-sev-ioctls.patch [new file with mode: 0644]
queue-6.18/crypto-chacha20poly1305-validate-poly1305-template-argument.patch [new file with mode: 0644]
queue-6.18/crypto-crypto4xx-remove-insecure-and-unused-rng_alg.patch [new file with mode: 0644]
queue-6.18/crypto-drbg-fix-drbg_max_addtl-on-64-bit-kernels.patch [new file with mode: 0644]
queue-6.18/crypto-drbg-fix-returning-success-on-failure-in-ctr_drbg.patch [new file with mode: 0644]
queue-6.18/crypto-drbg-fix-the-fips_enabled-priority-boost.patch [new file with mode: 0644]
queue-6.18/crypto-ecc-fix-carry-overflow-in-vli-multiplication.patch [new file with mode: 0644]
queue-6.18/crypto-hisi-trng-remove-crypto_rng-interface.patch [new file with mode: 0644]
queue-6.18/crypto-loongson-remove-broken-and-unused-loongson-rng.patch [new file with mode: 0644]
queue-6.18/crypto-loongson-select-crypto_rng.patch [new file with mode: 0644]
queue-6.18/crypto-pcrypt-restore-callback-for-non-parallel-fallback.patch [new file with mode: 0644]
queue-6.18/crypto-tegra-fix-refcount-leak-in-tegra_se_host1x_submit.patch [new file with mode: 0644]
queue-6.18/dm-ioctl-report-an-error-if-a-device-has-no-table.patch [new file with mode: 0644]
queue-6.18/hwrng-jh7110-fix-refcount-leak-in-starfive_trng_read.patch [new file with mode: 0644]
queue-6.18/isofs-bound-rock-ridge-symlink-components-to-the-sl-record.patch [new file with mode: 0644]
queue-6.18/nvme-multipath-set-bio_remapped-on-bios-remapped-to-per-path-namespace-disks.patch [new file with mode: 0644]
queue-6.18/nvme-target-rdma-fix-ndev-refcount-leak-on-queue-connect.patch [new file with mode: 0644]
queue-6.18/nvmet-auth-validate-reply-message-payload-bounds-against-transfer-length.patch [new file with mode: 0644]
queue-6.18/nvmet-fix-pre-auth-out-of-bounds-heap-read-in-discovery-get-log-page.patch [new file with mode: 0644]
queue-6.18/partitions-aix-bound-the-pp_count-scan-to-the-ppe-array.patch [new file with mode: 0644]
queue-6.18/series
queue-6.18/udf-validate-free-block-extents-against-the-partition-length.patch [new file with mode: 0644]
queue-6.18/udf-validate-sparing-table-length-as-an-entry-count-not-a-byte-count.patch [new file with mode: 0644]
queue-6.18/udf-validate-vat-header-length-against-the-vat-inode-size.patch [new file with mode: 0644]

diff --git a/queue-6.18/block-partitions-fix-of_node-refcount-leak-in-of_partition.patch b/queue-6.18/block-partitions-fix-of_node-refcount-leak-in-of_partition.patch
new file mode 100644 (file)
index 0000000..d7fefff
--- /dev/null
@@ -0,0 +1,54 @@
+From 148cd4873115feb266c002d4d4618ea7f14342d9 Mon Sep 17 00:00:00 2001
+From: Wentao Liang <vulab@iscas.ac.cn>
+Date: Tue, 26 May 2026 10:21:24 +0000
+Subject: block: partitions: fix of_node refcount leak in of_partition()
+
+From: Wentao Liang <vulab@iscas.ac.cn>
+
+commit 148cd4873115feb266c002d4d4618ea7f14342d9 upstream.
+
+of_partition() calls of_node_get() on the parent device node at the
+beginning of the function, storing the reference in 'partitions_np'.
+This reference is leaked in two paths:
+
+1. The compatibility check at the top of the function returns 0
+   without releasing partitions_np when the node exists but is not
+   "fixed-partitions" compatible.
+
+2. The function returns 1 at the end after successfully processing
+   all partitions without releasing partitions_np.
+
+Fix both leaks by adding of_node_put(partitions_np) on each path.
+
+Fixes: 2e3a191e89f9 ("block: add support for partition table defined in OF")
+Cc: stable@vger.kernel.org
+Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
+Reviewed-by: Md Haris Iqbal <haris.iqbal@linux.dev>
+Link: https://patch.msgid.link/20260526102124.2283846-1-vulab@iscas.ac.cn
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ block/partitions/of.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/block/partitions/of.c
++++ b/block/partitions/of.c
+@@ -76,8 +76,10 @@ int of_partition(struct parsed_partition
+       struct device_node *partitions_np = of_node_get(ddev->of_node);
+       if (!partitions_np ||
+-          !of_device_is_compatible(partitions_np, "fixed-partitions"))
++          !of_device_is_compatible(partitions_np, "fixed-partitions")) {
++              of_node_put(partitions_np);
+               return 0;
++      }
+       slot = 1;
+       /* Validate parition offset and size */
+@@ -106,5 +108,6 @@ int of_partition(struct parsed_partition
+       strlcat(state->pp_buf, "\n", PAGE_SIZE);
++      of_node_put(partitions_np);
+       return 1;
+ }
diff --git a/queue-6.18/btrfs-check-and-set-extent_delalloc_new-before-clearing-extent_delalloc.patch b/queue-6.18/btrfs-check-and-set-extent_delalloc_new-before-clearing-extent_delalloc.patch
new file mode 100644 (file)
index 0000000..4a2ebf2
--- /dev/null
@@ -0,0 +1,265 @@
+From 95ee2231896d5f2a31760411429075a99d6045a7 Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Mon, 20 Apr 2026 18:32:49 +0930
+Subject: btrfs: check and set EXTENT_DELALLOC_NEW before clearing EXTENT_DELALLOC
+
+From: Qu Wenruo <wqu@suse.com>
+
+commit 95ee2231896d5f2a31760411429075a99d6045a7 upstream.
+
+[WARNING]
+When running test cases with injected errors or shutdown, e.g.
+generic/388 or generic/475, there is a chance that the following kernel
+warning is triggered:
+
+  BTRFS info (device dm-2): first mount of filesystem d8a19a28-3232-4809-b0df-38df83e71bff
+  BTRFS info (device dm-2): using crc32c checksum algorithm
+  BTRFS info (device dm-2): checking UUID tree
+  BTRFS info (device dm-2): turning on async discard
+  BTRFS info (device dm-2): enabling free space tree
+  BTRFS critical (device dm-2 state E): emergency shutdown
+  ------------[ cut here ]------------
+  WARNING: extent_io.c:1742 at extent_writepage_io+0x437/0x520 [btrfs], CPU#2: kworker/u43:2/651591
+  CPU: 2 UID: 0 PID: 651591 Comm: kworker/u43:2 Tainted: G        W  OE       7.0.0-rc6-custom+ #365 PREEMPT(full)  5804053f02137e627472d94b5128cc9fcb110e88
+  RIP: 0010:extent_writepage_io+0x437/0x520 [btrfs]
+  Call Trace:
+   <TASK>
+   extent_write_cache_pages+0x2a5/0x820 [btrfs 70299925d0856939e93b17d480651713b3cbba58]
+   btrfs_writepages+0x74/0x130 [btrfs 70299925d0856939e93b17d480651713b3cbba58]
+   do_writepages+0xd0/0x160
+   __writeback_single_inode+0x42/0x340
+   writeback_sb_inodes+0x22d/0x580
+   wb_writeback+0xc6/0x360
+   wb_workfn+0xbd/0x470
+   process_one_work+0x198/0x3b0
+   worker_thread+0x1c8/0x330
+   kthread+0xee/0x120
+   ret_from_fork+0x2a6/0x330
+   ret_from_fork_asm+0x11/0x20
+   </TASK>
+  ---[ end trace 0000000000000000 ]---
+  BTRFS error (device dm-2 state E): root 5 ino 259 folio 1323008 is marked dirty without notifying the fs
+  BTRFS error (device dm-2 state E): failed to submit blocks, root=5 inode=259 folio=1323008 submit_bitmap=0: -117
+  BTRFS info (device dm-2 state E): last unmount of filesystem d8a19a28-3232-4809-b0df-38df83e71bff
+
+[CAUSE]
+Inside btrfs we have the following pattern in several locations, for
+example inside btrfs_dirty_folio():
+
+       btrfs_clear_extent_bit(&inode->io_tree, start_pos, end_of_last_block,
+                              EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG,
+                              cached);
+
+       ret = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block,
+                                       extra_bits, cached);
+       if (ret)
+               return ret;
+
+However btrfs_set_extent_delalloc() can return IO errors other than -ENOMEM
+through the following callchain:
+
+ btrfs_set_extent_delalloc()
+ \- btrfs_find_new_delalloc_bytes()
+    \- btrfs_get_extent()
+       \- btrfs_lookup_file_extent()
+          \- btrfs_search_slot()
+
+When such IO error happened, the previous btrfs_clear_extent_bit() has
+cleared the EXTENT_DELALLOC for the range, and we're expecting
+btrfs_set_extent_delalloc() to re-set EXTENT_DELALLOC.
+
+But since btrfs_set_extent_delalloc() failed before
+btrfs_set_extent_bit(), EXTENT_DELALLOC flag is no longer present.
+
+And if the folio range is dirty before entering
+btrfs_set_extent_delalloc(), we got a dirty folio but no EXTENT_DELALLOC
+flag now.
+
+Then we hit the folio writeback:
+
+  extent_writepage()
+  |- writepage_delalloc()
+  |  No ordered extent is created, as there is no EXTENT_DELALLOC set
+  |  for the folio range.
+  |  This also means the folio has no ordered flag set.
+  |
+  |- extent_writepage_io()
+     \- if (unlikely(!folio_test_ordered(folio))
+        Now we hit the warning.
+
+[FIX]
+Introduce a new helper, btrfs_reset_extent_delalloc() to replace the
+currently open-coded btrfs_clear_extent_bit() +
+btrfs_set_extent_delalloc() combination.
+
+Instead of calling btrfs_clear_extent_bit() first, update
+EXTENT_DELALLOC_NEW first, as that part can fail due to metadata IO,
+meanwhile btrfs_clear_extent_bit() and btrfs_set_extent_bit() won't
+return any error but retry memory allocation until succeeded.
+
+This allows us to fail early without clearing EXTENT_DELALLOC bit, so
+even if that new btrfs_reset_extent_delalloc() failed before touching
+EXTENT_DELALLOC, the existing dirty range will still have their old
+EXTENT_DELALLOC flag present, thus avoid the warning.
+
+CC: stable@vger.kernel.org # 6.1+
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/btrfs_inode.h |    2 +
+ fs/btrfs/file.c        |   25 ++------------------
+ fs/btrfs/inode.c       |   61 +++++++++++++++++++++++++++++++++++++++++++------
+ fs/btrfs/reflink.c     |    4 ---
+ 4 files changed, 60 insertions(+), 32 deletions(-)
+
+--- a/fs/btrfs/btrfs_inode.h
++++ b/fs/btrfs/btrfs_inode.h
+@@ -575,6 +575,8 @@ int btrfs_start_delalloc_roots(struct bt
+ int btrfs_set_extent_delalloc(struct btrfs_inode *inode, u64 start, u64 end,
+                             unsigned int extra_bits,
+                             struct extent_state **cached_state);
++int btrfs_reset_extent_delalloc(struct btrfs_inode *inode, u64 start, u64 end,
++                              unsigned int extra_bits, struct extent_state **cached_state);
+ struct btrfs_new_inode_args {
+       /* Input */
+--- a/fs/btrfs/file.c
++++ b/fs/btrfs/file.c
+@@ -93,16 +93,8 @@ int btrfs_dirty_folio(struct btrfs_inode
+       end_of_last_block = start_pos + num_bytes - 1;
+-      /*
+-       * The pages may have already been dirty, clear out old accounting so
+-       * we can set things up properly
+-       */
+-      btrfs_clear_extent_bit(&inode->io_tree, start_pos, end_of_last_block,
+-                             EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG,
+-                             cached);
+-
+-      ret = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block,
+-                                      extra_bits, cached);
++      ret = btrfs_reset_extent_delalloc(inode, start_pos, end_of_last_block,
++                                        extra_bits, cached);
+       if (ret)
+               return ret;
+@@ -1962,18 +1954,7 @@ again:
+               }
+       }
+-      /*
+-       * page_mkwrite gets called when the page is firstly dirtied after it's
+-       * faulted in, but write(2) could also dirty a page and set delalloc
+-       * bits, thus in this case for space account reason, we still need to
+-       * clear any delalloc bits within this page range since we have to
+-       * reserve data&meta space before lock_page() (see above comments).
+-       */
+-      btrfs_clear_extent_bit(io_tree, page_start, end,
+-                             EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING |
+-                             EXTENT_DEFRAG, &cached_state);
+-
+-      ret = btrfs_set_extent_delalloc(inode, page_start, end, 0, &cached_state);
++      ret = btrfs_reset_extent_delalloc(inode, page_start, end, 0, &cached_state);
+       if (ret < 0) {
+               btrfs_unlock_extent(io_tree, page_start, page_end, &cached_state);
+               goto out_unlock;
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -2720,7 +2720,13 @@ int btrfs_set_extent_delalloc(struct btr
+                             unsigned int extra_bits,
+                             struct extent_state **cached_state)
+ {
+-      WARN_ON(PAGE_ALIGNED(end));
++      const u32 blocksize = inode->root->fs_info->sectorsize;
++
++      /* Basic alignment check. */
++      ASSERT(IS_ALIGNED(start, blocksize), "start=%llu blocksize=%u",
++             start, blocksize);
++      ASSERT(IS_ALIGNED(end + 1, blocksize), "inclusive end=%llu blocksize=%u",
++             end, blocksize);
+       if (start >= i_size_read(&inode->vfs_inode) &&
+           !(inode->flags & BTRFS_INODE_PREALLOC)) {
+@@ -2943,6 +2949,52 @@ int btrfs_writepage_cow_fixup(struct fol
+       return -EAGAIN;
+ }
++/*
++ * Clear the old accounting flags and set EXTENT_DELALLOC for the range.
++ *
++ * Return <0 for error, in that case no range has EXTENT_DELALLOC bit cleared or set.
++ */
++int btrfs_reset_extent_delalloc(struct btrfs_inode *inode, u64 start, u64 end,
++                              unsigned int extra_bits, struct extent_state **cached_state)
++{
++      const u32 blocksize = inode->root->fs_info->sectorsize;
++
++      /* The @extra_bits can only be EXTENT_NORESERVE for now. */
++      ASSERT(!(extra_bits & ~EXTENT_NORESERVE), "extra_bits=0x%x", extra_bits);
++
++      /* Basic alignment check. */
++      ASSERT(IS_ALIGNED(start, blocksize), "start=%llu blocksize=%u",
++             start, blocksize);
++      ASSERT(IS_ALIGNED(end + 1, blocksize), "inclusive end=%llu blocksize=%u",
++             end, blocksize);
++
++      /*
++       * Check and set DELALLOC_NEW flag, this needs to search tree thus can
++       * fail early.  Thus we want to do this before clearing EXTENT_DELALLOC.
++       */
++      if (start >= i_size_read(&inode->vfs_inode) &&
++          !(inode->flags & BTRFS_INODE_PREALLOC)) {
++              /*
++               * There can't be any extents following EOF in this case so just
++               * set the delalloc new bit for the range directly.
++               */
++              extra_bits |= EXTENT_DELALLOC_NEW;
++      } else {
++              int ret;
++
++              ret = btrfs_find_new_delalloc_bytes(inode, start, end + 1 - start,
++                                                  NULL);
++              if (unlikely(ret))
++                      return ret;
++      }
++      /* Clear the old accounting as the range may already be dirty. */
++      btrfs_clear_extent_bit(&inode->io_tree, start, end,
++                             EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING |
++                             EXTENT_DEFRAG, cached_state);
++      return btrfs_set_extent_bit(&inode->io_tree, start, end,
++                                  EXTENT_DELALLOC | extra_bits, cached_state);
++}
++
+ static int insert_reserved_file_extent(struct btrfs_trans_handle *trans,
+                                      struct btrfs_inode *inode, u64 file_pos,
+                                      struct btrfs_file_extent_item *stack_fi,
+@@ -5053,12 +5105,7 @@ again:
+               goto again;
+       }
+-      btrfs_clear_extent_bit(&inode->io_tree, block_start, block_end,
+-                             EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG,
+-                             &cached_state);
+-
+-      ret = btrfs_set_extent_delalloc(inode, block_start, block_end, 0,
+-                                      &cached_state);
++      ret = btrfs_reset_extent_delalloc(inode, block_start, block_end, 0, &cached_state);
+       if (ret) {
+               btrfs_unlock_extent(io_tree, block_start, block_end, &cached_state);
+               goto out_unlock;
+--- a/fs/btrfs/reflink.c
++++ b/fs/btrfs/reflink.c
+@@ -93,9 +93,7 @@ static int copy_inline_to_page(struct bt
+       if (ret < 0)
+               goto out_unlock;
+-      btrfs_clear_extent_bit(&inode->io_tree, file_offset, range_end,
+-                             EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, NULL);
+-      ret = btrfs_set_extent_delalloc(inode, file_offset, range_end, 0, NULL);
++      ret = btrfs_reset_extent_delalloc(inode, file_offset, range_end, 0, NULL);
+       if (ret)
+               goto out_unlock;
diff --git a/queue-6.18/btrfs-do-not-trim-a-device-which-is-not-writeable.patch b/queue-6.18/btrfs-do-not-trim-a-device-which-is-not-writeable.patch
new file mode 100644 (file)
index 0000000..f51f817
--- /dev/null
@@ -0,0 +1,140 @@
+From 1b1937eb08f51319bf71575484cde2b8c517aedc Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Tue, 2 Jun 2026 13:34:46 +0930
+Subject: btrfs: do not trim a device which is not writeable
+
+From: Qu Wenruo <wqu@suse.com>
+
+commit 1b1937eb08f51319bf71575484cde2b8c517aedc upstream.
+
+[BUG]
+There is a bug report that btrfs/242 can randomly fail with the
+following NULL pointer dereference:
+
+  run fstests btrfs/242 at 2026-06-01 10:25:08
+  BTRFS: device fsid d4d7f234-487c-4787-88e4-47a8b68c9874 devid 1 transid 9 /dev/sdc (8:32) scanned by mount (122609)
+  BTRFS info (device sdc): first mount of filesystem d4d7f234-487c-4787-88e4-47a8b68c9874
+  BTRFS info (device sdc): using crc32c checksum algorithm
+  BTRFS warning (device sdc): devid 2 uuid fbe72d72-3272-482d-80fb-ab88ed398192 is missing
+  BTRFS warning (device sdc): devid 2 uuid fbe72d72-3272-482d-80fb-ab88ed398192 is missing
+  BTRFS info (device sdc): allowing degraded mounts
+  BTRFS info (device sdc): turning on async discard
+  BTRFS info (device sdc): enabling free space tree
+  Unable to handle kernel NULL pointer dereference at virtual address 0000000000000018
+  user pgtable: 4k pages, 48-bit VAs, pgdp=000000013fd6b000
+  CPU: 4 UID: 0 PID: 122625 Comm: fstrim Not tainted 7.0.10-2-default #1 PREEMPT(full) openSUSE Tumbleweed e9a5f6b24978fba3bf015a992f865837fdfff3dd
+  Hardware name: QEMU KVM Virtual Machine, BIOS edk2-20250812-19.fc42 08/12/2025
+  pstate: 01400005 (nzcv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
+  pc : btrfs_trim_fs+0x34c/0xa00 [btrfs]
+  lr : btrfs_trim_fs+0x1f0/0xa00 [btrfs]
+  Call trace:
+   btrfs_trim_fs+0x34c/0xa00 [btrfs f02c1d570ceea621c69d302ba75dd61868083840] (P)
+   btrfs_ioctl_fitrim+0xe8/0x178 [btrfs f02c1d570ceea621c69d302ba75dd61868083840]
+   btrfs_ioctl+0xdd4/0x2bd8 [btrfs f02c1d570ceea621c69d302ba75dd61868083840]
+   __arm64_sys_ioctl+0xac/0x108
+   invoke_syscall.constprop.0+0x5c/0xd0
+   el0_svc_common.constprop.0+0x40/0xf0
+   do_el0_svc+0x24/0x40
+   el0_svc+0x40/0x1d0
+   el0t_64_sync_handler+0xa0/0xe8
+   el0t_64_sync+0x1b0/0x1b8
+  Code: 17ffff83 f94017e0 f9002be0 f9402ea0 (f9400c00)
+  ---[ end trace 0000000000000000  ]---
+
+Also the reporter is very kind to test the following ASSERT() added to
+btrfs_trim_free_extents_throttle():
+
+       ASSERT(device->bdev,
+              "devid=%llu path=%s dev_state=0x%lx\n",
+              device->devid, btrfs_dev_name(device), device->dev_state);
+
+And it shows the following output:
+
+  assertion failed: device->bdev, in extent-tree.c:6630 (devid=2 path=/dev/sdd dev_state=0x82)
+
+Which means the device->bdev is NULL, and the dev_state is
+BTRFS_DEV_STATE_IN_FS_METADATA | BTRFS_DEV_STATE_ITEM_FOUND, without
+BTRFS_DEV_STATE_WRITEABLE flag set.
+
+[CAUSE]
+The pc points to the following call chain:
+
+  btrfs_trim_fs()
+  |- btrfs_trim_free_extents()
+     |- btrfs_trim_free_extents_throttle()
+        |- bdev_max_discard_sectors(device->bdev)
+
+So the NULL pointer dereference is caused by device->bdev being NULL.
+
+This looks impossible by a quick glance, as just before calling
+btrfs_trim_free_extents_throttle(), we have skipped any device that has
+BTRFS_DEV_STATE_MISSING flag set.
+
+However in this particular case, there is a window where the missing
+device is later re-scanned, causing btrfs to remove the
+BTRFS_DEV_STATE_MISSING flag:
+
+  btrfs_control_ioctl()
+  |- btrfs_scan_one_device()
+     |- device_list_add()
+        |- rcu_assign_pointer(device->name, name);
+        |  This updates the missing device's path to the new good path.
+        |
+        |- clear_bit(BTRFS_DEV_STATE_MISSING, &device->dev_state)
+           This removes the BTRFS_DEV_STATE_MISSING flag.
+
+This allows the missing device to re-appear and clear the
+BTRFS_DEV_STATE_MISSING flag.  However the device still does not have
+the BTRFS_DEV_STATE_WRITEABLE flag set, nor is its bdev pointer updated.
+
+The bdev pointer remains NULL, triggering the crash later.
+
+[FIX]
+This is a big de-synchronization between BTRFS_DEV_STATE_MISSING and
+device->bdev pointer, and shows a gap in btrfs's re-appearing-device
+handling.
+
+The proper handling of re-appearing device will need quite some extra
+work, which is out of the context of this small fix.
+
+Thankfully the regular bbio submission path has already handled it well
+by checking if the device->bdev is NULL before submitting.
+
+So here we just fix the crash by checking if the device is writeable and
+has a bdev pointer before calling bdev_max_discard_sectors().
+
+Reported-by: Su Yue <glass.su@suse.com>
+Link: https://lore.kernel.org/linux-btrfs/wlwir19t.fsf@damenly.org/
+Fixes: 499f377f49f0 ("btrfs: iterate over unused chunk space in FITRIM")
+CC: stable@vger.kernel.org # 5.10+
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/extent-tree.c |   12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -6411,12 +6411,16 @@ static int btrfs_trim_free_extents(struc
+       *trimmed = 0;
+-      /* Discard not supported = nothing to do. */
+-      if (!bdev_max_discard_sectors(device->bdev))
++      /*
++       * The caller only filters out MISSING devices, but a device that was
++       * missing at mount and later rescanned has MISSING cleared while bdev
++       * is still NULL and WRITEABLE is still unset. Skip those here.
++       */
++      if (!test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state) || !device->bdev)
+               return 0;
+-      /* Not writable = nothing to do. */
+-      if (!test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state))
++      /* Discard not supported = nothing to do. */
++      if (!bdev_max_discard_sectors(device->bdev))
+               return 0;
+       /* No free space = nothing to do. */
diff --git a/queue-6.18/crypto-af_alg-remove-zero-copy-support-from-skcipher-and-aead.patch b/queue-6.18/crypto-af_alg-remove-zero-copy-support-from-skcipher-and-aead.patch
new file mode 100644 (file)
index 0000000..5dd0b92
--- /dev/null
@@ -0,0 +1,211 @@
+From ffdd2bc378953b525aca61902534e753f1f8e734 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@kernel.org>
+Date: Mon, 4 May 2026 15:53:28 -0700
+Subject: crypto: af_alg - Remove zero-copy support from skcipher and aead
+
+From: Eric Biggers <ebiggers@kernel.org>
+
+commit ffdd2bc378953b525aca61902534e753f1f8e734 upstream.
+
+The zero-copy support is one of the riskiest aspects of AF_ALG.  It
+allows userspace to request cryptographic operations directly on
+pagecache pages of files like the 'su' binary.  It also allows userspace
+to concurrently modify the memory which is being operated on, a recipe
+for TOCTOU vulnerabilities.
+
+While zero-copy support is more valuable in other areas of the kernel
+like the frequently used networking and file I/O code, it has far less
+value in AF_ALG, which is a niche UAPI.  AF_ALG primarily just exists
+for backwards compatibility with a small set of userspace programs such
+as 'iwd' that haven't yet been fixed to use userspace crypto code.
+
+Originally AF_ALG was intended to be used to access hardware crypto
+accelerators.  However, it isn't an efficient interface for that anyway,
+and it turned out to be rarely used in this way in practice.
+
+Thus, the risks of the zero-copy support in AF_ALG vastly outweigh its
+benefits.  Let's just remove it.
+
+This commit removes it from the "skcipher" and "aead" algorithm types.
+"hash" will be handled separately.
+
+This is a soft break, not a hard break.  Even after this commit, it
+still works to use splice() or sendfile() to transfer data to an AF_ALG
+request socket from a pipe or any file, respectively.  What changes is
+just that the kernel now makes an internal, stable copy of the data
+before doing the crypto operation.  So performance is slightly reduced,
+but the UAPI isn't broken.  And, very importantly, it's much safer.
+
+Tested with libkcapi/test.sh.  All its test cases still pass.  I also
+verified that this would have prevented the copy.fail exploit as well.
+I also used a custom test program to verify that sendfile() still works.
+
+Fixes: 8ff590903d5f ("crypto: algif_skcipher - User-space interface for skcipher operations")
+Fixes: 400c40cf78da ("crypto: algif - add AEAD support")
+Reported-by: Taeyang Lee <0wn@theori.io>
+Link: https://copy.fail/
+Reported-by: Feng Ning <feng@innora.ai>
+Closes: https://lore.kernel.org/r/afYcc-tZFwvZZo76@ans-MacBook-Pro.local
+Reviewed-by: Demi Marie Obenour <demiobenour@gmail.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Eric Biggers <ebiggers@kernel.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/crypto/userspace-if.rst |   31 +-------------
+ crypto/af_alg.c                       |   71 +++++++++++-----------------------
+ crypto/algif_aead.c                   |    8 +--
+ 3 files changed, 32 insertions(+), 78 deletions(-)
+
+--- a/Documentation/crypto/userspace-if.rst
++++ b/Documentation/crypto/userspace-if.rst
+@@ -328,33 +328,10 @@ CRYPTO_USER_API_RNG_CAVP option:
+ Zero-Copy Interface
+ -------------------
+-In addition to the send/write/read/recv system call family, the AF_ALG
+-interface can be accessed with the zero-copy interface of
+-splice/vmsplice. As the name indicates, the kernel tries to avoid a copy
+-operation into kernel space.
+-
+-The zero-copy operation requires data to be aligned at the page
+-boundary. Non-aligned data can be used as well, but may require more
+-operations of the kernel which would defeat the speed gains obtained
+-from the zero-copy interface.
+-
+-The system-inherent limit for the size of one zero-copy operation is 16
+-pages. If more data is to be sent to AF_ALG, user space must slice the
+-input into segments with a maximum size of 16 pages.
+-
+-Zero-copy can be used with the following code example (a complete
+-working example is provided with libkcapi):
+-
+-::
+-
+-    int pipes[2];
+-
+-    pipe(pipes);
+-    /* input data in iov */
+-    vmsplice(pipes[1], iov, iovlen, SPLICE_F_GIFT);
+-    /* opfd is the file descriptor returned from accept() system call */
+-    splice(pipes[0], NULL, opfd, NULL, ret, 0);
+-    read(opfd, out, outlen);
++AF_ALG used to have zero-copy support, but it was removed due to it being a
++frequent source of vulnerabilities.  For backwards compatibility the splice()
++and sendfile() system calls are still supported, but the kernel will make an
++internal copy of the data before passing it to the crypto code.
+ Setsockopt Interface
+--- a/crypto/af_alg.c
++++ b/crypto/af_alg.c
+@@ -977,7 +977,7 @@ int af_alg_sendmsg(struct socket *sock,
+               ssize_t plen;
+               /* use the existing memory in an allocated page */
+-              if (ctx->merge && !(msg->msg_flags & MSG_SPLICE_PAGES)) {
++              if (ctx->merge) {
+                       sgl = list_entry(ctx->tsgl_list.prev,
+                                        struct af_alg_tsgl, list);
+                       sg = sgl->sg + sgl->cur - 1;
+@@ -1021,60 +1021,37 @@ int af_alg_sendmsg(struct socket *sock,
+               if (sgl->cur)
+                       sg_unmark_end(sg + sgl->cur - 1);
+-              if (msg->msg_flags & MSG_SPLICE_PAGES) {
+-                      struct sg_table sgtable = {
+-                              .sgl            = sg,
+-                              .nents          = sgl->cur,
+-                              .orig_nents     = sgl->cur,
+-                      };
+-
+-                      plen = extract_iter_to_sg(&msg->msg_iter, len, &sgtable,
+-                                                MAX_SGL_ENTS - sgl->cur, 0);
+-                      if (plen < 0) {
+-                              err = plen;
++              do {
++                      struct page *pg;
++                      unsigned int i = sgl->cur;
++
++                      plen = min_t(size_t, len, PAGE_SIZE);
++
++                      pg = alloc_page(GFP_KERNEL);
++                      if (!pg) {
++                              err = -ENOMEM;
+                               goto unlock;
+                       }
+-                      for (; sgl->cur < sgtable.nents; sgl->cur++)
+-                              get_page(sg_page(&sg[sgl->cur]));
++                      sg_assign_page(sg + i, pg);
++
++                      err = memcpy_from_msg(page_address(sg_page(sg + i)),
++                                            msg, plen);
++                      if (err) {
++                              __free_page(sg_page(sg + i));
++                              sg_assign_page(sg + i, NULL);
++                              goto unlock;
++                      }
++
++                      sg[i].length = plen;
+                       len -= plen;
+                       ctx->used += plen;
+                       copied += plen;
+                       size -= plen;
+-              } else {
+-                      do {
+-                              struct page *pg;
+-                              unsigned int i = sgl->cur;
+-
+-                              plen = min_t(size_t, len, PAGE_SIZE);
+-
+-                              pg = alloc_page(GFP_KERNEL);
+-                              if (!pg) {
+-                                      err = -ENOMEM;
+-                                      goto unlock;
+-                              }
+-
+-                              sg_assign_page(sg + i, pg);
+-
+-                              err = memcpy_from_msg(
+-                                      page_address(sg_page(sg + i)),
+-                                      msg, plen);
+-                              if (err) {
+-                                      __free_page(sg_page(sg + i));
+-                                      sg_assign_page(sg + i, NULL);
+-                                      goto unlock;
+-                              }
+-
+-                              sg[i].length = plen;
+-                              len -= plen;
+-                              ctx->used += plen;
+-                              copied += plen;
+-                              size -= plen;
+-                              sgl->cur++;
+-                      } while (len && sgl->cur < MAX_SGL_ENTS);
++                      sgl->cur++;
++              } while (len && sgl->cur < MAX_SGL_ENTS);
+-                      ctx->merge = plen & (PAGE_SIZE - 1);
+-              }
++              ctx->merge = plen & (PAGE_SIZE - 1);
+               if (!size)
+                       sg_mark_end(sg + sgl->cur - 1);
+--- a/crypto/algif_aead.c
++++ b/crypto/algif_aead.c
+@@ -9,10 +9,10 @@
+  * The following concept of the memory management is used:
+  *
+  * The kernel maintains two SGLs, the TX SGL and the RX SGL. The TX SGL is
+- * filled by user space with the data submitted via sendmsg (maybe with
+- * MSG_SPLICE_PAGES).  Filling up the TX SGL does not cause a crypto operation
+- * -- the data will only be tracked by the kernel. Upon receipt of one recvmsg
+- * call, the caller must provide a buffer which is tracked with the RX SGL.
++ * filled by user space with the data submitted via sendmsg.  Filling up the TX
++ * SGL does not cause a crypto operation -- the data will only be tracked by the
++ * kernel. Upon receipt of one recvmsg call, the caller must provide a buffer
++ * which is tracked with the RX SGL.
+  *
+  * During the processing of the recvmsg operation, the cipher request is
+  * allocated and prepared. As part of the recvmsg operation, the processed
diff --git a/queue-6.18/crypto-atmel-sha204a-drop-hwrng-quality-reduction-for-atsha204a.patch b/queue-6.18/crypto-atmel-sha204a-drop-hwrng-quality-reduction-for-atsha204a.patch
new file mode 100644 (file)
index 0000000..9eb3829
--- /dev/null
@@ -0,0 +1,97 @@
+From ea5e57cc97185329dcc5ebdcaae7e1500bf0ad0b Mon Sep 17 00:00:00 2001
+From: Thorsten Blum <thorsten.blum@linux.dev>
+Date: Tue, 28 Apr 2026 12:14:32 +0200
+Subject: crypto: atmel-sha204a - drop hwrng quality reduction for ATSHA204A
+
+From: Thorsten Blum <thorsten.blum@linux.dev>
+
+commit ea5e57cc97185329dcc5ebdcaae7e1500bf0ad0b upstream.
+
+Commit 8006aff15516 ("crypto: atmel-sha204a - Set hwrng quality to
+lowest possible") reduced the hwrng quality to 1 based on a review by
+Bill Cox [1]. However, despite its title, the review only tested the
+ATSHA204, not the ATSHA204A.
+
+In the same thread, Atmel engineer Landon Cox wrote "this behavior has
+been eliminated entirely"[2] in the ATSHA204A and "this problem does not
+affect the ATECC108 or the ATECC108A (or the ATSHA204A)"[3].
+
+According to the official ATSHA204A datasheet [4], the device contains a
+high-quality hardware RNG that combines its output with an internal seed
+value stored in EEPROM or SRAM to generate random numbers. The device
+also implements all security functions using SHA-256, and the driver
+uses the chip's Random command in seed-update mode.
+
+Keep 'quality = 1' for ATSHA204, but drop the explicit hwrng quality
+reduction for ATSHA204A and fall back to the hwrng core default.
+
+[1] https://www.metzdowd.com/pipermail/cryptography/2014-December/023858.html
+[2] https://www.metzdowd.com/pipermail/cryptography/2014-December/023852.html
+[3] https://www.metzdowd.com/pipermail/cryptography/2014-December/023886.html
+[4] https://ww1.microchip.com/downloads/en/DeviceDoc/ATSHA204A-Data-Sheet-40002025A.pdf
+
+Fixes: 8006aff15516 ("crypto: atmel-sha204a - Set hwrng quality to lowest possible")
+Cc: stable@vger.kernel.org
+Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
+Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/atmel-sha204a.c |   19 ++++++++++++-------
+ 1 file changed, 12 insertions(+), 7 deletions(-)
+
+--- a/drivers/crypto/atmel-sha204a.c
++++ b/drivers/crypto/atmel-sha204a.c
+@@ -19,6 +19,12 @@
+ #include <linux/workqueue.h>
+ #include "atmel-i2c.h"
++/*
++ * According to review by Bill Cox [1], the ATSHA204 has very low entropy.
++ * [1] https://www.metzdowd.com/pipermail/cryptography/2014-December/023858.html
++ */
++static const unsigned short atsha204_quality = 1;
++
+ static void atmel_sha204a_rng_done(struct atmel_i2c_work_data *work_data,
+                                  void *areq, int status)
+ {
+@@ -158,6 +164,7 @@ static const struct attribute_group atme
+ static int atmel_sha204a_probe(struct i2c_client *client)
+ {
+       struct atmel_i2c_client_priv *i2c_priv;
++      const unsigned short *quality;
+       int ret;
+       ret = atmel_i2c_probe(client);
+@@ -171,11 +178,9 @@ static int atmel_sha204a_probe(struct i2
+       i2c_priv->hwrng.name = dev_name(&client->dev);
+       i2c_priv->hwrng.read = atmel_sha204a_rng_read;
+-      /*
+-       * According to review by Bill Cox [1], this HWRNG has very low entropy.
+-       * [1] https://www.metzdowd.com/pipermail/cryptography/2014-December/023858.html
+-       */
+-      i2c_priv->hwrng.quality = 1;
++      quality = i2c_get_match_data(client);
++      if (quality)
++              i2c_priv->hwrng.quality = *quality;
+       ret = devm_hwrng_register(&client->dev, &i2c_priv->hwrng);
+       if (ret)
+@@ -207,14 +212,14 @@ static void atmel_sha204a_remove(struct
+ }
+ static const struct of_device_id atmel_sha204a_dt_ids[] __maybe_unused = {
+-      { .compatible = "atmel,atsha204", },
++      { .compatible = "atmel,atsha204", .data = &atsha204_quality },
+       { .compatible = "atmel,atsha204a", },
+       { /* sentinel */ }
+ };
+ MODULE_DEVICE_TABLE(of, atmel_sha204a_dt_ids);
+ static const struct i2c_device_id atmel_sha204a_id[] = {
+-      { "atsha204" },
++      { "atsha204", (kernel_ulong_t)&atsha204_quality },
+       { "atsha204a" },
+       { /* sentinel */ }
+ };
diff --git a/queue-6.18/crypto-caam-use-print_hex_dump_devel-to-guard-key-hex-dumps-again.patch b/queue-6.18/crypto-caam-use-print_hex_dump_devel-to-guard-key-hex-dumps-again.patch
new file mode 100644 (file)
index 0000000..99f3b61
--- /dev/null
@@ -0,0 +1,79 @@
+From 8005dc808bcce7d6cc2ae015a3cde1683bee602d Mon Sep 17 00:00:00 2001
+From: Thorsten Blum <thorsten.blum@linux.dev>
+Date: Mon, 27 Apr 2026 18:39:39 +0200
+Subject: crypto: caam - use print_hex_dump_devel to guard key hex dumps again
+
+From: Thorsten Blum <thorsten.blum@linux.dev>
+
+commit 8005dc808bcce7d6cc2ae015a3cde1683bee602d upstream.
+
+Use print_hex_dump_devel() for dumping sensitive key material in
+*_setkey() to avoid leaking secrets at runtime when CONFIG_DYNAMIC_DEBUG
+is enabled.
+
+Fixes: 8d818c105501 ("crypto: caam/qi2 - add DPAA2-CAAM driver")
+Fixes: 226853ac3ebe ("crypto: caam/qi2 - add skcipher algorithms")
+Cc: stable@vger.kernel.org
+Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/caam/caamalg_qi2.c |   12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/drivers/crypto/caam/caamalg_qi2.c
++++ b/drivers/crypto/caam/caamalg_qi2.c
+@@ -300,7 +300,7 @@ static int aead_setkey(struct crypto_aea
+       dev_dbg(dev, "keylen %d enckeylen %d authkeylen %d\n",
+               keys.authkeylen + keys.enckeylen, keys.enckeylen,
+               keys.authkeylen);
+-      print_hex_dump_debug("key in @" __stringify(__LINE__)": ",
++      print_hex_dump_devel("key in @" __stringify(__LINE__)": ",
+                            DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
+       ctx->adata.keylen = keys.authkeylen;
+@@ -314,7 +314,7 @@ static int aead_setkey(struct crypto_aea
+       memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey, keys.enckeylen);
+       dma_sync_single_for_device(dev, ctx->key_dma, ctx->adata.keylen_pad +
+                                  keys.enckeylen, ctx->dir);
+-      print_hex_dump_debug("ctx.key@" __stringify(__LINE__)": ",
++      print_hex_dump_devel("ctx.key@" __stringify(__LINE__)": ",
+                            DUMP_PREFIX_ADDRESS, 16, 4, ctx->key,
+                            ctx->adata.keylen_pad + keys.enckeylen, 1);
+@@ -731,7 +731,7 @@ static int gcm_setkey(struct crypto_aead
+       ret = aes_check_keylen(keylen);
+       if (ret)
+               return ret;
+-      print_hex_dump_debug("key in @" __stringify(__LINE__)": ",
++      print_hex_dump_devel("key in @" __stringify(__LINE__)": ",
+                            DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
+       memcpy(ctx->key, key, keylen);
+@@ -827,7 +827,7 @@ static int rfc4106_setkey(struct crypto_
+       if (ret)
+               return ret;
+-      print_hex_dump_debug("key in @" __stringify(__LINE__)": ",
++      print_hex_dump_devel("key in @" __stringify(__LINE__)": ",
+                            DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
+       memcpy(ctx->key, key, keylen);
+@@ -926,7 +926,7 @@ static int rfc4543_setkey(struct crypto_
+       if (ret)
+               return ret;
+-      print_hex_dump_debug("key in @" __stringify(__LINE__)": ",
++      print_hex_dump_devel("key in @" __stringify(__LINE__)": ",
+                            DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
+       memcpy(ctx->key, key, keylen);
+@@ -954,7 +954,7 @@ static int skcipher_setkey(struct crypto
+       u32 *desc;
+       const bool is_rfc3686 = alg->caam.rfc3686;
+-      print_hex_dump_debug("key in @" __stringify(__LINE__)": ",
++      print_hex_dump_devel("key in @" __stringify(__LINE__)": ",
+                            DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
+       ctx->cdata.keylen = keylen;
diff --git a/queue-6.18/crypto-caam-use-print_hex_dump_devel-to-guard-key-hex-dumps.patch b/queue-6.18/crypto-caam-use-print_hex_dump_devel-to-guard-key-hex-dumps.patch
new file mode 100644 (file)
index 0000000..d279922
--- /dev/null
@@ -0,0 +1,177 @@
+From 3f57657b6ea23f933371f2c2846322f441773cee Mon Sep 17 00:00:00 2001
+From: Thorsten Blum <thorsten.blum@linux.dev>
+Date: Mon, 27 Apr 2026 18:39:37 +0200
+Subject: crypto: caam - use print_hex_dump_devel to guard key hex dumps
+
+From: Thorsten Blum <thorsten.blum@linux.dev>
+
+commit 3f57657b6ea23f933371f2c2846322f441773cee upstream.
+
+Use print_hex_dump_devel() for dumping sensitive key material in
+*_setkey() and gen_split_key() to avoid leaking secrets at runtime when
+CONFIG_DYNAMIC_DEBUG is enabled.
+
+Fixes: 6e005503199b ("crypto: caam - print debug messages at debug level")
+Cc: stable@vger.kernel.org
+Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/caam/caamalg.c    |   12 ++++++------
+ drivers/crypto/caam/caamalg_qi.c |   12 ++++++------
+ drivers/crypto/caam/caamhash.c   |    4 ++--
+ drivers/crypto/caam/key_gen.c    |    4 ++--
+ 4 files changed, 16 insertions(+), 16 deletions(-)
+
+--- a/drivers/crypto/caam/caamalg.c
++++ b/drivers/crypto/caam/caamalg.c
+@@ -597,7 +597,7 @@ static int aead_setkey(struct crypto_aea
+       dev_dbg(jrdev, "keylen %d enckeylen %d authkeylen %d\n",
+              keys.authkeylen + keys.enckeylen, keys.enckeylen,
+              keys.authkeylen);
+-      print_hex_dump_debug("key in @"__stringify(__LINE__)": ",
++      print_hex_dump_devel("key in @"__stringify(__LINE__)": ",
+                            DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
+       /*
+@@ -633,7 +633,7 @@ static int aead_setkey(struct crypto_aea
+       dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->adata.keylen_pad +
+                                  keys.enckeylen, ctx->dir);
+-      print_hex_dump_debug("ctx.key@"__stringify(__LINE__)": ",
++      print_hex_dump_devel("ctx.key@"__stringify(__LINE__)": ",
+                            DUMP_PREFIX_ADDRESS, 16, 4, ctx->key,
+                            ctx->adata.keylen_pad + keys.enckeylen, 1);
+@@ -674,7 +674,7 @@ static int gcm_setkey(struct crypto_aead
+       if (err)
+               return err;
+-      print_hex_dump_debug("key in @"__stringify(__LINE__)": ",
++      print_hex_dump_devel("key in @"__stringify(__LINE__)": ",
+                            DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
+       memcpy(ctx->key, key, keylen);
+@@ -695,7 +695,7 @@ static int rfc4106_setkey(struct crypto_
+       if (err)
+               return err;
+-      print_hex_dump_debug("key in @"__stringify(__LINE__)": ",
++      print_hex_dump_devel("key in @"__stringify(__LINE__)": ",
+                            DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
+       memcpy(ctx->key, key, keylen);
+@@ -721,7 +721,7 @@ static int rfc4543_setkey(struct crypto_
+       if (err)
+               return err;
+-      print_hex_dump_debug("key in @"__stringify(__LINE__)": ",
++      print_hex_dump_devel("key in @"__stringify(__LINE__)": ",
+                            DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
+       memcpy(ctx->key, key, keylen);
+@@ -748,7 +748,7 @@ static int skcipher_setkey(struct crypto
+       u32 *desc;
+       const bool is_rfc3686 = alg->caam.rfc3686;
+-      print_hex_dump_debug("key in @"__stringify(__LINE__)": ",
++      print_hex_dump_devel("key in @"__stringify(__LINE__)": ",
+                            DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
+       ctx->cdata.keylen = keylen;
+--- a/drivers/crypto/caam/caamalg_qi.c
++++ b/drivers/crypto/caam/caamalg_qi.c
+@@ -212,7 +212,7 @@ static int aead_setkey(struct crypto_aea
+       dev_dbg(jrdev, "keylen %d enckeylen %d authkeylen %d\n",
+               keys.authkeylen + keys.enckeylen, keys.enckeylen,
+               keys.authkeylen);
+-      print_hex_dump_debug("key in @" __stringify(__LINE__)": ",
++      print_hex_dump_devel("key in @" __stringify(__LINE__)": ",
+                            DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
+       /*
+@@ -248,7 +248,7 @@ static int aead_setkey(struct crypto_aea
+                                  ctx->adata.keylen_pad + keys.enckeylen,
+                                  ctx->dir);
+-      print_hex_dump_debug("ctx.key@" __stringify(__LINE__)": ",
++      print_hex_dump_devel("ctx.key@" __stringify(__LINE__)": ",
+                            DUMP_PREFIX_ADDRESS, 16, 4, ctx->key,
+                            ctx->adata.keylen_pad + keys.enckeylen, 1);
+@@ -371,7 +371,7 @@ static int gcm_setkey(struct crypto_aead
+       if (ret)
+               return ret;
+-      print_hex_dump_debug("key in @" __stringify(__LINE__)": ",
++      print_hex_dump_devel("key in @" __stringify(__LINE__)": ",
+                            DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
+       memcpy(ctx->key, key, keylen);
+@@ -475,7 +475,7 @@ static int rfc4106_setkey(struct crypto_
+       if (ret)
+               return ret;
+-      print_hex_dump_debug("key in @" __stringify(__LINE__)": ",
++      print_hex_dump_devel("key in @" __stringify(__LINE__)": ",
+                            DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
+       memcpy(ctx->key, key, keylen);
+@@ -581,7 +581,7 @@ static int rfc4543_setkey(struct crypto_
+       if (ret)
+               return ret;
+-      print_hex_dump_debug("key in @" __stringify(__LINE__)": ",
++      print_hex_dump_devel("key in @" __stringify(__LINE__)": ",
+                            DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
+       memcpy(ctx->key, key, keylen);
+@@ -631,7 +631,7 @@ static int skcipher_setkey(struct crypto
+       const bool is_rfc3686 = alg->caam.rfc3686;
+       int ret = 0;
+-      print_hex_dump_debug("key in @" __stringify(__LINE__)": ",
++      print_hex_dump_devel("key in @" __stringify(__LINE__)": ",
+                            DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
+       ctx->cdata.keylen = keylen;
+--- a/drivers/crypto/caam/caamhash.c
++++ b/drivers/crypto/caam/caamhash.c
+@@ -505,7 +505,7 @@ static int axcbc_setkey(struct crypto_ah
+                                  DMA_TO_DEVICE);
+       ctx->adata.keylen = keylen;
+-      print_hex_dump_debug("axcbc ctx.key@" __stringify(__LINE__)" : ",
++      print_hex_dump_devel("axcbc ctx.key@" __stringify(__LINE__)" : ",
+                            DUMP_PREFIX_ADDRESS, 16, 4, ctx->key, keylen, 1);
+       return axcbc_set_sh_desc(ahash);
+@@ -525,7 +525,7 @@ static int acmac_setkey(struct crypto_ah
+       ctx->adata.key_virt = key;
+       ctx->adata.keylen = keylen;
+-      print_hex_dump_debug("acmac ctx.key@" __stringify(__LINE__)" : ",
++      print_hex_dump_devel("acmac ctx.key@" __stringify(__LINE__)" : ",
+                            DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
+       return acmac_set_sh_desc(ahash);
+--- a/drivers/crypto/caam/key_gen.c
++++ b/drivers/crypto/caam/key_gen.c
+@@ -58,7 +58,7 @@ int gen_split_key(struct device *jrdev,
+       dev_dbg(jrdev, "split keylen %d split keylen padded %d\n",
+               adata->keylen, adata->keylen_pad);
+-      print_hex_dump_debug("ctx.key@" __stringify(__LINE__)": ",
++      print_hex_dump_devel("ctx.key@" __stringify(__LINE__)": ",
+                            DUMP_PREFIX_ADDRESS, 16, 4, key_in, keylen, 1);
+       if (local_max > max_keylen)
+@@ -113,7 +113,7 @@ int gen_split_key(struct device *jrdev,
+               wait_for_completion(&result.completion);
+               ret = result.err;
+-              print_hex_dump_debug("ctx.key@"__stringify(__LINE__)": ",
++              print_hex_dump_devel("ctx.key@"__stringify(__LINE__)": ",
+                                    DUMP_PREFIX_ADDRESS, 16, 4, key_out,
+                                    adata->keylen_pad, 1);
+       }
diff --git a/queue-6.18/crypto-ccp-do-not-initialize-snp-for-ioctl-snp_commit.patch b/queue-6.18/crypto-ccp-do-not-initialize-snp-for-ioctl-snp_commit.patch
new file mode 100644 (file)
index 0000000..11e8e8f
--- /dev/null
@@ -0,0 +1,65 @@
+From 5a1364da2f04217a36e2fdfa2db4ee025b383a20 Mon Sep 17 00:00:00 2001
+From: "Tycho Andersen (AMD)" <tycho@kernel.org>
+Date: Mon, 4 May 2026 10:51:45 -0600
+Subject: crypto: ccp - Do not initialize SNP for ioctl(SNP_COMMIT)
+
+From: Tycho Andersen (AMD) <tycho@kernel.org>
+
+commit 5a1364da2f04217a36e2fdfa2db4ee025b383a20 upstream.
+
+Sashiko notes:
+
+> if SEV initialization fails and KVM is actively running normal VMs, could a
+> userspace process trigger this code path via /dev/sev ioctls (e.g.,
+> SEV_PDH_GEN) and zero out MSR_VM_HSAVE_PA globally? Would the next VMRUN
+> execution for an active VM trigger a general protection fault and crash the
+> host?
+
+The SNP_COMMIT command does not require the firmware to be in any
+particular state. Skip initializing it if it was previously uninitialized.
+
+The SEV-SNP firmware specification doc 56860 does not mention SNP_COMMIT in
+Table 5 as a command that is allowed in the UNINIT state, but it is in fact
+allowed and a future documentation update will reflect that.
+
+Fixes: ceac7fb89e8d ("crypto: ccp - Ensure implicit SEV/SNP init and shutdown in ioctls")
+Reported-by: Sashiko
+Assisted-by: Gemini:gemini-3.1-pro-preview
+Link: https://sashiko.dev/#/patchset/20260324161301.1353976-1-tycho%40kernel.org
+CC: <stable@vger.kernel.org>
+Signed-off-by: Tycho Andersen (AMD) <tycho@kernel.org>
+Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/ccp/sev-dev.c |   13 +------------
+ 1 file changed, 1 insertion(+), 12 deletions(-)
+
+--- a/drivers/crypto/ccp/sev-dev.c
++++ b/drivers/crypto/ccp/sev-dev.c
+@@ -2411,24 +2411,13 @@ cleanup:
+ static int sev_ioctl_do_snp_commit(struct sev_issue_cmd *argp)
+ {
+-      struct sev_device *sev = psp_master->sev_data;
+       struct sev_data_snp_commit buf;
+-      bool shutdown_required = false;
+-      int ret, error;
+-
+-      if (!sev->snp_initialized) {
+-              ret = snp_move_to_init_state(argp, &shutdown_required);
+-              if (ret)
+-                      return ret;
+-      }
++      int ret;
+       buf.len = sizeof(buf);
+       ret = __sev_do_cmd_locked(SEV_CMD_SNP_COMMIT, &buf, &argp->error);
+-      if (shutdown_required)
+-              __sev_snp_shutdown_locked(&error, false);
+-
+       return ret;
+ }
diff --git a/queue-6.18/crypto-ccp-do-not-initialize-snp-for-ioctl-snp_config.patch b/queue-6.18/crypto-ccp-do-not-initialize-snp-for-ioctl-snp_config.patch
new file mode 100644 (file)
index 0000000..58861ec
--- /dev/null
@@ -0,0 +1,103 @@
+From 08f0e65e784c4b20e6e620dd4f68d8636073a3d2 Mon Sep 17 00:00:00 2001
+From: "Tycho Andersen (AMD)" <tycho@kernel.org>
+Date: Mon, 4 May 2026 10:51:47 -0600
+Subject: crypto: ccp - Do not initialize SNP for ioctl(SNP_CONFIG)
+
+From: Tycho Andersen (AMD) <tycho@kernel.org>
+
+commit 08f0e65e784c4b20e6e620dd4f68d8636073a3d2 upstream.
+
+Sashiko notes:
+
+> if SEV initialization fails and KVM is actively running normal VMs, could a
+> userspace process trigger this code path via /dev/sev ioctls (e.g.,
+> SEV_PDH_GEN) and zero out MSR_VM_HSAVE_PA globally? Would the next VMRUN
+> execution for an active VM trigger a general protection fault and crash the
+> host?
+
+Refuse to re-try initialization if SNP is not already initialized for
+SNP_CONFIG.
+
+This is technically an ABI break: before if SNP initialization failed it
+could be transparently retriggered by this ioctl, and if no VMs were
+running, everything worked fine. Hopefully this is enough of a corner case
+that nobody will notice, but someone does, there are a few options:
+
+* do something like symbol_get() for kvm and refuse to initialize if KVM is
+  loaded
+* check each cpu's HSAVE_PA for non-zero data before re-initializing
+* once initialization has failed, continue to refuse to initialize until
+  the ccp module is unloaded
+
+Fixes: ceac7fb89e8d ("crypto: ccp - Ensure implicit SEV/SNP init and shutdown in ioctls")
+Reported-by: Sashiko
+Assisted-by: Gemini:gemini-3.1-pro-preview
+Link: https://sashiko.dev/#/patchset/20260324161301.1353976-1-tycho%40kernel.org
+CC: <stable@vger.kernel.org>
+Signed-off-by: Tycho Andersen (AMD) <tycho@kernel.org>
+Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/ccp/sev-dev.c |   33 ++++-----------------------------
+ 1 file changed, 4 insertions(+), 29 deletions(-)
+
+--- a/drivers/crypto/ccp/sev-dev.c
++++ b/drivers/crypto/ccp/sev-dev.c
+@@ -1700,21 +1700,6 @@ static int sev_move_to_init_state(struct
+       return 0;
+ }
+-static int snp_move_to_init_state(struct sev_issue_cmd *argp, bool *shutdown_required)
+-{
+-      int error, rc;
+-
+-      rc = __sev_snp_init_locked(&error, 0);
+-      if (rc) {
+-              argp->error = SEV_RET_INVALID_PLATFORM_STATE;
+-              return rc;
+-      }
+-
+-      *shutdown_required = true;
+-
+-      return 0;
+-}
+-
+ static int sev_ioctl_do_reset(struct sev_issue_cmd *argp, bool writable)
+ {
+       int state, rc;
+@@ -2425,8 +2410,6 @@ static int sev_ioctl_do_snp_set_config(s
+ {
+       struct sev_device *sev = psp_master->sev_data;
+       struct sev_user_data_snp_config config;
+-      bool shutdown_required = false;
+-      int ret, error;
+       if (!argp->data)
+               return -EINVAL;
+@@ -2434,21 +2417,13 @@ static int sev_ioctl_do_snp_set_config(s
+       if (!writable)
+               return -EPERM;
++      if (!sev->snp_initialized)
++              return -ENODEV;
++
+       if (copy_from_user(&config, (void __user *)argp->data, sizeof(config)))
+               return -EFAULT;
+-      if (!sev->snp_initialized) {
+-              ret = snp_move_to_init_state(argp, &shutdown_required);
+-              if (ret)
+-                      return ret;
+-      }
+-
+-      ret = __sev_do_cmd_locked(SEV_CMD_SNP_CONFIG, &config, &argp->error);
+-
+-      if (shutdown_required)
+-              __sev_snp_shutdown_locked(&error, false);
+-
+-      return ret;
++      return __sev_do_cmd_locked(SEV_CMD_SNP_CONFIG, &config, &argp->error);
+ }
+ static int sev_ioctl_do_snp_vlek_load(struct sev_issue_cmd *argp, bool writable)
diff --git a/queue-6.18/crypto-ccp-do-not-initialize-snp-for-ioctl-snp_vlek_load.patch b/queue-6.18/crypto-ccp-do-not-initialize-snp-for-ioctl-snp_vlek_load.patch
new file mode 100644 (file)
index 0000000..8698c19
--- /dev/null
@@ -0,0 +1,84 @@
+From f91e9dbb5845d1e5abf1028e6df57dcf61583e1b Mon Sep 17 00:00:00 2001
+From: "Tycho Andersen (AMD)" <tycho@kernel.org>
+Date: Mon, 4 May 2026 10:51:46 -0600
+Subject: crypto: ccp - Do not initialize SNP for ioctl(SNP_VLEK_LOAD)
+
+From: Tycho Andersen (AMD) <tycho@kernel.org>
+
+commit f91e9dbb5845d1e5abf1028e6df57dcf61583e1b upstream.
+
+Sashiko notes:
+
+> if SEV initialization fails and KVM is actively running normal VMs, could a
+> userspace process trigger this code path via /dev/sev ioctls (e.g.,
+> SEV_PDH_GEN) and zero out MSR_VM_HSAVE_PA globally? Would the next VMRUN
+> execution for an active VM trigger a general protection fault and crash the
+> host?
+
+The SEV firmware docs for SNP_VLEK_LOAD note:
+
+> On SNP_SHUTDOWN, the VLEK is deleted.
+
+That is, the initialization/shutdown wrapper here is pointless, because the
+firmware immediately throws away the key anyway. Instead, refuse to do
+anything if SNP has not been previously initialized.
+
+This is an ABI break: before, this was a no-op and almost certainly a
+mistake by userspace, and now it returns -ENODEV. ABI compatibility could be
+maintained here by simply returning 0 in the check instead.
+
+Fixes: ceac7fb89e8d ("crypto: ccp - Ensure implicit SEV/SNP init and shutdown in ioctls")
+Reported-by: Sashiko
+Assisted-by: Gemini:gemini-3.1-pro-preview
+Link: https://sashiko.dev/#/patchset/20260324161301.1353976-1-tycho%40kernel.org
+CC: <stable@vger.kernel.org>
+Signed-off-by: Tycho Andersen (AMD) <tycho@kernel.org>
+Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/ccp/sev-dev.c |   17 ++++-------------
+ 1 file changed, 4 insertions(+), 13 deletions(-)
+
+--- a/drivers/crypto/ccp/sev-dev.c
++++ b/drivers/crypto/ccp/sev-dev.c
+@@ -2455,9 +2455,8 @@ static int sev_ioctl_do_snp_vlek_load(st
+ {
+       struct sev_device *sev = psp_master->sev_data;
+       struct sev_user_data_snp_vlek_load input;
+-      bool shutdown_required = false;
+-      int ret, error;
+       void *blob;
++      int ret;
+       if (!argp->data)
+               return -EINVAL;
+@@ -2465,6 +2464,9 @@ static int sev_ioctl_do_snp_vlek_load(st
+       if (!writable)
+               return -EPERM;
++      if (!sev->snp_initialized)
++              return -ENODEV;
++
+       if (copy_from_user(&input, u64_to_user_ptr(argp->data), sizeof(input)))
+               return -EFAULT;
+@@ -2478,18 +2480,7 @@ static int sev_ioctl_do_snp_vlek_load(st
+       input.vlek_wrapped_address = __psp_pa(blob);
+-      if (!sev->snp_initialized) {
+-              ret = snp_move_to_init_state(argp, &shutdown_required);
+-              if (ret)
+-                      goto cleanup;
+-      }
+-
+       ret = __sev_do_cmd_locked(SEV_CMD_SNP_VLEK_LOAD, &input, &argp->error);
+-
+-      if (shutdown_required)
+-              __sev_snp_shutdown_locked(&error, false);
+-
+-cleanup:
+       kfree(blob);
+       return ret;
diff --git a/queue-6.18/crypto-ccp-do-not-initialize-snp-for-sev-ioctls.patch b/queue-6.18/crypto-ccp-do-not-initialize-snp-for-sev-ioctls.patch
new file mode 100644 (file)
index 0000000..5c34684
--- /dev/null
@@ -0,0 +1,67 @@
+From fb1758e74b8061aacfbce7bbb7a7cc650537e167 Mon Sep 17 00:00:00 2001
+From: "Tycho Andersen (AMD)" <tycho@kernel.org>
+Date: Mon, 4 May 2026 10:51:44 -0600
+Subject: crypto: ccp - Do not initialize SNP for SEV ioctls
+
+From: Tycho Andersen (AMD) <tycho@kernel.org>
+
+commit fb1758e74b8061aacfbce7bbb7a7cc650537e167 upstream.
+
+Sashiko notes:
+
+> if SEV initialization fails and KVM is actively running normal VMs, could a
+> userspace process trigger this code path via /dev/sev ioctls (e.g.,
+> SEV_PDH_GEN) and zero out MSR_VM_HSAVE_PA globally? Would the next VMRUN
+> execution for an active VM trigger a general protection fault and crash the
+> host?
+
+sev_move_to_init_state() is called for ioctls requiring only SEV firmware:
+SEV_PEK_GEN, SEV_PDH_GEN, SEV_PEK_CSR, SEV_PEK_CERT_IMPORT, and
+SEV_PDH_CERT_EXPORT. After the firmware command, it does SEV_SHUTDOWN on
+the SEV firmware. Since these commands do not require SNP to be
+initialized, skip it by calling __sev_platform_init_locked() which only
+initializes the SEV firmware. This way SNP is not Initialized at all, and
+HSAVE_PA is not cleared.
+
+The previous code saved any SEV initialization firmware error to
+init_args.error and then threw it away and hardcoded the return value of
+INVALID_PLATFORM_STATE regardless of the real firmware error. This patch
+changes it to surface the underlying error, which is hopefully both more
+useful and doesn't cause any problems.
+
+Note that it is still safe to call __sev_firmware_shutdown() directly: it
+calls __sev_snp_shutdown_locked(), which skips SNP shutdown if SNP was not
+initialized.
+
+Fixes: ceac7fb89e8d ("crypto: ccp - Ensure implicit SEV/SNP init and shutdown in ioctls")
+Reported-by: Sashiko
+Assisted-by: Gemini:gemini-3.1-pro-preview
+Link: https://sashiko.dev/#/patchset/20260324161301.1353976-1-tycho%40kernel.org
+CC: <stable@vger.kernel.org>
+Signed-off-by: Tycho Andersen (AMD) <tycho@kernel.org>
+Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/ccp/sev-dev.c |    7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+--- a/drivers/crypto/ccp/sev-dev.c
++++ b/drivers/crypto/ccp/sev-dev.c
+@@ -1689,14 +1689,11 @@ static int sev_get_platform_state(int *s
+ static int sev_move_to_init_state(struct sev_issue_cmd *argp, bool *shutdown_required)
+ {
+-      struct sev_platform_init_args init_args = {0};
+       int rc;
+-      rc = _sev_platform_init_locked(&init_args);
+-      if (rc) {
+-              argp->error = SEV_RET_INVALID_PLATFORM_STATE;
++      rc = __sev_platform_init_locked(&argp->error);
++      if (rc)
+               return rc;
+-      }
+       *shutdown_required = true;
diff --git a/queue-6.18/crypto-chacha20poly1305-validate-poly1305-template-argument.patch b/queue-6.18/crypto-chacha20poly1305-validate-poly1305-template-argument.patch
new file mode 100644 (file)
index 0000000..26252f5
--- /dev/null
@@ -0,0 +1,69 @@
+From 265b861bece38318b8e0fc8fac0643d4ef906d31 Mon Sep 17 00:00:00 2001
+From: Xiaonan Zhao <ngochuongbui67@gmail.com>
+Date: Tue, 26 May 2026 18:11:43 +0800
+Subject: crypto: chacha20poly1305 - validate poly1305 template argument
+
+From: Xiaonan Zhao <ngochuongbui67@gmail.com>
+
+commit 265b861bece38318b8e0fc8fac0643d4ef906d31 upstream.
+
+chachapoly_create() still accepts the compatibility poly1305 parameter
+in the template name, but it assumes the second template argument is
+always present and immediately passes it to strcmp().
+
+When the argument is missing, crypto_attr_alg_name() returns an error
+pointer. Check for that before comparing the name so malformed template
+instantiations fail with an error instead of dereferencing the error
+pointer in strcmp().
+
+This matches the surrounding Crypto API template pattern where
+crypto_attr_alg_name() results are validated before string-specific use.
+
+Fixes: a298765e28ad ("crypto: chacha20poly1305 - Use lib/crypto poly1305")
+Cc: stable@kernel.org
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Zhengchuan Liang <zcliangcn@gmail.com>
+Reported-by: Xin Liu <bird@lzu.edu.cn>
+Co-developed-by: Luxing Yin <tr0jan@lzu.edu.cn>
+Signed-off-by: Luxing Yin <tr0jan@lzu.edu.cn>
+Signed-off-by: Xiaonan Zhao <ngochuongbui67@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ crypto/chacha20poly1305.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/crypto/chacha20poly1305.c b/crypto/chacha20poly1305.c
+index b4b5a7198d84..27df9e1eb058 100644
+--- a/crypto/chacha20poly1305.c
++++ b/crypto/chacha20poly1305.c
+@@ -375,6 +375,7 @@ static int chachapoly_create(struct crypto_template *tmpl, struct rtattr **tb,
+       struct aead_instance *inst;
+       struct chachapoly_instance_ctx *ctx;
+       struct skcipher_alg_common *chacha;
++      const char *poly_name;
+       int err;
+       if (ivsize > CHACHAPOLY_IV_SIZE)
+@@ -396,9 +397,15 @@ static int chachapoly_create(struct crypto_template *tmpl, struct rtattr **tb,
+               goto err_free_inst;
+       chacha = crypto_spawn_skcipher_alg_common(&ctx->chacha);
++      poly_name = crypto_attr_alg_name(tb[2]);
++      if (IS_ERR(poly_name)) {
++              err = PTR_ERR(poly_name);
++              goto err_free_inst;
++      }
++
+       err = -EINVAL;
+-      if (strcmp(crypto_attr_alg_name(tb[2]), "poly1305") &&
+-          strcmp(crypto_attr_alg_name(tb[2]), "poly1305-generic"))
++      if (strcmp(poly_name, "poly1305") &&
++          strcmp(poly_name, "poly1305-generic"))
+               goto err_free_inst;
+       /* Need 16-byte IV size, including Initial Block Counter value */
+       if (chacha->ivsize != CHACHA_IV_SIZE)
+-- 
+2.55.0
+
diff --git a/queue-6.18/crypto-crypto4xx-remove-insecure-and-unused-rng_alg.patch b/queue-6.18/crypto-crypto4xx-remove-insecure-and-unused-rng_alg.patch
new file mode 100644 (file)
index 0000000..a560e20
--- /dev/null
@@ -0,0 +1,224 @@
+From 7811ec9e973d2c9e465083699f0c8240b98cb8c4 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@kernel.org>
+Date: Fri, 29 May 2026 15:04:30 -0700
+Subject: crypto: crypto4xx - Remove insecure and unused rng_alg
+
+From: Eric Biggers <ebiggers@kernel.org>
+
+commit 7811ec9e973d2c9e465083699f0c8240b98cb8c4 upstream.
+
+Remove crypto4xx_rng, as it is insecure and unused:
+
+- It has only a 64-bit security strength, which is highly inadequate.
+  This can be seen by the fact that crypto4xx_hw_init() seeds it with
+  only 64 bits of entropy, and the fact that the original commit
+  mentions that it implements ANSI X9.17 Annex C.
+
+  Another issue was that this driver didn't implement the crypto_rng API
+  correctly, as crypto4xx_prng_generate() didn't return 0 on success.
+
+- No user of this code is known.  It's usable only theoretically via the
+  "rng" algorithm type of AF_ALG.  But userspace actually just uses the
+  actual Linux RNG (/dev/random etc) instead.  And rng_algs don't
+  contribute entropy to the actual Linux RNG either.  (This may have
+  been confused with hwrng, which does contribute entropy.)
+
+Fixes: d072bfa48853 ("crypto: crypto4xx - add prng crypto support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Eric Biggers <ebiggers@kernel.org>
+Acked-by: Christian Lamparter <chunkeey@gmail.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/amcc/crypto4xx_core.c    |   88 --------------------------------
+ drivers/crypto/amcc/crypto4xx_core.h    |    4 -
+ drivers/crypto/amcc/crypto4xx_reg_def.h |   11 ----
+ 3 files changed, 103 deletions(-)
+
+--- a/drivers/crypto/amcc/crypto4xx_core.c
++++ b/drivers/crypto/amcc/crypto4xx_core.c
+@@ -31,11 +31,9 @@
+ #include <crypto/ctr.h>
+ #include <crypto/gcm.h>
+ #include <crypto/sha1.h>
+-#include <crypto/rng.h>
+ #include <crypto/scatterwalk.h>
+ #include <crypto/skcipher.h>
+ #include <crypto/internal/aead.h>
+-#include <crypto/internal/rng.h>
+ #include <crypto/internal/skcipher.h>
+ #include "crypto4xx_reg_def.h"
+ #include "crypto4xx_core.h"
+@@ -986,10 +984,6 @@ static int crypto4xx_register_alg(struct
+                       rc = crypto_register_aead(&alg->alg.u.aead);
+                       break;
+-              case CRYPTO_ALG_TYPE_RNG:
+-                      rc = crypto_register_rng(&alg->alg.u.rng);
+-                      break;
+-
+               default:
+                       rc = crypto_register_skcipher(&alg->alg.u.cipher);
+                       break;
+@@ -1015,10 +1009,6 @@ static void crypto4xx_unregister_alg(str
+                       crypto_unregister_aead(&alg->alg.u.aead);
+                       break;
+-              case CRYPTO_ALG_TYPE_RNG:
+-                      crypto_unregister_rng(&alg->alg.u.rng);
+-                      break;
+-
+               default:
+                       crypto_unregister_skcipher(&alg->alg.u.cipher);
+               }
+@@ -1077,69 +1067,6 @@ static irqreturn_t crypto4xx_ce_interrup
+               PPC4XX_TMO_ERR_INT);
+ }
+-static int ppc4xx_prng_data_read(struct crypto4xx_device *dev,
+-                               u8 *data, unsigned int max)
+-{
+-      unsigned int i, curr = 0;
+-      u32 val[2];
+-
+-      do {
+-              /* trigger PRN generation */
+-              writel(PPC4XX_PRNG_CTRL_AUTO_EN,
+-                     dev->ce_base + CRYPTO4XX_PRNG_CTRL);
+-
+-              for (i = 0; i < 1024; i++) {
+-                      /* usually 19 iterations are enough */
+-                      if ((readl(dev->ce_base + CRYPTO4XX_PRNG_STAT) &
+-                           CRYPTO4XX_PRNG_STAT_BUSY))
+-                              continue;
+-
+-                      val[0] = readl_be(dev->ce_base + CRYPTO4XX_PRNG_RES_0);
+-                      val[1] = readl_be(dev->ce_base + CRYPTO4XX_PRNG_RES_1);
+-                      break;
+-              }
+-              if (i == 1024)
+-                      return -ETIMEDOUT;
+-
+-              if ((max - curr) >= 8) {
+-                      memcpy(data, &val, 8);
+-                      data += 8;
+-                      curr += 8;
+-              } else {
+-                      /* copy only remaining bytes */
+-                      memcpy(data, &val, max - curr);
+-                      break;
+-              }
+-      } while (curr < max);
+-
+-      return curr;
+-}
+-
+-static int crypto4xx_prng_generate(struct crypto_rng *tfm,
+-                                 const u8 *src, unsigned int slen,
+-                                 u8 *dstn, unsigned int dlen)
+-{
+-      struct rng_alg *alg = crypto_rng_alg(tfm);
+-      struct crypto4xx_alg *amcc_alg;
+-      struct crypto4xx_device *dev;
+-      int ret;
+-
+-      amcc_alg = container_of(alg, struct crypto4xx_alg, alg.u.rng);
+-      dev = amcc_alg->dev;
+-
+-      mutex_lock(&dev->core_dev->rng_lock);
+-      ret = ppc4xx_prng_data_read(dev, dstn, dlen);
+-      mutex_unlock(&dev->core_dev->rng_lock);
+-      return ret;
+-}
+-
+-
+-static int crypto4xx_prng_seed(struct crypto_rng *tfm, const u8 *seed,
+-                      unsigned int slen)
+-{
+-      return 0;
+-}
+-
+ /*
+  * Supported Crypto Algorithms
+  */
+@@ -1269,18 +1196,6 @@ static struct crypto4xx_alg_common crypt
+                       .cra_module     = THIS_MODULE,
+               },
+       } },
+-      { .type = CRYPTO_ALG_TYPE_RNG, .u.rng = {
+-              .base = {
+-                      .cra_name               = "stdrng",
+-                      .cra_driver_name        = "crypto4xx_rng",
+-                      .cra_priority           = 300,
+-                      .cra_ctxsize            = 0,
+-                      .cra_module             = THIS_MODULE,
+-              },
+-              .generate               = crypto4xx_prng_generate,
+-              .seed                   = crypto4xx_prng_seed,
+-              .seedsize               = 0,
+-      } },
+ };
+ /*
+@@ -1354,9 +1269,6 @@ static int crypto4xx_probe(struct platfo
+       core_dev->dev->core_dev = core_dev;
+       core_dev->dev->is_revb = is_revb;
+       core_dev->device = dev;
+-      rc = devm_mutex_init(&ofdev->dev, &core_dev->rng_lock);
+-      if (rc)
+-              return rc;
+       spin_lock_init(&core_dev->lock);
+       INIT_LIST_HEAD(&core_dev->dev->alg_list);
+       ratelimit_default_init(&core_dev->dev->aead_ratelimit);
+--- a/drivers/crypto/amcc/crypto4xx_core.h
++++ b/drivers/crypto/amcc/crypto4xx_core.h
+@@ -14,10 +14,8 @@
+ #define __CRYPTO4XX_CORE_H__
+ #include <linux/ratelimit.h>
+-#include <linux/mutex.h>
+ #include <linux/scatterlist.h>
+ #include <crypto/internal/aead.h>
+-#include <crypto/internal/rng.h>
+ #include <crypto/internal/skcipher.h>
+ #include "crypto4xx_reg_def.h"
+ #include "crypto4xx_sa.h"
+@@ -111,7 +109,6 @@ struct crypto4xx_core_device {
+       u32 irq;
+       struct tasklet_struct tasklet;
+       spinlock_t lock;
+-      struct mutex rng_lock;
+ };
+ struct crypto4xx_ctx {
+@@ -135,7 +132,6 @@ struct crypto4xx_alg_common {
+       union {
+               struct skcipher_alg cipher;
+               struct aead_alg aead;
+-              struct rng_alg rng;
+       } u;
+ };
+--- a/drivers/crypto/amcc/crypto4xx_reg_def.h
++++ b/drivers/crypto/amcc/crypto4xx_reg_def.h
+@@ -90,20 +90,9 @@
+ #define CRYPTO4XX_BYTE_ORDER_CFG              0x000600d8
+ #define CRYPTO4XX_ENDIAN_CFG                  0x000600d8
+-#define CRYPTO4XX_PRNG_STAT                   0x00070000
+-#define CRYPTO4XX_PRNG_STAT_BUSY              0x1
+ #define CRYPTO4XX_PRNG_CTRL                   0x00070004
+ #define CRYPTO4XX_PRNG_SEED_L                 0x00070008
+ #define CRYPTO4XX_PRNG_SEED_H                 0x0007000c
+-
+-#define CRYPTO4XX_PRNG_RES_0                  0x00070020
+-#define CRYPTO4XX_PRNG_RES_1                  0x00070024
+-#define CRYPTO4XX_PRNG_RES_2                  0x00070028
+-#define CRYPTO4XX_PRNG_RES_3                  0x0007002C
+-
+-#define CRYPTO4XX_PRNG_LFSR_L                 0x00070030
+-#define CRYPTO4XX_PRNG_LFSR_H                 0x00070034
+-
+ /*
+  * Initialize CRYPTO ENGINE registers, and memory bases.
+  */
diff --git a/queue-6.18/crypto-drbg-fix-drbg_max_addtl-on-64-bit-kernels.patch b/queue-6.18/crypto-drbg-fix-drbg_max_addtl-on-64-bit-kernels.patch
new file mode 100644 (file)
index 0000000..ad24b8b
--- /dev/null
@@ -0,0 +1,60 @@
+From 6f49f00c981bbb9ef602966f19bfdbef46b681d2 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@kernel.org>
+Date: Sun, 19 Apr 2026 23:33:48 -0700
+Subject: crypto: drbg - Fix drbg_max_addtl() on 64-bit kernels
+
+From: Eric Biggers <ebiggers@kernel.org>
+
+commit 6f49f00c981bbb9ef602966f19bfdbef46b681d2 upstream.
+
+On 64-bit kernels, drbg_max_addtl() returns 2**35 bytes.  That's too
+large, for two reasons:
+
+1. SP800-90A says the maximum limit is 2**35 *bits*, not 2**35 bytes.
+   So the implemented limit has confused bits and bytes.
+
+2. When drbg_kcapi_hash() calls crypto_shash_update() on the additional
+   information string, the length is implicitly cast to 'unsigned int'.
+   That truncates the additional information string to U32_MAX bytes.
+
+Fix the maximum additional information string length to always be
+U32_MAX - 1, causing an error to be returned for any longer lengths.
+
+Fixes: 541af946fe13 ("crypto: drbg - SP800-90A Deterministic Random Bit Generator")
+Cc: stable@vger.kernel.org
+Signed-off-by: Eric Biggers <ebiggers@kernel.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/crypto/drbg.h |   18 +++++++-----------
+ 1 file changed, 7 insertions(+), 11 deletions(-)
+
+--- a/include/crypto/drbg.h
++++ b/include/crypto/drbg.h
+@@ -171,19 +171,15 @@ static inline size_t drbg_max_request_by
+       return (1 << 16);
+ }
++/*
++ * SP800-90A allows implementations to support additional info / personalization
++ * strings of up to 2**35 bits.  Implementations can have a smaller maximum.  We
++ * use 2**35 - 16 bits == U32_MAX - 1 bytes so that the max + 1 always fits in a
++ * size_t, allowing drbg_healthcheck_sanity() to verify its enforcement.
++ */
+ static inline size_t drbg_max_addtl(struct drbg_state *drbg)
+ {
+-      /* SP800-90A requires 2**35 bytes additional info str / pers str */
+-#if (__BITS_PER_LONG == 32)
+-      /*
+-       * SP800-90A allows smaller maximum numbers to be returned -- we
+-       * return SIZE_MAX - 1 to allow the verification of the enforcement
+-       * of this value in drbg_healthcheck_sanity.
+-       */
+-      return (SIZE_MAX - 1);
+-#else
+-      return (1UL<<35);
+-#endif
++      return U32_MAX - 1;
+ }
+ static inline size_t drbg_max_requests(struct drbg_state *drbg)
diff --git a/queue-6.18/crypto-drbg-fix-returning-success-on-failure-in-ctr_drbg.patch b/queue-6.18/crypto-drbg-fix-returning-success-on-failure-in-ctr_drbg.patch
new file mode 100644 (file)
index 0000000..bb00621
--- /dev/null
@@ -0,0 +1,32 @@
+From 39a31ad9e2a5ed7e9c9c6f711dca96c8c8f5f26b Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@kernel.org>
+Date: Sun, 19 Apr 2026 23:33:45 -0700
+Subject: crypto: drbg - Fix returning success on failure in CTR_DRBG
+
+From: Eric Biggers <ebiggers@kernel.org>
+
+commit 39a31ad9e2a5ed7e9c9c6f711dca96c8c8f5f26b upstream.
+
+drbg_ctr_generate() sometimes returns success when it fails, leaving the
+output buffer uninitialized.  Fix it.
+
+Fixes: cde001e4c3c3 ("crypto: rng - RNGs must return 0 in success case")
+Cc: stable@vger.kernel.org
+Signed-off-by: Eric Biggers <ebiggers@kernel.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ crypto/drbg.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/crypto/drbg.c
++++ b/crypto/drbg.c
+@@ -592,7 +592,7 @@ static int drbg_ctr_generate(struct drbg
+       if (addtl && !list_empty(addtl)) {
+               ret = drbg_ctr_update(drbg, addtl, 2);
+               if (ret)
+-                      return 0;
++                      return ret;
+       }
+       /* 10.2.1.5.2 step 4.1 */
diff --git a/queue-6.18/crypto-drbg-fix-the-fips_enabled-priority-boost.patch b/queue-6.18/crypto-drbg-fix-the-fips_enabled-priority-boost.patch
new file mode 100644 (file)
index 0000000..fff5097
--- /dev/null
@@ -0,0 +1,39 @@
+From a8a1f93080efc83a9ff8452954429ae379e9e614 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@kernel.org>
+Date: Sun, 19 Apr 2026 23:33:49 -0700
+Subject: crypto: drbg - Fix the fips_enabled priority boost
+
+From: Eric Biggers <ebiggers@kernel.org>
+
+commit a8a1f93080efc83a9ff8452954429ae379e9e614 upstream.
+
+When fips_enabled=1, it seems to have been intended for one of the
+algorithms defined in crypto/drbg.c to be the highest priority "stdrng"
+algorithm, so that it is what is used by "stdrng" users.
+
+However, the code only boosts the priority to 400, which is less than
+the priority 500 used in drivers/crypto/caam/caamprng.c.  Thus, the CAAM
+RNG could be used instead.
+
+Fix this by boosting the priority by 2000 instead of 200.
+
+Fixes: 541af946fe13 ("crypto: drbg - SP800-90A Deterministic Random Bit Generator")
+Cc: stable@vger.kernel.org
+Signed-off-by: Eric Biggers <ebiggers@kernel.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ crypto/drbg.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/crypto/drbg.c
++++ b/crypto/drbg.c
+@@ -2082,7 +2082,7 @@ static inline void __init drbg_fill_arra
+        * it is selected.
+        */
+       if (fips_enabled)
+-              alg->base.cra_priority += 200;
++              alg->base.cra_priority += 2000;
+       alg->base.cra_ctxsize   = sizeof(struct drbg_state);
+       alg->base.cra_module    = THIS_MODULE;
diff --git a/queue-6.18/crypto-ecc-fix-carry-overflow-in-vli-multiplication.patch b/queue-6.18/crypto-ecc-fix-carry-overflow-in-vli-multiplication.patch
new file mode 100644 (file)
index 0000000..d252256
--- /dev/null
@@ -0,0 +1,98 @@
+From 27b536a2ec8e2f85a0380c2d13c9ecbc7aaab406 Mon Sep 17 00:00:00 2001
+From: Anastasia Tishchenko <sv3iry@gmail.com>
+Date: Wed, 13 May 2026 13:57:40 +0300
+Subject: crypto: ecc - Fix carry overflow in vli multiplication
+
+From: Anastasia Tishchenko <sv3iry@gmail.com>
+
+commit 27b536a2ec8e2f85a0380c2d13c9ecbc7aaab406 upstream.
+
+The carry flag calculation fails when r01.m_high is saturated
+(0xFFFFFFFFFFFFFFFF) and addition of lower bits overflows.
+
+The condition (r01.m_high < product.m_high) doesn't handle the case
+where r01.m_high == product.m_high and an additional carry exists
+from lower-bit overflow.
+
+When commit 3c4b23901a0c ("crypto: ecdh - Add ECDH software support")
+introduced crypto/ecc.c, it split the muladd() function in the
+micro-ecc library into separate mul_64_64() and add_128_128() helpers.
+It seems the check got lost in translation.
+
+Add proper handling for this boundary by accounting for the carry
+from the lower addition.
+
+Fixes: 3c4b23901a0c ("crypto: ecdh - Add ECDH software support")
+Signed-off-by: Anastasia Tishchenko <sv3iry@gmail.com>
+Cc: stable@vger.kernel.org # v4.8+
+Reviewed-by: Lukas Wunner <lukas@wunner.de>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ crypto/ecc.c |   31 ++++++++++++++++++++-----------
+ 1 file changed, 20 insertions(+), 11 deletions(-)
+
+--- a/crypto/ecc.c
++++ b/crypto/ecc.c
+@@ -402,14 +402,26 @@ static uint128_t mul_64_64(u64 left, u64
+       return result;
+ }
+-static uint128_t add_128_128(uint128_t a, uint128_t b)
++/* Calculate addition with overflow checking. Returns true on wrap-around,
++ * false otherwise.
++ */
++static bool check_add_128_128_overflow(uint128_t *result, uint128_t a,
++                                     uint128_t b)
+ {
+-      uint128_t result;
++      bool carry;
+-      result.m_low = a.m_low + b.m_low;
+-      result.m_high = a.m_high + b.m_high + (result.m_low < a.m_low);
++      result->m_low = a.m_low + b.m_low;
++      carry = (result->m_low < a.m_low);
+-      return result;
++      result->m_high = a.m_high + b.m_high + carry;
++
++      /* Using constant-time bitwise arithmetic to prevent timing
++       * side-channels.
++       */
++      carry = (result->m_high < a.m_high) |
++              ((result->m_high == a.m_high) & carry);
++
++      return carry;
+ }
+ static void vli_mult(u64 *result, const u64 *left, const u64 *right,
+@@ -434,9 +446,7 @@ static void vli_mult(u64 *result, const
+                       uint128_t product;
+                       product = mul_64_64(left[i], right[k - i]);
+-
+-                      r01 = add_128_128(r01, product);
+-                      r2 += (r01.m_high < product.m_high);
++                      r2 += check_add_128_128_overflow(&r01, r01, product);
+               }
+               result[k] = r01.m_low;
+@@ -459,7 +469,7 @@ static void vli_umult(u64 *result, const
+               uint128_t product;
+               product = mul_64_64(left[k], right);
+-              r01 = add_128_128(r01, product);
++              check_add_128_128_overflow(&r01, r01, product);
+               /* no carry */
+               result[k] = r01.m_low;
+               r01.m_low = r01.m_high;
+@@ -496,8 +506,7 @@ static void vli_square(u64 *result, cons
+                               product.m_low <<= 1;
+                       }
+-                      r01 = add_128_128(r01, product);
+-                      r2 += (r01.m_high < product.m_high);
++                      r2 += check_add_128_128_overflow(&r01, r01, product);
+               }
+               result[k] = r01.m_low;
diff --git a/queue-6.18/crypto-hisi-trng-remove-crypto_rng-interface.patch b/queue-6.18/crypto-hisi-trng-remove-crypto_rng-interface.patch
new file mode 100644 (file)
index 0000000..7e574e8
--- /dev/null
@@ -0,0 +1,404 @@
+From 216a7795ec210bdabd5dad42323eee70bbfc8d90 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@kernel.org>
+Date: Sat, 30 May 2026 13:26:23 -0700
+Subject: crypto: hisi-trng - Remove crypto_rng interface
+
+From: Eric Biggers <ebiggers@kernel.org>
+
+commit 216a7795ec210bdabd5dad42323eee70bbfc8d90 upstream.
+
+drivers/crypto/hisilicon/trng/trng.c exposes the same hardware through
+two completely separate interfaces, crypto_rng and hwrng.  However, the
+implementation of this is buggy because it permits generation operations
+from these interfaces to run concurrently with each other, accessing the
+same registers.  That is, hisi_trng_generate() synchronizes with itself
+but not with hisi_trng_read().  This results in potential repetition of
+output from the RNG, output of non-random values, etc.
+
+Fortunately, there's actually no point in hardware RNG drivers
+implementing the crypto_rng interface.  It's not actually used by
+anything besides the "rng" algorithm type of AF_ALG, which in turn is
+not actually used in practice.  Other crypto_rng hardware drivers are
+likewise being phased out, leaving just the hwrng support.
+
+Thus, remove it to simplify the code and avoid conflict (and confusion)
+with the hwrng interface which is the one that actually matters.
+
+Fixes: e4d9d10ef4be ("crypto: hisilicon/trng - add support for PRNG")
+Cc: stable@vger.kernel.org
+Signed-off-by: Eric Biggers <ebiggers@kernel.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/hisilicon/Kconfig     |    1 
+ drivers/crypto/hisilicon/trng/trng.c |  296 -----------------------------------
+ 2 files changed, 2 insertions(+), 295 deletions(-)
+
+--- a/drivers/crypto/hisilicon/Kconfig
++++ b/drivers/crypto/hisilicon/Kconfig
+@@ -79,6 +79,5 @@ config CRYPTO_DEV_HISI_TRNG
+       tristate "Support for HISI TRNG Driver"
+       depends on ARM64 && ACPI
+       select HW_RANDOM
+-      select CRYPTO_RNG
+       help
+         Support for HiSilicon TRNG Driver.
+--- a/drivers/crypto/hisilicon/trng/trng.c
++++ b/drivers/crypto/hisilicon/trng/trng.c
+@@ -1,234 +1,27 @@
+ // SPDX-License-Identifier: GPL-2.0
+ /* Copyright (c) 2019 HiSilicon Limited. */
+-#include <crypto/internal/rng.h>
+ #include <linux/acpi.h>
+-#include <linux/crypto.h>
+ #include <linux/err.h>
+ #include <linux/hw_random.h>
+ #include <linux/io.h>
+ #include <linux/iopoll.h>
+ #include <linux/kernel.h>
+-#include <linux/list.h>
+ #include <linux/module.h>
+-#include <linux/mutex.h>
+ #include <linux/platform_device.h>
+ #include <linux/random.h>
+ #define HISI_TRNG_REG         0x00F0
+ #define HISI_TRNG_BYTES               4
+ #define HISI_TRNG_QUALITY     512
+-#define HISI_TRNG_VERSION     0x01B8
+-#define HISI_TRNG_VER_V1      GENMASK(31, 0)
+ #define SLEEP_US              10
+ #define TIMEOUT_US            10000
+-#define SW_DRBG_NUM_SHIFT     2
+-#define SW_DRBG_KEY_BASE      0x082C
+-#define SW_DRBG_SEED(n)         (SW_DRBG_KEY_BASE - ((n) << SW_DRBG_NUM_SHIFT))
+-#define SW_DRBG_SEED_REGS_NUM 12
+-#define SW_DRBG_SEED_SIZE     48
+-#define SW_DRBG_BLOCKS                0x0830
+-#define SW_DRBG_INIT          0x0834
+-#define SW_DRBG_GEN           0x083c
+-#define SW_DRBG_STATUS                0x0840
+-#define SW_DRBG_BLOCKS_NUM    4095
+-#define SW_DRBG_DATA_BASE     0x0850
+-#define SW_DRBG_DATA_NUM      4
+-#define SW_DRBG_DATA(n)               (SW_DRBG_DATA_BASE - ((n) << SW_DRBG_NUM_SHIFT))
+-#define SW_DRBG_BYTES         16
+-#define SW_DRBG_ENABLE_SHIFT  12
+-#define SEED_SHIFT_24         24
+-#define SEED_SHIFT_16         16
+-#define SEED_SHIFT_8          8
+-#define SW_MAX_RANDOM_BYTES   65520
+-
+-struct hisi_trng_list {
+-      struct mutex lock;
+-      struct list_head list;
+-      bool is_init;
+-};
+ struct hisi_trng {
+       void __iomem *base;
+-      struct hisi_trng_list *trng_list;
+-      struct list_head list;
+       struct hwrng rng;
+-      u32 ver;
+-      u32 ctx_num;
+-      /* The bytes of the random number generated since the last seeding. */
+-      u32 random_bytes;
+-      struct mutex lock;
+-};
+-
+-struct hisi_trng_ctx {
+-      struct hisi_trng *trng;
+ };
+-static atomic_t trng_active_devs;
+-static struct hisi_trng_list trng_devices;
+-static int hisi_trng_read(struct hwrng *rng, void *buf, size_t max, bool wait);
+-
+-static int hisi_trng_set_seed(struct hisi_trng *trng, const u8 *seed)
+-{
+-      u32 val, seed_reg, i;
+-      int ret;
+-
+-      writel(0x0, trng->base + SW_DRBG_BLOCKS);
+-
+-      for (i = 0; i < SW_DRBG_SEED_SIZE;
+-           i += SW_DRBG_SEED_SIZE / SW_DRBG_SEED_REGS_NUM) {
+-              val = seed[i] << SEED_SHIFT_24;
+-              val |= seed[i + 1UL] << SEED_SHIFT_16;
+-              val |= seed[i + 2UL] << SEED_SHIFT_8;
+-              val |= seed[i + 3UL];
+-
+-              seed_reg = (i >> SW_DRBG_NUM_SHIFT) % SW_DRBG_SEED_REGS_NUM;
+-              writel(val, trng->base + SW_DRBG_SEED(seed_reg));
+-      }
+-
+-      writel(SW_DRBG_BLOCKS_NUM | (0x1 << SW_DRBG_ENABLE_SHIFT),
+-             trng->base + SW_DRBG_BLOCKS);
+-      writel(0x1, trng->base + SW_DRBG_INIT);
+-      ret = readl_relaxed_poll_timeout(trng->base + SW_DRBG_STATUS,
+-                                       val, val & BIT(0), SLEEP_US, TIMEOUT_US);
+-      if (ret) {
+-              pr_err("failed to init trng(%d)\n", ret);
+-              return -EIO;
+-      }
+-
+-      trng->random_bytes = 0;
+-
+-      return 0;
+-}
+-
+-static int hisi_trng_seed(struct crypto_rng *tfm, const u8 *seed,
+-                        unsigned int slen)
+-{
+-      struct hisi_trng_ctx *ctx = crypto_rng_ctx(tfm);
+-      struct hisi_trng *trng = ctx->trng;
+-      int ret;
+-
+-      if (slen < SW_DRBG_SEED_SIZE) {
+-              pr_err("slen(%u) is not matched with trng(%d)\n", slen,
+-                      SW_DRBG_SEED_SIZE);
+-              return -EINVAL;
+-      }
+-
+-      mutex_lock(&trng->lock);
+-      ret = hisi_trng_set_seed(trng, seed);
+-      mutex_unlock(&trng->lock);
+-
+-      return ret;
+-}
+-
+-static int hisi_trng_reseed(struct hisi_trng *trng)
+-{
+-      u8 seed[SW_DRBG_SEED_SIZE];
+-      int size;
+-
+-      if (!trng->random_bytes)
+-              return 0;
+-
+-      size = hisi_trng_read(&trng->rng, seed, SW_DRBG_SEED_SIZE, false);
+-      if (size != SW_DRBG_SEED_SIZE)
+-              return -EIO;
+-
+-      return hisi_trng_set_seed(trng, seed);
+-}
+-
+-static int hisi_trng_get_bytes(struct hisi_trng *trng, u8 *dstn, unsigned int dlen)
+-{
+-      u32 data[SW_DRBG_DATA_NUM];
+-      u32 currsize = 0;
+-      u32 val = 0;
+-      int ret;
+-      u32 i;
+-
+-      ret = hisi_trng_reseed(trng);
+-      if (ret)
+-              return ret;
+-
+-      do {
+-              ret = readl_relaxed_poll_timeout(trng->base + SW_DRBG_STATUS,
+-                                               val, val & BIT(1), SLEEP_US, TIMEOUT_US);
+-              if (ret) {
+-                      pr_err("failed to generate random number(%d)!\n", ret);
+-                      break;
+-              }
+-
+-              for (i = 0; i < SW_DRBG_DATA_NUM; i++)
+-                      data[i] = readl(trng->base + SW_DRBG_DATA(i));
+-
+-              if (dlen - currsize >= SW_DRBG_BYTES) {
+-                      memcpy(dstn + currsize, data, SW_DRBG_BYTES);
+-                      currsize += SW_DRBG_BYTES;
+-              } else {
+-                      memcpy(dstn + currsize, data, dlen - currsize);
+-                      currsize = dlen;
+-              }
+-
+-              trng->random_bytes += SW_DRBG_BYTES;
+-              writel(0x1, trng->base + SW_DRBG_GEN);
+-      } while (currsize < dlen);
+-
+-      return ret;
+-}
+-
+-static int hisi_trng_generate(struct crypto_rng *tfm, const u8 *src,
+-                            unsigned int slen, u8 *dstn, unsigned int dlen)
+-{
+-      struct hisi_trng_ctx *ctx = crypto_rng_ctx(tfm);
+-      struct hisi_trng *trng = ctx->trng;
+-      unsigned int currsize = 0;
+-      unsigned int block_size;
+-      int ret;
+-
+-      if (!dstn || !dlen) {
+-              pr_err("output is error, dlen %u!\n", dlen);
+-              return -EINVAL;
+-      }
+-
+-      do {
+-              block_size = min_t(unsigned int, dlen - currsize, SW_MAX_RANDOM_BYTES);
+-              mutex_lock(&trng->lock);
+-              ret = hisi_trng_get_bytes(trng, dstn + currsize, block_size);
+-              mutex_unlock(&trng->lock);
+-              if (ret)
+-                      return ret;
+-              currsize += block_size;
+-      } while (currsize < dlen);
+-
+-      return 0;
+-}
+-
+-static int hisi_trng_init(struct crypto_tfm *tfm)
+-{
+-      struct hisi_trng_ctx *ctx = crypto_tfm_ctx(tfm);
+-      struct hisi_trng *trng;
+-      u32 ctx_num = ~0;
+-
+-      mutex_lock(&trng_devices.lock);
+-      list_for_each_entry(trng, &trng_devices.list, list) {
+-              if (trng->ctx_num < ctx_num) {
+-                      ctx_num = trng->ctx_num;
+-                      ctx->trng = trng;
+-              }
+-      }
+-      ctx->trng->ctx_num++;
+-      mutex_unlock(&trng_devices.lock);
+-
+-      return 0;
+-}
+-
+-static void hisi_trng_exit(struct crypto_tfm *tfm)
+-{
+-      struct hisi_trng_ctx *ctx = crypto_tfm_ctx(tfm);
+-
+-      mutex_lock(&trng_devices.lock);
+-      ctx->trng->ctx_num--;
+-      mutex_unlock(&trng_devices.lock);
+-}
+-
+ static int hisi_trng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
+ {
+       struct hisi_trng *trng;
+@@ -260,42 +53,6 @@ static int hisi_trng_read(struct hwrng *
+       return currsize;
+ }
+-static struct rng_alg hisi_trng_alg = {
+-      .generate = hisi_trng_generate,
+-      .seed = hisi_trng_seed,
+-      .seedsize = SW_DRBG_SEED_SIZE,
+-      .base = {
+-              .cra_name = "stdrng",
+-              .cra_driver_name = "hisi_stdrng",
+-              .cra_priority = 300,
+-              .cra_ctxsize = sizeof(struct hisi_trng_ctx),
+-              .cra_module = THIS_MODULE,
+-              .cra_init = hisi_trng_init,
+-              .cra_exit = hisi_trng_exit,
+-      },
+-};
+-
+-static void hisi_trng_add_to_list(struct hisi_trng *trng)
+-{
+-      mutex_lock(&trng_devices.lock);
+-      list_add_tail(&trng->list, &trng_devices.list);
+-      mutex_unlock(&trng_devices.lock);
+-}
+-
+-static int hisi_trng_del_from_list(struct hisi_trng *trng)
+-{
+-      int ret = -EBUSY;
+-
+-      mutex_lock(&trng_devices.lock);
+-      if (!trng->ctx_num) {
+-              list_del(&trng->list);
+-              ret = 0;
+-      }
+-      mutex_unlock(&trng_devices.lock);
+-
+-      return ret;
+-}
+-
+ static int hisi_trng_probe(struct platform_device *pdev)
+ {
+       struct hisi_trng *trng;
+@@ -305,68 +62,20 @@ static int hisi_trng_probe(struct platfo
+       if (!trng)
+               return -ENOMEM;
+-      platform_set_drvdata(pdev, trng);
+-
+       trng->base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(trng->base))
+               return PTR_ERR(trng->base);
+-      trng->ctx_num = 0;
+-      trng->random_bytes = SW_MAX_RANDOM_BYTES;
+-      mutex_init(&trng->lock);
+-      trng->ver = readl(trng->base + HISI_TRNG_VERSION);
+-      if (!trng_devices.is_init) {
+-              INIT_LIST_HEAD(&trng_devices.list);
+-              mutex_init(&trng_devices.lock);
+-              trng_devices.is_init = true;
+-      }
+-
+-      hisi_trng_add_to_list(trng);
+-      if (trng->ver != HISI_TRNG_VER_V1 &&
+-          atomic_inc_return(&trng_active_devs) == 1) {
+-              ret = crypto_register_rng(&hisi_trng_alg);
+-              if (ret) {
+-                      dev_err(&pdev->dev,
+-                              "failed to register crypto(%d)\n", ret);
+-                      atomic_dec_return(&trng_active_devs);
+-                      goto err_remove_from_list;
+-              }
+-      }
+-
+       trng->rng.name = pdev->name;
+       trng->rng.read = hisi_trng_read;
+       trng->rng.quality = HISI_TRNG_QUALITY;
++
+       ret = devm_hwrng_register(&pdev->dev, &trng->rng);
+-      if (ret) {
++      if (ret)
+               dev_err(&pdev->dev, "failed to register hwrng: %d!\n", ret);
+-              goto err_crypto_unregister;
+-      }
+-
+-      return ret;
+-
+-err_crypto_unregister:
+-      if (trng->ver != HISI_TRNG_VER_V1 &&
+-          atomic_dec_return(&trng_active_devs) == 0)
+-              crypto_unregister_rng(&hisi_trng_alg);
+-
+-err_remove_from_list:
+-      hisi_trng_del_from_list(trng);
+       return ret;
+ }
+-static void hisi_trng_remove(struct platform_device *pdev)
+-{
+-      struct hisi_trng *trng = platform_get_drvdata(pdev);
+-
+-      /* Wait until the task is finished */
+-      while (hisi_trng_del_from_list(trng))
+-              ;
+-
+-      if (trng->ver != HISI_TRNG_VER_V1 &&
+-          atomic_dec_return(&trng_active_devs) == 0)
+-              crypto_unregister_rng(&hisi_trng_alg);
+-}
+-
+ static const struct acpi_device_id hisi_trng_acpi_match[] = {
+       { "HISI02B3", 0 },
+       { }
+@@ -375,7 +84,6 @@ MODULE_DEVICE_TABLE(acpi, hisi_trng_acpi
+ static struct platform_driver hisi_trng_driver = {
+       .probe          = hisi_trng_probe,
+-      .remove         = hisi_trng_remove,
+       .driver         = {
+               .name   = "hisi-trng-v2",
+               .acpi_match_table = ACPI_PTR(hisi_trng_acpi_match),
diff --git a/queue-6.18/crypto-loongson-remove-broken-and-unused-loongson-rng.patch b/queue-6.18/crypto-loongson-remove-broken-and-unused-loongson-rng.patch
new file mode 100644 (file)
index 0000000..3906836
--- /dev/null
@@ -0,0 +1,345 @@
+From af3d1bb9a09daf928fc3f173689fb7904d6a6d4f Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@kernel.org>
+Date: Fri, 29 May 2026 16:32:08 -0700
+Subject: crypto: loongson - Remove broken and unused loongson-rng
+
+From: Eric Biggers <ebiggers@kernel.org>
+
+commit af3d1bb9a09daf928fc3f173689fb7904d6a6d4f upstream.
+
+The loongson-rng rng_alg has several vulnerabilities, including not
+providing forward security, and a use-after-free bug due to the use of
+wait_for_completion_interruptible().
+
+Meanwhile, the rng_alg framework doesn't really have any purpose in the
+first place other than to access the software algorithms crypto/drbg.c
+and crypto/jitterentropy.c.  Hardware-specific rng_algs have no
+in-kernel user, and unlike hwrng there's no feed into the actual Linux
+RNG.  As such, there's really no point to this code.  There are of
+course other rng_alg drivers that are similarly unused, but they're
+similarly in the process of being phased out, e.g.
+https://lore.kernel.org/r/20260529193648.18172-1-ebiggers@kernel.org and
+https://lore.kernel.org/r/20260529220430.34135-1-ebiggers@kernel.org
+
+Given that, there's no point in fixing forward these vulnerabilities,
+and it makes much more sense to simply roll back the addition of this
+driver.  If this platform provides TRNG (not PRNG) functionality, it
+could make sense to add a hwrng driver, but it would be quite different.
+
+Link: https://lore.kernel.org/linux-crypto/20260525145939.GC2018@quark/
+Fixes: 766b2d724c8d ("crypto: loongson - add Loongson RNG driver support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Eric Biggers <ebiggers@kernel.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ MAINTAINERS                                 |   1 -
+ arch/loongarch/configs/loongson32_defconfig |   1 -
+ arch/loongarch/configs/loongson64_defconfig |   1 -
+ drivers/crypto/Kconfig                      |   1 -
+ drivers/crypto/Makefile                     |   1 -
+ drivers/crypto/loongson/Kconfig             |   6 -
+ drivers/crypto/loongson/Makefile            |   1 -
+ drivers/crypto/loongson/loongson-rng.c      | 209 --------------------
+ 8 files changed, 221 deletions(-)
+ delete mode 100644 drivers/crypto/loongson/Kconfig
+ delete mode 100644 drivers/crypto/loongson/Makefile
+ delete mode 100644 drivers/crypto/loongson/loongson-rng.c
+
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 882214b0e7db..6c805560c77c 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -15070,7 +15070,6 @@ M:     Qunqin Zhao <zhaoqunqin@loongson.cn>
+ L:    linux-crypto@vger.kernel.org
+ S:    Maintained
+ F:    drivers/char/tpm/tpm_loongson.c
+-F:    drivers/crypto/loongson/
+ F:    drivers/mfd/loongson-se.c
+ F:    include/linux/mfd/loongson-se.h
+diff --git a/arch/loongarch/configs/loongson32_defconfig b/arch/loongarch/configs/loongson32_defconfig
+index d5ef396dffe3..82897236863f 100644
+--- a/arch/loongarch/configs/loongson32_defconfig
++++ b/arch/loongarch/configs/loongson32_defconfig
+@@ -1091,7 +1091,6 @@ CONFIG_CRYPTO_USER_API_SKCIPHER=m
+ CONFIG_CRYPTO_USER_API_RNG=m
+ CONFIG_CRYPTO_USER_API_AEAD=m
+ CONFIG_CRYPTO_DEV_VIRTIO=m
+-CONFIG_CRYPTO_DEV_LOONGSON_RNG=m
+ CONFIG_DMA_CMA=y
+ CONFIG_CMA_SIZE_MBYTES=0
+ CONFIG_PRINTK_TIME=y
+diff --git a/arch/loongarch/configs/loongson64_defconfig b/arch/loongarch/configs/loongson64_defconfig
+index cba4cdff5acd..a94e88bd7ec5 100644
+--- a/arch/loongarch/configs/loongson64_defconfig
++++ b/arch/loongarch/configs/loongson64_defconfig
+@@ -1124,7 +1124,6 @@ CONFIG_CRYPTO_USER_API_SKCIPHER=m
+ CONFIG_CRYPTO_USER_API_RNG=m
+ CONFIG_CRYPTO_USER_API_AEAD=m
+ CONFIG_CRYPTO_DEV_VIRTIO=m
+-CONFIG_CRYPTO_DEV_LOONGSON_RNG=m
+ CONFIG_DMA_CMA=y
+ CONFIG_DMA_NUMA_CMA=y
+ CONFIG_CMA_SIZE_MBYTES=0
+diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
+index 5dab813a9f74..223cb3c32261 100644
+--- a/drivers/crypto/Kconfig
++++ b/drivers/crypto/Kconfig
+@@ -845,7 +845,6 @@ config CRYPTO_DEV_CCREE
+         If unsure say Y.
+ source "drivers/crypto/hisilicon/Kconfig"
+-source "drivers/crypto/loongson/Kconfig"
+ source "drivers/crypto/amlogic/Kconfig"
+diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
+index 283bbc650b5b..ad773158ae56 100644
+--- a/drivers/crypto/Makefile
++++ b/drivers/crypto/Makefile
+@@ -43,7 +43,6 @@ obj-y += inside-secure/
+ obj-$(CONFIG_CRYPTO_DEV_ARTPEC6) += axis/
+ obj-y += xilinx/
+ obj-y += hisilicon/
+-obj-y += loongson/
+ obj-$(CONFIG_CRYPTO_DEV_AMLOGIC_GXL) += amlogic/
+ obj-y += intel/
+ obj-y += starfive/
+diff --git a/drivers/crypto/loongson/Kconfig b/drivers/crypto/loongson/Kconfig
+deleted file mode 100644
+index f4e1544ffbb4..000000000000
+--- a/drivers/crypto/loongson/Kconfig
++++ /dev/null
+@@ -1,6 +0,0 @@
+-config CRYPTO_DEV_LOONGSON_RNG
+-      tristate "Support for Loongson RNG Driver"
+-      depends on MFD_LOONGSON_SE
+-      select CRYPTO_RNG
+-      help
+-        Support for Loongson RNG Driver.
+diff --git a/drivers/crypto/loongson/Makefile b/drivers/crypto/loongson/Makefile
+deleted file mode 100644
+index 1ce5ec32b553..000000000000
+--- a/drivers/crypto/loongson/Makefile
++++ /dev/null
+@@ -1 +0,0 @@
+-obj-$(CONFIG_CRYPTO_DEV_LOONGSON_RNG)  += loongson-rng.o
+diff --git a/drivers/crypto/loongson/loongson-rng.c b/drivers/crypto/loongson/loongson-rng.c
+deleted file mode 100644
+index 3a4940260f9e..000000000000
+--- a/drivers/crypto/loongson/loongson-rng.c
++++ /dev/null
+@@ -1,209 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0
+-/* Copyright (c) 2019 HiSilicon Limited. */
+-/* Copyright (c) 2025 Loongson Technology Corporation Limited. */
+-
+-#include <linux/crypto.h>
+-#include <linux/err.h>
+-#include <linux/hw_random.h>
+-#include <linux/io.h>
+-#include <linux/iopoll.h>
+-#include <linux/kernel.h>
+-#include <linux/list.h>
+-#include <linux/mfd/loongson-se.h>
+-#include <linux/module.h>
+-#include <linux/mutex.h>
+-#include <linux/platform_device.h>
+-#include <linux/random.h>
+-#include <crypto/internal/rng.h>
+-
+-#define SE_SEED_SIZE 32
+-
+-struct loongson_rng_list {
+-      struct mutex lock;
+-      struct list_head list;
+-      int registered;
+-};
+-
+-struct loongson_rng {
+-      u32 used;
+-      struct loongson_se_engine *engine;
+-      struct list_head list;
+-      struct mutex lock;
+-};
+-
+-struct loongson_rng_ctx {
+-      struct loongson_rng *rng;
+-};
+-
+-struct loongson_rng_cmd {
+-      u32 cmd_id;
+-      union {
+-              u32 len;
+-              u32 ret;
+-      } u;
+-      u32 seed_off;
+-      u32 out_off;
+-      u32 pad[4];
+-};
+-
+-static struct loongson_rng_list rng_devices = {
+-      .lock = __MUTEX_INITIALIZER(rng_devices.lock),
+-      .list = LIST_HEAD_INIT(rng_devices.list),
+-};
+-
+-static int loongson_rng_generate(struct crypto_rng *tfm, const u8 *src,
+-                        unsigned int slen, u8 *dstn, unsigned int dlen)
+-{
+-      struct loongson_rng_ctx *ctx = crypto_rng_ctx(tfm);
+-      struct loongson_rng *rng = ctx->rng;
+-      struct loongson_rng_cmd *cmd = rng->engine->command;
+-      int err, len;
+-
+-      mutex_lock(&rng->lock);
+-      cmd->seed_off = 0;
+-      do {
+-              len = min(dlen, rng->engine->buffer_size);
+-              cmd = rng->engine->command;
+-              cmd->u.len = len;
+-              err = loongson_se_send_engine_cmd(rng->engine);
+-              if (err)
+-                      break;
+-
+-              cmd = rng->engine->command_ret;
+-              if (cmd->u.ret) {
+-                      err = -EIO;
+-                      break;
+-              }
+-
+-              memcpy(dstn, rng->engine->data_buffer, len);
+-              dlen -= len;
+-              dstn += len;
+-      } while (dlen > 0);
+-      mutex_unlock(&rng->lock);
+-
+-      return err;
+-}
+-
+-static int loongson_rng_init(struct crypto_tfm *tfm)
+-{
+-      struct loongson_rng_ctx *ctx = crypto_tfm_ctx(tfm);
+-      struct loongson_rng *rng;
+-      u32 min_used = U32_MAX;
+-
+-      mutex_lock(&rng_devices.lock);
+-      list_for_each_entry(rng, &rng_devices.list, list) {
+-              if (rng->used < min_used) {
+-                      ctx->rng = rng;
+-                      min_used = rng->used;
+-              }
+-      }
+-      ctx->rng->used++;
+-      mutex_unlock(&rng_devices.lock);
+-
+-      return 0;
+-}
+-
+-static void loongson_rng_exit(struct crypto_tfm *tfm)
+-{
+-      struct loongson_rng_ctx *ctx = crypto_tfm_ctx(tfm);
+-
+-      mutex_lock(&rng_devices.lock);
+-      ctx->rng->used--;
+-      mutex_unlock(&rng_devices.lock);
+-}
+-
+-static int loongson_rng_seed(struct crypto_rng *tfm, const u8 *seed,
+-                           unsigned int slen)
+-{
+-      struct loongson_rng_ctx *ctx = crypto_rng_ctx(tfm);
+-      struct loongson_rng *rng = ctx->rng;
+-      struct loongson_rng_cmd *cmd;
+-      int err;
+-
+-      if (slen < SE_SEED_SIZE)
+-              return -EINVAL;
+-
+-      slen = min(slen, rng->engine->buffer_size);
+-
+-      mutex_lock(&rng->lock);
+-      cmd = rng->engine->command;
+-      cmd->u.len = slen;
+-      cmd->seed_off = rng->engine->buffer_off;
+-      memcpy(rng->engine->data_buffer, seed, slen);
+-      err = loongson_se_send_engine_cmd(rng->engine);
+-      if (err)
+-              goto out;
+-
+-      cmd = rng->engine->command_ret;
+-      if (cmd->u.ret)
+-              err = -EIO;
+-out:
+-      mutex_unlock(&rng->lock);
+-
+-      return err;
+-}
+-
+-static struct rng_alg loongson_rng_alg = {
+-      .generate = loongson_rng_generate,
+-      .seed = loongson_rng_seed,
+-      .seedsize = SE_SEED_SIZE,
+-      .base = {
+-              .cra_name = "stdrng",
+-              .cra_driver_name = "loongson_stdrng",
+-              .cra_priority = 300,
+-              .cra_ctxsize = sizeof(struct loongson_rng_ctx),
+-              .cra_module = THIS_MODULE,
+-              .cra_init = loongson_rng_init,
+-              .cra_exit = loongson_rng_exit,
+-      },
+-};
+-
+-static int loongson_rng_probe(struct platform_device *pdev)
+-{
+-      struct loongson_rng_cmd *cmd;
+-      struct loongson_rng *rng;
+-      int ret = 0;
+-
+-      rng = devm_kzalloc(&pdev->dev, sizeof(*rng), GFP_KERNEL);
+-      if (!rng)
+-              return -ENOMEM;
+-
+-      rng->engine = loongson_se_init_engine(pdev->dev.parent, SE_ENGINE_RNG);
+-      if (!rng->engine)
+-              return -ENODEV;
+-      cmd = rng->engine->command;
+-      cmd->cmd_id = SE_CMD_RNG;
+-      cmd->out_off = rng->engine->buffer_off;
+-      mutex_init(&rng->lock);
+-
+-      mutex_lock(&rng_devices.lock);
+-
+-      if (!rng_devices.registered) {
+-              ret = crypto_register_rng(&loongson_rng_alg);
+-              if (ret) {
+-                      dev_err(&pdev->dev, "failed to register crypto(%d)\n", ret);
+-                      goto out;
+-              }
+-              rng_devices.registered = 1;
+-      }
+-
+-      list_add_tail(&rng->list, &rng_devices.list);
+-out:
+-      mutex_unlock(&rng_devices.lock);
+-
+-      return ret;
+-}
+-
+-static struct platform_driver loongson_rng_driver = {
+-      .probe          = loongson_rng_probe,
+-      .driver         = {
+-              .name   = "loongson-rng",
+-      },
+-};
+-module_platform_driver(loongson_rng_driver);
+-
+-MODULE_ALIAS("platform:loongson-rng");
+-MODULE_LICENSE("GPL");
+-MODULE_AUTHOR("Yinggang Gu <guyinggang@loongson.cn>");
+-MODULE_AUTHOR("Qunqin Zhao <zhaoqunqin@loongson.cn>");
+-MODULE_DESCRIPTION("Loongson Random Number Generator driver");
+-- 
+2.55.0
+
diff --git a/queue-6.18/crypto-loongson-select-crypto_rng.patch b/queue-6.18/crypto-loongson-select-crypto_rng.patch
new file mode 100644 (file)
index 0000000..38367f7
--- /dev/null
@@ -0,0 +1,32 @@
+From 4c600ab0d8cfc9d75b92f3426dbcb2ad85eac91d Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@kernel.org>
+Date: Thu, 21 May 2026 21:25:25 -0500
+Subject: crypto: loongson - Select CRYPTO_RNG
+
+From: Eric Biggers <ebiggers@kernel.org>
+
+commit 4c600ab0d8cfc9d75b92f3426dbcb2ad85eac91d upstream.
+
+This driver registers a rng_alg, so it requires CRYPTO_RNG.
+
+Fixes: 766b2d724c8d ("crypto: loongson - add Loongson RNG driver support")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202605201622.qWOiiZTV-lkp@intel.com/
+Cc: stable@vger.kernel.org
+Signed-off-by: Eric Biggers <ebiggers@kernel.org>
+Reviewed-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/loongson/Kconfig |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/crypto/loongson/Kconfig
++++ b/drivers/crypto/loongson/Kconfig
+@@ -1,5 +1,6 @@
+ config CRYPTO_DEV_LOONGSON_RNG
+       tristate "Support for Loongson RNG Driver"
+       depends on MFD_LOONGSON_SE
++      select CRYPTO_RNG
+       help
+         Support for Loongson RNG Driver.
diff --git a/queue-6.18/crypto-pcrypt-restore-callback-for-non-parallel-fallback.patch b/queue-6.18/crypto-pcrypt-restore-callback-for-non-parallel-fallback.patch
new file mode 100644 (file)
index 0000000..b390475
--- /dev/null
@@ -0,0 +1,57 @@
+From ed459fe319376e876de433d12b6c6772e612ca36 Mon Sep 17 00:00:00 2001
+From: Ruijie Li <ruijieli51@gmail.com>
+Date: Mon, 25 May 2026 19:45:21 +0800
+Subject: crypto: pcrypt - restore callback for non-parallel fallback
+
+From: Ruijie Li <ruijieli51@gmail.com>
+
+commit ed459fe319376e876de433d12b6c6772e612ca36 upstream.
+
+pcrypt installs pcrypt_aead_done() on the child AEAD request before
+trying to submit it through padata.  If padata_do_parallel() returns
+-EBUSY, pcrypt falls back to calling the child AEAD directly.
+
+That fallback must not keep the padata completion callback.  Otherwise
+an asynchronous completion runs pcrypt_aead_done() even though the
+request was never enrolled in padata.
+
+Restore the original request callback and callback data before calling
+the child AEAD directly.  This keeps the fallback path aligned with a
+direct AEAD request while leaving the parallel path unchanged.
+
+Fixes: 662f2f13e66d ("crypto: pcrypt - Call crypto layer directly when padata_do_parallel() return -EBUSY")
+Cc: stable@kernel.org
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Yifan Wu <yifanwucs@gmail.com>
+Reported-by: Juefei Pu <tomapufckgml@gmail.com>
+Reported-by: Zhengchuan Liang <zcliangcn@gmail.com>
+Reported-by: Xin Liu <bird@lzu.edu.cn>
+Assisted-by: Codex:gpt-5.4
+Signed-off-by: Ruijie Li <ruijieli51@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ crypto/pcrypt.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/crypto/pcrypt.c
++++ b/crypto/pcrypt.c
+@@ -122,6 +122,8 @@ static int pcrypt_aead_encrypt(struct ae
+               return -EINPROGRESS;
+       if (err == -EBUSY) {
+               /* try non-parallel mode */
++              aead_request_set_callback(creq, flags, req->base.complete,
++                                        req->base.data);
+               return crypto_aead_encrypt(creq);
+       }
+@@ -173,6 +175,8 @@ static int pcrypt_aead_decrypt(struct ae
+               return -EINPROGRESS;
+       if (err == -EBUSY) {
+               /* try non-parallel mode */
++              aead_request_set_callback(creq, flags, req->base.complete,
++                                        req->base.data);
+               return crypto_aead_decrypt(creq);
+       }
diff --git a/queue-6.18/crypto-tegra-fix-refcount-leak-in-tegra_se_host1x_submit.patch b/queue-6.18/crypto-tegra-fix-refcount-leak-in-tegra_se_host1x_submit.patch
new file mode 100644 (file)
index 0000000..b2f4723
--- /dev/null
@@ -0,0 +1,41 @@
+From 6ea0ce3a19f9c37a014099e2b0a46b27fa164564 Mon Sep 17 00:00:00 2001
+From: Wentao Liang <vulab@iscas.ac.cn>
+Date: Thu, 4 Jun 2026 10:27:06 +0000
+Subject: crypto: tegra - fix refcount leak in tegra_se_host1x_submit()
+
+From: Wentao Liang <vulab@iscas.ac.cn>
+
+commit 6ea0ce3a19f9c37a014099e2b0a46b27fa164564 upstream.
+
+The timeout error path in tegra_se_host1x_submit() returns without
+calling host1x_job_put(), while all other paths (success, submit
+error, pin error) properly release the job reference through the
+job_put label.  Since host1x_job_alloc() initializes the reference
+count and host1x_job_put() is required to drop it, omitting it on
+timeout causes a permanent refcount leak.
+
+Fix this by redirecting the timeout return to the existing job_put
+label, ensuring the job reference and any associated syncpt
+references are consistently released.
+
+Cc: stable@vger.kernel.org
+Fixes: 0880bb3b00c8 ("crypto: tegra - Add Tegra Security Engine driver")
+Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
+Reviewed-by: Akhil R <akhilrajeev@nvidia.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/tegra/tegra-se-main.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/crypto/tegra/tegra-se-main.c
++++ b/drivers/crypto/tegra/tegra-se-main.c
+@@ -180,7 +180,7 @@ int tegra_se_host1x_submit(struct tegra_
+                                MAX_SCHEDULE_TIMEOUT, NULL);
+       if (ret) {
+               dev_err(se->dev, "host1x job timed out\n");
+-              return ret;
++              goto job_put;
+       }
+       host1x_job_put(job);
diff --git a/queue-6.18/dm-ioctl-report-an-error-if-a-device-has-no-table.patch b/queue-6.18/dm-ioctl-report-an-error-if-a-device-has-no-table.patch
new file mode 100644 (file)
index 0000000..6eb2216
--- /dev/null
@@ -0,0 +1,35 @@
+From 457e32348d606a77f9b20e25e989734189834c07 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Mon, 11 May 2026 13:04:16 +0200
+Subject: dm-ioctl: report an error if a device has no table
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit 457e32348d606a77f9b20e25e989734189834c07 upstream.
+
+When we send a message to a device that has no table, the return code was
+not set. The code would return "2", which is not considered a valid return value.
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/md/dm-ioctl.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/md/dm-ioctl.c
++++ b/drivers/md/dm-ioctl.c
+@@ -1806,8 +1806,11 @@ static int target_message(struct file *f
+               goto out_argv;
+       table = dm_get_live_table(md, &srcu_idx);
+-      if (!table)
++      if (!table) {
++              DMERR("The device has no table.");
++              r = -EINVAL;
+               goto out_table;
++      }
+       if (dm_deleting_md(md)) {
+               r = -ENXIO;
diff --git a/queue-6.18/hwrng-jh7110-fix-refcount-leak-in-starfive_trng_read.patch b/queue-6.18/hwrng-jh7110-fix-refcount-leak-in-starfive_trng_read.patch
new file mode 100644 (file)
index 0000000..22fc3d3
--- /dev/null
@@ -0,0 +1,59 @@
+From 8d13f7a8450206e3f820cdb26e33e91d181071b4 Mon Sep 17 00:00:00 2001
+From: Wentao Liang <vulab@iscas.ac.cn>
+Date: Wed, 3 Jun 2026 11:03:27 +0000
+Subject: hwrng: jh7110 - fix refcount leak in starfive_trng_read()
+
+From: Wentao Liang <vulab@iscas.ac.cn>
+
+commit 8d13f7a8450206e3f820cdb26e33e91d181071b4 upstream.
+
+The starfive_trng_read() function acquires a runtime PM reference
+via pm_runtime_get_sync() but fails to release it on two error
+paths.  If starfive_trng_wait_idle() or starfive_trng_cmd() returns
+an error, the function exits without calling
+pm_runtime_put_sync_autosuspend(), leaving the runtime PM usage
+counter permanently elevated and preventing the device from entering
+runtime suspend.
+
+Refactor the function to use a unified error path that calls
+pm_runtime_put_sync_autosuspend() before returning.
+
+Cc: stable@vger.kernel.org
+Fixes: c388f458bc34 ("hwrng: starfive - Add TRNG driver for StarFive SoC")
+Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/char/hw_random/jh7110-trng.c |   13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+--- a/drivers/char/hw_random/jh7110-trng.c
++++ b/drivers/char/hw_random/jh7110-trng.c
+@@ -256,19 +256,22 @@ static int starfive_trng_read(struct hwr
+       if (wait) {
+               ret = starfive_trng_wait_idle(trng);
+-              if (ret)
+-                      return -ETIMEDOUT;
++              if (ret) {
++                      ret = -ETIMEDOUT;
++                      goto out_put;
++              }
+       }
+       ret = starfive_trng_cmd(trng, STARFIVE_CTRL_GENE_RANDNUM, wait);
+       if (ret)
+-              return ret;
++              goto out_put;
+       memcpy_fromio(buf, trng->base + STARFIVE_RAND0, max);
++      ret = max;
++out_put:
+       pm_runtime_put_sync_autosuspend(trng->dev);
+-
+-      return max;
++      return ret;
+ }
+ static int starfive_trng_probe(struct platform_device *pdev)
diff --git a/queue-6.18/isofs-bound-rock-ridge-symlink-components-to-the-sl-record.patch b/queue-6.18/isofs-bound-rock-ridge-symlink-components-to-the-sl-record.patch
new file mode 100644 (file)
index 0000000..0c573fe
--- /dev/null
@@ -0,0 +1,74 @@
+From 5fa1d6a5ec2356d2107dead614437c66fa7138b1 Mon Sep 17 00:00:00 2001
+From: Bryam Vargas <hexlabsecurity@proton.me>
+Date: Sun, 7 Jun 2026 01:18:27 +0000
+Subject: isofs: bound Rock Ridge symlink components to the SL record
+
+From: Bryam Vargas <hexlabsecurity@proton.me>
+
+commit 5fa1d6a5ec2356d2107dead614437c66fa7138b1 upstream.
+
+get_symlink_chunk() and the SL handling in
+parse_rock_ridge_inode_internal() walk the variable-length components of
+a Rock Ridge "SL" (symbolic link) record.  Each component is a two-byte
+header (flags, len) followed by len bytes of text, so it occupies
+slp->len + 2 bytes.  Both loops read slp->len and advance to the next
+component, and get_symlink_chunk() additionally does
+memcpy(rpnt, slp->text, slp->len), but neither checks that the component
+lies within the SL record before dereferencing it.
+
+A crafted SL record whose component declares a len that runs past the
+record (rr->len) therefore triggers an out-of-bounds read of up to 255
+bytes.  When the record sits at the tail of its backing buffer - for
+example a small kmalloc()ed continuation block reached through a CE
+record - the read crosses the allocation; get_symlink_chunk() then
+copies the out-of-bounds bytes into the symlink body returned to user
+space by readlink(), disclosing adjacent kernel memory.
+
+ISO 9660 images are routinely mounted from untrusted removable media -
+desktop environments auto-mount them (e.g. via udisks2) without
+CAP_SYS_ADMIN - so the record contents are attacker-controlled.
+
+Reject any component that does not fit in the remaining record bytes
+before using it.  In get_symlink_chunk() return NULL, like the existing
+output-buffer (plimit) checks, so a malformed record makes readlink()
+fail with -EIO rather than silently returning a truncated target; in
+parse_rock_ridge_inode_internal() stop the inode-size walk.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable@vger.kernel.org
+Suggested-by: Michael Bommarito <michael.bommarito@gmail.com>
+Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
+Link: https://patch.msgid.link/20260607011823.217748-1-hexlabsecurity@proton.me
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/isofs/rock.c |   11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/fs/isofs/rock.c
++++ b/fs/isofs/rock.c
+@@ -466,6 +466,9 @@ repeat:
+                               inode->i_size = symlink_len;
+                               while (slen > 1) {
+                                       rootflag = 0;
++                                      /* keep the component within the SL record */
++                                      if (slp->len + 2 > slen)
++                                              goto eio;
+                                       switch (slp->flags & ~1) {
+                                       case 0:
+                                               inode->i_size +=
+@@ -621,6 +624,14 @@ static char *get_symlink_chunk(char *rpn
+       slp = &rr->u.SL.link;
+       while (slen > 1) {
+               rootflag = 0;
++              /*
++               * A component is slp->len + 2 bytes (a two-byte header plus
++               * len bytes of text).  If it does not fit in the bytes left in
++               * the SL record the record is malformed: fail like the plimit
++               * checks below so readlink() returns -EIO, not a truncated path.
++               */
++              if (slp->len + 2 > slen)
++                      return NULL;
+               switch (slp->flags & ~1) {
+               case 0:
+                       if (slp->len > plimit - rpnt)
diff --git a/queue-6.18/nvme-multipath-set-bio_remapped-on-bios-remapped-to-per-path-namespace-disks.patch b/queue-6.18/nvme-multipath-set-bio_remapped-on-bios-remapped-to-per-path-namespace-disks.patch
new file mode 100644 (file)
index 0000000..325c7e4
--- /dev/null
@@ -0,0 +1,88 @@
+From 88bac2c1a72b8f4f71e9845699aa872df04e5850 Mon Sep 17 00:00:00 2001
+From: "Achkinazi, Igor" <Igor.Achkinazi@dell.com>
+Date: Thu, 28 May 2026 15:24:27 +0000
+Subject: nvme-multipath: set BIO_REMAPPED on bios remapped to per-path namespace disks
+
+From: Achkinazi, Igor <Igor.Achkinazi@dell.com>
+
+commit 88bac2c1a72b8f4f71e9845699aa872df04e5850 upstream.
+
+When nvme_ns_head_submit_bio() remaps a bio from the multipath head to a
+per-path namespace, bio_set_dev() clears BIO_REMAPPED.  The remapped bio
+is then resubmitted through submit_bio_noacct() which calls
+bio_check_eod() because BIO_REMAPPED is not set.
+
+This races with nvme_ns_remove() which zeroes the per-path capacity
+before synchronize_srcu():
+
+  CPU 0 (IO submission)
+  ---------------------
+  srcu_read_lock()
+  nvme_find_path() -> ns
+    [NVME_NS_READY is set]
+
+  CPU 1 (namespace removal)
+  -------------------------
+  clear_bit(NVME_NS_READY)
+  set_capacity(ns->disk, 0)
+  synchronize_srcu()  <- blocks
+
+  CPU 0 (IO submission)
+  ---------------------
+  bio_set_dev(bio, ns->disk->part0)
+    [clears BIO_REMAPPED]
+  submit_bio_noacct(bio)
+    -> bio_check_eod() sees capacity=0
+    -> bio fails with IO error
+
+The SRCU read lock prevents synchronize_srcu() from completing, but does
+not prevent set_capacity(0) from executing.  The bio fails the EOD check
+before it reaches the NVMe driver, so nvme_failover_req() never gets a
+chance to redirect it to another path of multipath.  IO errors are
+reported to the application despite another path being available.
+
+On older kernels (before commit 0b64682e78f7 "block: skip unnecessary
+checks for split bio"), the same race was also reachable through split
+remainders resubmitted via submit_bio_noacct().
+
+Fix this by setting BIO_REMAPPED after bio_set_dev() in
+nvme_ns_head_submit_bio().  This skips bio_check_eod() on the per-path
+device; the EOD check already passed on the multipath head.
+
+NVMe per-path namespace devices are always whole disks (bd_partno=0), so
+the blk_partition_remap() skip also gated by BIO_REMAPPED is a no-op.
+The flag does not persist across failover and cannot go stale if the
+namespace geometry changes between attempts: nvme_failover_req() calls
+bio_set_dev() to redirect the bio back to the multipath head, which
+clears BIO_REMAPPED.  When nvme_requeue_work() resubmits through
+submit_bio_noacct(), bio_check_eod() runs normally against the current
+capacity.
+
+Same approach as commit 3a905c37c351 ("block: skip bio_check_eod for
+partition-remapped bios").
+
+Fixes: a7c7f7b2b641 ("nvme: use bio_set_dev to assign ->bi_bdev")
+Cc: stable@vger.kernel.org
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Igor Achkinazi <igor.achkinazi@dell.com>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvme/host/multipath.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/nvme/host/multipath.c
++++ b/drivers/nvme/host/multipath.c
+@@ -528,6 +528,12 @@ static void nvme_ns_head_submit_bio(stru
+       ns = nvme_find_path(head);
+       if (likely(ns)) {
+               bio_set_dev(bio, ns->disk->part0);
++              /*
++               * Use BIO_REMAPPED to skip bio_check_eod() when this bio
++               * enters submit_bio_noacct() for the per-path device. The EOD
++               * check already passed on the multipath head.
++               */
++              bio_set_flag(bio, BIO_REMAPPED);
+               bio->bi_opf |= REQ_NVME_MPATH;
+               trace_block_bio_remap(bio, disk_devt(ns->head->disk),
+                                     bio->bi_iter.bi_sector);
diff --git a/queue-6.18/nvme-target-rdma-fix-ndev-refcount-leak-on-queue-connect.patch b/queue-6.18/nvme-target-rdma-fix-ndev-refcount-leak-on-queue-connect.patch
new file mode 100644 (file)
index 0000000..0393ae2
--- /dev/null
@@ -0,0 +1,43 @@
+From badc53620fe813b3a9f727ef9526f98567c2c898 Mon Sep 17 00:00:00 2001
+From: Wentao Liang <vulab@iscas.ac.cn>
+Date: Wed, 27 May 2026 08:45:44 +0000
+Subject: nvme: target: rdma: fix ndev refcount leak on queue connect
+
+From: Wentao Liang <vulab@iscas.ac.cn>
+
+commit badc53620fe813b3a9f727ef9526f98567c2c898 upstream.
+
+nvmet_rdma_queue_connect() calls nvmet_rdma_find_get_device() which
+acquires a reference on the returned ndev via kref_get(). On the path
+where the host queue backlog is exceeded and the function returns
+NVME_SC_CONNECT_CTRL_BUSY, reference of ndev is not released, leaking
+the kref.
+
+Fix this by adding a goto to the existing put_device label before the
+early return.
+
+Fixes: 31deaeb11ba7 ("nvmet-rdma: avoid circular locking dependency on install_queue()")
+Cc: stable@vger.kernel.org
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvme/target/rdma.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/nvme/target/rdma.c
++++ b/drivers/nvme/target/rdma.c
+@@ -1599,8 +1599,10 @@ static int nvmet_rdma_queue_connect(stru
+                               pending++;
+               }
+               mutex_unlock(&nvmet_rdma_queue_mutex);
+-              if (pending > NVMET_RDMA_BACKLOG)
+-                      return NVME_SC_CONNECT_CTRL_BUSY;
++              if (pending > NVMET_RDMA_BACKLOG) {
++                      ret = NVME_SC_CONNECT_CTRL_BUSY;
++                      goto put_device;
++              }
+       }
+       ret = nvmet_rdma_cm_accept(cm_id, queue, &event->param.conn);
diff --git a/queue-6.18/nvmet-auth-validate-reply-message-payload-bounds-against-transfer-length.patch b/queue-6.18/nvmet-auth-validate-reply-message-payload-bounds-against-transfer-length.patch
new file mode 100644 (file)
index 0000000..fe2f769
--- /dev/null
@@ -0,0 +1,73 @@
+From 3a413ece2504c70aa34a20be4dafec04e8c741f9 Mon Sep 17 00:00:00 2001
+From: Tianchu Chen <flynnnchen@tencent.com>
+Date: Fri, 29 May 2026 14:18:39 +0000
+Subject: nvmet-auth: validate reply message payload bounds against transfer length
+
+From: Tianchu Chen <flynnnchen@tencent.com>
+
+commit 3a413ece2504c70aa34a20be4dafec04e8c741f9 upstream.
+
+nvmet_auth_reply() accesses the variable-length rval[] array using
+attacker-controlled hl (hash length) and dhvlen (DH value length) fields
+without verifying they fit within the allocated buffer of tl bytes.
+
+A malicious NVMe-oF initiator can craft a DHCHAP_REPLY message with a
+small transfer length but large hl/dhvlen values, causing out-of-bounds
+heap reads when the target processes the DH public key (rval + 2*hl) or
+performs the host response memcmp.
+
+With DH authentication configured, the OOB pointer is passed directly to
+sg_init_one() and read by crypto_kpp_compute_shared_secret(), reaching
+up to 526 bytes past the buffer. This is exploitable pre-authentication.
+
+Add bounds validation ensuring sizeof(*data) + 2*hl + dhvlen <= tl before
+any access to the variable-length fields.
+
+Discovered by Atuin - Automated Vulnerability Discovery Engine.
+
+Fixes: db1312dd9548 ("nvmet: implement basic In-Band Authentication")
+Cc: stable@vger.kernel.org
+Reviewed-by: Hannes Reinecke <hare@kernel.org>
+Signed-off-by: Tianchu Chen <flynnnchen@tencent.com>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvme/target/fabrics-cmd-auth.c |   15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+--- a/drivers/nvme/target/fabrics-cmd-auth.c
++++ b/drivers/nvme/target/fabrics-cmd-auth.c
+@@ -134,13 +134,22 @@ static u8 nvmet_auth_negotiate(struct nv
+       return 0;
+ }
+-static u8 nvmet_auth_reply(struct nvmet_req *req, void *d)
++static u8 nvmet_auth_reply(struct nvmet_req *req, void *d, u32 tl)
+ {
+       struct nvmet_ctrl *ctrl = req->sq->ctrl;
+       struct nvmf_auth_dhchap_reply_data *data = d;
+-      u16 dhvlen = le16_to_cpu(data->dhvlen);
++      u16 dhvlen;
+       u8 *response;
++      if (tl < sizeof(*data))
++              return NVME_AUTH_DHCHAP_FAILURE_INCORRECT_PAYLOAD;
++
++      dhvlen = le16_to_cpu(data->dhvlen);
++
++      /* Validate that hl and dhvlen fit within the transfer length */
++      if (sizeof(*data) + 2 * (size_t)data->hl + dhvlen > tl)
++              return NVME_AUTH_DHCHAP_FAILURE_INCORRECT_PAYLOAD;
++
+       pr_debug("%s: ctrl %d qid %d: data hl %d cvalid %d dhvlen %u\n",
+                __func__, ctrl->cntlid, req->sq->qid,
+                data->hl, data->cvalid, dhvlen);
+@@ -339,7 +348,7 @@ void nvmet_execute_auth_send(struct nvme
+       switch (data->auth_id) {
+       case NVME_AUTH_DHCHAP_MESSAGE_REPLY:
+-              dhchap_status = nvmet_auth_reply(req, d);
++              dhchap_status = nvmet_auth_reply(req, d, tl);
+               if (dhchap_status == 0)
+                       req->sq->dhchap_step =
+                               NVME_AUTH_DHCHAP_MESSAGE_SUCCESS1;
diff --git a/queue-6.18/nvmet-fix-pre-auth-out-of-bounds-heap-read-in-discovery-get-log-page.patch b/queue-6.18/nvmet-fix-pre-auth-out-of-bounds-heap-read-in-discovery-get-log-page.patch
new file mode 100644 (file)
index 0000000..9b45215
--- /dev/null
@@ -0,0 +1,101 @@
+From 53cd102a7a56079b11b897835bd9b94c14e6322c Mon Sep 17 00:00:00 2001
+From: Bryam Vargas <hexlabsecurity@proton.me>
+Date: Wed, 27 May 2026 15:00:00 -0500
+Subject: nvmet: fix pre-auth out-of-bounds heap read in Discovery Get Log Page
+
+From: Bryam Vargas <hexlabsecurity@proton.me>
+
+commit 53cd102a7a56079b11b897835bd9b94c14e6322c upstream.
+
+nvmet_execute_disc_get_log_page() validates only the dword alignment
+of the host-supplied Log Page Offset (lpo).  The 64-bit offset is then
+added to a small kzalloc'd buffer that holds the discovery log page
+and the result is passed straight to nvmet_copy_to_sgl(), which
+memcpy()s data_len bytes out to the host with no source-side bound
+check:
+
+    u64 offset      = nvmet_get_log_page_offset(req->cmd);  /* 64-bit host */
+    size_t data_len = nvmet_get_log_page_len(req->cmd);     /* 32-bit host */
+    ...
+    if (offset & 0x3) { ... }                               /* only check */
+    ...
+    alloc_len = sizeof(*hdr) + entry_size * discovery_log_entries(req);
+    buffer = kzalloc(alloc_len, GFP_KERNEL);
+    ...
+    status = nvmet_copy_to_sgl(req, 0, buffer + offset, data_len);
+
+The Discovery controller is unauthenticated -- nvmet_host_allowed()
+returns true unconditionally for the discovery subsystem -- so the call
+is reachable pre-authentication by any TCP/RDMA/FC peer that can reach
+the nvmet target.  With a discovery log page of ~1 KiB, an attacker
+requesting up to 4 KiB starting at offset == alloc_len reads the next
+slab page out and gets its content returned over the fabric (an
+empirical run on a default nvmet-tcp loopback target leaked 81
+canonical kernel pointers in one Get Log Page response).  Pointing the
+offset at unmapped kernel memory faults the in-kernel memcpy and
+crashes (or panics, on panic_on_oops=1) the target host instead.
+
+The attacker-controlled source-side offset pattern
+"nvmet_copy_to_sgl(req, 0, buffer + ATTACKER_OFFSET, ...)" is unique
+to nvmet_execute_disc_get_log_page in the entire nvmet codebase: every
+other Get Log Page handler in admin-cmd.c either ignores lpo (and
+silently starts every response at offset 0) or tracks a local
+destination offset with a fixed source pointer.
+
+Validate the host-supplied offset against the log page size, cap the
+copy length to what is actually available, and zero-fill any remainder
+of the host transfer buffer.  The zero-fill matches the existing
+short-response pattern in nvmet_execute_get_log_changed_ns()
+(admin-cmd.c) and prevents leaking transport SGL contents when the
+host asks for more bytes than the log page contains.
+
+Fixes: a07b4970f464 ("nvmet: add a generic NVMe target")
+Cc: stable@vger.kernel.org
+Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvme/target/discovery.c |   23 ++++++++++++++++++++++-
+ 1 file changed, 22 insertions(+), 1 deletion(-)
+
+--- a/drivers/nvme/target/discovery.c
++++ b/drivers/nvme/target/discovery.c
+@@ -166,6 +166,7 @@ static void nvmet_execute_disc_get_log_p
+       u64 offset = nvmet_get_log_page_offset(req->cmd);
+       size_t data_len = nvmet_get_log_page_len(req->cmd);
+       size_t alloc_len;
++      size_t copy_len;
+       struct nvmet_subsys_link *p;
+       struct nvmet_port *r;
+       u32 numrec = 0;
+@@ -242,7 +243,27 @@ static void nvmet_execute_disc_get_log_p
+       up_read(&nvmet_config_sem);
+-      status = nvmet_copy_to_sgl(req, 0, buffer + offset, data_len);
++      /*
++       * Validate the host-supplied log page offset before copying out.
++       * Without this check, the host controls a 64-bit byte offset into
++       * a small kzalloc'd buffer: a value past the log page lets the
++       * subsequent memcpy read adjacent kernel heap, and a value aimed
++       * at unmapped kernel memory faults the in-kernel copy and crashes
++       * the target host. The Discovery controller is unauthenticated,
++       * so the bug is reachable from any reachable fabric peer.
++       */
++      if (offset > alloc_len) {
++              req->error_loc =
++                      offsetof(struct nvme_get_log_page_command, lpo);
++              status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR;
++              goto out_free_buffer;
++      }
++
++      copy_len = min_t(size_t, data_len, alloc_len - offset);
++      status = nvmet_copy_to_sgl(req, 0, buffer + offset, copy_len);
++      if (!status && copy_len < data_len)
++              status = nvmet_zero_sgl(req, copy_len, data_len - copy_len);
++out_free_buffer:
+       kfree(buffer);
+ out:
+       nvmet_req_complete(req, status);
diff --git a/queue-6.18/partitions-aix-bound-the-pp_count-scan-to-the-ppe-array.patch b/queue-6.18/partitions-aix-bound-the-pp_count-scan-to-the-ppe-array.patch
new file mode 100644 (file)
index 0000000..acf5b89
--- /dev/null
@@ -0,0 +1,62 @@
+From 2dc0bfd2fe355fb930de63c2f2eb8ced8570c579 Mon Sep 17 00:00:00 2001
+From: Bryam Vargas <hexlabsecurity@proton.me>
+Date: Sun, 7 Jun 2026 06:41:43 +0000
+Subject: partitions: aix: bound the pp_count scan to the ppe array
+
+From: Bryam Vargas <hexlabsecurity@proton.me>
+
+commit 2dc0bfd2fe355fb930de63c2f2eb8ced8570c579 upstream.
+
+aix_partition() reads the physical volume descriptor into a fixed-size
+struct pvd and then scans its physical-partition-extent array:
+
+       int numpps = be16_to_cpu(pvd->pp_count);
+       ...
+       for (i = 0; i < numpps; i += 1) {
+               struct ppe *p = pvd->ppe + i;
+               ...
+               lp_ix = be16_to_cpu(p->lp_ix);
+
+pvd points at a single kmalloc()'d struct pvd whose ppe[] member holds a
+fixed ARRAY_SIZE(pvd->ppe) (1016) entries, but the loop runs up to the
+on-disk pp_count.  pp_count is an unvalidated __be16 read straight from
+the descriptor, so a crafted AIX image with pp_count larger than 1016
+drives the loop to read pvd->ppe[i] past the end of the allocation (up
+to 65535 entries, ~2 MB out of bounds).
+
+The partition scan runs without mounting anything, when a block device
+with a crafted AIX/IBM partition table appears (an attacker-supplied
+image attached with losetup -P, or a device auto-scanned by udev), via
+msdos_partition() -> aix_partition().
+
+Clamp the scan to the number of entries the ppe[] array can hold.
+
+Fixes: 6ceea22bbbc8 ("partitions: add aix lvm partition support files")
+Cc: stable@vger.kernel.org
+Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
+Acked-by: Philippe De Muyter <phdm@macqel.be>
+Link: https://patch.msgid.link/20260607064137.302574-1-hexlabsecurity@proton.me
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ block/partitions/aix.c |    9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/block/partitions/aix.c
++++ b/block/partitions/aix.c
+@@ -228,6 +228,15 @@ int aix_partition(struct parsed_partitio
+               int next_lp_ix = 1;
+               int lp_ix;
++              /*
++               * pvd was read into a fixed-size struct pvd whose ppe[] array
++               * holds ARRAY_SIZE(pvd->ppe) entries.  pp_count is an
++               * unvalidated on-disk __be16, so clamp the scan to the array
++               * size to avoid walking past the allocation.
++               */
++              if (numpps > ARRAY_SIZE(pvd->ppe))
++                      numpps = ARRAY_SIZE(pvd->ppe);
++
+               for (i = 0; i < numpps; i += 1) {
+                       struct ppe *p = pvd->ppe + i;
+                       unsigned int lv_ix;
index 2ee5802168592bffcff5d5dd7dbe22518cb8a393..bae483a40f907fe08c740a41f1a87357410b8fb3 100644 (file)
@@ -328,3 +328,36 @@ bpf-restrict-jit-predictor-flush-to-cbpf.patch
 bpf-skip-redundant-ibpb-in-pack-allocator.patch
 bpf-prefer-packs-that-won-t-trigger-an-ibpb-flush-on.patch
 bpf-prefer-dirty-packs-for-ebpf-allocations.patch
+udf-validate-free-block-extents-against-the-partition-length.patch
+udf-validate-vat-header-length-against-the-vat-inode-size.patch
+udf-validate-sparing-table-length-as-an-entry-count-not-a-byte-count.patch
+hwrng-jh7110-fix-refcount-leak-in-starfive_trng_read.patch
+crypto-atmel-sha204a-drop-hwrng-quality-reduction-for-atsha204a.patch
+nvme-target-rdma-fix-ndev-refcount-leak-on-queue-connect.patch
+block-partitions-fix-of_node-refcount-leak-in-of_partition.patch
+dm-ioctl-report-an-error-if-a-device-has-no-table.patch
+nvme-multipath-set-bio_remapped-on-bios-remapped-to-per-path-namespace-disks.patch
+nvmet-fix-pre-auth-out-of-bounds-heap-read-in-discovery-get-log-page.patch
+nvmet-auth-validate-reply-message-payload-bounds-against-transfer-length.patch
+btrfs-check-and-set-extent_delalloc_new-before-clearing-extent_delalloc.patch
+btrfs-do-not-trim-a-device-which-is-not-writeable.patch
+partitions-aix-bound-the-pp_count-scan-to-the-ppe-array.patch
+isofs-bound-rock-ridge-symlink-components-to-the-sl-record.patch
+crypto-af_alg-remove-zero-copy-support-from-skcipher-and-aead.patch
+crypto-caam-use-print_hex_dump_devel-to-guard-key-hex-dumps.patch
+crypto-caam-use-print_hex_dump_devel-to-guard-key-hex-dumps-again.patch
+crypto-chacha20poly1305-validate-poly1305-template-argument.patch
+crypto-crypto4xx-remove-insecure-and-unused-rng_alg.patch
+crypto-ecc-fix-carry-overflow-in-vli-multiplication.patch
+crypto-hisi-trng-remove-crypto_rng-interface.patch
+crypto-pcrypt-restore-callback-for-non-parallel-fallback.patch
+crypto-tegra-fix-refcount-leak-in-tegra_se_host1x_submit.patch
+crypto-loongson-select-crypto_rng.patch
+crypto-ccp-do-not-initialize-snp-for-sev-ioctls.patch
+crypto-ccp-do-not-initialize-snp-for-ioctl-snp_commit.patch
+crypto-ccp-do-not-initialize-snp-for-ioctl-snp_vlek_load.patch
+crypto-ccp-do-not-initialize-snp-for-ioctl-snp_config.patch
+crypto-drbg-fix-returning-success-on-failure-in-ctr_drbg.patch
+crypto-drbg-fix-drbg_max_addtl-on-64-bit-kernels.patch
+crypto-drbg-fix-the-fips_enabled-priority-boost.patch
+crypto-loongson-remove-broken-and-unused-loongson-rng.patch
diff --git a/queue-6.18/udf-validate-free-block-extents-against-the-partition-length.patch b/queue-6.18/udf-validate-free-block-extents-against-the-partition-length.patch
new file mode 100644 (file)
index 0000000..73fffc5
--- /dev/null
@@ -0,0 +1,65 @@
+From 5f0419457f89dce1a3f1c8e62a3adf2f39ab8168 Mon Sep 17 00:00:00 2001
+From: Michael Bommarito <michael.bommarito@gmail.com>
+Date: Fri, 15 May 2026 10:23:27 -0400
+Subject: udf: validate free block extents against the partition length
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+commit 5f0419457f89dce1a3f1c8e62a3adf2f39ab8168 upstream.
+
+udf_free_blocks() checks the logical block number and count against the
+partition length, but drops the extent offset from that final bound.  A
+crafted extent can pass the guard while logicalBlockNum + offset + count
+points past the partition, which later indexes past the space bitmap
+array.
+
+A single ftruncate(2) on a file backed by such an extent reliably
+panics the kernel.  This is a local availability issue.  On desktop
+systems where UDisks/polkit allows the active user to mount removable
+UDF media without CAP_SYS_ADMIN, an unprivileged local user can supply
+the crafted filesystem and trigger the panic by truncating a writable
+file on it.  Systems that require root or CAP_SYS_ADMIN to mount the
+image have a higher prerequisite.
+
+No confidentiality or integrity impact is claimed: the reproduced
+primitive is an out-of-bounds read of a bitmap pointer slot followed by
+a kernel panic.
+
+Use the already computed logicalBlockNum + offset + count value for the
+partition length check.  Also make load_block_bitmap() reject an
+out-of-range block group before indexing s_block_bitmap[], so corrupted
+callers cannot walk past the flexible array.
+
+Fixes: 56e69e59751d ("udf: prevent integer overflow in udf_bitmap_free_blocks()")
+Cc: stable@vger.kernel.org
+Assisted-by: Claude:claude-opus-4-7
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Link: https://patch.msgid.link/20260515142327.1120767-1-michael.bommarito@gmail.com
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/udf/balloc.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/fs/udf/balloc.c
++++ b/fs/udf/balloc.c
+@@ -82,8 +82,9 @@ static int load_block_bitmap(struct supe
+       int nr_groups = bitmap->s_nr_groups;
+       if (block_group >= nr_groups) {
+-              udf_debug("block_group (%u) > nr_groups (%d)\n",
++              udf_debug("block_group (%u) >= nr_groups (%d)\n",
+                         block_group, nr_groups);
++              return -EFSCORRUPTED;
+       }
+       if (bitmap->s_block_bitmap[block_group]) {
+@@ -662,7 +663,7 @@ void udf_free_blocks(struct super_block
+       if (check_add_overflow(bloc->logicalBlockNum, offset, &blk) ||
+           check_add_overflow(blk, count, &blk) ||
+-          bloc->logicalBlockNum + count > map->s_partition_len) {
++          blk > map->s_partition_len) {
+               udf_debug("Invalid request to free blocks: (%d, %u), off %u, "
+                         "len %u, partition len %u\n",
+                         partition, bloc->logicalBlockNum, offset, count,
diff --git a/queue-6.18/udf-validate-sparing-table-length-as-an-entry-count-not-a-byte-count.patch b/queue-6.18/udf-validate-sparing-table-length-as-an-entry-count-not-a-byte-count.patch
new file mode 100644 (file)
index 0000000..b8ede71
--- /dev/null
@@ -0,0 +1,57 @@
+From 3ec997bd5508e9b25210b5bbec89031629cdb093 Mon Sep 17 00:00:00 2001
+From: Bryam Vargas <hexlabsecurity@proton.me>
+Date: Fri, 12 Jun 2026 01:40:01 -0500
+Subject: udf: validate sparing table length as an entry count, not a byte count
+
+From: Bryam Vargas <hexlabsecurity@proton.me>
+
+commit 3ec997bd5508e9b25210b5bbec89031629cdb093 upstream.
+
+udf_load_sparable_map() accepts a sparing table when
+
+       sizeof(*st) + le16_to_cpu(st->reallocationTableLen) > sb->s_blocksize
+
+is false, i.e. it treats reallocationTableLen as a number of BYTES that
+must fit in the block.  But the table is walked as an array of 8-byte
+sparingEntry elements:
+
+       for (i = 0; i < le16_to_cpu(st->reallocationTableLen); i++) {
+               struct sparingEntry *entry = &st->mapEntry[i];
+               ... entry->origLocation ...
+       }
+
+in udf_get_pblock_spar15() and udf_relocate_blocks().  A
+reallocationTableLen of N therefore passes the check whenever
+sizeof(*st) + N <= blocksize, yet the consumers index
+sizeof(*st) + N * sizeof(struct sparingEntry) bytes -- up to ~8x the
+block.  On a crafted UDF image this is an out-of-bounds read in
+udf_get_pblock_spar15(); udf_relocate_blocks() additionally feeds the
+same length to udf_update_tag(), whose crc_itu_t() reads far past the
+block, and its memmove() through st->mapEntry[] is an out-of-bounds
+write.
+
+Validate reallocationTableLen as the entry count it is, with
+struct_size().
+
+Fixes: 1df2ae31c724 ("udf: Fortify loading of sparing table")
+Cc: stable@vger.kernel.org
+Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
+Link: https://patch.msgid.link/20260612-b4-disp-91780c4e-v1-1-f15112ff6882@proton.me
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/udf/super.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/udf/super.c
++++ b/fs/udf/super.c
+@@ -1426,7 +1426,8 @@ static int udf_load_sparable_map(struct
+               if (ident != 0 ||
+                   strncmp(st->sparingIdent.ident, UDF_ID_SPARING,
+                           strlen(UDF_ID_SPARING)) ||
+-                  sizeof(*st) + le16_to_cpu(st->reallocationTableLen) >
++                  struct_size(st, mapEntry,
++                              le16_to_cpu(st->reallocationTableLen)) >
+                                                       sb->s_blocksize) {
+                       brelse(bh);
+                       continue;
diff --git a/queue-6.18/udf-validate-vat-header-length-against-the-vat-inode-size.patch b/queue-6.18/udf-validate-vat-header-length-against-the-vat-inode-size.patch
new file mode 100644 (file)
index 0000000..abf81fc
--- /dev/null
@@ -0,0 +1,60 @@
+From d8202786b3d75125c84ebc4de6d946f92fde0ee8 Mon Sep 17 00:00:00 2001
+From: Bryam Vargas <hexlabsecurity@proton.me>
+Date: Fri, 12 Jun 2026 02:53:31 -0500
+Subject: udf: validate VAT header length against the VAT inode size
+
+From: Bryam Vargas <hexlabsecurity@proton.me>
+
+commit d8202786b3d75125c84ebc4de6d946f92fde0ee8 upstream.
+
+udf_load_vat() takes the virtual partition's start offset straight from
+the on-disk VAT 2.0 header without checking it against the VAT inode
+size:
+
+       map->s_type_specific.s_virtual.s_start_offset =
+               le16_to_cpu(vat20->lengthHeader);
+       map->s_type_specific.s_virtual.s_num_entries =
+               (sbi->s_vat_inode->i_size -
+                       map->s_type_specific.s_virtual.s_start_offset) >> 2;
+
+lengthHeader is a fully attacker-controlled 16-bit value.  If it exceeds
+the VAT inode size, the s_num_entries subtraction underflows to a huge
+count, which defeats the "block > s_num_entries" bound in
+udf_get_pblock_virt15(); and on the ICB-inline path that function reads
+
+       ((__le32 *)(iinfo->i_data + s_start_offset))[block]
+
+so a large s_start_offset indexes past the inode's in-ICB data.  Mounting
+a crafted UDF image with a virtual (VAT) partition then triggers an
+out-of-bounds read.
+
+Reject a VAT whose header length does not leave room for at least one
+entry within the VAT inode.
+
+Fixes: fa5e08156335 ("udf: Handle VAT packed inside inode properly")
+Cc: stable@vger.kernel.org
+Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
+Link: https://patch.msgid.link/20260612-b4-disp-9a2317ee-v1-1-fefef5736154@proton.me
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/udf/super.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/fs/udf/super.c
++++ b/fs/udf/super.c
+@@ -1263,6 +1263,14 @@ static int udf_load_vat(struct super_blo
+               map->s_type_specific.s_virtual.s_start_offset =
+                       le16_to_cpu(vat20->lengthHeader);
++              if (map->s_type_specific.s_virtual.s_start_offset
++                  > sbi->s_vat_inode->i_size) {
++                      udf_err(sb, "Corrupted VAT header length %u (VAT inode size %lld)\n",
++                              map->s_type_specific.s_virtual.s_start_offset,
++                              sbi->s_vat_inode->i_size);
++                      brelse(bh);
++                      return -EFSCORRUPTED;
++              }
+               map->s_type_specific.s_virtual.s_num_entries =
+                       (sbi->s_vat_inode->i_size -
+                               map->s_type_specific.s_virtual.