From: Greg Kroah-Hartman Date: Wed, 15 Jul 2026 10:22:03 +0000 (+0200) Subject: 6.6-stable patches X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8f0b2b19c9ce9715c2e92e289d125f2a33d078c1;p=thirdparty%2Fkernel%2Fstable-queue.git 6.6-stable patches added patches: btrfs-do-not-trim-a-device-which-is-not-writeable.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-again.patch crypto-caam-use-print_hex_dump_devel-to-guard-key-hex-dumps.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-pcrypt-restore-callback-for-non-parallel-fallback.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 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 --- diff --git a/queue-6.6/btrfs-do-not-trim-a-device-which-is-not-writeable.patch b/queue-6.6/btrfs-do-not-trim-a-device-which-is-not-writeable.patch new file mode 100644 index 0000000000..712194c215 --- /dev/null +++ b/queue-6.6/btrfs-do-not-trim-a-device-which-is-not-writeable.patch @@ -0,0 +1,140 @@ +From 1b1937eb08f51319bf71575484cde2b8c517aedc Mon Sep 17 00:00:00 2001 +From: Qu Wenruo +Date: Tue, 2 Jun 2026 13:34:46 +0930 +Subject: btrfs: do not trim a device which is not writeable + +From: Qu Wenruo + +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 +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 +Signed-off-by: Qu Wenruo +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -6053,12 +6053,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.6/crypto-af_alg-remove-zero-copy-support-from-skcipher-and-aead.patch b/queue-6.6/crypto-af_alg-remove-zero-copy-support-from-skcipher-and-aead.patch new file mode 100644 index 0000000000..b2b6af47d9 --- /dev/null +++ b/queue-6.6/crypto-af_alg-remove-zero-copy-support-from-skcipher-and-aead.patch @@ -0,0 +1,211 @@ +From ffdd2bc378953b525aca61902534e753f1f8e734 Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Mon, 4 May 2026 15:53:28 -0700 +Subject: crypto: af_alg - Remove zero-copy support from skcipher and aead + +From: Eric Biggers + +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 +Closes: https://lore.kernel.org/r/afYcc-tZFwvZZo76@ans-MacBook-Pro.local +Reviewed-by: Demi Marie Obenour +Cc: stable@vger.kernel.org +Signed-off-by: Eric Biggers +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -976,7 +976,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; +@@ -1020,60 +1020,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.6/crypto-caam-use-print_hex_dump_devel-to-guard-key-hex-dumps-again.patch b/queue-6.6/crypto-caam-use-print_hex_dump_devel-to-guard-key-hex-dumps-again.patch new file mode 100644 index 0000000000..91dea350e6 --- /dev/null +++ b/queue-6.6/crypto-caam-use-print_hex_dump_devel-to-guard-key-hex-dumps-again.patch @@ -0,0 +1,79 @@ +From 8005dc808bcce7d6cc2ae015a3cde1683bee602d Mon Sep 17 00:00:00 2001 +From: Thorsten Blum +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 + +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 +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -299,7 +299,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; +@@ -313,7 +313,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); + +@@ -730,7 +730,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); +@@ -826,7 +826,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); +@@ -925,7 +925,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); +@@ -953,7 +953,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.6/crypto-caam-use-print_hex_dump_devel-to-guard-key-hex-dumps.patch b/queue-6.6/crypto-caam-use-print_hex_dump_devel-to-guard-key-hex-dumps.patch new file mode 100644 index 0000000000..d279922882 --- /dev/null +++ b/queue-6.6/crypto-caam-use-print_hex_dump_devel-to-guard-key-hex-dumps.patch @@ -0,0 +1,177 @@ +From 3f57657b6ea23f933371f2c2846322f441773cee Mon Sep 17 00:00:00 2001 +From: Thorsten Blum +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 + +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 +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman +--- + 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.6/crypto-drbg-fix-drbg_max_addtl-on-64-bit-kernels.patch b/queue-6.6/crypto-drbg-fix-drbg_max_addtl-on-64-bit-kernels.patch new file mode 100644 index 0000000000..ad24b8b02f --- /dev/null +++ b/queue-6.6/crypto-drbg-fix-drbg_max_addtl-on-64-bit-kernels.patch @@ -0,0 +1,60 @@ +From 6f49f00c981bbb9ef602966f19bfdbef46b681d2 Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Sun, 19 Apr 2026 23:33:48 -0700 +Subject: crypto: drbg - Fix drbg_max_addtl() on 64-bit kernels + +From: Eric Biggers + +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 +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman +--- + 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.6/crypto-drbg-fix-returning-success-on-failure-in-ctr_drbg.patch b/queue-6.6/crypto-drbg-fix-returning-success-on-failure-in-ctr_drbg.patch new file mode 100644 index 0000000000..05ee083445 --- /dev/null +++ b/queue-6.6/crypto-drbg-fix-returning-success-on-failure-in-ctr_drbg.patch @@ -0,0 +1,32 @@ +From 39a31ad9e2a5ed7e9c9c6f711dca96c8c8f5f26b Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Sun, 19 Apr 2026 23:33:45 -0700 +Subject: crypto: drbg - Fix returning success on failure in CTR_DRBG + +From: Eric Biggers + +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 +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman +--- + crypto/drbg.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/crypto/drbg.c ++++ b/crypto/drbg.c +@@ -603,7 +603,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.6/crypto-drbg-fix-the-fips_enabled-priority-boost.patch b/queue-6.6/crypto-drbg-fix-the-fips_enabled-priority-boost.patch new file mode 100644 index 0000000000..9b7203d8ec --- /dev/null +++ b/queue-6.6/crypto-drbg-fix-the-fips_enabled-priority-boost.patch @@ -0,0 +1,39 @@ +From a8a1f93080efc83a9ff8452954429ae379e9e614 Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Sun, 19 Apr 2026 23:33:49 -0700 +Subject: crypto: drbg - Fix the fips_enabled priority boost + +From: Eric Biggers + +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 +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman +--- + crypto/drbg.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/crypto/drbg.c ++++ b/crypto/drbg.c +@@ -2095,7 +2095,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.6/crypto-ecc-fix-carry-overflow-in-vli-multiplication.patch b/queue-6.6/crypto-ecc-fix-carry-overflow-in-vli-multiplication.patch new file mode 100644 index 0000000000..9399736d3f --- /dev/null +++ b/queue-6.6/crypto-ecc-fix-carry-overflow-in-vli-multiplication.patch @@ -0,0 +1,98 @@ +From 27b536a2ec8e2f85a0380c2d13c9ecbc7aaab406 Mon Sep 17 00:00:00 2001 +From: Anastasia Tishchenko +Date: Wed, 13 May 2026 13:57:40 +0300 +Subject: crypto: ecc - Fix carry overflow in vli multiplication + +From: Anastasia Tishchenko + +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 +Cc: stable@vger.kernel.org # v4.8+ +Reviewed-by: Lukas Wunner +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman +--- + crypto/ecc.c | 31 ++++++++++++++++++++----------- + 1 file changed, 20 insertions(+), 11 deletions(-) + +--- a/crypto/ecc.c ++++ b/crypto/ecc.c +@@ -400,14 +400,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, +@@ -432,9 +444,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; +@@ -457,7 +467,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; +@@ -494,8 +504,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.6/crypto-pcrypt-restore-callback-for-non-parallel-fallback.patch b/queue-6.6/crypto-pcrypt-restore-callback-for-non-parallel-fallback.patch new file mode 100644 index 0000000000..b390475070 --- /dev/null +++ b/queue-6.6/crypto-pcrypt-restore-callback-for-non-parallel-fallback.patch @@ -0,0 +1,57 @@ +From ed459fe319376e876de433d12b6c6772e612ca36 Mon Sep 17 00:00:00 2001 +From: Ruijie Li +Date: Mon, 25 May 2026 19:45:21 +0800 +Subject: crypto: pcrypt - restore callback for non-parallel fallback + +From: Ruijie Li + +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 +Reported-by: Yifan Wu +Reported-by: Juefei Pu +Reported-by: Zhengchuan Liang +Reported-by: Xin Liu +Assisted-by: Codex:gpt-5.4 +Signed-off-by: Ruijie Li +Signed-off-by: Ren Wei +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman +--- + 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.6/dm-ioctl-report-an-error-if-a-device-has-no-table.patch b/queue-6.6/dm-ioctl-report-an-error-if-a-device-has-no-table.patch new file mode 100644 index 0000000000..6eb2216b11 --- /dev/null +++ b/queue-6.6/dm-ioctl-report-an-error-if-a-device-has-no-table.patch @@ -0,0 +1,35 @@ +From 457e32348d606a77f9b20e25e989734189834c07 Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Mon, 11 May 2026 13:04:16 +0200 +Subject: dm-ioctl: report an error if a device has no table + +From: Mikulas Patocka + +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 +Cc: stable@vger.kernel.org +Reviewed-by: Benjamin Marzinski +Signed-off-by: Greg Kroah-Hartman +--- + 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.6/hwrng-jh7110-fix-refcount-leak-in-starfive_trng_read.patch b/queue-6.6/hwrng-jh7110-fix-refcount-leak-in-starfive_trng_read.patch new file mode 100644 index 0000000000..22fc3d3e5c --- /dev/null +++ b/queue-6.6/hwrng-jh7110-fix-refcount-leak-in-starfive_trng_read.patch @@ -0,0 +1,59 @@ +From 8d13f7a8450206e3f820cdb26e33e91d181071b4 Mon Sep 17 00:00:00 2001 +From: Wentao Liang +Date: Wed, 3 Jun 2026 11:03:27 +0000 +Subject: hwrng: jh7110 - fix refcount leak in starfive_trng_read() + +From: Wentao Liang + +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 +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman +--- + 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.6/isofs-bound-rock-ridge-symlink-components-to-the-sl-record.patch b/queue-6.6/isofs-bound-rock-ridge-symlink-components-to-the-sl-record.patch new file mode 100644 index 0000000000..6aa61490b1 --- /dev/null +++ b/queue-6.6/isofs-bound-rock-ridge-symlink-components-to-the-sl-record.patch @@ -0,0 +1,74 @@ +From 5fa1d6a5ec2356d2107dead614437c66fa7138b1 Mon Sep 17 00:00:00 2001 +From: Bryam Vargas +Date: Sun, 7 Jun 2026 01:18:27 +0000 +Subject: isofs: bound Rock Ridge symlink components to the SL record + +From: Bryam Vargas + +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 +Signed-off-by: Bryam Vargas +Link: https://patch.msgid.link/20260607011823.217748-1-hexlabsecurity@proton.me +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman +--- + fs/isofs/rock.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/fs/isofs/rock.c ++++ b/fs/isofs/rock.c +@@ -462,6 +462,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 += +@@ -617,6 +620,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.6/nvme-multipath-set-bio_remapped-on-bios-remapped-to-per-path-namespace-disks.patch b/queue-6.6/nvme-multipath-set-bio_remapped-on-bios-remapped-to-per-path-namespace-disks.patch new file mode 100644 index 0000000000..bb9db94701 --- /dev/null +++ b/queue-6.6/nvme-multipath-set-bio_remapped-on-bios-remapped-to-per-path-namespace-disks.patch @@ -0,0 +1,88 @@ +From 88bac2c1a72b8f4f71e9845699aa872df04e5850 Mon Sep 17 00:00:00 2001 +From: "Achkinazi, Igor" +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 + +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 +Signed-off-by: Igor Achkinazi +Signed-off-by: Keith Busch +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvme/host/multipath.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/nvme/host/multipath.c ++++ b/drivers/nvme/host/multipath.c +@@ -467,6 +467,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.6/partitions-aix-bound-the-pp_count-scan-to-the-ppe-array.patch b/queue-6.6/partitions-aix-bound-the-pp_count-scan-to-the-ppe-array.patch new file mode 100644 index 0000000000..acf5b89ba1 --- /dev/null +++ b/queue-6.6/partitions-aix-bound-the-pp_count-scan-to-the-ppe-array.patch @@ -0,0 +1,62 @@ +From 2dc0bfd2fe355fb930de63c2f2eb8ced8570c579 Mon Sep 17 00:00:00 2001 +From: Bryam Vargas +Date: Sun, 7 Jun 2026 06:41:43 +0000 +Subject: partitions: aix: bound the pp_count scan to the ppe array + +From: Bryam Vargas + +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 +Acked-by: Philippe De Muyter +Link: https://patch.msgid.link/20260607064137.302574-1-hexlabsecurity@proton.me +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + 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; diff --git a/queue-6.6/series b/queue-6.6/series index 8738a37174..c893b2bb62 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -259,3 +259,20 @@ usb-typec-ucsi-ccg-fix-use-after-free-of-ucsi-on-remove.patch usb-typec-ucsi-cancel-pending-work-on-system-suspend.patch iio-temperature-ltc2983-fix-n_wires-default-bypassin.patch pci-always-lift-2.5gt-s-restriction-in-pcie-failed-l.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 +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 +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-ecc-fix-carry-overflow-in-vli-multiplication.patch +crypto-pcrypt-restore-callback-for-non-parallel-fallback.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 diff --git a/queue-6.6/udf-validate-free-block-extents-against-the-partition-length.patch b/queue-6.6/udf-validate-free-block-extents-against-the-partition-length.patch new file mode 100644 index 0000000000..4bcfbc2aab --- /dev/null +++ b/queue-6.6/udf-validate-free-block-extents-against-the-partition-length.patch @@ -0,0 +1,65 @@ +From 5f0419457f89dce1a3f1c8e62a3adf2f39ab8168 Mon Sep 17 00:00:00 2001 +From: Michael Bommarito +Date: Fri, 15 May 2026 10:23:27 -0400 +Subject: udf: validate free block extents against the partition length + +From: Michael Bommarito + +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 +Link: https://patch.msgid.link/20260515142327.1120767-1-michael.bommarito@gmail.com +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman +--- + 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 su + 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]) { +@@ -679,7 +680,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.6/udf-validate-sparing-table-length-as-an-entry-count-not-a-byte-count.patch b/queue-6.6/udf-validate-sparing-table-length-as-an-entry-count-not-a-byte-count.patch new file mode 100644 index 0000000000..1acb464788 --- /dev/null +++ b/queue-6.6/udf-validate-sparing-table-length-as-an-entry-count-not-a-byte-count.patch @@ -0,0 +1,57 @@ +From 3ec997bd5508e9b25210b5bbec89031629cdb093 Mon Sep 17 00:00:00 2001 +From: Bryam Vargas +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 + +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 +Link: https://patch.msgid.link/20260612-b4-disp-91780c4e-v1-1-f15112ff6882@proton.me +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman +--- + fs/udf/super.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/udf/super.c ++++ b/fs/udf/super.c +@@ -1395,7 +1395,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.6/udf-validate-vat-header-length-against-the-vat-inode-size.patch b/queue-6.6/udf-validate-vat-header-length-against-the-vat-inode-size.patch new file mode 100644 index 0000000000..a88278ff92 --- /dev/null +++ b/queue-6.6/udf-validate-vat-header-length-against-the-vat-inode-size.patch @@ -0,0 +1,60 @@ +From d8202786b3d75125c84ebc4de6d946f92fde0ee8 Mon Sep 17 00:00:00 2001 +From: Bryam Vargas +Date: Fri, 12 Jun 2026 02:53:31 -0500 +Subject: udf: validate VAT header length against the VAT inode size + +From: Bryam Vargas + +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 +Link: https://patch.msgid.link/20260612-b4-disp-9a2317ee-v1-1-fefef5736154@proton.me +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman +--- + fs/udf/super.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/fs/udf/super.c ++++ b/fs/udf/super.c +@@ -1232,6 +1232,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.