From: Greg Kroah-Hartman Date: Thu, 8 Jan 2026 15:57:50 +0000 (+0100) Subject: 5.10-stable patches X-Git-Tag: v6.1.160~31 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2ce9be1ee8321a89ccca3f8dc98de0dd12ea7958;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: alsa-wavefront-clear-substream-pointers-on-close.patch alsa-wavefront-fix-integer-overflow-in-sample-size-validation.patch arm-dts-microchip-sama5d2-fix-spi-flexcom-fifo-size-to-32.patch btrfs-don-t-rewrite-ret-from-inode_permission.patch crypto-af_alg-zero-initialize-memory-allocated-via-sock_kmalloc.patch ext4-fix-string-copying-in-parse_apply_sb_mount_options.patch f2fs-fix-to-avoid-updating-zero-sized-extent-in-extent-cache.patch f2fs-fix-to-detect-recoverable-inode-during-dryrun-of-find_fsync_dnodes.patch f2fs-fix-to-propagate-error-from-f2fs_enable_checkpoint.patch f2fs-use-global-inline_xattr_slab-instead-of-per-sb-slab-cache.patch hid-core-harden-s32ton-against-conversion-to-0-bits.patch hwmon-max16065-use-local-variable-to-avoid-toctou.patch hwmon-replace-snprintf-in-show-functions-with-sysfs_emit.patch iommu-qcom-fix-device-leak-on-of_xlate.patch ipv4-fix-uninit-value-access-in-__ip_make_skb.patch ipv6-fix-potential-uninit-value-access-in-__ip6_make_skb.patch jbd2-fix-the-inconsistency-between-checksum-and-data-in-memory-for-journal-sb.patch kvm-arm64-sys_regs-disable-wuninitialized-const-pointer-warning.patch media-renesas-rcar_drif-fix-device-node-reference-leak-in-rcar_drif_bond_enabled.patch mptcp-pm-ignore-unknown-endpoint-flags.patch net-mlx5e-avoid-field-overflowing-memcpy.patch nfsd-clear-seclabel-in-the-suppattr_exclcreat-bitmap.patch pci-brcmstb-fix-disabling-l0s-capability.patch powerpc-64s-slb-fix-slb-multihit-issue-during-slb-preload.patch powerpc-pseries-cmm-call-balloon_devinfo_init-also-without-config_balloon_compaction.patch sunrpc-svcauth_gss-avoid-null-deref-on-zero-length-gss_token-in-gss_read_proxy_verf.patch tpm-cap-the-number-of-pcr-banks.patch usb-dwc3-keep-susphy-enabled-during-exit-to-avoid-controller-faults.patch usb-gadget-udc-fix-use-after-free-in-usb_gadget_state_work.patch usb-ohci-nxp-fix-device-leak-on-probe-failure.patch usb-ohci-nxp-use-helper-function-devm_clk_get_enabled.patch xfs-fix-a-memory-leak-in-xfs_buf_item_init.patch xhci-dbgtty-fix-device-unregister.patch --- diff --git a/queue-5.10/alsa-wavefront-clear-substream-pointers-on-close.patch b/queue-5.10/alsa-wavefront-clear-substream-pointers-on-close.patch new file mode 100644 index 0000000000..6b2794c52b --- /dev/null +++ b/queue-5.10/alsa-wavefront-clear-substream-pointers-on-close.patch @@ -0,0 +1,48 @@ +From stable+bounces-202246-greg=kroah.com@vger.kernel.org Tue Dec 16 13:39:23 2025 +From: Sasha Levin +Date: Tue, 16 Dec 2025 07:14:27 -0500 +Subject: ALSA: wavefront: Clear substream pointers on close +To: stable@vger.kernel.org +Cc: Junrui Luo , Yuhao Jiang , Takashi Iwai , Sasha Levin +Message-ID: <20251216121427.2792618-1-sashal@kernel.org> + +From: Junrui Luo + +[ Upstream commit e11c5c13ce0ab2325d38fe63500be1dd88b81e38 ] + +Clear substream pointers in close functions to avoid leaving dangling +pointers, helping to improve code safety and +prevents potential issues. + +Reported-by: Yuhao Jiang +Reported-by: Junrui Luo +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Cc: stable@vger.kernel.org +Signed-off-by: Junrui Luo +Link: https://patch.msgid.link/SYBPR01MB7881DF762CAB45EE42F6D812AFC2A@SYBPR01MB7881.ausprd01.prod.outlook.com +Signed-off-by: Takashi Iwai +[ No guard() in older trees ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + sound/isa/wavefront/wavefront_midi.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/sound/isa/wavefront/wavefront_midi.c ++++ b/sound/isa/wavefront/wavefront_midi.c +@@ -291,6 +291,7 @@ static int snd_wavefront_midi_input_clos + return -EIO; + + spin_lock_irqsave (&midi->open, flags); ++ midi->substream_input[mpu] = NULL; + midi->mode[mpu] &= ~MPU401_MODE_INPUT; + spin_unlock_irqrestore (&midi->open, flags); + +@@ -314,6 +315,7 @@ static int snd_wavefront_midi_output_clo + return -EIO; + + spin_lock_irqsave (&midi->open, flags); ++ midi->substream_output[mpu] = NULL; + midi->mode[mpu] &= ~MPU401_MODE_OUTPUT; + spin_unlock_irqrestore (&midi->open, flags); + return 0; diff --git a/queue-5.10/alsa-wavefront-fix-integer-overflow-in-sample-size-validation.patch b/queue-5.10/alsa-wavefront-fix-integer-overflow-in-sample-size-validation.patch new file mode 100644 index 0000000000..4e341f9567 --- /dev/null +++ b/queue-5.10/alsa-wavefront-fix-integer-overflow-in-sample-size-validation.patch @@ -0,0 +1,44 @@ +From stable+bounces-201964-greg=kroah.com@vger.kernel.org Tue Dec 16 13:39:28 2025 +From: Sasha Levin +Date: Tue, 16 Dec 2025 06:59:20 -0500 +Subject: ALSA: wavefront: Fix integer overflow in sample size validation +To: stable@vger.kernel.org +Cc: Junrui Luo , Takashi Iwai , Sasha Levin +Message-ID: <20251216115920.2789337-1-sashal@kernel.org> + +From: Junrui Luo + +[ Upstream commit 0c4a13ba88594fd4a27292853e736c6b4349823d ] + +The wavefront_send_sample() function has an integer overflow issue +when validating sample size. The header->size field is u32 but gets +cast to int for comparison with dev->freemem + +Fix by using unsigned comparison to avoid integer overflow. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Cc: stable@vger.kernel.org +Signed-off-by: Junrui Luo +Link: https://patch.msgid.link/SYBPR01MB7881B47789D1B060CE8BF4C3AFC2A@SYBPR01MB7881.ausprd01.prod.outlook.com +Signed-off-by: Takashi Iwai +[ Adjust context ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + sound/isa/wavefront/wavefront_synth.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/sound/isa/wavefront/wavefront_synth.c ++++ b/sound/isa/wavefront/wavefront_synth.c +@@ -944,9 +944,9 @@ wavefront_send_sample (snd_wavefront_t * + if (header->size) { + dev->freemem = wavefront_freemem (dev); + +- if (dev->freemem < (int)header->size) { ++ if (dev->freemem < 0 || dev->freemem < header->size) { + snd_printk ("insufficient memory to " +- "load %d byte sample.\n", ++ "load %u byte sample.\n", + header->size); + return -ENOMEM; + } diff --git a/queue-5.10/arm-dts-microchip-sama5d2-fix-spi-flexcom-fifo-size-to-32.patch b/queue-5.10/arm-dts-microchip-sama5d2-fix-spi-flexcom-fifo-size-to-32.patch new file mode 100644 index 0000000000..f718ebaece --- /dev/null +++ b/queue-5.10/arm-dts-microchip-sama5d2-fix-spi-flexcom-fifo-size-to-32.patch @@ -0,0 +1,73 @@ +From stable+bounces-204395-greg=kroah.com@vger.kernel.org Wed Dec 31 23:32:07 2025 +From: Sasha Levin +Date: Wed, 31 Dec 2025 17:32:02 -0500 +Subject: ARM: dts: microchip: sama5d2: fix spi flexcom fifo size to 32 +To: stable@vger.kernel.org +Cc: Nicolas Ferre , Claudiu Beznea , Sasha Levin +Message-ID: <20251231223202.3548026-1-sashal@kernel.org> + +From: Nicolas Ferre + +[ Upstream commit 7d5864dc5d5ea6a35983dd05295fb17f2f2f44ce ] + +Unlike standalone spi peripherals, on sama5d2, the flexcom spi have fifo +size of 32 data. Fix flexcom/spi nodes where this property is wrong. + +Fixes: 6b9a3584c7ed ("ARM: dts: at91: sama5d2: Add missing flexcom definitions") +Cc: stable@vger.kernel.org # 5.8+ +Signed-off-by: Nicolas Ferre +Link: https://lore.kernel.org/r/20251114140225.30372-1-nicolas.ferre@microchip.com +Signed-off-by: Claudiu Beznea +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm/boot/dts/sama5d2.dtsi | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/arch/arm/boot/dts/sama5d2.dtsi ++++ b/arch/arm/boot/dts/sama5d2.dtsi +@@ -555,7 +555,7 @@ + AT91_XDMAC_DT_PER_IF(1) | + AT91_XDMAC_DT_PERID(12))>; + dma-names = "tx", "rx"; +- atmel,fifo-size = <16>; ++ atmel,fifo-size = <32>; + status = "disabled"; + }; + +@@ -625,7 +625,7 @@ + AT91_XDMAC_DT_PER_IF(1) | + AT91_XDMAC_DT_PERID(14))>; + dma-names = "tx", "rx"; +- atmel,fifo-size = <16>; ++ atmel,fifo-size = <32>; + status = "disabled"; + }; + +@@ -835,7 +835,7 @@ + AT91_XDMAC_DT_PER_IF(1) | + AT91_XDMAC_DT_PERID(16))>; + dma-names = "tx", "rx"; +- atmel,fifo-size = <16>; ++ atmel,fifo-size = <32>; + status = "disabled"; + }; + +@@ -925,7 +925,7 @@ + AT91_XDMAC_DT_PER_IF(1) | + AT91_XDMAC_DT_PERID(18))>; + dma-names = "tx", "rx"; +- atmel,fifo-size = <16>; ++ atmel,fifo-size = <32>; + status = "disabled"; + }; + +@@ -976,7 +976,7 @@ + AT91_XDMAC_DT_PER_IF(1) | + AT91_XDMAC_DT_PERID(20))>; + dma-names = "tx", "rx"; +- atmel,fifo-size = <16>; ++ atmel,fifo-size = <32>; + status = "disabled"; + }; + diff --git a/queue-5.10/btrfs-don-t-rewrite-ret-from-inode_permission.patch b/queue-5.10/btrfs-don-t-rewrite-ret-from-inode_permission.patch new file mode 100644 index 0000000000..262de8bab0 --- /dev/null +++ b/queue-5.10/btrfs-don-t-rewrite-ret-from-inode_permission.patch @@ -0,0 +1,51 @@ +From stable+bounces-204146-greg=kroah.com@vger.kernel.org Mon Dec 29 23:45:07 2025 +From: Sasha Levin +Date: Mon, 29 Dec 2025 17:44:59 -0500 +Subject: btrfs: don't rewrite ret from inode_permission +To: stable@vger.kernel.org +Cc: Josef Bacik , Johannes Thumshirn , Daniel Vacek , David Sterba , Sasha Levin +Message-ID: <20251229224459.1750388-1-sashal@kernel.org> + +From: Josef Bacik + +[ Upstream commit 0185c2292c600993199bc6b1f342ad47a9e8c678 ] + +In our user safe ino resolve ioctl we'll just turn any ret into -EACCES +from inode_permission(). This is redundant, and could potentially be +wrong if we had an ENOMEM in the security layer or some such other +error, so simply return the actual return value. + +Note: The patch was taken from v5 of fscrypt patchset +(https://lore.kernel.org/linux-btrfs/cover.1706116485.git.josef@toxicpanda.com/) +which was handled over time by various people: Omar Sandoval, Sweet Tea +Dorminy, Josef Bacik. + +Fixes: 23d0b79dfaed ("btrfs: Add unprivileged version of ino_lookup ioctl") +CC: stable@vger.kernel.org # 5.4+ +Reviewed-by: Johannes Thumshirn +Signed-off-by: Josef Bacik +Signed-off-by: Daniel Vacek +Reviewed-by: David Sterba +[ add note ] +Signed-off-by: David Sterba +[ Adjust context ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/ioctl.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/fs/btrfs/ioctl.c ++++ b/fs/btrfs/ioctl.c +@@ -2573,10 +2573,8 @@ static int btrfs_search_path_in_tree_use + } + ret = inode_permission(temp_inode, MAY_READ | MAY_EXEC); + iput(temp_inode); +- if (ret) { +- ret = -EACCES; ++ if (ret) + goto out_put; +- } + + if (key.offset == upper_limit.objectid) + break; diff --git a/queue-5.10/crypto-af_alg-zero-initialize-memory-allocated-via-sock_kmalloc.patch b/queue-5.10/crypto-af_alg-zero-initialize-memory-allocated-via-sock_kmalloc.patch new file mode 100644 index 0000000000..f755167722 --- /dev/null +++ b/queue-5.10/crypto-af_alg-zero-initialize-memory-allocated-via-sock_kmalloc.patch @@ -0,0 +1,102 @@ +From stable+bounces-204386-greg=kroah.com@vger.kernel.org Wed Dec 31 21:41:46 2025 +From: Sasha Levin +Date: Wed, 31 Dec 2025 15:41:40 -0500 +Subject: crypto: af_alg - zero initialize memory allocated via sock_kmalloc +To: stable@vger.kernel.org +Cc: Shivani Agarwal , Herbert Xu , Sasha Levin +Message-ID: <20251231204140.3475630-1-sashal@kernel.org> + +From: Shivani Agarwal + +[ Upstream commit 6f6e309328d53a10c0fe1f77dec2db73373179b6 ] + +Several crypto user API contexts and requests allocated with +sock_kmalloc() were left uninitialized, relying on callers to +set fields explicitly. This resulted in the use of uninitialized +data in certain error paths or when new fields are added in the +future. + +The ACVP patches also contain two user-space interface files: +algif_kpp.c and algif_akcipher.c. These too rely on proper +initialization of their context structures. + +A particular issue has been observed with the newly added +'inflight' variable introduced in af_alg_ctx by commit: + + 67b164a871af ("crypto: af_alg - Disallow multiple in-flight AIO requests") + +Because the context is not memset to zero after allocation, +the inflight variable has contained garbage values. As a result, +af_alg_alloc_areq() has incorrectly returned -EBUSY randomly when +the garbage value was interpreted as true: + + https://github.com/gregkh/linux/blame/master/crypto/af_alg.c#L1209 + +The check directly tests ctx->inflight without explicitly +comparing against true/false. Since inflight is only ever set to +true or false later, an uninitialized value has triggered +-EBUSY failures. Zero-initializing memory allocated with +sock_kmalloc() ensures inflight and other fields start in a known +state, removing random issues caused by uninitialized data. + +Fixes: fe869cdb89c9 ("crypto: algif_hash - User-space interface for hash operations") +Fixes: 5afdfd22e6ba ("crypto: algif_rng - add random number generator support") +Fixes: 2d97591ef43d ("crypto: af_alg - consolidation of duplicate code") +Fixes: 67b164a871af ("crypto: af_alg - Disallow multiple in-flight AIO requests") +Cc: stable@vger.kernel.org +Signed-off-by: Shivani Agarwal +Signed-off-by: Herbert Xu +[ Adjust context ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + crypto/af_alg.c | 5 ++--- + crypto/algif_hash.c | 3 +-- + crypto/algif_rng.c | 3 +-- + 3 files changed, 4 insertions(+), 7 deletions(-) + +--- a/crypto/af_alg.c ++++ b/crypto/af_alg.c +@@ -1127,14 +1127,13 @@ struct af_alg_async_req *af_alg_alloc_ar + if (unlikely(!areq)) + return ERR_PTR(-ENOMEM); + ++ memset(areq, 0, areqlen); ++ + ctx->inflight = true; + + areq->areqlen = areqlen; + areq->sk = sk; +- areq->last_rsgl = NULL; + INIT_LIST_HEAD(&areq->rsgl_list); +- areq->tsgl = NULL; +- areq->tsgl_entries = 0; + + return areq; + } +--- a/crypto/algif_hash.c ++++ b/crypto/algif_hash.c +@@ -423,9 +423,8 @@ static int hash_accept_parent_nokey(void + if (!ctx) + return -ENOMEM; + +- ctx->result = NULL; ++ memset(ctx, 0, len); + ctx->len = len; +- ctx->more = false; + crypto_init_wait(&ctx->wait); + + ask->private = ctx; +--- a/crypto/algif_rng.c ++++ b/crypto/algif_rng.c +@@ -250,9 +250,8 @@ static int rng_accept_parent(void *priva + if (!ctx) + return -ENOMEM; + ++ memset(ctx, 0, len); + ctx->len = len; +- ctx->addtl = NULL; +- ctx->addtl_len = 0; + + /* + * No seeding done at that point -- if multiple accepts are diff --git a/queue-5.10/ext4-fix-string-copying-in-parse_apply_sb_mount_options.patch b/queue-5.10/ext4-fix-string-copying-in-parse_apply_sb_mount_options.patch new file mode 100644 index 0000000000..e2f7764590 --- /dev/null +++ b/queue-5.10/ext4-fix-string-copying-in-parse_apply_sb_mount_options.patch @@ -0,0 +1,82 @@ +From stable+bounces-204166-greg=kroah.com@vger.kernel.org Tue Dec 30 02:26:22 2025 +From: Sasha Levin +Date: Mon, 29 Dec 2025 20:26:14 -0500 +Subject: ext4: fix string copying in parse_apply_sb_mount_options() +To: stable@vger.kernel.org +Cc: Fedor Pchelkin , Baokun Li , Jan Kara , Theodore Ts'o , Sasha Levin +Message-ID: <20251230012614.1920692-1-sashal@kernel.org> + +From: Fedor Pchelkin + +[ Upstream commit ee5a977b4e771cc181f39d504426dbd31ed701cc ] + +strscpy_pad() can't be used to copy a non-NUL-term string into a NUL-term +string of possibly bigger size. Commit 0efc5990bca5 ("string.h: Introduce +memtostr() and memtostr_pad()") provides additional information in that +regard. So if this happens, the following warning is observed: + +strnlen: detected buffer overflow: 65 byte read of buffer size 64 +WARNING: CPU: 0 PID: 28655 at lib/string_helpers.c:1032 __fortify_report+0x96/0xc0 lib/string_helpers.c:1032 +Modules linked in: +CPU: 0 UID: 0 PID: 28655 Comm: syz-executor.3 Not tainted 6.12.54-syzkaller-00144-g5f0270f1ba00 #0 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 +RIP: 0010:__fortify_report+0x96/0xc0 lib/string_helpers.c:1032 +Call Trace: + + __fortify_panic+0x1f/0x30 lib/string_helpers.c:1039 + strnlen include/linux/fortify-string.h:235 [inline] + sized_strscpy include/linux/fortify-string.h:309 [inline] + parse_apply_sb_mount_options fs/ext4/super.c:2504 [inline] + __ext4_fill_super fs/ext4/super.c:5261 [inline] + ext4_fill_super+0x3c35/0xad00 fs/ext4/super.c:5706 + get_tree_bdev_flags+0x387/0x620 fs/super.c:1636 + vfs_get_tree+0x93/0x380 fs/super.c:1814 + do_new_mount fs/namespace.c:3553 [inline] + path_mount+0x6ae/0x1f70 fs/namespace.c:3880 + do_mount fs/namespace.c:3893 [inline] + __do_sys_mount fs/namespace.c:4103 [inline] + __se_sys_mount fs/namespace.c:4080 [inline] + __x64_sys_mount+0x280/0x300 fs/namespace.c:4080 + do_syscall_x64 arch/x86/entry/common.c:52 [inline] + do_syscall_64+0x64/0x140 arch/x86/entry/common.c:83 + entry_SYSCALL_64_after_hwframe+0x76/0x7e + +Since userspace is expected to provide s_mount_opts field to be at most 63 +characters long with the ending byte being NUL-term, use a 64-byte buffer +which matches the size of s_mount_opts, so that strscpy_pad() does its job +properly. Return with error if the user still managed to provide a +non-NUL-term string here. + +Found by Linux Verification Center (linuxtesting.org) with Syzkaller. + +Fixes: 8ecb790ea8c3 ("ext4: avoid potential buffer over-read in parse_apply_sb_mount_options()") +Cc: stable@vger.kernel.org +Signed-off-by: Fedor Pchelkin +Reviewed-by: Baokun Li +Reviewed-by: Jan Kara +Message-ID: <20251101160430.222297-1-pchelkin@ispras.ru> +Signed-off-by: Theodore Ts'o +[ goto failed_mount instead of return ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/super.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -4282,10 +4282,11 @@ static int ext4_fill_super(struct super_ + } + + if (sbi->s_es->s_mount_opts[0]) { +- char s_mount_opts[65]; ++ char s_mount_opts[64]; + +- strscpy_pad(s_mount_opts, sbi->s_es->s_mount_opts, +- sizeof(s_mount_opts)); ++ if (strscpy_pad(s_mount_opts, sbi->s_es->s_mount_opts, ++ sizeof(s_mount_opts)) < 0) ++ goto failed_mount; + if (!parse_options(s_mount_opts, sb, &journal_devnum, + &journal_ioprio, 0)) { + ext4_msg(sb, KERN_WARNING, diff --git a/queue-5.10/f2fs-fix-to-avoid-updating-zero-sized-extent-in-extent-cache.patch b/queue-5.10/f2fs-fix-to-avoid-updating-zero-sized-extent-in-extent-cache.patch new file mode 100644 index 0000000000..a2458b0012 --- /dev/null +++ b/queue-5.10/f2fs-fix-to-avoid-updating-zero-sized-extent-in-extent-cache.patch @@ -0,0 +1,65 @@ +From stable+bounces-204265-greg=kroah.com@vger.kernel.org Tue Dec 30 18:35:07 2025 +From: Sasha Levin +Date: Tue, 30 Dec 2025 12:35:01 -0500 +Subject: f2fs: fix to avoid updating zero-sized extent in extent cache +To: stable@vger.kernel.org +Cc: Chao Yu , stable@kernel.org, syzbot+24124df3170c3638b35f@syzkaller.appspotmail.com, Jaegeuk Kim , Sasha Levin +Message-ID: <20251230173501.2352293-1-sashal@kernel.org> + +From: Chao Yu + +[ Upstream commit 7c37c79510329cd951a4dedf3f7bf7e2b18dccec ] + +As syzbot reported: + +F2FS-fs (loop0): __update_extent_tree_range: extent len is zero, type: 0, extent [0, 0, 0], age [0, 0] +------------[ cut here ]------------ +kernel BUG at fs/f2fs/extent_cache.c:678! +Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI +CPU: 0 UID: 0 PID: 5336 Comm: syz.0.0 Not tainted syzkaller #0 PREEMPT(full) +Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014 +RIP: 0010:__update_extent_tree_range+0x13bc/0x1500 fs/f2fs/extent_cache.c:678 +Call Trace: + + f2fs_update_read_extent_cache_range+0x192/0x3e0 fs/f2fs/extent_cache.c:1085 + f2fs_do_zero_range fs/f2fs/file.c:1657 [inline] + f2fs_zero_range+0x10c1/0x1580 fs/f2fs/file.c:1737 + f2fs_fallocate+0x583/0x990 fs/f2fs/file.c:2030 + vfs_fallocate+0x669/0x7e0 fs/open.c:342 + ioctl_preallocate fs/ioctl.c:289 [inline] + file_ioctl+0x611/0x780 fs/ioctl.c:-1 + do_vfs_ioctl+0xb33/0x1430 fs/ioctl.c:576 + __do_sys_ioctl fs/ioctl.c:595 [inline] + __se_sys_ioctl+0x82/0x170 fs/ioctl.c:583 + do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] + do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94 + entry_SYSCALL_64_after_hwframe+0x77/0x7f +RIP: 0033:0x7f07bc58eec9 + +In error path of f2fs_zero_range(), it may add a zero-sized extent +into extent cache, it should be avoided. + +Fixes: 6e9619499f53 ("f2fs: support in batch fzero in dnode page") +Cc: stable@kernel.org +Reported-by: syzbot+24124df3170c3638b35f@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/linux-f2fs-devel/68e5d698.050a0220.256323.0032.GAE@google.com +Signed-off-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + fs/f2fs/file.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/f2fs/file.c ++++ b/fs/f2fs/file.c +@@ -1458,7 +1458,8 @@ static int f2fs_do_zero_range(struct dno + f2fs_set_data_blkaddr(dn); + } + +- f2fs_update_extent_cache_range(dn, start, 0, index - start); ++ if (index > start) ++ f2fs_update_extent_cache_range(dn, start, 0, index - start); + + return ret; + } diff --git a/queue-5.10/f2fs-fix-to-detect-recoverable-inode-during-dryrun-of-find_fsync_dnodes.patch b/queue-5.10/f2fs-fix-to-detect-recoverable-inode-during-dryrun-of-find_fsync_dnodes.patch new file mode 100644 index 0000000000..585aa0ff52 --- /dev/null +++ b/queue-5.10/f2fs-fix-to-detect-recoverable-inode-during-dryrun-of-find_fsync_dnodes.patch @@ -0,0 +1,93 @@ +From stable+bounces-204288-greg=kroah.com@vger.kernel.org Tue Dec 30 21:31:39 2025 +From: Sasha Levin +Date: Tue, 30 Dec 2025 15:31:33 -0500 +Subject: f2fs: fix to detect recoverable inode during dryrun of find_fsync_dnodes() +To: stable@vger.kernel.org +Cc: Chao Yu , stable@kernel.org, Jaegeuk Kim , Sasha Levin +Message-ID: <20251230203133.2457797-1-sashal@kernel.org> + +From: Chao Yu + +[ Upstream commit 68d05693f8c031257a0822464366e1c2a239a512 ] + +mkfs.f2fs -f /dev/vdd +mount /dev/vdd /mnt/f2fs +touch /mnt/f2fs/foo +sync # avoid CP_UMOUNT_FLAG in last f2fs_checkpoint.ckpt_flags +touch /mnt/f2fs/bar +f2fs_io fsync /mnt/f2fs/bar +f2fs_io shutdown 2 /mnt/f2fs +umount /mnt/f2fs +blockdev --setro /dev/vdd +mount /dev/vdd /mnt/f2fs +mount: /mnt/f2fs: WARNING: source write-protected, mounted read-only. + +For the case if we create and fsync a new inode before sudden power-cut, +without norecovery or disable_roll_forward mount option, the following +mount will succeed w/o recovering last fsynced inode. + +The problem here is that we only check inode_list list after +find_fsync_dnodes() in f2fs_recover_fsync_data() to find out whether +there is recoverable data in the iamge, but there is a missed case, if +last fsynced inode is not existing in last checkpoint, then, we will +fail to get its inode due to nat of inode node is not existing in last +checkpoint, so the inode won't be linked in inode_list. + +Let's detect such case in dyrun mode to fix this issue. + +After this change, mount will fail as expected below: +mount: /mnt/f2fs: cannot mount /dev/vdd read-only. + dmesg(1) may have more information after failed mount system call. +demsg: +F2FS-fs (vdd): Need to recover fsync data, but write access unavailable, please try mount w/ disable_roll_forward or norecovery + +Cc: stable@kernel.org +Fixes: 6781eabba1bd ("f2fs: give -EINVAL for norecovery and rw mount") +Signed-off-by: Chao Yu +Signed-off-by: Jaegeuk Kim +[ folio => page ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + fs/f2fs/recovery.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/fs/f2fs/recovery.c ++++ b/fs/f2fs/recovery.c +@@ -328,7 +328,7 @@ static int recover_inode(struct inode *i + } + + static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head, +- bool check_only) ++ bool check_only, bool *new_inode) + { + struct curseg_info *curseg; + struct page *page = NULL; +@@ -385,6 +385,8 @@ static int find_fsync_dnodes(struct f2fs + if (IS_ERR(entry)) { + err = PTR_ERR(entry); + if (err == -ENOENT) { ++ if (check_only) ++ *new_inode = true; + err = 0; + goto next; + } +@@ -789,6 +791,7 @@ int f2fs_recover_fsync_data(struct f2fs_ + unsigned long s_flags = sbi->sb->s_flags; + bool need_writecp = false; + bool fix_curseg_write_pointer = false; ++ bool new_inode = false; + #ifdef CONFIG_QUOTA + int quota_enabled; + #endif +@@ -813,8 +816,8 @@ int f2fs_recover_fsync_data(struct f2fs_ + mutex_lock(&sbi->cp_mutex); + + /* step #1: find fsynced inode numbers */ +- err = find_fsync_dnodes(sbi, &inode_list, check_only); +- if (err || list_empty(&inode_list)) ++ err = find_fsync_dnodes(sbi, &inode_list, check_only, &new_inode); ++ if (err < 0 || (list_empty(&inode_list) && (!check_only || !new_inode))) + goto skip; + + if (check_only) { diff --git a/queue-5.10/f2fs-fix-to-propagate-error-from-f2fs_enable_checkpoint.patch b/queue-5.10/f2fs-fix-to-propagate-error-from-f2fs_enable_checkpoint.patch new file mode 100644 index 0000000000..8cdec4cc3a --- /dev/null +++ b/queue-5.10/f2fs-fix-to-propagate-error-from-f2fs_enable_checkpoint.patch @@ -0,0 +1,83 @@ +From stable+bounces-204267-greg=kroah.com@vger.kernel.org Tue Dec 30 18:57:08 2025 +From: Sasha Levin +Date: Tue, 30 Dec 2025 12:57:00 -0500 +Subject: f2fs: fix to propagate error from f2fs_enable_checkpoint() +To: stable@vger.kernel.org +Cc: Chao Yu , stable@kernel.org, Jaegeuk Kim , Sasha Levin +Message-ID: <20251230175700.2368734-1-sashal@kernel.org> + +From: Chao Yu + +[ Upstream commit be112e7449a6e1b54aa9feac618825d154b3a5c7 ] + +In order to let userspace detect such error rather than suffering +silent failure. + +Fixes: 4354994f097d ("f2fs: checkpoint disabling") +Cc: stable@kernel.org +Signed-off-by: Chao Yu +Signed-off-by: Jaegeuk Kim +[ adapted error handling to use restore_gc ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + fs/f2fs/super.c | 24 +++++++++++++++--------- + 1 file changed, 15 insertions(+), 9 deletions(-) + +--- a/fs/f2fs/super.c ++++ b/fs/f2fs/super.c +@@ -1836,9 +1836,10 @@ restore_flag: + return err; + } + +-static void f2fs_enable_checkpoint(struct f2fs_sb_info *sbi) ++static int f2fs_enable_checkpoint(struct f2fs_sb_info *sbi) + { + int retry = DEFAULT_RETRY_IO_COUNT; ++ int ret; + + /* we should flush all the data to keep data consistency */ + do { +@@ -1857,7 +1858,11 @@ static void f2fs_enable_checkpoint(struc + set_sbi_flag(sbi, SBI_IS_DIRTY); + up_write(&sbi->gc_lock); + +- f2fs_sync_fs(sbi->sb, 1); ++ ret = f2fs_sync_fs(sbi->sb, 1); ++ if (ret) ++ f2fs_err(sbi, "%s sync_fs failed, ret: %d", __func__, ret); ++ ++ return ret; + } + + static int f2fs_remount(struct super_block *sb, int *flags, char *data) +@@ -2005,7 +2010,9 @@ static int f2fs_remount(struct super_blo + if (err) + goto restore_gc; + } else { +- f2fs_enable_checkpoint(sbi); ++ err = f2fs_enable_checkpoint(sbi); ++ if (err) ++ goto restore_gc; + } + } + +@@ -3933,13 +3940,12 @@ reset_checkpoint: + /* f2fs_recover_fsync_data() cleared this already */ + clear_sbi_flag(sbi, SBI_POR_DOING); + +- if (test_opt(sbi, DISABLE_CHECKPOINT)) { ++ if (test_opt(sbi, DISABLE_CHECKPOINT)) + err = f2fs_disable_checkpoint(sbi); +- if (err) +- goto sync_free_meta; +- } else if (is_set_ckpt_flags(sbi, CP_DISABLED_FLAG)) { +- f2fs_enable_checkpoint(sbi); +- } ++ else if (is_set_ckpt_flags(sbi, CP_DISABLED_FLAG)) ++ err = f2fs_enable_checkpoint(sbi); ++ if (err) ++ goto sync_free_meta; + + /* + * If filesystem is not mounted as read-only then diff --git a/queue-5.10/f2fs-use-global-inline_xattr_slab-instead-of-per-sb-slab-cache.patch b/queue-5.10/f2fs-use-global-inline_xattr_slab-instead-of-per-sb-slab-cache.patch new file mode 100644 index 0000000000..10b49aeca6 --- /dev/null +++ b/queue-5.10/f2fs-use-global-inline_xattr_slab-instead-of-per-sb-slab-cache.patch @@ -0,0 +1,237 @@ +From stable+bounces-204298-greg=kroah.com@vger.kernel.org Tue Dec 30 23:04:04 2025 +From: Sasha Levin +Date: Tue, 30 Dec 2025 17:03:56 -0500 +Subject: f2fs: use global inline_xattr_slab instead of per-sb slab cache +To: stable@vger.kernel.org +Cc: Chao Yu , stable@kernel.org, Hong Yun , Jaegeuk Kim , Sasha Levin +Message-ID: <20251230220356.2525348-1-sashal@kernel.org> + +From: Chao Yu + +[ Upstream commit 1f27ef42bb0b7c0740c5616ec577ec188b8a1d05 ] + +As Hong Yun reported in mailing list: + +loop7: detected capacity change from 0 to 131072 +------------[ cut here ]------------ +kmem_cache of name 'f2fs_xattr_entry-7:7' already exists +WARNING: CPU: 0 PID: 24426 at mm/slab_common.c:110 kmem_cache_sanity_check mm/slab_common.c:109 [inline] +WARNING: CPU: 0 PID: 24426 at mm/slab_common.c:110 __kmem_cache_create_args+0xa6/0x320 mm/slab_common.c:307 +CPU: 0 UID: 0 PID: 24426 Comm: syz.7.1370 Not tainted 6.17.0-rc4 #1 PREEMPT(full) +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014 +RIP: 0010:kmem_cache_sanity_check mm/slab_common.c:109 [inline] +RIP: 0010:__kmem_cache_create_args+0xa6/0x320 mm/slab_common.c:307 +Call Trace: + __kmem_cache_create include/linux/slab.h:353 [inline] + f2fs_kmem_cache_create fs/f2fs/f2fs.h:2943 [inline] + f2fs_init_xattr_caches+0xa5/0xe0 fs/f2fs/xattr.c:843 + f2fs_fill_super+0x1645/0x2620 fs/f2fs/super.c:4918 + get_tree_bdev_flags+0x1fb/0x260 fs/super.c:1692 + vfs_get_tree+0x43/0x140 fs/super.c:1815 + do_new_mount+0x201/0x550 fs/namespace.c:3808 + do_mount fs/namespace.c:4136 [inline] + __do_sys_mount fs/namespace.c:4347 [inline] + __se_sys_mount+0x298/0x2f0 fs/namespace.c:4324 + do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] + do_syscall_64+0x8e/0x3a0 arch/x86/entry/syscall_64.c:94 + entry_SYSCALL_64_after_hwframe+0x76/0x7e + +The bug can be reproduced w/ below scripts: +- mount /dev/vdb /mnt1 +- mount /dev/vdc /mnt2 +- umount /mnt1 +- mounnt /dev/vdb /mnt1 + +The reason is if we created two slab caches, named f2fs_xattr_entry-7:3 +and f2fs_xattr_entry-7:7, and they have the same slab size. Actually, +slab system will only create one slab cache core structure which has +slab name of "f2fs_xattr_entry-7:3", and two slab caches share the same +structure and cache address. + +So, if we destroy f2fs_xattr_entry-7:3 cache w/ cache address, it will +decrease reference count of slab cache, rather than release slab cache +entirely, since there is one more user has referenced the cache. + +Then, if we try to create slab cache w/ name "f2fs_xattr_entry-7:3" again, +slab system will find that there is existed cache which has the same name +and trigger the warning. + +Let's changes to use global inline_xattr_slab instead of per-sb slab cache +for fixing. + +Fixes: a999150f4fe3 ("f2fs: use kmem_cache pool during inline xattr lookups") +Cc: stable@kernel.org +Reported-by: Hong Yun +Tested-by: Hong Yun +Signed-off-by: Chao Yu +Signed-off-by: Jaegeuk Kim +[ No f2fs_kmem_cache_alloc() ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + fs/f2fs/f2fs.h | 3 --- + fs/f2fs/super.c | 15 +++++++-------- + fs/f2fs/xattr.c | 32 +++++++++++--------------------- + fs/f2fs/xattr.h | 10 ++++++---- + 4 files changed, 24 insertions(+), 36 deletions(-) + +--- a/fs/f2fs/f2fs.h ++++ b/fs/f2fs/f2fs.h +@@ -1573,9 +1573,6 @@ struct f2fs_sb_info { + + struct workqueue_struct *post_read_wq; /* post read workqueue */ + +- struct kmem_cache *inline_xattr_slab; /* inline xattr entry */ +- unsigned int inline_xattr_slab_size; /* default inline xattr slab size */ +- + #ifdef CONFIG_F2FS_FS_COMPRESSION + struct kmem_cache *page_array_slab; /* page array entry */ + unsigned int page_array_slab_size; /* default page array slab size */ +--- a/fs/f2fs/super.c ++++ b/fs/f2fs/super.c +@@ -1351,7 +1351,6 @@ static void f2fs_put_super(struct super_ + + destroy_device_list(sbi); + f2fs_destroy_page_array_cache(sbi); +- f2fs_destroy_xattr_caches(sbi); + mempool_destroy(sbi->write_io_dummy); + #ifdef CONFIG_QUOTA + for (i = 0; i < MAXQUOTAS; i++) +@@ -3722,13 +3721,9 @@ try_onemore: + } + } + +- /* init per sbi slab cache */ +- err = f2fs_init_xattr_caches(sbi); +- if (err) +- goto free_io_dummy; + err = f2fs_init_page_array_cache(sbi); + if (err) +- goto free_xattr_cache; ++ goto free_io_dummy; + + /* get an inode for meta space */ + sbi->meta_inode = f2fs_iget(sb, F2FS_META_INO(sbi)); +@@ -4021,8 +4016,6 @@ free_meta_inode: + sbi->meta_inode = NULL; + free_page_array_cache: + f2fs_destroy_page_array_cache(sbi); +-free_xattr_cache: +- f2fs_destroy_xattr_caches(sbi); + free_io_dummy: + mempool_destroy(sbi->write_io_dummy); + free_percpu: +@@ -4174,7 +4167,12 @@ static int __init init_f2fs_fs(void) + err = f2fs_init_compress_cache(); + if (err) + goto free_compress_mempool; ++ err = f2fs_init_xattr_cache(); ++ if (err) ++ goto free_compress_cache; + return 0; ++free_compress_cache: ++ f2fs_destroy_compress_cache(); + free_compress_mempool: + f2fs_destroy_compress_mempool(); + free_bioset: +@@ -4210,6 +4208,7 @@ fail: + + static void __exit exit_f2fs_fs(void) + { ++ f2fs_destroy_xattr_cache(); + f2fs_destroy_compress_cache(); + f2fs_destroy_compress_mempool(); + f2fs_destroy_bioset(); +--- a/fs/f2fs/xattr.c ++++ b/fs/f2fs/xattr.c +@@ -23,11 +23,12 @@ + #include "xattr.h" + #include "segment.h" + ++static struct kmem_cache *inline_xattr_slab; + static void *xattr_alloc(struct f2fs_sb_info *sbi, int size, bool *is_inline) + { +- if (likely(size == sbi->inline_xattr_slab_size)) { ++ if (likely(size == DEFAULT_XATTR_SLAB_SIZE)) { + *is_inline = true; +- return kmem_cache_zalloc(sbi->inline_xattr_slab, GFP_NOFS); ++ return kmem_cache_zalloc(inline_xattr_slab, GFP_NOFS); + } + *is_inline = false; + return f2fs_kzalloc(sbi, size, GFP_NOFS); +@@ -37,7 +38,7 @@ static void xattr_free(struct f2fs_sb_in + bool is_inline) + { + if (is_inline) +- kmem_cache_free(sbi->inline_xattr_slab, xattr_addr); ++ kmem_cache_free(inline_xattr_slab, xattr_addr); + else + kfree(xattr_addr); + } +@@ -814,25 +815,14 @@ int f2fs_setxattr(struct inode *inode, i + return err; + } + +-int f2fs_init_xattr_caches(struct f2fs_sb_info *sbi) ++int __init f2fs_init_xattr_cache(void) + { +- dev_t dev = sbi->sb->s_bdev->bd_dev; +- char slab_name[32]; +- +- sprintf(slab_name, "f2fs_xattr_entry-%u:%u", MAJOR(dev), MINOR(dev)); +- +- sbi->inline_xattr_slab_size = F2FS_OPTION(sbi).inline_xattr_size * +- sizeof(__le32) + XATTR_PADDING_SIZE; +- +- sbi->inline_xattr_slab = f2fs_kmem_cache_create(slab_name, +- sbi->inline_xattr_slab_size); +- if (!sbi->inline_xattr_slab) +- return -ENOMEM; +- +- return 0; ++ inline_xattr_slab = f2fs_kmem_cache_create("f2fs_xattr_entry", ++ DEFAULT_XATTR_SLAB_SIZE); ++ return inline_xattr_slab ? 0 : -ENOMEM; + } + +-void f2fs_destroy_xattr_caches(struct f2fs_sb_info *sbi) ++void f2fs_destroy_xattr_cache(void) + { +- kmem_cache_destroy(sbi->inline_xattr_slab); +-} ++ kmem_cache_destroy(inline_xattr_slab); ++} +\ No newline at end of file +--- a/fs/f2fs/xattr.h ++++ b/fs/f2fs/xattr.h +@@ -88,6 +88,8 @@ struct f2fs_xattr_entry { + F2FS_TOTAL_EXTRA_ATTR_SIZE / sizeof(__le32) - \ + DEF_INLINE_RESERVED_SIZE - \ + MIN_INLINE_DENTRY_SIZE / sizeof(__le32)) ++#define DEFAULT_XATTR_SLAB_SIZE (DEFAULT_INLINE_XATTR_ADDRS * \ ++ sizeof(__le32) + XATTR_PADDING_SIZE) + + /* + * On-disk structure of f2fs_xattr +@@ -131,8 +133,8 @@ extern int f2fs_setxattr(struct inode *, + extern int f2fs_getxattr(struct inode *, int, const char *, void *, + size_t, struct page *); + extern ssize_t f2fs_listxattr(struct dentry *, char *, size_t); +-extern int f2fs_init_xattr_caches(struct f2fs_sb_info *); +-extern void f2fs_destroy_xattr_caches(struct f2fs_sb_info *); ++extern int __init f2fs_init_xattr_cache(void); ++extern void f2fs_destroy_xattr_cache(void); + #else + + #define f2fs_xattr_handlers NULL +@@ -149,8 +151,8 @@ static inline int f2fs_getxattr(struct i + { + return -EOPNOTSUPP; + } +-static inline int f2fs_init_xattr_caches(struct f2fs_sb_info *sbi) { return 0; } +-static inline void f2fs_destroy_xattr_caches(struct f2fs_sb_info *sbi) { } ++static inline int __init f2fs_init_xattr_cache(void) { return 0; } ++static inline void f2fs_destroy_xattr_cache(void) { } + #endif + + #ifdef CONFIG_F2FS_FS_SECURITY diff --git a/queue-5.10/hid-core-harden-s32ton-against-conversion-to-0-bits.patch b/queue-5.10/hid-core-harden-s32ton-against-conversion-to-0-bits.patch new file mode 100644 index 0000000000..d8010694df --- /dev/null +++ b/queue-5.10/hid-core-harden-s32ton-against-conversion-to-0-bits.patch @@ -0,0 +1,55 @@ +From stable+bounces-200016-greg=kroah.com@vger.kernel.org Thu Dec 4 13:41:45 2025 +From: jetlan9@163.com +Date: Thu, 4 Dec 2025 12:40:34 +0000 +Subject: HID: core: Harden s32ton() against conversion to 0 bits +To: stable@vger.kernel.org +Cc: Alan Stern , syzbot+b63d677d63bcac06cf90@syzkaller.appspotmail.com, Benjamin Tissoires , Wenshan Lan +Message-ID: <20251204124034.4145-1-jetlan9@163.com> + +From: Alan Stern + +[ Upstream commit a6b87bfc2ab5bccb7ad953693c85d9062aef3fdd ] + +Testing by the syzbot fuzzer showed that the HID core gets a +shift-out-of-bounds exception when it tries to convert a 32-bit +quantity to a 0-bit quantity. Ideally this should never occur, but +there are buggy devices and some might have a report field with size +set to zero; we shouldn't reject the report or the device just because +of that. + +Instead, harden the s32ton() routine so that it returns a reasonable +result instead of crashing when it is called with the number of bits +set to 0 -- the same as what snto32() does. + +Signed-off-by: Alan Stern +Reported-by: syzbot+b63d677d63bcac06cf90@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/linux-usb/68753a08.050a0220.33d347.0008.GAE@google.com/ +Tested-by: syzbot+b63d677d63bcac06cf90@syzkaller.appspotmail.com +Fixes: dde5845a529f ("[PATCH] Generic HID layer - code split") +Cc: stable@vger.kernel.org +Link: https://patch.msgid.link/613a66cd-4309-4bce-a4f7-2905f9bce0c9@rowland.harvard.edu +Signed-off-by: Benjamin Tissoires +[ s32ton() was moved by c653ffc28340 ("HID: stop exporting hid_snto32()"). + Minor context change fixed. ] +Signed-off-by: Wenshan Lan +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hid/hid-core.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -1349,7 +1349,12 @@ EXPORT_SYMBOL_GPL(hid_snto32); + + static u32 s32ton(__s32 value, unsigned n) + { +- s32 a = value >> (n - 1); ++ s32 a; ++ ++ if (!value || !n) ++ return 0; ++ ++ a = value >> (n - 1); + if (a && a != -1) + return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1; + return value & ((1 << n) - 1); diff --git a/queue-5.10/hwmon-max16065-use-local-variable-to-avoid-toctou.patch b/queue-5.10/hwmon-max16065-use-local-variable-to-avoid-toctou.patch new file mode 100644 index 0000000000..c60f6d2d2e --- /dev/null +++ b/queue-5.10/hwmon-max16065-use-local-variable-to-avoid-toctou.patch @@ -0,0 +1,55 @@ +From stable+bounces-204385-greg=kroah.com@vger.kernel.org Wed Dec 31 21:41:45 2025 +From: Sasha Levin +Date: Wed, 31 Dec 2025 15:41:36 -0500 +Subject: hwmon: (max16065) Use local variable to avoid TOCTOU +To: stable@vger.kernel.org +Cc: Gui-Dong Han , Guenter Roeck , Sasha Levin +Message-ID: <20251231204136.3475586-2-sashal@kernel.org> + +From: Gui-Dong Han + +[ Upstream commit b8d5acdcf525f44e521ca4ef51dce4dac403dab4 ] + +In max16065_current_show, data->curr_sense is read twice: once for the +error check and again for the calculation. Since +i2c_smbus_read_byte_data returns negative error codes on failure, if the +data changes to an error code between the check and the use, ADC_TO_CURR +results in an incorrect calculation. + +Read data->curr_sense into a local variable to ensure consistency. Note +that data->curr_gain is constant and safe to access directly. + +This aligns max16065_current_show with max16065_input_show, which +already uses a local variable for the same reason. + +Link: https://lore.kernel.org/all/CALbr=LYJ_ehtp53HXEVkSpYoub+XYSTU8Rg=o1xxMJ8=5z8B-g@mail.gmail.com/ +Fixes: f5bae2642e3d ("hwmon: Driver for MAX16065 System Manager and compatibles") +Cc: stable@vger.kernel.org +Signed-off-by: Gui-Dong Han +Link: https://lore.kernel.org/r/20251128124709.3876-1-hanguidong02@gmail.com +Signed-off-by: Guenter Roeck +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hwmon/max16065.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/hwmon/max16065.c ++++ b/drivers/hwmon/max16065.c +@@ -216,12 +216,13 @@ static ssize_t max16065_current_show(str + struct device_attribute *da, char *buf) + { + struct max16065_data *data = max16065_update_device(dev); ++ int curr_sense = data->curr_sense; + +- if (unlikely(data->curr_sense < 0)) +- return data->curr_sense; ++ if (unlikely(curr_sense < 0)) ++ return curr_sense; + + return sysfs_emit(buf, "%d\n", +- ADC_TO_CURR(data->curr_sense, data->curr_gain)); ++ ADC_TO_CURR(curr_sense, data->curr_gain)); + } + + static ssize_t max16065_limit_store(struct device *dev, diff --git a/queue-5.10/hwmon-replace-snprintf-in-show-functions-with-sysfs_emit.patch b/queue-5.10/hwmon-replace-snprintf-in-show-functions-with-sysfs_emit.patch new file mode 100644 index 0000000000..f61de0ae06 --- /dev/null +++ b/queue-5.10/hwmon-replace-snprintf-in-show-functions-with-sysfs_emit.patch @@ -0,0 +1,1205 @@ +From stable+bounces-204384-greg=kroah.com@vger.kernel.org Wed Dec 31 21:41:44 2025 +From: Sasha Levin +Date: Wed, 31 Dec 2025 15:41:35 -0500 +Subject: hwmon: replace snprintf in show functions with sysfs_emit +To: stable@vger.kernel.org +Cc: Guenter Roeck , Zihao Tang , Jay Fang , Sasha Levin +Message-ID: <20251231204136.3475586-1-sashal@kernel.org> + +From: Guenter Roeck + +[ Upstream commit 1f4d4af4d7a1c794a4f003f75fcfd38fafb5dff3 ] + +coccicheck complains about the use of snprintf() in sysfs +show functions. + +drivers/hwmon/ina3221.c:701:8-16: WARNING: use scnprintf or sprintf + +This results in a large number of patch submissions. Fix it all in +one go using the following coccinelle rules. Use sysfs_emit instead +of scnprintf or sprintf since that makes more sense. + +@depends on patch@ +identifier show, dev, attr, buf; +@@ + +ssize_t show(struct device *dev, struct device_attribute *attr, char *buf) +{ + <... + return +- snprintf(buf, \( PAGE_SIZE \| PAGE_SIZE - 1 \), ++ sysfs_emit(buf, + ...); + ...> +} + +@depends on patch@ +identifier show, dev, attr, buf, rc; +@@ + +ssize_t show(struct device *dev, struct device_attribute *attr, char *buf) +{ + <... + rc = +- snprintf(buf, \( PAGE_SIZE \| PAGE_SIZE - 1 \), ++ sysfs_emit(buf, + ...); + ...> +} + +While at it, remove unnecessary braces and as well as unnecessary +else after return statements to address checkpatch warnings in the +resulting patch. + +Cc: Zihao Tang +Cc: Jay Fang +Signed-off-by: Guenter Roeck +Stable-dep-of: b8d5acdcf525 ("hwmon: (max16065) Use local variable to avoid TOCTOU") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hwmon/applesmc.c | 34 +++++++++--------- + drivers/hwmon/ina209.c | 6 +-- + drivers/hwmon/ina2xx.c | 2 - + drivers/hwmon/ina3221.c | 2 - + drivers/hwmon/lineage-pem.c | 8 ++-- + drivers/hwmon/ltc2945.c | 4 +- + drivers/hwmon/ltc2990.c | 2 - + drivers/hwmon/ltc4151.c | 2 - + drivers/hwmon/ltc4215.c | 8 ++-- + drivers/hwmon/ltc4222.c | 4 +- + drivers/hwmon/ltc4260.c | 4 +- + drivers/hwmon/ltc4261.c | 4 +- + drivers/hwmon/max16065.c | 14 +++---- + drivers/hwmon/occ/common.c | 69 ++++++++++++++++++------------------- + drivers/hwmon/occ/sysfs.c | 4 +- + drivers/hwmon/pmbus/inspur-ipsps.c | 28 +++++++-------- + drivers/hwmon/pmbus/pmbus_core.c | 8 ++-- + drivers/hwmon/s3c-hwmon.c | 4 +- + drivers/hwmon/sch5627.c | 24 ++++++------ + drivers/hwmon/sch5636.c | 20 +++++----- + drivers/hwmon/smm665.c | 4 +- + drivers/hwmon/stts751.c | 20 +++++----- + drivers/hwmon/vexpress-hwmon.c | 12 +++--- + drivers/hwmon/xgene-hwmon.c | 14 +++---- + 24 files changed, 151 insertions(+), 150 deletions(-) + +--- a/drivers/hwmon/applesmc.c ++++ b/drivers/hwmon/applesmc.c +@@ -741,7 +741,7 @@ static void applesmc_idev_poll(struct in + static ssize_t applesmc_name_show(struct device *dev, + struct device_attribute *attr, char *buf) + { +- return snprintf(buf, PAGE_SIZE, "applesmc\n"); ++ return sysfs_emit(buf, "applesmc\n"); + } + + static ssize_t applesmc_position_show(struct device *dev, +@@ -763,8 +763,8 @@ static ssize_t applesmc_position_show(st + out: + if (ret) + return ret; +- else +- return snprintf(buf, PAGE_SIZE, "(%d,%d,%d)\n", x, y, z); ++ ++ return sysfs_emit(buf, "(%d,%d,%d)\n", x, y, z); + } + + static ssize_t applesmc_light_show(struct device *dev, +@@ -804,8 +804,8 @@ static ssize_t applesmc_light_show(struc + out: + if (ret) + return ret; +- else +- return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", left, right); ++ ++ return sysfs_emit(sysfsbuf, "(%d,%d)\n", left, right); + } + + /* Displays sensor key as label */ +@@ -814,7 +814,7 @@ static ssize_t applesmc_show_sensor_labe + { + const char *key = smcreg.index[to_index(devattr)]; + +- return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key); ++ return sysfs_emit(sysfsbuf, "%s\n", key); + } + + /* Displays degree Celsius * 1000 */ +@@ -832,7 +832,7 @@ static ssize_t applesmc_show_temperature + + temp = 250 * (value >> 6); + +- return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", temp); ++ return sysfs_emit(sysfsbuf, "%d\n", temp); + } + + static ssize_t applesmc_show_fan_speed(struct device *dev, +@@ -851,7 +851,7 @@ static ssize_t applesmc_show_fan_speed(s + return ret; + + speed = ((buffer[0] << 8 | buffer[1]) >> 2); +- return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", speed); ++ return sysfs_emit(sysfsbuf, "%u\n", speed); + } + + static ssize_t applesmc_store_fan_speed(struct device *dev, +@@ -891,7 +891,7 @@ static ssize_t applesmc_show_fan_manual( + return ret; + + manual = ((buffer[0] << 8 | buffer[1]) >> to_index(attr)) & 0x01; +- return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", manual); ++ return sysfs_emit(sysfsbuf, "%d\n", manual); + } + + static ssize_t applesmc_store_fan_manual(struct device *dev, +@@ -943,14 +943,14 @@ static ssize_t applesmc_show_fan_positio + + if (ret) + return ret; +- else +- return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", buffer+4); ++ ++ return sysfs_emit(sysfsbuf, "%s\n", buffer + 4); + } + + static ssize_t applesmc_calibrate_show(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { +- return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", rest_x, rest_y); ++ return sysfs_emit(sysfsbuf, "(%d,%d)\n", rest_x, rest_y); + } + + static ssize_t applesmc_calibrate_store(struct device *dev, +@@ -992,7 +992,7 @@ static ssize_t applesmc_key_count_show(s + + count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) + + ((u32)buffer[2]<<8) + buffer[3]; +- return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", count); ++ return sysfs_emit(sysfsbuf, "%d\n", count); + } + + static ssize_t applesmc_key_at_index_read_show(struct device *dev, +@@ -1020,7 +1020,7 @@ static ssize_t applesmc_key_at_index_dat + if (IS_ERR(entry)) + return PTR_ERR(entry); + +- return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", entry->len); ++ return sysfs_emit(sysfsbuf, "%d\n", entry->len); + } + + static ssize_t applesmc_key_at_index_type_show(struct device *dev, +@@ -1032,7 +1032,7 @@ static ssize_t applesmc_key_at_index_typ + if (IS_ERR(entry)) + return PTR_ERR(entry); + +- return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", entry->type); ++ return sysfs_emit(sysfsbuf, "%s\n", entry->type); + } + + static ssize_t applesmc_key_at_index_name_show(struct device *dev, +@@ -1044,13 +1044,13 @@ static ssize_t applesmc_key_at_index_nam + if (IS_ERR(entry)) + return PTR_ERR(entry); + +- return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", entry->key); ++ return sysfs_emit(sysfsbuf, "%s\n", entry->key); + } + + static ssize_t applesmc_key_at_index_show(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { +- return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", key_at_index); ++ return sysfs_emit(sysfsbuf, "%d\n", key_at_index); + } + + static ssize_t applesmc_key_at_index_store(struct device *dev, +--- a/drivers/hwmon/ina209.c ++++ b/drivers/hwmon/ina209.c +@@ -259,7 +259,7 @@ static ssize_t ina209_interval_show(stru + { + struct ina209_data *data = dev_get_drvdata(dev); + +- return snprintf(buf, PAGE_SIZE, "%d\n", data->update_interval); ++ return sysfs_emit(buf, "%d\n", data->update_interval); + } + + /* +@@ -343,7 +343,7 @@ static ssize_t ina209_value_show(struct + return PTR_ERR(data); + + val = ina209_from_reg(attr->index, data->regs[attr->index]); +- return snprintf(buf, PAGE_SIZE, "%ld\n", val); ++ return sysfs_emit(buf, "%ld\n", val); + } + + static ssize_t ina209_alarm_show(struct device *dev, +@@ -363,7 +363,7 @@ static ssize_t ina209_alarm_show(struct + * All alarms are in the INA209_STATUS register. To avoid a long + * switch statement, the mask is passed in attr->index + */ +- return snprintf(buf, PAGE_SIZE, "%u\n", !!(status & mask)); ++ return sysfs_emit(buf, "%u\n", !!(status & mask)); + } + + /* Shunt voltage, history, limits, alarms */ +--- a/drivers/hwmon/ina2xx.c ++++ b/drivers/hwmon/ina2xx.c +@@ -386,7 +386,7 @@ static ssize_t ina226_alert_show(struct + val = ina226_reg_to_alert(data, attr->index, regval); + } + +- ret = snprintf(buf, PAGE_SIZE, "%d\n", val); ++ ret = sysfs_emit(buf, "%d\n", val); + abort: + mutex_unlock(&data->config_lock); + return ret; +--- a/drivers/hwmon/ina3221.c ++++ b/drivers/hwmon/ina3221.c +@@ -698,7 +698,7 @@ static ssize_t ina3221_shunt_show(struct + unsigned int channel = sd_attr->index; + struct ina3221_input *input = &ina->inputs[channel]; + +- return snprintf(buf, PAGE_SIZE, "%d\n", input->shunt_resistor); ++ return sysfs_emit(buf, "%d\n", input->shunt_resistor); + } + + static ssize_t ina3221_shunt_store(struct device *dev, +--- a/drivers/hwmon/lineage-pem.c ++++ b/drivers/hwmon/lineage-pem.c +@@ -280,7 +280,7 @@ static ssize_t pem_bool_show(struct devi + return PTR_ERR(data); + + status = data->data_string[attr->nr] & attr->index; +- return snprintf(buf, PAGE_SIZE, "%d\n", !!status); ++ return sysfs_emit(buf, "%d\n", !!status); + } + + static ssize_t pem_data_show(struct device *dev, struct device_attribute *da, +@@ -296,7 +296,7 @@ static ssize_t pem_data_show(struct devi + value = pem_get_data(data->data_string, sizeof(data->data_string), + attr->index); + +- return snprintf(buf, PAGE_SIZE, "%ld\n", value); ++ return sysfs_emit(buf, "%ld\n", value); + } + + static ssize_t pem_input_show(struct device *dev, struct device_attribute *da, +@@ -312,7 +312,7 @@ static ssize_t pem_input_show(struct dev + value = pem_get_input(data->input_string, sizeof(data->input_string), + attr->index); + +- return snprintf(buf, PAGE_SIZE, "%ld\n", value); ++ return sysfs_emit(buf, "%ld\n", value); + } + + static ssize_t pem_fan_show(struct device *dev, struct device_attribute *da, +@@ -328,7 +328,7 @@ static ssize_t pem_fan_show(struct devic + value = pem_get_fan(data->fan_speed, sizeof(data->fan_speed), + attr->index); + +- return snprintf(buf, PAGE_SIZE, "%ld\n", value); ++ return sysfs_emit(buf, "%ld\n", value); + } + + /* Voltages */ +--- a/drivers/hwmon/ltc2945.c ++++ b/drivers/hwmon/ltc2945.c +@@ -226,7 +226,7 @@ static ssize_t ltc2945_value_show(struct + value = ltc2945_reg_to_val(dev, attr->index); + if (value < 0) + return value; +- return snprintf(buf, PAGE_SIZE, "%lld\n", value); ++ return sysfs_emit(buf, "%lld\n", value); + } + + static ssize_t ltc2945_value_store(struct device *dev, +@@ -335,7 +335,7 @@ static ssize_t ltc2945_bool_show(struct + if (fault) /* Clear reported faults in chip register */ + regmap_update_bits(regmap, LTC2945_FAULT, attr->index, 0); + +- return snprintf(buf, PAGE_SIZE, "%d\n", !!fault); ++ return sysfs_emit(buf, "%d\n", !!fault); + } + + /* Input voltages */ +--- a/drivers/hwmon/ltc2990.c ++++ b/drivers/hwmon/ltc2990.c +@@ -147,7 +147,7 @@ static ssize_t ltc2990_value_show(struct + if (unlikely(ret < 0)) + return ret; + +- return snprintf(buf, PAGE_SIZE, "%d\n", value); ++ return sysfs_emit(buf, "%d\n", value); + } + + static umode_t ltc2990_attrs_visible(struct kobject *kobj, +--- a/drivers/hwmon/ltc4151.c ++++ b/drivers/hwmon/ltc4151.c +@@ -128,7 +128,7 @@ static ssize_t ltc4151_value_show(struct + return PTR_ERR(data); + + value = ltc4151_get_value(data, attr->index); +- return snprintf(buf, PAGE_SIZE, "%d\n", value); ++ return sysfs_emit(buf, "%d\n", value); + } + + /* +--- a/drivers/hwmon/ltc4215.c ++++ b/drivers/hwmon/ltc4215.c +@@ -139,7 +139,7 @@ static ssize_t ltc4215_voltage_show(stru + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + const int voltage = ltc4215_get_voltage(dev, attr->index); + +- return snprintf(buf, PAGE_SIZE, "%d\n", voltage); ++ return sysfs_emit(buf, "%d\n", voltage); + } + + static ssize_t ltc4215_current_show(struct device *dev, +@@ -147,7 +147,7 @@ static ssize_t ltc4215_current_show(stru + { + const unsigned int curr = ltc4215_get_current(dev); + +- return snprintf(buf, PAGE_SIZE, "%u\n", curr); ++ return sysfs_emit(buf, "%u\n", curr); + } + + static ssize_t ltc4215_power_show(struct device *dev, +@@ -159,7 +159,7 @@ static ssize_t ltc4215_power_show(struct + /* current in mA * voltage in mV == power in uW */ + const unsigned int power = abs(output_voltage * curr); + +- return snprintf(buf, PAGE_SIZE, "%u\n", power); ++ return sysfs_emit(buf, "%u\n", power); + } + + static ssize_t ltc4215_alarm_show(struct device *dev, +@@ -170,7 +170,7 @@ static ssize_t ltc4215_alarm_show(struct + const u8 reg = data->regs[LTC4215_STATUS]; + const u32 mask = attr->index; + +- return snprintf(buf, PAGE_SIZE, "%u\n", !!(reg & mask)); ++ return sysfs_emit(buf, "%u\n", !!(reg & mask)); + } + + /* +--- a/drivers/hwmon/ltc4222.c ++++ b/drivers/hwmon/ltc4222.c +@@ -94,7 +94,7 @@ static ssize_t ltc4222_value_show(struct + value = ltc4222_get_value(dev, attr->index); + if (value < 0) + return value; +- return snprintf(buf, PAGE_SIZE, "%d\n", value); ++ return sysfs_emit(buf, "%d\n", value); + } + + static ssize_t ltc4222_bool_show(struct device *dev, +@@ -112,7 +112,7 @@ static ssize_t ltc4222_bool_show(struct + if (fault) /* Clear reported faults in chip register */ + regmap_update_bits(regmap, attr->nr, attr->index, 0); + +- return snprintf(buf, PAGE_SIZE, "%d\n", !!fault); ++ return sysfs_emit(buf, "%d\n", !!fault); + } + + /* Voltages */ +--- a/drivers/hwmon/ltc4260.c ++++ b/drivers/hwmon/ltc4260.c +@@ -79,7 +79,7 @@ static ssize_t ltc4260_value_show(struct + value = ltc4260_get_value(dev, attr->index); + if (value < 0) + return value; +- return snprintf(buf, PAGE_SIZE, "%d\n", value); ++ return sysfs_emit(buf, "%d\n", value); + } + + static ssize_t ltc4260_bool_show(struct device *dev, +@@ -98,7 +98,7 @@ static ssize_t ltc4260_bool_show(struct + if (fault) /* Clear reported faults in chip register */ + regmap_update_bits(regmap, LTC4260_FAULT, attr->index, 0); + +- return snprintf(buf, PAGE_SIZE, "%d\n", !!fault); ++ return sysfs_emit(buf, "%d\n", !!fault); + } + + /* Voltages */ +--- a/drivers/hwmon/ltc4261.c ++++ b/drivers/hwmon/ltc4261.c +@@ -130,7 +130,7 @@ static ssize_t ltc4261_value_show(struct + return PTR_ERR(data); + + value = ltc4261_get_value(data, attr->index); +- return snprintf(buf, PAGE_SIZE, "%d\n", value); ++ return sysfs_emit(buf, "%d\n", value); + } + + static ssize_t ltc4261_bool_show(struct device *dev, +@@ -147,7 +147,7 @@ static ssize_t ltc4261_bool_show(struct + if (fault) /* Clear reported faults in chip register */ + i2c_smbus_write_byte_data(data->client, LTC4261_FAULT, ~fault); + +- return snprintf(buf, PAGE_SIZE, "%d\n", fault ? 1 : 0); ++ return sysfs_emit(buf, "%d\n", fault ? 1 : 0); + } + + /* +--- a/drivers/hwmon/max16065.c ++++ b/drivers/hwmon/max16065.c +@@ -195,7 +195,7 @@ static ssize_t max16065_alarm_show(struc + i2c_smbus_write_byte_data(data->client, + MAX16065_FAULT(attr2->nr), val); + +- return snprintf(buf, PAGE_SIZE, "%d\n", !!val); ++ return sysfs_emit(buf, "%d\n", !!val); + } + + static ssize_t max16065_input_show(struct device *dev, +@@ -208,8 +208,8 @@ static ssize_t max16065_input_show(struc + if (unlikely(adc < 0)) + return adc; + +- return snprintf(buf, PAGE_SIZE, "%d\n", +- ADC_TO_MV(adc, data->range[attr->index])); ++ return sysfs_emit(buf, "%d\n", ++ ADC_TO_MV(adc, data->range[attr->index])); + } + + static ssize_t max16065_current_show(struct device *dev, +@@ -220,8 +220,8 @@ static ssize_t max16065_current_show(str + if (unlikely(data->curr_sense < 0)) + return data->curr_sense; + +- return snprintf(buf, PAGE_SIZE, "%d\n", +- ADC_TO_CURR(data->curr_sense, data->curr_gain)); ++ return sysfs_emit(buf, "%d\n", ++ ADC_TO_CURR(data->curr_sense, data->curr_gain)); + } + + static ssize_t max16065_limit_store(struct device *dev, +@@ -257,8 +257,8 @@ static ssize_t max16065_limit_show(struc + struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(da); + struct max16065_data *data = dev_get_drvdata(dev); + +- return snprintf(buf, PAGE_SIZE, "%d\n", +- data->limit[attr2->nr][attr2->index]); ++ return sysfs_emit(buf, "%d\n", ++ data->limit[attr2->nr][attr2->index]); + } + + /* Construct a sensor_device_attribute structure for each register */ +--- a/drivers/hwmon/occ/common.c ++++ b/drivers/hwmon/occ/common.c +@@ -261,7 +261,7 @@ static ssize_t occ_show_temp_1(struct de + return -EINVAL; + } + +- return snprintf(buf, PAGE_SIZE - 1, "%u\n", val); ++ return sysfs_emit(buf, "%u\n", val); + } + + static ssize_t occ_show_temp_2(struct device *dev, +@@ -312,7 +312,7 @@ static ssize_t occ_show_temp_2(struct de + return -EINVAL; + } + +- return snprintf(buf, PAGE_SIZE - 1, "%u\n", val); ++ return sysfs_emit(buf, "%u\n", val); + } + + static ssize_t occ_show_temp_10(struct device *dev, +@@ -359,7 +359,7 @@ static ssize_t occ_show_temp_10(struct d + return -EINVAL; + } + +- return snprintf(buf, PAGE_SIZE - 1, "%u\n", val); ++ return sysfs_emit(buf, "%u\n", val); + } + + static ssize_t occ_show_freq_1(struct device *dev, +@@ -389,7 +389,7 @@ static ssize_t occ_show_freq_1(struct de + return -EINVAL; + } + +- return snprintf(buf, PAGE_SIZE - 1, "%u\n", val); ++ return sysfs_emit(buf, "%u\n", val); + } + + static ssize_t occ_show_freq_2(struct device *dev, +@@ -419,7 +419,7 @@ static ssize_t occ_show_freq_2(struct de + return -EINVAL; + } + +- return snprintf(buf, PAGE_SIZE - 1, "%u\n", val); ++ return sysfs_emit(buf, "%u\n", val); + } + + static ssize_t occ_show_power_1(struct device *dev, +@@ -458,7 +458,7 @@ static ssize_t occ_show_power_1(struct d + return -EINVAL; + } + +- return snprintf(buf, PAGE_SIZE - 1, "%llu\n", val); ++ return sysfs_emit(buf, "%llu\n", val); + } + + static u64 occ_get_powr_avg(u64 accum, u32 samples) +@@ -485,9 +485,9 @@ static ssize_t occ_show_power_2(struct d + + switch (sattr->nr) { + case 0: +- return snprintf(buf, PAGE_SIZE - 1, "%u_%u_%u\n", +- get_unaligned_be32(&power->sensor_id), +- power->function_id, power->apss_channel); ++ return sysfs_emit(buf, "%u_%u_%u\n", ++ get_unaligned_be32(&power->sensor_id), ++ power->function_id, power->apss_channel); + case 1: + val = occ_get_powr_avg(get_unaligned_be64(&power->accumulator), + get_unaligned_be32(&power->update_tag)); +@@ -503,7 +503,7 @@ static ssize_t occ_show_power_2(struct d + return -EINVAL; + } + +- return snprintf(buf, PAGE_SIZE - 1, "%llu\n", val); ++ return sysfs_emit(buf, "%llu\n", val); + } + + static ssize_t occ_show_power_a0(struct device *dev, +@@ -524,8 +524,8 @@ static ssize_t occ_show_power_a0(struct + + switch (sattr->nr) { + case 0: +- return snprintf(buf, PAGE_SIZE - 1, "%u_system\n", +- get_unaligned_be32(&power->sensor_id)); ++ return sysfs_emit(buf, "%u_system\n", ++ get_unaligned_be32(&power->sensor_id)); + case 1: + val = occ_get_powr_avg(get_unaligned_be64(&power->system.accumulator), + get_unaligned_be32(&power->system.update_tag)); +@@ -538,8 +538,8 @@ static ssize_t occ_show_power_a0(struct + val = get_unaligned_be16(&power->system.value) * 1000000ULL; + break; + case 4: +- return snprintf(buf, PAGE_SIZE - 1, "%u_proc\n", +- get_unaligned_be32(&power->sensor_id)); ++ return sysfs_emit(buf, "%u_proc\n", ++ get_unaligned_be32(&power->sensor_id)); + case 5: + val = occ_get_powr_avg(get_unaligned_be64(&power->proc.accumulator), + get_unaligned_be32(&power->proc.update_tag)); +@@ -552,8 +552,8 @@ static ssize_t occ_show_power_a0(struct + val = get_unaligned_be16(&power->proc.value) * 1000000ULL; + break; + case 8: +- return snprintf(buf, PAGE_SIZE - 1, "%u_vdd\n", +- get_unaligned_be32(&power->sensor_id)); ++ return sysfs_emit(buf, "%u_vdd\n", ++ get_unaligned_be32(&power->sensor_id)); + case 9: + val = occ_get_powr_avg(get_unaligned_be64(&power->vdd.accumulator), + get_unaligned_be32(&power->vdd.update_tag)); +@@ -566,8 +566,8 @@ static ssize_t occ_show_power_a0(struct + val = get_unaligned_be16(&power->vdd.value) * 1000000ULL; + break; + case 12: +- return snprintf(buf, PAGE_SIZE - 1, "%u_vdn\n", +- get_unaligned_be32(&power->sensor_id)); ++ return sysfs_emit(buf, "%u_vdn\n", ++ get_unaligned_be32(&power->sensor_id)); + case 13: + val = occ_get_powr_avg(get_unaligned_be64(&power->vdn.accumulator), + get_unaligned_be32(&power->vdn.update_tag)); +@@ -583,7 +583,7 @@ static ssize_t occ_show_power_a0(struct + return -EINVAL; + } + +- return snprintf(buf, PAGE_SIZE - 1, "%llu\n", val); ++ return sysfs_emit(buf, "%llu\n", val); + } + + static ssize_t occ_show_caps_1_2(struct device *dev, +@@ -604,7 +604,7 @@ static ssize_t occ_show_caps_1_2(struct + + switch (sattr->nr) { + case 0: +- return snprintf(buf, PAGE_SIZE - 1, "system\n"); ++ return sysfs_emit(buf, "system\n"); + case 1: + val = get_unaligned_be16(&caps->cap) * 1000000ULL; + break; +@@ -633,7 +633,7 @@ static ssize_t occ_show_caps_1_2(struct + return -EINVAL; + } + +- return snprintf(buf, PAGE_SIZE - 1, "%llu\n", val); ++ return sysfs_emit(buf, "%llu\n", val); + } + + static ssize_t occ_show_caps_3(struct device *dev, +@@ -654,7 +654,7 @@ static ssize_t occ_show_caps_3(struct de + + switch (sattr->nr) { + case 0: +- return snprintf(buf, PAGE_SIZE - 1, "system\n"); ++ return sysfs_emit(buf, "system\n"); + case 1: + val = get_unaligned_be16(&caps->cap) * 1000000ULL; + break; +@@ -683,7 +683,7 @@ static ssize_t occ_show_caps_3(struct de + return -EINVAL; + } + +- return snprintf(buf, PAGE_SIZE - 1, "%llu\n", val); ++ return sysfs_emit(buf, "%llu\n", val); + } + + static ssize_t occ_store_caps_user(struct device *dev, +@@ -726,21 +726,22 @@ static ssize_t occ_show_extended(struct + + switch (sattr->nr) { + case 0: +- if (extn->flags & EXTN_FLAG_SENSOR_ID) +- rc = snprintf(buf, PAGE_SIZE - 1, "%u", +- get_unaligned_be32(&extn->sensor_id)); +- else +- rc = snprintf(buf, PAGE_SIZE - 1, "%02x%02x%02x%02x\n", +- extn->name[0], extn->name[1], +- extn->name[2], extn->name[3]); ++ if (extn->flags & EXTN_FLAG_SENSOR_ID) { ++ rc = sysfs_emit(buf, "%u", ++ get_unaligned_be32(&extn->sensor_id)); ++ } else { ++ rc = sysfs_emit(buf, "%02x%02x%02x%02x\n", ++ extn->name[0], extn->name[1], ++ extn->name[2], extn->name[3]); ++ } + break; + case 1: +- rc = snprintf(buf, PAGE_SIZE - 1, "%02x\n", extn->flags); ++ rc = sysfs_emit(buf, "%02x\n", extn->flags); + break; + case 2: +- rc = snprintf(buf, PAGE_SIZE - 1, "%02x%02x%02x%02x%02x%02x\n", +- extn->data[0], extn->data[1], extn->data[2], +- extn->data[3], extn->data[4], extn->data[5]); ++ rc = sysfs_emit(buf, "%02x%02x%02x%02x%02x%02x\n", ++ extn->data[0], extn->data[1], extn->data[2], ++ extn->data[3], extn->data[4], extn->data[5]); + break; + default: + return -EINVAL; +--- a/drivers/hwmon/occ/sysfs.c ++++ b/drivers/hwmon/occ/sysfs.c +@@ -67,7 +67,7 @@ static ssize_t occ_sysfs_show(struct dev + return -EINVAL; + } + +- return snprintf(buf, PAGE_SIZE - 1, "%d\n", val); ++ return sysfs_emit(buf, "%d\n", val); + } + + static ssize_t occ_error_show(struct device *dev, +@@ -77,7 +77,7 @@ static ssize_t occ_error_show(struct dev + + occ_update_response(occ); + +- return snprintf(buf, PAGE_SIZE - 1, "%d\n", occ->error); ++ return sysfs_emit(buf, "%d\n", occ->error); + } + + static SENSOR_DEVICE_ATTR(occ_master, 0444, occ_sysfs_show, NULL, 0); +--- a/drivers/hwmon/pmbus/inspur-ipsps.c ++++ b/drivers/hwmon/pmbus/inspur-ipsps.c +@@ -70,7 +70,7 @@ static ssize_t ipsps_string_show(struct + p = memscan(data, '#', rc); + *p = '\0'; + +- return snprintf(buf, PAGE_SIZE, "%s\n", data); ++ return sysfs_emit(buf, "%s\n", data); + } + + static ssize_t ipsps_fw_version_show(struct device *dev, +@@ -91,9 +91,9 @@ static ssize_t ipsps_fw_version_show(str + if (rc != 6) + return -EPROTO; + +- return snprintf(buf, PAGE_SIZE, "%u.%02u%u-%u.%02u\n", +- data[1], data[2]/* < 100 */, data[3]/*< 10*/, +- data[4], data[5]/* < 100 */); ++ return sysfs_emit(buf, "%u.%02u%u-%u.%02u\n", ++ data[1], data[2]/* < 100 */, data[3]/*< 10*/, ++ data[4], data[5]/* < 100 */); + } + + static ssize_t ipsps_mode_show(struct device *dev, +@@ -111,19 +111,19 @@ static ssize_t ipsps_mode_show(struct de + + switch (rc) { + case MODE_ACTIVE: +- return snprintf(buf, PAGE_SIZE, "[%s] %s %s\n", +- MODE_ACTIVE_STRING, +- MODE_STANDBY_STRING, MODE_REDUNDANCY_STRING); ++ return sysfs_emit(buf, "[%s] %s %s\n", ++ MODE_ACTIVE_STRING, ++ MODE_STANDBY_STRING, MODE_REDUNDANCY_STRING); + case MODE_STANDBY: +- return snprintf(buf, PAGE_SIZE, "%s [%s] %s\n", +- MODE_ACTIVE_STRING, +- MODE_STANDBY_STRING, MODE_REDUNDANCY_STRING); ++ return sysfs_emit(buf, "%s [%s] %s\n", ++ MODE_ACTIVE_STRING, ++ MODE_STANDBY_STRING, MODE_REDUNDANCY_STRING); + case MODE_REDUNDANCY: +- return snprintf(buf, PAGE_SIZE, "%s %s [%s]\n", +- MODE_ACTIVE_STRING, +- MODE_STANDBY_STRING, MODE_REDUNDANCY_STRING); ++ return sysfs_emit(buf, "%s %s [%s]\n", ++ MODE_ACTIVE_STRING, ++ MODE_STANDBY_STRING, MODE_REDUNDANCY_STRING); + default: +- return snprintf(buf, PAGE_SIZE, "unspecified\n"); ++ return sysfs_emit(buf, "unspecified\n"); + } + } + +--- a/drivers/hwmon/pmbus/pmbus_core.c ++++ b/drivers/hwmon/pmbus/pmbus_core.c +@@ -962,7 +962,7 @@ static ssize_t pmbus_show_boolean(struct + val = pmbus_get_boolean(client, boolean, attr->index); + if (val < 0) + return val; +- return snprintf(buf, PAGE_SIZE, "%d\n", val); ++ return sysfs_emit(buf, "%d\n", val); + } + + static ssize_t pmbus_show_sensor(struct device *dev, +@@ -978,7 +978,7 @@ static ssize_t pmbus_show_sensor(struct + if (sensor->data < 0) + ret = sensor->data; + else +- ret = snprintf(buf, PAGE_SIZE, "%lld\n", pmbus_reg2data(data, sensor)); ++ ret = sysfs_emit(buf, "%lld\n", pmbus_reg2data(data, sensor)); + mutex_unlock(&data->update_lock); + return ret; + } +@@ -1014,7 +1014,7 @@ static ssize_t pmbus_show_label(struct d + { + struct pmbus_label *label = to_pmbus_label(da); + +- return snprintf(buf, PAGE_SIZE, "%s\n", label->label); ++ return sysfs_emit(buf, "%s\n", label->label); + } + + static int pmbus_add_attribute(struct pmbus_data *data, struct attribute *attr) +@@ -2054,7 +2054,7 @@ static ssize_t pmbus_show_samples(struct + if (val < 0) + return val; + +- return snprintf(buf, PAGE_SIZE, "%d\n", val); ++ return sysfs_emit(buf, "%d\n", val); + } + + static ssize_t pmbus_set_samples(struct device *dev, +--- a/drivers/hwmon/s3c-hwmon.c ++++ b/drivers/hwmon/s3c-hwmon.c +@@ -166,7 +166,7 @@ static ssize_t s3c_hwmon_ch_show(struct + ret *= cfg->mult; + ret = DIV_ROUND_CLOSEST(ret, cfg->div); + +- return snprintf(buf, PAGE_SIZE, "%d\n", ret); ++ return sysfs_emit(buf, "%d\n", ret); + } + + /** +@@ -187,7 +187,7 @@ static ssize_t s3c_hwmon_label_show(stru + + cfg = pdata->in[sen_attr->index]; + +- return snprintf(buf, PAGE_SIZE, "%s\n", cfg->name); ++ return sysfs_emit(buf, "%s\n", cfg->name); + } + + /** +--- a/drivers/hwmon/sch5627.c ++++ b/drivers/hwmon/sch5627.c +@@ -195,7 +195,7 @@ static int reg_to_rpm(u16 reg) + static ssize_t name_show(struct device *dev, struct device_attribute *devattr, + char *buf) + { +- return snprintf(buf, PAGE_SIZE, "%s\n", DEVNAME); ++ return sysfs_emit(buf, "%s\n", DEVNAME); + } + + static ssize_t temp_show(struct device *dev, struct device_attribute *devattr, +@@ -209,7 +209,7 @@ static ssize_t temp_show(struct device * + return PTR_ERR(data); + + val = reg_to_temp(data->temp[attr->index]); +- return snprintf(buf, PAGE_SIZE, "%d\n", val); ++ return sysfs_emit(buf, "%d\n", val); + } + + static ssize_t temp_fault_show(struct device *dev, +@@ -221,7 +221,7 @@ static ssize_t temp_fault_show(struct de + if (IS_ERR(data)) + return PTR_ERR(data); + +- return snprintf(buf, PAGE_SIZE, "%d\n", data->temp[attr->index] == 0); ++ return sysfs_emit(buf, "%d\n", data->temp[attr->index] == 0); + } + + static ssize_t temp_max_show(struct device *dev, +@@ -232,7 +232,7 @@ static ssize_t temp_max_show(struct devi + int val; + + val = reg_to_temp_limit(data->temp_max[attr->index]); +- return snprintf(buf, PAGE_SIZE, "%d\n", val); ++ return sysfs_emit(buf, "%d\n", val); + } + + static ssize_t temp_crit_show(struct device *dev, +@@ -243,7 +243,7 @@ static ssize_t temp_crit_show(struct dev + int val; + + val = reg_to_temp_limit(data->temp_crit[attr->index]); +- return snprintf(buf, PAGE_SIZE, "%d\n", val); ++ return sysfs_emit(buf, "%d\n", val); + } + + static ssize_t fan_show(struct device *dev, struct device_attribute *devattr, +@@ -260,7 +260,7 @@ static ssize_t fan_show(struct device *d + if (val < 0) + return val; + +- return snprintf(buf, PAGE_SIZE, "%d\n", val); ++ return sysfs_emit(buf, "%d\n", val); + } + + static ssize_t fan_fault_show(struct device *dev, +@@ -272,8 +272,8 @@ static ssize_t fan_fault_show(struct dev + if (IS_ERR(data)) + return PTR_ERR(data); + +- return snprintf(buf, PAGE_SIZE, "%d\n", +- data->fan[attr->index] == 0xffff); ++ return sysfs_emit(buf, "%d\n", ++ data->fan[attr->index] == 0xffff); + } + + static ssize_t fan_min_show(struct device *dev, +@@ -285,7 +285,7 @@ static ssize_t fan_min_show(struct devic + if (val < 0) + return val; + +- return snprintf(buf, PAGE_SIZE, "%d\n", val); ++ return sysfs_emit(buf, "%d\n", val); + } + + static ssize_t in_show(struct device *dev, struct device_attribute *devattr, +@@ -301,7 +301,7 @@ static ssize_t in_show(struct device *de + val = DIV_ROUND_CLOSEST( + data->in[attr->index] * SCH5627_REG_IN_FACTOR[attr->index], + 10000); +- return snprintf(buf, PAGE_SIZE, "%d\n", val); ++ return sysfs_emit(buf, "%d\n", val); + } + + static ssize_t in_label_show(struct device *dev, +@@ -309,8 +309,8 @@ static ssize_t in_label_show(struct devi + { + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + +- return snprintf(buf, PAGE_SIZE, "%s\n", +- SCH5627_IN_LABELS[attr->index]); ++ return sysfs_emit(buf, "%s\n", ++ SCH5627_IN_LABELS[attr->index]); + } + + static DEVICE_ATTR_RO(name); +--- a/drivers/hwmon/sch5636.c ++++ b/drivers/hwmon/sch5636.c +@@ -160,7 +160,7 @@ static int reg_to_rpm(u16 reg) + static ssize_t name_show(struct device *dev, struct device_attribute *devattr, + char *buf) + { +- return snprintf(buf, PAGE_SIZE, "%s\n", DEVNAME); ++ return sysfs_emit(buf, "%s\n", DEVNAME); + } + + static ssize_t in_value_show(struct device *dev, +@@ -176,7 +176,7 @@ static ssize_t in_value_show(struct devi + val = DIV_ROUND_CLOSEST( + data->in[attr->index] * SCH5636_REG_IN_FACTORS[attr->index], + 255); +- return snprintf(buf, PAGE_SIZE, "%d\n", val); ++ return sysfs_emit(buf, "%d\n", val); + } + + static ssize_t in_label_show(struct device *dev, +@@ -184,8 +184,8 @@ static ssize_t in_label_show(struct devi + { + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + +- return snprintf(buf, PAGE_SIZE, "%s\n", +- SCH5636_IN_LABELS[attr->index]); ++ return sysfs_emit(buf, "%s\n", ++ SCH5636_IN_LABELS[attr->index]); + } + + static ssize_t temp_value_show(struct device *dev, +@@ -199,7 +199,7 @@ static ssize_t temp_value_show(struct de + return PTR_ERR(data); + + val = (data->temp_val[attr->index] - 64) * 1000; +- return snprintf(buf, PAGE_SIZE, "%d\n", val); ++ return sysfs_emit(buf, "%d\n", val); + } + + static ssize_t temp_fault_show(struct device *dev, +@@ -213,7 +213,7 @@ static ssize_t temp_fault_show(struct de + return PTR_ERR(data); + + val = (data->temp_ctrl[attr->index] & SCH5636_TEMP_WORKING) ? 0 : 1; +- return snprintf(buf, PAGE_SIZE, "%d\n", val); ++ return sysfs_emit(buf, "%d\n", val); + } + + static ssize_t temp_alarm_show(struct device *dev, +@@ -227,7 +227,7 @@ static ssize_t temp_alarm_show(struct de + return PTR_ERR(data); + + val = (data->temp_ctrl[attr->index] & SCH5636_TEMP_ALARM) ? 1 : 0; +- return snprintf(buf, PAGE_SIZE, "%d\n", val); ++ return sysfs_emit(buf, "%d\n", val); + } + + static ssize_t fan_value_show(struct device *dev, +@@ -244,7 +244,7 @@ static ssize_t fan_value_show(struct dev + if (val < 0) + return val; + +- return snprintf(buf, PAGE_SIZE, "%d\n", val); ++ return sysfs_emit(buf, "%d\n", val); + } + + static ssize_t fan_fault_show(struct device *dev, +@@ -258,7 +258,7 @@ static ssize_t fan_fault_show(struct dev + return PTR_ERR(data); + + val = (data->fan_ctrl[attr->index] & SCH5636_FAN_NOT_PRESENT) ? 1 : 0; +- return snprintf(buf, PAGE_SIZE, "%d\n", val); ++ return sysfs_emit(buf, "%d\n", val); + } + + static ssize_t fan_alarm_show(struct device *dev, +@@ -272,7 +272,7 @@ static ssize_t fan_alarm_show(struct dev + return PTR_ERR(data); + + val = (data->fan_ctrl[attr->index] & SCH5636_FAN_ALARM) ? 1 : 0; +- return snprintf(buf, PAGE_SIZE, "%d\n", val); ++ return sysfs_emit(buf, "%d\n", val); + } + + static struct sensor_device_attribute sch5636_attr[] = { +--- a/drivers/hwmon/smm665.c ++++ b/drivers/hwmon/smm665.c +@@ -351,7 +351,7 @@ static ssize_t smm665_show_crit_alarm(st + if (data->faults & (1 << attr->index)) + val = 1; + +- return snprintf(buf, PAGE_SIZE, "%d\n", val); ++ return sysfs_emit(buf, "%d\n", val); + } + + static ssize_t smm665_show_input(struct device *dev, +@@ -366,7 +366,7 @@ static ssize_t smm665_show_input(struct + return PTR_ERR(data); + + val = smm665_convert(data->adc[adc], adc); +- return snprintf(buf, PAGE_SIZE, "%d\n", val); ++ return sysfs_emit(buf, "%d\n", val); + } + + #define SMM665_SHOW(what) \ +--- a/drivers/hwmon/stts751.c ++++ b/drivers/hwmon/stts751.c +@@ -387,7 +387,7 @@ static ssize_t max_alarm_show(struct dev + if (ret < 0) + return ret; + +- return snprintf(buf, PAGE_SIZE, "%d\n", priv->max_alert); ++ return sysfs_emit(buf, "%d\n", priv->max_alert); + } + + static ssize_t min_alarm_show(struct device *dev, +@@ -404,7 +404,7 @@ static ssize_t min_alarm_show(struct dev + if (ret < 0) + return ret; + +- return snprintf(buf, PAGE_SIZE, "%d\n", priv->min_alert); ++ return sysfs_emit(buf, "%d\n", priv->min_alert); + } + + static ssize_t input_show(struct device *dev, struct device_attribute *attr, +@@ -419,7 +419,7 @@ static ssize_t input_show(struct device + if (ret < 0) + return ret; + +- return snprintf(buf, PAGE_SIZE, "%d\n", priv->temp); ++ return sysfs_emit(buf, "%d\n", priv->temp); + } + + static ssize_t therm_show(struct device *dev, struct device_attribute *attr, +@@ -427,7 +427,7 @@ static ssize_t therm_show(struct device + { + struct stts751_priv *priv = dev_get_drvdata(dev); + +- return snprintf(buf, PAGE_SIZE, "%d\n", priv->therm); ++ return sysfs_emit(buf, "%d\n", priv->therm); + } + + static ssize_t therm_store(struct device *dev, struct device_attribute *attr, +@@ -469,7 +469,7 @@ static ssize_t hyst_show(struct device * + { + struct stts751_priv *priv = dev_get_drvdata(dev); + +- return snprintf(buf, PAGE_SIZE, "%d\n", priv->hyst); ++ return sysfs_emit(buf, "%d\n", priv->hyst); + } + + static ssize_t hyst_store(struct device *dev, struct device_attribute *attr, +@@ -509,7 +509,7 @@ static ssize_t therm_trip_show(struct de + if (ret < 0) + return ret; + +- return snprintf(buf, PAGE_SIZE, "%d\n", priv->therm_trip); ++ return sysfs_emit(buf, "%d\n", priv->therm_trip); + } + + static ssize_t max_show(struct device *dev, struct device_attribute *attr, +@@ -517,7 +517,7 @@ static ssize_t max_show(struct device *d + { + struct stts751_priv *priv = dev_get_drvdata(dev); + +- return snprintf(buf, PAGE_SIZE, "%d\n", priv->event_max); ++ return sysfs_emit(buf, "%d\n", priv->event_max); + } + + static ssize_t max_store(struct device *dev, struct device_attribute *attr, +@@ -551,7 +551,7 @@ static ssize_t min_show(struct device *d + { + struct stts751_priv *priv = dev_get_drvdata(dev); + +- return snprintf(buf, PAGE_SIZE, "%d\n", priv->event_min); ++ return sysfs_emit(buf, "%d\n", priv->event_min); + } + + static ssize_t min_store(struct device *dev, struct device_attribute *attr, +@@ -585,8 +585,8 @@ static ssize_t interval_show(struct devi + { + struct stts751_priv *priv = dev_get_drvdata(dev); + +- return snprintf(buf, PAGE_SIZE, "%d\n", +- stts751_intervals[priv->interval]); ++ return sysfs_emit(buf, "%d\n", ++ stts751_intervals[priv->interval]); + } + + static ssize_t interval_store(struct device *dev, +--- a/drivers/hwmon/vexpress-hwmon.c ++++ b/drivers/hwmon/vexpress-hwmon.c +@@ -27,7 +27,7 @@ static ssize_t vexpress_hwmon_label_show + { + const char *label = of_get_property(dev->of_node, "label", NULL); + +- return snprintf(buffer, PAGE_SIZE, "%s\n", label); ++ return sysfs_emit(buffer, "%s\n", label); + } + + static ssize_t vexpress_hwmon_u32_show(struct device *dev, +@@ -41,8 +41,8 @@ static ssize_t vexpress_hwmon_u32_show(s + if (err) + return err; + +- return snprintf(buffer, PAGE_SIZE, "%u\n", value / +- to_sensor_dev_attr(dev_attr)->index); ++ return sysfs_emit(buffer, "%u\n", value / ++ to_sensor_dev_attr(dev_attr)->index); + } + + static ssize_t vexpress_hwmon_u64_show(struct device *dev, +@@ -60,9 +60,9 @@ static ssize_t vexpress_hwmon_u64_show(s + if (err) + return err; + +- return snprintf(buffer, PAGE_SIZE, "%llu\n", +- div_u64(((u64)value_hi << 32) | value_lo, +- to_sensor_dev_attr(dev_attr)->index)); ++ return sysfs_emit(buffer, "%llu\n", ++ div_u64(((u64)value_hi << 32) | value_lo, ++ to_sensor_dev_attr(dev_attr)->index)); + } + + static umode_t vexpress_hwmon_attr_is_visible(struct kobject *kobj, +--- a/drivers/hwmon/xgene-hwmon.c ++++ b/drivers/hwmon/xgene-hwmon.c +@@ -329,14 +329,14 @@ static ssize_t temp1_input_show(struct d + + temp = sign_extend32(val, TEMP_NEGATIVE_BIT); + +- return snprintf(buf, PAGE_SIZE, "%d\n", CELSIUS_TO_mCELSIUS(temp)); ++ return sysfs_emit(buf, "%d\n", CELSIUS_TO_mCELSIUS(temp)); + } + + static ssize_t temp1_label_show(struct device *dev, + struct device_attribute *attr, + char *buf) + { +- return snprintf(buf, PAGE_SIZE, "SoC Temperature\n"); ++ return sysfs_emit(buf, "SoC Temperature\n"); + } + + static ssize_t temp1_critical_alarm_show(struct device *dev, +@@ -345,21 +345,21 @@ static ssize_t temp1_critical_alarm_show + { + struct xgene_hwmon_dev *ctx = dev_get_drvdata(dev); + +- return snprintf(buf, PAGE_SIZE, "%d\n", ctx->temp_critical_alarm); ++ return sysfs_emit(buf, "%d\n", ctx->temp_critical_alarm); + } + + static ssize_t power1_label_show(struct device *dev, + struct device_attribute *attr, + char *buf) + { +- return snprintf(buf, PAGE_SIZE, "CPU power\n"); ++ return sysfs_emit(buf, "CPU power\n"); + } + + static ssize_t power2_label_show(struct device *dev, + struct device_attribute *attr, + char *buf) + { +- return snprintf(buf, PAGE_SIZE, "IO power\n"); ++ return sysfs_emit(buf, "IO power\n"); + } + + static ssize_t power1_input_show(struct device *dev, +@@ -374,7 +374,7 @@ static ssize_t power1_input_show(struct + if (rc < 0) + return rc; + +- return snprintf(buf, PAGE_SIZE, "%u\n", mWATT_TO_uWATT(val)); ++ return sysfs_emit(buf, "%u\n", mWATT_TO_uWATT(val)); + } + + static ssize_t power2_input_show(struct device *dev, +@@ -389,7 +389,7 @@ static ssize_t power2_input_show(struct + if (rc < 0) + return rc; + +- return snprintf(buf, PAGE_SIZE, "%u\n", mWATT_TO_uWATT(val)); ++ return sysfs_emit(buf, "%u\n", mWATT_TO_uWATT(val)); + } + + static DEVICE_ATTR_RO(temp1_label); diff --git a/queue-5.10/iommu-qcom-fix-device-leak-on-of_xlate.patch b/queue-5.10/iommu-qcom-fix-device-leak-on-of_xlate.patch new file mode 100644 index 0000000000..20c91f9ee1 --- /dev/null +++ b/queue-5.10/iommu-qcom-fix-device-leak-on-of_xlate.patch @@ -0,0 +1,66 @@ +From stable+bounces-204849-greg=kroah.com@vger.kernel.org Mon Jan 5 17:22:34 2026 +From: Sasha Levin +Date: Mon, 5 Jan 2026 11:22:27 -0500 +Subject: iommu/qcom: fix device leak on of_xlate() +To: stable@vger.kernel.org +Cc: Johan Hovold , Rob Clark , Yu Kuai , Robin Murphy , Joerg Roedel , Sasha Levin +Message-ID: <20260105162227.2665126-1-sashal@kernel.org> + +From: Johan Hovold + +[ Upstream commit 6a3908ce56e6879920b44ef136252b2f0c954194 ] + +Make sure to drop the reference taken to the iommu platform device when +looking up its driver data during of_xlate(). + +Note that commit e2eae09939a8 ("iommu/qcom: add missing put_device() +call in qcom_iommu_of_xlate()") fixed the leak in a couple of error +paths, but the reference is still leaking on success and late failures. + +Fixes: 0ae349a0f33f ("iommu/qcom: Add qcom_iommu") +Cc: stable@vger.kernel.org # 4.14: e2eae09939a8 +Cc: Rob Clark +Cc: Yu Kuai +Acked-by: Robin Murphy +Signed-off-by: Johan Hovold +Signed-off-by: Joerg Roedel +[ adapted validation logic from max_asid to num_ctxs ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iommu/arm/arm-smmu/qcom_iommu.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c ++++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c +@@ -586,15 +586,15 @@ static int qcom_iommu_of_xlate(struct de + + qcom_iommu = platform_get_drvdata(iommu_pdev); + ++ put_device(&iommu_pdev->dev); ++ + /* make sure the asid specified in dt is valid, so we don't have + * to sanity check this elsewhere, since 'asid - 1' is used to + * index into qcom_iommu->ctxs: + */ + if (WARN_ON(asid < 1) || +- WARN_ON(asid > qcom_iommu->num_ctxs)) { +- put_device(&iommu_pdev->dev); ++ WARN_ON(asid > qcom_iommu->num_ctxs)) + return -EINVAL; +- } + + if (!dev_iommu_priv_get(dev)) { + dev_iommu_priv_set(dev, qcom_iommu); +@@ -603,10 +603,8 @@ static int qcom_iommu_of_xlate(struct de + * multiple different iommu devices. Multiple context + * banks are ok, but multiple devices are not: + */ +- if (WARN_ON(qcom_iommu != dev_iommu_priv_get(dev))) { +- put_device(&iommu_pdev->dev); ++ if (WARN_ON(qcom_iommu != dev_iommu_priv_get(dev))) + return -EINVAL; +- } + } + + return iommu_fwspec_add_ids(dev, &asid, 1); diff --git a/queue-5.10/ipv4-fix-uninit-value-access-in-__ip_make_skb.patch b/queue-5.10/ipv4-fix-uninit-value-access-in-__ip_make_skb.patch new file mode 100644 index 0000000000..c91fbcb672 --- /dev/null +++ b/queue-5.10/ipv4-fix-uninit-value-access-in-__ip_make_skb.patch @@ -0,0 +1,106 @@ +From stable+bounces-203406-greg=kroah.com@vger.kernel.org Thu Dec 25 16:53:56 2025 +From: skulkarni@mvista.com +Date: Thu, 25 Dec 2025 21:22:37 +0530 +Subject: ipv4: Fix uninit-value access in __ip_make_skb() +To: stable@vger.kernel.org +Cc: Shigeru Yoshida , syzkaller , Paolo Abeni , Shubham Kulkarni +Message-ID: <20251225155236.1881304-1-skulkarni@mvista.com> + +From: Shigeru Yoshida + +commit fc1092f51567277509563800a3c56732070b6aa4 upstream. + +KMSAN reported uninit-value access in __ip_make_skb() [1]. __ip_make_skb() +tests HDRINCL to know if the skb has icmphdr. However, HDRINCL can cause a +race condition. If calling setsockopt(2) with IP_HDRINCL changes HDRINCL +while __ip_make_skb() is running, the function will access icmphdr in the +skb even if it is not included. This causes the issue reported by KMSAN. + +Check FLOWI_FLAG_KNOWN_NH on fl4->flowi4_flags instead of testing HDRINCL +on the socket. + +Also, fl4->fl4_icmp_type and fl4->fl4_icmp_code are not initialized. These +are union in struct flowi4 and are implicitly initialized by +flowi4_init_output(), but we should not rely on specific union layout. + +Initialize these explicitly in raw_sendmsg(). + +[1] +BUG: KMSAN: uninit-value in __ip_make_skb+0x2b74/0x2d20 net/ipv4/ip_output.c:1481 + __ip_make_skb+0x2b74/0x2d20 net/ipv4/ip_output.c:1481 + ip_finish_skb include/net/ip.h:243 [inline] + ip_push_pending_frames+0x4c/0x5c0 net/ipv4/ip_output.c:1508 + raw_sendmsg+0x2381/0x2690 net/ipv4/raw.c:654 + inet_sendmsg+0x27b/0x2a0 net/ipv4/af_inet.c:851 + sock_sendmsg_nosec net/socket.c:730 [inline] + __sock_sendmsg+0x274/0x3c0 net/socket.c:745 + __sys_sendto+0x62c/0x7b0 net/socket.c:2191 + __do_sys_sendto net/socket.c:2203 [inline] + __se_sys_sendto net/socket.c:2199 [inline] + __x64_sys_sendto+0x130/0x200 net/socket.c:2199 + do_syscall_64+0xd8/0x1f0 arch/x86/entry/common.c:83 + entry_SYSCALL_64_after_hwframe+0x6d/0x75 + +Uninit was created at: + slab_post_alloc_hook mm/slub.c:3804 [inline] + slab_alloc_node mm/slub.c:3845 [inline] + kmem_cache_alloc_node+0x5f6/0xc50 mm/slub.c:3888 + kmalloc_reserve+0x13c/0x4a0 net/core/skbuff.c:577 + __alloc_skb+0x35a/0x7c0 net/core/skbuff.c:668 + alloc_skb include/linux/skbuff.h:1318 [inline] + __ip_append_data+0x49ab/0x68c0 net/ipv4/ip_output.c:1128 + ip_append_data+0x1e7/0x260 net/ipv4/ip_output.c:1365 + raw_sendmsg+0x22b1/0x2690 net/ipv4/raw.c:648 + inet_sendmsg+0x27b/0x2a0 net/ipv4/af_inet.c:851 + sock_sendmsg_nosec net/socket.c:730 [inline] + __sock_sendmsg+0x274/0x3c0 net/socket.c:745 + __sys_sendto+0x62c/0x7b0 net/socket.c:2191 + __do_sys_sendto net/socket.c:2203 [inline] + __se_sys_sendto net/socket.c:2199 [inline] + __x64_sys_sendto+0x130/0x200 net/socket.c:2199 + do_syscall_64+0xd8/0x1f0 arch/x86/entry/common.c:83 + entry_SYSCALL_64_after_hwframe+0x6d/0x75 + +CPU: 1 PID: 15709 Comm: syz-executor.7 Not tainted 6.8.0-11567-gb3603fcb79b1 #25 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-1.fc39 04/01/2014 + +Fixes: 99e5acae193e ("ipv4: Fix potential uninit variable access bug in __ip_make_skb()") +Reported-by: syzkaller +Signed-off-by: Shigeru Yoshida +Link: https://lore.kernel.org/r/20240430123945.2057348-1-syoshida@redhat.com +Signed-off-by: Paolo Abeni +Signed-off-by: Shubham Kulkarni +Signed-off-by: Greg Kroah-Hartman +--- +Referred stable v6.1.y version of the patch to generate this one + [ v6.1 link: https://github.com/gregkh/linux/commit/55bf541e018b76b3750cb6c6ea18c46e1ac5562e ] +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/ip_output.c | 3 ++- + net/ipv4/raw.c | 3 +++ + 2 files changed, 5 insertions(+), 1 deletion(-) + +--- a/net/ipv4/ip_output.c ++++ b/net/ipv4/ip_output.c +@@ -1572,7 +1572,8 @@ struct sk_buff *__ip_make_skb(struct soc + * so icmphdr does not in skb linear region and can not get icmp_type + * by icmp_hdr(skb)->type. + */ +- if (sk->sk_type == SOCK_RAW && !inet_sk(sk)->hdrincl) ++ if (sk->sk_type == SOCK_RAW && ++ !(fl4->flowi4_flags & FLOWI_FLAG_KNOWN_NH)) + icmp_type = fl4->fl4_icmp_type; + else + icmp_type = icmp_hdr(skb)->type; +--- a/net/ipv4/raw.c ++++ b/net/ipv4/raw.c +@@ -634,6 +634,9 @@ static int raw_sendmsg(struct sock *sk, + (hdrincl ? FLOWI_FLAG_KNOWN_NH : 0), + daddr, saddr, 0, 0, sk->sk_uid); + ++ fl4.fl4_icmp_type = 0; ++ fl4.fl4_icmp_code = 0; ++ + if (!hdrincl) { + rfv.msg = msg; + rfv.hlen = 0; diff --git a/queue-5.10/ipv6-fix-potential-uninit-value-access-in-__ip6_make_skb.patch b/queue-5.10/ipv6-fix-potential-uninit-value-access-in-__ip6_make_skb.patch new file mode 100644 index 0000000000..59724af8c6 --- /dev/null +++ b/queue-5.10/ipv6-fix-potential-uninit-value-access-in-__ip6_make_skb.patch @@ -0,0 +1,42 @@ +From stable+bounces-203330-greg=kroah.com@vger.kernel.org Tue Dec 23 19:54:34 2025 +From: skulkarni@mvista.com +Date: Wed, 24 Dec 2025 00:23:41 +0530 +Subject: ipv6: Fix potential uninit-value access in __ip6_make_skb() +To: stable@vger.kernel.org +Cc: Shigeru Yoshida , "David S . Miller" , Shubham Kulkarni +Message-ID: <20251223185341.1850880-1-skulkarni@mvista.com> + +From: Shigeru Yoshida + +commit 4e13d3a9c25b7080f8a619f961e943fe08c2672c upstream. + +As it was done in commit fc1092f51567 ("ipv4: Fix uninit-value access in +__ip_make_skb()") for IPv4, check FLOWI_FLAG_KNOWN_NH on fl6->flowi6_flags +instead of testing HDRINCL on the socket to avoid a race condition which +causes uninit-value access. + +Fixes: ea30388baebc ("ipv6: Fix an uninit variable access bug in __ip6_make_skb()") +Signed-off-by: Shigeru Yoshida +Signed-off-by: David S. Miller +Signed-off-by: Shubham Kulkarni +Signed-off-by: Greg Kroah-Hartman +--- +Referred stable v6.1.y version of the patch to generate this one + [ v6.1 link: https://github.com/gregkh/linux/commit/a05c1ede50e9656f0752e523c7b54f3a3489e9a8 ] +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/ip6_output.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -1917,7 +1917,8 @@ struct sk_buff *__ip6_make_skb(struct so + struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb)); + u8 icmp6_type; + +- if (sk->sk_socket->type == SOCK_RAW && !inet_sk(sk)->hdrincl) ++ if (sk->sk_socket->type == SOCK_RAW && ++ !(fl6->flowi6_flags & FLOWI_FLAG_KNOWN_NH)) + icmp6_type = fl6->fl6_icmp_type; + else + icmp6_type = icmp6_hdr(skb)->icmp6_type; diff --git a/queue-5.10/jbd2-fix-the-inconsistency-between-checksum-and-data-in-memory-for-journal-sb.patch b/queue-5.10/jbd2-fix-the-inconsistency-between-checksum-and-data-in-memory-for-journal-sb.patch new file mode 100644 index 0000000000..e916242d8f --- /dev/null +++ b/queue-5.10/jbd2-fix-the-inconsistency-between-checksum-and-data-in-memory-for-journal-sb.patch @@ -0,0 +1,94 @@ +From stable+bounces-204163-greg=kroah.com@vger.kernel.org Tue Dec 30 02:06:46 2025 +From: Sasha Levin +Date: Mon, 29 Dec 2025 20:06:38 -0500 +Subject: jbd2: fix the inconsistency between checksum and data in memory for journal sb +To: stable@vger.kernel.org +Cc: Ye Bin , Baokun Li , "Darrick J. Wong" , Jan Kara , Theodore Ts'o , stable@kernel.org, Sasha Levin +Message-ID: <20251230010638.1905408-1-sashal@kernel.org> + +From: Ye Bin + +[ Upstream commit 6abfe107894af7e8ce3a2e120c619d81ee764ad5 ] + +Copying the file system while it is mounted as read-only results in +a mount failure: +[~]# mkfs.ext4 -F /dev/sdc +[~]# mount /dev/sdc -o ro /mnt/test +[~]# dd if=/dev/sdc of=/dev/sda bs=1M +[~]# mount /dev/sda /mnt/test1 +[ 1094.849826] JBD2: journal checksum error +[ 1094.850927] EXT4-fs (sda): Could not load journal inode +mount: mount /dev/sda on /mnt/test1 failed: Bad message + +The process described above is just an abstracted way I came up with to +reproduce the issue. In the actual scenario, the file system was mounted +read-only and then copied while it was still mounted. It was found that +the mount operation failed. The user intended to verify the data or use +it as a backup, and this action was performed during a version upgrade. +Above issue may happen as follows: +ext4_fill_super + set_journal_csum_feature_set(sb) + if (ext4_has_metadata_csum(sb)) + incompat = JBD2_FEATURE_INCOMPAT_CSUM_V3; + if (test_opt(sb, JOURNAL_CHECKSUM) + jbd2_journal_set_features(sbi->s_journal, compat, 0, incompat); + lock_buffer(journal->j_sb_buffer); + sb->s_feature_incompat |= cpu_to_be32(incompat); + //The data in the journal sb was modified, but the checksum was not + updated, so the data remaining in memory has a mismatch between the + data and the checksum. + unlock_buffer(journal->j_sb_buffer); + +In this case, the journal sb copied over is in a state where the checksum +and data are inconsistent, so mounting fails. +To solve the above issue, update the checksum in memory after modifying +the journal sb. + +Fixes: 4fd5ea43bc11 ("jbd2: checksum journal superblock") +Signed-off-by: Ye Bin +Reviewed-by: Baokun Li +Reviewed-by: Darrick J. Wong +Reviewed-by: Jan Kara +Message-ID: <20251103010123.3753631-1-yebin@huaweicloud.com> +Signed-off-by: Theodore Ts'o +Cc: stable@kernel.org +[ Changed jbd2_superblock_csum(sb) to jbd2_superblock_csum(journal, sb) ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + fs/jbd2/journal.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +--- a/fs/jbd2/journal.c ++++ b/fs/jbd2/journal.c +@@ -2224,6 +2224,12 @@ int jbd2_journal_set_features(journal_t + sb->s_feature_compat |= cpu_to_be32(compat); + sb->s_feature_ro_compat |= cpu_to_be32(ro); + sb->s_feature_incompat |= cpu_to_be32(incompat); ++ /* ++ * Update the checksum now so that it is valid even for read-only ++ * filesystems where jbd2_write_superblock() doesn't get called. ++ */ ++ if (jbd2_journal_has_csum_v2or3(journal)) ++ sb->s_checksum = jbd2_superblock_csum(journal, sb); + unlock_buffer(journal->j_sb_buffer); + journal->j_revoke_records_per_block = + journal_revoke_records_per_block(journal); +@@ -2254,9 +2260,17 @@ void jbd2_journal_clear_features(journal + + sb = journal->j_superblock; + ++ lock_buffer(journal->j_sb_buffer); + sb->s_feature_compat &= ~cpu_to_be32(compat); + sb->s_feature_ro_compat &= ~cpu_to_be32(ro); + sb->s_feature_incompat &= ~cpu_to_be32(incompat); ++ /* ++ * Update the checksum now so that it is valid even for read-only ++ * filesystems where jbd2_write_superblock() doesn't get called. ++ */ ++ if (jbd2_journal_has_csum_v2or3(journal)) ++ sb->s_checksum = jbd2_superblock_csum(journal, sb); ++ unlock_buffer(journal->j_sb_buffer); + journal->j_revoke_records_per_block = + journal_revoke_records_per_block(journal); + } diff --git a/queue-5.10/kvm-arm64-sys_regs-disable-wuninitialized-const-pointer-warning.patch b/queue-5.10/kvm-arm64-sys_regs-disable-wuninitialized-const-pointer-warning.patch new file mode 100644 index 0000000000..8e6dc718af --- /dev/null +++ b/queue-5.10/kvm-arm64-sys_regs-disable-wuninitialized-const-pointer-warning.patch @@ -0,0 +1,58 @@ +From justinstitt@google.com Thu Jan 8 16:52:32 2026 +From: Justin Stitt +Date: Thu, 04 Dec 2025 12:44:48 -0800 +Subject: KVM: arm64: sys_regs: disable -Wuninitialized-const-pointer warning +To: Marc Zyngier , Oliver Upton , Alexandru Elisei , Joey Gouly , Suzuki K Poulose , Catalin Marinas , Zenghui Yu , Will Deacon , Nathan Chancellor , Christopher Covington +Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, linux-kernel@vger.kernel.org, llvm@lists.linux.dev, stable@vger.kernel.org, Justin Stitt +Message-ID: <20251204-b4-stable-disable-uninit-ptr-warn-5-15-v1-1-41212e2c6409@google.com> + +From: Justin Stitt + +A new warning in Clang 22 [1] complains that @clidr passed to +get_clidr_el1() is an uninitialized const pointer. get_clidr_el1() +doesn't really care since it casts away the const-ness anyways -- it is +a false positive. + +| ../arch/arm64/kvm/sys_regs.c:2838:23: warning: variable 'clidr' is uninitialized when passed as a const pointer argument here [-Wuninitialized-const-pointer] +| 2838 | get_clidr_el1(NULL, &clidr); /* Ugly... */ +| | ^~~~~ + +This patch isn't needed for anything past 6.1 as this code section was +reworked in Commit 7af0c2534f4c ("KVM: arm64: Normalize cache +configuration"). Since there is no upstream equivalent, this patch just +needs to be applied to 5.15. + +Disable this warning for sys_regs.o with an iron fist as it doesn't make +sense to waste maintainer's time or potentially break builds by +backporting large changelists from 6.2+. + +Cc: stable@vger.kernel.org +Fixes: 7c8c5e6a9101e ("arm64: KVM: system register handling") +Link: https://github.com/llvm/llvm-project/commit/00dacf8c22f065cb52efb14cd091d441f19b319e [1] +Reviewed-by: Nathan Chancellor +Signed-off-by: Justin Stitt +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/kvm/Makefile | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile +index 989bb5dad2c8..109cca425d3e 100644 +--- a/arch/arm64/kvm/Makefile ++++ b/arch/arm64/kvm/Makefile +@@ -25,3 +25,6 @@ kvm-y := $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o \ + vgic/vgic-its.o vgic/vgic-debug.o + + kvm-$(CONFIG_HW_PERF_EVENTS) += pmu-emul.o ++ ++# Work around a false positive Clang 22 -Wuninitialized-const-pointer warning ++CFLAGS_sys_regs.o := $(call cc-disable-warning, uninitialized-const-pointer) + +--- +base-commit: 8bb7eca972ad531c9b149c0a51ab43a417385813 +change-id: 20250728-b4-stable-disable-uninit-ptr-warn-5-15-c0c9db3df206 + +Best regards, +-- +Justin Stitt + diff --git a/queue-5.10/media-renesas-rcar_drif-fix-device-node-reference-leak-in-rcar_drif_bond_enabled.patch b/queue-5.10/media-renesas-rcar_drif-fix-device-node-reference-leak-in-rcar_drif_bond_enabled.patch new file mode 100644 index 0000000000..3e902893ab --- /dev/null +++ b/queue-5.10/media-renesas-rcar_drif-fix-device-node-reference-leak-in-rcar_drif_bond_enabled.patch @@ -0,0 +1,45 @@ +From stable+bounces-204912-greg=kroah.com@vger.kernel.org Mon Jan 5 21:19:47 2026 +From: Sasha Levin +Date: Mon, 5 Jan 2026 15:18:26 -0500 +Subject: media: renesas: rcar_drif: fix device node reference leak in rcar_drif_bond_enabled +To: stable@vger.kernel.org +Cc: Miaoqian Lin , Geert Uytterhoeven , Fabrizio Castro , Hans Verkuil , Sasha Levin +Message-ID: <20260105201826.2771666-1-sashal@kernel.org> + +From: Miaoqian Lin + +[ Upstream commit 445e1658894fd74eab7e53071fa16233887574ed ] + +The function calls of_parse_phandle() which returns +a device node with an incremented reference count. When the bonded device +is not available, the function +returns NULL without releasing the reference, causing a reference leak. + +Add of_node_put(np) to release the device node reference. +The of_node_put function handles NULL pointers. + +Found through static analysis by reviewing the doc of of_parse_phandle() +and cross-checking its usage patterns across the codebase. + +Fixes: 7625ee981af1 ("[media] media: platform: rcar_drif: Add DRIF support") +Cc: stable@vger.kernel.org +Signed-off-by: Miaoqian Lin +Reviewed-by: Geert Uytterhoeven +Reviewed-by: Fabrizio Castro +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/platform/rcar_drif.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/media/platform/rcar_drif.c ++++ b/drivers/media/platform/rcar_drif.c +@@ -1253,6 +1253,7 @@ static struct device_node *rcar_drif_bon + if (np && of_device_is_available(np)) + return np; + ++ of_node_put(np); + return NULL; + } + diff --git a/queue-5.10/mptcp-pm-ignore-unknown-endpoint-flags.patch b/queue-5.10/mptcp-pm-ignore-unknown-endpoint-flags.patch new file mode 100644 index 0000000000..eecd3ff88f --- /dev/null +++ b/queue-5.10/mptcp-pm-ignore-unknown-endpoint-flags.patch @@ -0,0 +1,68 @@ +From stable+bounces-204225-greg=kroah.com@vger.kernel.org Tue Dec 30 15:35:51 2025 +From: Sasha Levin +Date: Tue, 30 Dec 2025 09:34:34 -0500 +Subject: mptcp: pm: ignore unknown endpoint flags +To: stable@vger.kernel.org +Cc: "Matthieu Baerts (NGI0)" , Mat Martineau , Jakub Kicinski , Sasha Levin +Message-ID: <20251230143434.2246658-1-sashal@kernel.org> + +From: "Matthieu Baerts (NGI0)" + +[ Upstream commit 0ace3297a7301911e52d8195cb1006414897c859 ] + +Before this patch, the kernel was saving any flags set by the userspace, +even unknown ones. This doesn't cause critical issues because the kernel +is only looking at specific ones. But on the other hand, endpoints dumps +could tell the userspace some recent flags seem to be supported on older +kernel versions. + +Instead, ignore all unknown flags when parsing them. By doing that, the +userspace can continue to set unsupported flags, but it has a way to +verify what is supported by the kernel. + +Note that it sounds better to continue accepting unsupported flags not +to change the behaviour, but also that eases things on the userspace +side by adding "optional" endpoint types only supported by newer kernel +versions without having to deal with the different kernel versions. + +A note for the backports: there will be conflicts in mptcp.h on older +versions not having the mentioned flags, the new line should still be +added last, and the '5' needs to be adapted to have the same value as +the last entry. + +Fixes: 01cacb00b35c ("mptcp: add netlink-based PM") +Cc: stable@vger.kernel.org +Reviewed-by: Mat Martineau +Signed-off-by: Matthieu Baerts (NGI0) +Link: https://patch.msgid.link/20251205-net-mptcp-misc-fixes-6-19-rc1-v1-1-9e4781a6c1b8@kernel.org +Signed-off-by: Jakub Kicinski +[ GENMASK(5, 0) => GENMASK(2, 0) and applied fix to mptcp_pm_parse_addr() ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + include/uapi/linux/mptcp.h | 1 + + net/mptcp/pm_netlink.c | 3 ++- + 2 files changed, 3 insertions(+), 1 deletion(-) + +--- a/include/uapi/linux/mptcp.h ++++ b/include/uapi/linux/mptcp.h +@@ -72,6 +72,7 @@ enum { + #define MPTCP_PM_ADDR_FLAG_SIGNAL (1 << 0) + #define MPTCP_PM_ADDR_FLAG_SUBFLOW (1 << 1) + #define MPTCP_PM_ADDR_FLAG_BACKUP (1 << 2) ++#define MPTCP_PM_ADDR_FLAGS_MASK GENMASK(2, 0) + + enum { + MPTCP_PM_CMD_UNSPEC, +--- a/net/mptcp/pm_netlink.c ++++ b/net/mptcp/pm_netlink.c +@@ -721,7 +721,8 @@ skip_family: + entry->addr.id = nla_get_u8(tb[MPTCP_PM_ADDR_ATTR_ID]); + + if (tb[MPTCP_PM_ADDR_ATTR_FLAGS]) +- entry->addr.flags = nla_get_u32(tb[MPTCP_PM_ADDR_ATTR_FLAGS]); ++ entry->addr.flags = nla_get_u32(tb[MPTCP_PM_ADDR_ATTR_FLAGS]) & ++ MPTCP_PM_ADDR_FLAGS_MASK; + + return 0; + } diff --git a/queue-5.10/net-mlx5e-avoid-field-overflowing-memcpy.patch b/queue-5.10/net-mlx5e-avoid-field-overflowing-memcpy.patch new file mode 100644 index 0000000000..82c20a2589 --- /dev/null +++ b/queue-5.10/net-mlx5e-avoid-field-overflowing-memcpy.patch @@ -0,0 +1,137 @@ +From stable+bounces-200750-greg=kroah.com@vger.kernel.org Wed Dec 10 22:37:06 2025 +From: Brennan Lamoreaux +Date: Wed, 10 Dec 2025 21:16:33 +0000 +Subject: net/mlx5e: Avoid field-overflowing memcpy() +To: stable@vger.kernel.org +Cc: ajay.kaher@broadcom.com, alexey.makhalov@broadcom.com, vamsi-krishna.brahmajosyula@broadcom.com, yin.ding@broadcom.com, tapas.kundu@broadcom.com, Kees Cook , Saeed Mahameed , Greg Kroah-Hartman , Brennan Lamoreaux +Message-ID: <20251210211633.634693-1-brennan.lamoreaux@broadcom.com> + +From: Kees Cook + +commit ad5185735f7dab342fdd0dd41044da4c9ccfef67 upstream. + +In preparation for FORTIFY_SOURCE performing compile-time and run-time +field bounds checking for memcpy(), memmove(), and memset(), avoid +intentionally writing across neighboring fields. + +Use flexible arrays instead of zero-element arrays (which look like they +are always overflowing) and split the cross-field memcpy() into two halves +that can be appropriately bounds-checked by the compiler. + +We were doing: + + #define ETH_HLEN 14 + #define VLAN_HLEN 4 + ... + #define MLX5E_XDP_MIN_INLINE (ETH_HLEN + VLAN_HLEN) + ... + struct mlx5e_tx_wqe *wqe = mlx5_wq_cyc_get_wqe(wq, pi); + ... + struct mlx5_wqe_eth_seg *eseg = &wqe->eth; + struct mlx5_wqe_data_seg *dseg = wqe->data; + ... + memcpy(eseg->inline_hdr.start, xdptxd->data, MLX5E_XDP_MIN_INLINE); + +target is wqe->eth.inline_hdr.start (which the compiler sees as being +2 bytes in size), but copying 18, intending to write across start +(really vlan_tci, 2 bytes). The remaining 16 bytes get written into +wqe->data[0], covering byte_count (4 bytes), lkey (4 bytes), and addr +(8 bytes). + +struct mlx5e_tx_wqe { + struct mlx5_wqe_ctrl_seg ctrl; /* 0 16 */ + struct mlx5_wqe_eth_seg eth; /* 16 16 */ + struct mlx5_wqe_data_seg data[]; /* 32 0 */ + + /* size: 32, cachelines: 1, members: 3 */ + /* last cacheline: 32 bytes */ +}; + +struct mlx5_wqe_eth_seg { + u8 swp_outer_l4_offset; /* 0 1 */ + u8 swp_outer_l3_offset; /* 1 1 */ + u8 swp_inner_l4_offset; /* 2 1 */ + u8 swp_inner_l3_offset; /* 3 1 */ + u8 cs_flags; /* 4 1 */ + u8 swp_flags; /* 5 1 */ + __be16 mss; /* 6 2 */ + __be32 flow_table_metadata; /* 8 4 */ + union { + struct { + __be16 sz; /* 12 2 */ + u8 start[2]; /* 14 2 */ + } inline_hdr; /* 12 4 */ + struct { + __be16 type; /* 12 2 */ + __be16 vlan_tci; /* 14 2 */ + } insert; /* 12 4 */ + __be32 trailer; /* 12 4 */ + }; /* 12 4 */ + + /* size: 16, cachelines: 1, members: 9 */ + /* last cacheline: 16 bytes */ +}; + +struct mlx5_wqe_data_seg { + __be32 byte_count; /* 0 4 */ + __be32 lkey; /* 4 4 */ + __be64 addr; /* 8 8 */ + + /* size: 16, cachelines: 1, members: 3 */ + /* last cacheline: 16 bytes */ +}; + +So, split the memcpy() so the compiler can reason about the buffer +sizes. + +"pahole" shows no size nor member offset changes to struct mlx5e_tx_wqe +nor struct mlx5e_umr_wqe. "objdump -d" shows no meaningful object +code changes (i.e. only source line number induced differences and +optimizations). + +Fixes: b5503b994ed5 ("net/mlx5e: XDP TX forwarding support") +Signed-off-by: Kees Cook +Signed-off-by: Saeed Mahameed +Signed-off-by: Greg Kroah-Hartman +[ Brennan : Applied to v5.10, convert inline_mtts to flex array (not in union) ] +Signed-off-by: Brennan Lamoreaux +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/mellanox/mlx5/core/en.h | 4 ++-- + drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c | 4 +++- + 2 files changed, 5 insertions(+), 3 deletions(-) + +--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h +@@ -199,7 +199,7 @@ static inline int mlx5e_get_max_num_chan + struct mlx5e_tx_wqe { + struct mlx5_wqe_ctrl_seg ctrl; + struct mlx5_wqe_eth_seg eth; +- struct mlx5_wqe_data_seg data[0]; ++ struct mlx5_wqe_data_seg data[]; + }; + + struct mlx5e_rx_wqe_ll { +@@ -215,7 +215,7 @@ struct mlx5e_umr_wqe { + struct mlx5_wqe_ctrl_seg ctrl; + struct mlx5_wqe_umr_ctrl_seg uctrl; + struct mlx5_mkey_seg mkc; +- struct mlx5_mtt inline_mtts[0]; ++ struct mlx5_mtt inline_mtts[]; + }; + + extern const char mlx5e_self_tests[][ETH_GSTRING_LEN]; +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c +@@ -341,8 +341,10 @@ mlx5e_xmit_xdp_frame(struct mlx5e_xdpsq + + /* copy the inline part if required */ + if (sq->min_inline_mode != MLX5_INLINE_MODE_NONE) { +- memcpy(eseg->inline_hdr.start, xdptxd->data, MLX5E_XDP_MIN_INLINE); ++ memcpy(eseg->inline_hdr.start, xdptxd->data, sizeof(eseg->inline_hdr.start)); + eseg->inline_hdr.sz = cpu_to_be16(MLX5E_XDP_MIN_INLINE); ++ memcpy(dseg, xdptxd->data + sizeof(eseg->inline_hdr.start), ++ MLX5E_XDP_MIN_INLINE - sizeof(eseg->inline_hdr.start)); + dma_len -= MLX5E_XDP_MIN_INLINE; + dma_addr += MLX5E_XDP_MIN_INLINE; + dseg++; diff --git a/queue-5.10/nfsd-clear-seclabel-in-the-suppattr_exclcreat-bitmap.patch b/queue-5.10/nfsd-clear-seclabel-in-the-suppattr_exclcreat-bitmap.patch new file mode 100644 index 0000000000..cf21b6f257 --- /dev/null +++ b/queue-5.10/nfsd-clear-seclabel-in-the-suppattr_exclcreat-bitmap.patch @@ -0,0 +1,57 @@ +From stable+bounces-204347-greg=kroah.com@vger.kernel.org Wed Dec 31 14:50:17 2025 +From: Sasha Levin +Date: Wed, 31 Dec 2025 08:50:07 -0500 +Subject: NFSD: Clear SECLABEL in the suppattr_exclcreat bitmap +To: stable@vger.kernel.org +Cc: Chuck Lever , Jeff Layton , Sasha Levin +Message-ID: <20251231135007.2902697-1-sashal@kernel.org> + +From: Chuck Lever + +[ Upstream commit 27d17641cacfedd816789b75d342430f6b912bd2 ] + +>>From RFC 8881: + +5.8.1.14. Attribute 75: suppattr_exclcreat + +> The bit vector that would set all REQUIRED and RECOMMENDED +> attributes that are supported by the EXCLUSIVE4_1 method of file +> creation via the OPEN operation. The scope of this attribute +> applies to all objects with a matching fsid. + +There's nothing in RFC 8881 that states that suppattr_exclcreat is +or is not allowed to contain bits for attributes that are clear in +the reported supported_attrs bitmask. But it doesn't make sense for +an NFS server to indicate that it /doesn't/ implement an attribute, +but then also indicate that clients /are/ allowed to set that +attribute using OPEN(create) with EXCLUSIVE4_1. + +Ensure that the SECURITY_LABEL and ACL bits are not set in the +suppattr_exclcreat bitmask when they are also not set in the +supported_attrs bitmask. + +Fixes: 8c18f2052e75 ("nfsd41: SUPPATTR_EXCLCREAT attribute") +Cc: stable@vger.kernel.org +Reviewed-by: Jeff Layton +Signed-off-by: Chuck Lever +[ Adjust context ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfs4xdr.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/fs/nfsd/nfs4xdr.c ++++ b/fs/nfsd/nfs4xdr.c +@@ -3408,6 +3408,11 @@ out_acl: + u32 supp[3]; + + memcpy(supp, nfsd_suppattrs[minorversion], sizeof(supp)); ++ if (!IS_POSIXACL(d_inode(dentry))) ++ supp[0] &= ~FATTR4_WORD0_ACL; ++ if (!contextsupport) ++ supp[2] &= ~FATTR4_WORD2_SECURITY_LABEL; ++ + supp[0] &= NFSD_SUPPATTR_EXCLCREAT_WORD0; + supp[1] &= NFSD_SUPPATTR_EXCLCREAT_WORD1; + supp[2] &= NFSD_SUPPATTR_EXCLCREAT_WORD2; diff --git a/queue-5.10/pci-brcmstb-fix-disabling-l0s-capability.patch b/queue-5.10/pci-brcmstb-fix-disabling-l0s-capability.patch new file mode 100644 index 0000000000..ca05f0dd01 --- /dev/null +++ b/queue-5.10/pci-brcmstb-fix-disabling-l0s-capability.patch @@ -0,0 +1,79 @@ +From stable+bounces-204906-greg=kroah.com@vger.kernel.org Mon Jan 5 20:47:21 2026 +From: Sasha Levin +Date: Mon, 5 Jan 2026 14:47:15 -0500 +Subject: PCI: brcmstb: Fix disabling L0s capability +To: stable@vger.kernel.org +Cc: Jim Quinlan , Bjorn Helgaas , Manivannan Sadhasivam , Florian Fainelli , Sasha Levin +Message-ID: <20260105194715.2753386-1-sashal@kernel.org> + +From: Jim Quinlan + +[ Upstream commit 9583f9d22991d2cfb5cc59a2552040c4ae98d998 ] + +caab002d5069 ("PCI: brcmstb: Disable L0s component of ASPM if requested") +set PCI_EXP_LNKCAP_ASPM_L1 and (optionally) PCI_EXP_LNKCAP_ASPM_L0S in +PCI_EXP_LNKCAP (aka PCIE_RC_CFG_PRIV1_LINK_CAPABILITY in brcmstb). + +But instead of using PCI_EXP_LNKCAP_ASPM_L1 and PCI_EXP_LNKCAP_ASPM_L0S +directly, it used PCIE_LINK_STATE_L1 and PCIE_LINK_STATE_L0S, which are +Linux-created values that only coincidentally matched the PCIe spec. +b478e162f227 ("PCI/ASPM: Consolidate link state defines") later changed +them so they no longer matched the PCIe spec, so the bits ended up in the +wrong place in PCI_EXP_LNKCAP. + +Use PCI_EXP_LNKCAP_ASPM_L0S to clear L0s support when there's an +'aspm-no-l0s' property. Rely on brcmstb hardware to advertise L0s and/or +L1 support otherwise. + +Fixes: caab002d5069 ("PCI: brcmstb: Disable L0s component of ASPM if requested") +Reported-by: Bjorn Helgaas +Closes: https://lore.kernel.org/linux-pci/20250925194424.GA2197200@bhelgaas +Signed-off-by: Jim Quinlan +[mani: reworded subject and description, added closes tag and CCed stable] +Signed-off-by: Manivannan Sadhasivam +[bhelgaas: commit log] +Signed-off-by: Bjorn Helgaas +Reviewed-by: Florian Fainelli +Cc: stable@vger.kernel.org +Link: https://patch.msgid.link/20251003170436.1446030-1-james.quinlan@broadcom.com +[ Adjust context in variable declaration ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pcie-brcmstb.c | 10 +++------- + 1 file changed, 3 insertions(+), 7 deletions(-) + +--- a/drivers/pci/controller/pcie-brcmstb.c ++++ b/drivers/pci/controller/pcie-brcmstb.c +@@ -43,7 +43,6 @@ + #define PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK 0xffffff + + #define PCIE_RC_CFG_PRIV1_LINK_CAPABILITY 0x04dc +-#define PCIE_RC_CFG_PRIV1_LINK_CAPABILITY_ASPM_SUPPORT_MASK 0xc00 + + #define PCIE_RC_DL_MDIO_ADDR 0x1100 + #define PCIE_RC_DL_MDIO_WR_DATA 0x1104 +@@ -865,7 +864,7 @@ static int brcm_pcie_setup(struct brcm_p + int num_out_wins = 0; + u16 nlw, cls, lnksta; + int i, ret, memc; +- u32 tmp, burst, aspm_support; ++ u32 tmp, burst; + + /* Reset the bridge */ + pcie->bridge_sw_init_set(pcie, 1); +@@ -987,12 +986,9 @@ static int brcm_pcie_setup(struct brcm_p + } + + /* Don't advertise L0s capability if 'aspm-no-l0s' */ +- aspm_support = PCIE_LINK_STATE_L1; +- if (!of_property_read_bool(pcie->np, "aspm-no-l0s")) +- aspm_support |= PCIE_LINK_STATE_L0S; + tmp = readl(base + PCIE_RC_CFG_PRIV1_LINK_CAPABILITY); +- u32p_replace_bits(&tmp, aspm_support, +- PCIE_RC_CFG_PRIV1_LINK_CAPABILITY_ASPM_SUPPORT_MASK); ++ if (of_property_read_bool(pcie->np, "aspm-no-l0s")) ++ tmp &= ~PCI_EXP_LNKCAP_ASPM_L0S; + writel(tmp, base + PCIE_RC_CFG_PRIV1_LINK_CAPABILITY); + + /* diff --git a/queue-5.10/powerpc-64s-slb-fix-slb-multihit-issue-during-slb-preload.patch b/queue-5.10/powerpc-64s-slb-fix-slb-multihit-issue-during-slb-preload.patch new file mode 100644 index 0000000000..3f946e464e --- /dev/null +++ b/queue-5.10/powerpc-64s-slb-fix-slb-multihit-issue-during-slb-preload.patch @@ -0,0 +1,312 @@ +From stable+bounces-204866-greg=kroah.com@vger.kernel.org Mon Jan 5 18:27:42 2026 +From: Sasha Levin +Date: Mon, 5 Jan 2026 12:26:36 -0500 +Subject: powerpc/64s/slb: Fix SLB multihit issue during SLB preload +To: stable@vger.kernel.org +Cc: Donet Tom , Nicholas Piggin , "Ritesh Harjani (IBM)" , Madhavan Srinivasan , Sasha Levin +Message-ID: <20260105172636.2688666-1-sashal@kernel.org> + +From: Donet Tom + +[ Upstream commit 00312419f0863964625d6dcda8183f96849412c6 ] + +On systems using the hash MMU, there is a software SLB preload cache that +mirrors the entries loaded into the hardware SLB buffer. This preload +cache is subject to periodic eviction — typically after every 256 context +switches — to remove old entry. + +To optimize performance, the kernel skips switch_mmu_context() in +switch_mm_irqs_off() when the prev and next mm_struct are the same. +However, on hash MMU systems, this can lead to inconsistencies between +the hardware SLB and the software preload cache. + +If an SLB entry for a process is evicted from the software cache on one +CPU, and the same process later runs on another CPU without executing +switch_mmu_context(), the hardware SLB may retain stale entries. If the +kernel then attempts to reload that entry, it can trigger an SLB +multi-hit error. + +The following timeline shows how stale SLB entries are created and can +cause a multi-hit error when a process moves between CPUs without a +MMU context switch. + +CPU 0 CPU 1 +----- ----- +Process P +exec swapper/1 + load_elf_binary + begin_new_exc + activate_mm + switch_mm_irqs_off + switch_mmu_context + switch_slb + /* + * This invalidates all + * the entries in the HW + * and setup the new HW + * SLB entries as per the + * preload cache. + */ +context_switch +sched_migrate_task migrates process P to cpu-1 + +Process swapper/0 context switch (to process P) +(uses mm_struct of Process P) switch_mm_irqs_off() + switch_slb + load_slb++ + /* + * load_slb becomes 0 here + * and we evict an entry from + * the preload cache with + * preload_age(). We still + * keep HW SLB and preload + * cache in sync, that is + * because all HW SLB entries + * anyways gets evicted in + * switch_slb during SLBIA. + * We then only add those + * entries back in HW SLB, + * which are currently + * present in preload_cache + * (after eviction). + */ + load_elf_binary continues... + setup_new_exec() + slb_setup_new_exec() + + sched_switch event + sched_migrate_task migrates + process P to cpu-0 + +context_switch from swapper/0 to Process P + switch_mm_irqs_off() + /* + * Since both prev and next mm struct are same we don't call + * switch_mmu_context(). This will cause the HW SLB and SW preload + * cache to go out of sync in preload_new_slb_context. Because there + * was an SLB entry which was evicted from both HW and preload cache + * on cpu-1. Now later in preload_new_slb_context(), when we will try + * to add the same preload entry again, we will add this to the SW + * preload cache and then will add it to the HW SLB. Since on cpu-0 + * this entry was never invalidated, hence adding this entry to the HW + * SLB will cause a SLB multi-hit error. + */ +load_elf_binary continues... + START_THREAD + start_thread + preload_new_slb_context + /* + * This tries to add a new EA to preload cache which was earlier + * evicted from both cpu-1 HW SLB and preload cache. This caused the + * HW SLB of cpu-0 to go out of sync with the SW preload cache. The + * reason for this was, that when we context switched back on CPU-0, + * we should have ideally called switch_mmu_context() which will + * bring the HW SLB entries on CPU-0 in sync with SW preload cache + * entries by setting up the mmu context properly. But we didn't do + * that since the prev mm_struct running on cpu-0 was same as the + * next mm_struct (which is true for swapper / kernel threads). So + * now when we try to add this new entry into the HW SLB of cpu-0, + * we hit a SLB multi-hit error. + */ + +WARNING: CPU: 0 PID: 1810970 at arch/powerpc/mm/book3s64/slb.c:62 +assert_slb_presence+0x2c/0x50(48 results) 02:47:29 [20157/42149] +Modules linked in: +CPU: 0 UID: 0 PID: 1810970 Comm: dd Not tainted 6.16.0-rc3-dirty #12 +VOLUNTARY +Hardware name: IBM pSeries (emulated by qemu) POWER8 (architected) +0x4d0200 0xf000004 of:SLOF,HEAD hv:linux,kvm pSeries +NIP: c00000000015426c LR: c0000000001543b4 CTR: 0000000000000000 +REGS: c0000000497c77e0 TRAP: 0700 Not tainted (6.16.0-rc3-dirty) +MSR: 8000000002823033 CR: 28888482 XER: 00000000 +CFAR: c0000000001543b0 IRQMASK: 3 +<...> +NIP [c00000000015426c] assert_slb_presence+0x2c/0x50 +LR [c0000000001543b4] slb_insert_entry+0x124/0x390 +Call Trace: + 0x7fffceb5ffff (unreliable) + preload_new_slb_context+0x100/0x1a0 + start_thread+0x26c/0x420 + load_elf_binary+0x1b04/0x1c40 + bprm_execve+0x358/0x680 + do_execveat_common+0x1f8/0x240 + sys_execve+0x58/0x70 + system_call_exception+0x114/0x300 + system_call_common+0x160/0x2c4 + +>>From the above analysis, during early exec the hardware SLB is cleared, +and entries from the software preload cache are reloaded into hardware +by switch_slb. However, preload_new_slb_context and slb_setup_new_exec +also attempt to load some of the same entries, which can trigger a +multi-hit. In most cases, these additional preloads simply hit existing +entries and add nothing new. Removing these functions avoids redundant +preloads and eliminates the multi-hit issue. This patch removes these +two functions. + +We tested process switching performance using the context_switch +benchmark on POWER9/hash, and observed no regression. + +Without this patch: 129041 ops/sec +With this patch: 129341 ops/sec + +We also measured SLB faults during boot, and the counts are essentially +the same with and without this patch. + +SLB faults without this patch: 19727 +SLB faults with this patch: 19786 + +Fixes: 5434ae74629a ("powerpc/64s/hash: Add a SLB preload cache") +cc: stable@vger.kernel.org +Suggested-by: Nicholas Piggin +Signed-off-by: Donet Tom +Signed-off-by: Ritesh Harjani (IBM) +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/0ac694ae683494fe8cadbd911a1a5018d5d3c541.1761834163.git.ritesh.list@gmail.com +[ Adjust context ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + arch/powerpc/kernel/process.c | 5 - + arch/powerpc/mm/book3s64/internal.h | 1 + arch/powerpc/mm/book3s64/mmu_context.c | 2 + arch/powerpc/mm/book3s64/slb.c | 88 --------------------------------- + 4 files changed, 96 deletions(-) + +--- a/arch/powerpc/kernel/process.c ++++ b/arch/powerpc/kernel/process.c +@@ -1767,8 +1767,6 @@ int copy_thread(unsigned long clone_flag + return 0; + } + +-void preload_new_slb_context(unsigned long start, unsigned long sp); +- + /* + * Set up a thread for executing a new program + */ +@@ -1776,9 +1774,6 @@ void start_thread(struct pt_regs *regs, + { + #ifdef CONFIG_PPC64 + unsigned long load_addr = regs->gpr[2]; /* saved by ELF_PLAT_INIT */ +- +- if (IS_ENABLED(CONFIG_PPC_BOOK3S_64) && !radix_enabled()) +- preload_new_slb_context(start, sp); + #endif + + /* +--- a/arch/powerpc/mm/book3s64/internal.h ++++ b/arch/powerpc/mm/book3s64/internal.h +@@ -13,6 +13,5 @@ static inline bool stress_slb(void) + return static_branch_unlikely(&stress_slb_key); + } + +-void slb_setup_new_exec(void); + + #endif /* ARCH_POWERPC_MM_BOOK3S64_INTERNAL_H */ +--- a/arch/powerpc/mm/book3s64/mmu_context.c ++++ b/arch/powerpc/mm/book3s64/mmu_context.c +@@ -147,8 +147,6 @@ static int hash__init_new_context(struct + void hash__setup_new_exec(void) + { + slice_setup_new_exec(); +- +- slb_setup_new_exec(); + } + + static int radix__init_new_context(struct mm_struct *mm) +--- a/arch/powerpc/mm/book3s64/slb.c ++++ b/arch/powerpc/mm/book3s64/slb.c +@@ -352,94 +352,6 @@ static void preload_age(struct thread_in + ti->slb_preload_tail = (ti->slb_preload_tail + 1) % SLB_PRELOAD_NR; + } + +-void slb_setup_new_exec(void) +-{ +- struct thread_info *ti = current_thread_info(); +- struct mm_struct *mm = current->mm; +- unsigned long exec = 0x10000000; +- +- WARN_ON(irqs_disabled()); +- +- /* +- * preload cache can only be used to determine whether a SLB +- * entry exists if it does not start to overflow. +- */ +- if (ti->slb_preload_nr + 2 > SLB_PRELOAD_NR) +- return; +- +- hard_irq_disable(); +- +- /* +- * We have no good place to clear the slb preload cache on exec, +- * flush_thread is about the earliest arch hook but that happens +- * after we switch to the mm and have aleady preloaded the SLBEs. +- * +- * For the most part that's probably okay to use entries from the +- * previous exec, they will age out if unused. It may turn out to +- * be an advantage to clear the cache before switching to it, +- * however. +- */ +- +- /* +- * preload some userspace segments into the SLB. +- * Almost all 32 and 64bit PowerPC executables are linked at +- * 0x10000000 so it makes sense to preload this segment. +- */ +- if (!is_kernel_addr(exec)) { +- if (preload_add(ti, exec)) +- slb_allocate_user(mm, exec); +- } +- +- /* Libraries and mmaps. */ +- if (!is_kernel_addr(mm->mmap_base)) { +- if (preload_add(ti, mm->mmap_base)) +- slb_allocate_user(mm, mm->mmap_base); +- } +- +- /* see switch_slb */ +- asm volatile("isync" : : : "memory"); +- +- local_irq_enable(); +-} +- +-void preload_new_slb_context(unsigned long start, unsigned long sp) +-{ +- struct thread_info *ti = current_thread_info(); +- struct mm_struct *mm = current->mm; +- unsigned long heap = mm->start_brk; +- +- WARN_ON(irqs_disabled()); +- +- /* see above */ +- if (ti->slb_preload_nr + 3 > SLB_PRELOAD_NR) +- return; +- +- hard_irq_disable(); +- +- /* Userspace entry address. */ +- if (!is_kernel_addr(start)) { +- if (preload_add(ti, start)) +- slb_allocate_user(mm, start); +- } +- +- /* Top of stack, grows down. */ +- if (!is_kernel_addr(sp)) { +- if (preload_add(ti, sp)) +- slb_allocate_user(mm, sp); +- } +- +- /* Bottom of heap, grows up. */ +- if (heap && !is_kernel_addr(heap)) { +- if (preload_add(ti, heap)) +- slb_allocate_user(mm, heap); +- } +- +- /* see switch_slb */ +- asm volatile("isync" : : : "memory"); +- +- local_irq_enable(); +-} +- + static void slb_cache_slbie_kernel(unsigned int index) + { + unsigned long slbie_data = get_paca()->slb_cache[index]; diff --git a/queue-5.10/powerpc-pseries-cmm-call-balloon_devinfo_init-also-without-config_balloon_compaction.patch b/queue-5.10/powerpc-pseries-cmm-call-balloon_devinfo_init-also-without-config_balloon_compaction.patch new file mode 100644 index 0000000000..405a443f57 --- /dev/null +++ b/queue-5.10/powerpc-pseries-cmm-call-balloon_devinfo_init-also-without-config_balloon_compaction.patch @@ -0,0 +1,63 @@ +From stable+bounces-204909-greg=kroah.com@vger.kernel.org Mon Jan 5 21:09:50 2026 +From: Sasha Levin +Date: Mon, 5 Jan 2026 15:08:50 -0500 +Subject: powerpc/pseries/cmm: call balloon_devinfo_init() also without CONFIG_BALLOON_COMPACTION +To: stable@vger.kernel.org +Cc: David Hildenbrand , "Ritesh Harjani (IBM)" , Christophe Leroy , Madhavan Srinivasan , Michael Ellerman , Nicholas Piggin , Andrew Morton , Sasha Levin +Message-ID: <20260105200850.2767781-1-sashal@kernel.org> + +From: David Hildenbrand + +[ Upstream commit fc6bcf9ac4de76f5e7bcd020b3c0a86faff3f2d5 ] + +Patch series "powerpc/pseries/cmm: two smaller fixes". + +Two smaller fixes identified while doing a bigger rework. + +This patch (of 2): + +We always have to initialize the balloon_dev_info, even when compaction is +not configured in: otherwise the containing list and the lock are left +uninitialized. + +Likely not many such configs exist in practice, but let's CC stable to +be sure. + +This was found by code inspection. + +Link: https://lkml.kernel.org/r/20251021100606.148294-1-david@redhat.com +Link: https://lkml.kernel.org/r/20251021100606.148294-2-david@redhat.com +Fixes: fe030c9b85e6 ("powerpc/pseries/cmm: Implement balloon compaction") +Signed-off-by: David Hildenbrand +Reviewed-by: Ritesh Harjani (IBM) +Cc: Christophe Leroy +Cc: Madhavan Srinivasan +Cc: Michael Ellerman +Cc: Nicholas Piggin +Cc: +Signed-off-by: Andrew Morton +[ moved balloon_devinfo_init() call from inside cmm_balloon_compaction_init() to cmm_init() ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + arch/powerpc/platforms/pseries/cmm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/powerpc/platforms/pseries/cmm.c ++++ b/arch/powerpc/platforms/pseries/cmm.c +@@ -570,7 +570,6 @@ static int cmm_balloon_compaction_init(v + { + int rc; + +- balloon_devinfo_init(&b_dev_info); + b_dev_info.migratepage = cmm_migratepage; + + balloon_mnt = kern_mount(&balloon_fs); +@@ -624,6 +623,7 @@ static int cmm_init(void) + if (!firmware_has_feature(FW_FEATURE_CMO) && !simulate) + return -EOPNOTSUPP; + ++ balloon_devinfo_init(&b_dev_info); + rc = cmm_balloon_compaction_init(); + if (rc) + return rc; diff --git a/queue-5.10/series b/queue-5.10/series index 36865ed8f2..c45a10a2b1 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -345,3 +345,36 @@ fbcon-avoid-using-fntcharcnt-and-hard-coded-built-in-font-charcount.patch drm-vmwgfx-fix-a-null-ptr-access-in-the-cursor-snooper.patch usb-xhci-move-link-chain-bit-quirk-checks-into-one-helper-function.patch usb-xhci-apply-the-link-chain-quirk-on-nec-isoc-endpoints.patch +ipv6-fix-potential-uninit-value-access-in-__ip6_make_skb.patch +ipv4-fix-uninit-value-access-in-__ip_make_skb.patch +hid-core-harden-s32ton-against-conversion-to-0-bits.patch +xhci-dbgtty-fix-device-unregister.patch +usb-gadget-udc-fix-use-after-free-in-usb_gadget_state_work.patch +net-mlx5e-avoid-field-overflowing-memcpy.patch +alsa-wavefront-clear-substream-pointers-on-close.patch +alsa-wavefront-fix-integer-overflow-in-sample-size-validation.patch +ext4-fix-string-copying-in-parse_apply_sb_mount_options.patch +btrfs-don-t-rewrite-ret-from-inode_permission.patch +xfs-fix-a-memory-leak-in-xfs_buf_item_init.patch +f2fs-use-global-inline_xattr_slab-instead-of-per-sb-slab-cache.patch +f2fs-fix-to-detect-recoverable-inode-during-dryrun-of-find_fsync_dnodes.patch +f2fs-fix-to-propagate-error-from-f2fs_enable_checkpoint.patch +f2fs-fix-to-avoid-updating-zero-sized-extent-in-extent-cache.patch +usb-dwc3-keep-susphy-enabled-during-exit-to-avoid-controller-faults.patch +mptcp-pm-ignore-unknown-endpoint-flags.patch +usb-ohci-nxp-use-helper-function-devm_clk_get_enabled.patch +usb-ohci-nxp-fix-device-leak-on-probe-failure.patch +jbd2-fix-the-inconsistency-between-checksum-and-data-in-memory-for-journal-sb.patch +tpm-cap-the-number-of-pcr-banks.patch +nfsd-clear-seclabel-in-the-suppattr_exclcreat-bitmap.patch +sunrpc-svcauth_gss-avoid-null-deref-on-zero-length-gss_token-in-gss_read_proxy_verf.patch +hwmon-replace-snprintf-in-show-functions-with-sysfs_emit.patch +hwmon-max16065-use-local-variable-to-avoid-toctou.patch +crypto-af_alg-zero-initialize-memory-allocated-via-sock_kmalloc.patch +arm-dts-microchip-sama5d2-fix-spi-flexcom-fifo-size-to-32.patch +iommu-qcom-fix-device-leak-on-of_xlate.patch +powerpc-64s-slb-fix-slb-multihit-issue-during-slb-preload.patch +pci-brcmstb-fix-disabling-l0s-capability.patch +powerpc-pseries-cmm-call-balloon_devinfo_init-also-without-config_balloon_compaction.patch +media-renesas-rcar_drif-fix-device-node-reference-leak-in-rcar_drif_bond_enabled.patch +kvm-arm64-sys_regs-disable-wuninitialized-const-pointer-warning.patch diff --git a/queue-5.10/sunrpc-svcauth_gss-avoid-null-deref-on-zero-length-gss_token-in-gss_read_proxy_verf.patch b/queue-5.10/sunrpc-svcauth_gss-avoid-null-deref-on-zero-length-gss_token-in-gss_read_proxy_verf.patch new file mode 100644 index 0000000000..85df911b71 --- /dev/null +++ b/queue-5.10/sunrpc-svcauth_gss-avoid-null-deref-on-zero-length-gss_token-in-gss_read_proxy_verf.patch @@ -0,0 +1,41 @@ +From stable+bounces-204360-greg=kroah.com@vger.kernel.org Wed Dec 31 15:44:12 2025 +From: Sasha Levin +Date: Wed, 31 Dec 2025 09:43:03 -0500 +Subject: SUNRPC: svcauth_gss: avoid NULL deref on zero length gss_token in gss_read_proxy_verf +To: stable@vger.kernel.org +Cc: Joshua Rogers , Chuck Lever , Sasha Levin +Message-ID: <20251231144303.3088891-1-sashal@kernel.org> + +From: Joshua Rogers + +[ Upstream commit d4b69a6186b215d2dc1ebcab965ed88e8d41768d ] + +A zero length gss_token results in pages == 0 and in_token->pages[0] +is NULL. The code unconditionally evaluates +page_address(in_token->pages[0]) for the initial memcpy, which can +dereference NULL even when the copy length is 0. Guard the first +memcpy so it only runs when length > 0. + +Fixes: 5866efa8cbfb ("SUNRPC: Fix svcauth_gss_proxy_init()") +Cc: stable@vger.kernel.org +Signed-off-by: Joshua Rogers +Signed-off-by: Chuck Lever +[ adapted xdr buffer pointer API to older argv iov_base/iov_len API ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + net/sunrpc/auth_gss/svcauth_gss.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/sunrpc/auth_gss/svcauth_gss.c ++++ b/net/sunrpc/auth_gss/svcauth_gss.c +@@ -1177,7 +1177,8 @@ static int gss_read_proxy_verf(struct sv + } + + length = min_t(unsigned int, inlen, argv->iov_len); +- memcpy(page_address(in_token->pages[0]), argv->iov_base, length); ++ if (length) ++ memcpy(page_address(in_token->pages[0]), argv->iov_base, length); + inlen -= length; + + to_offs = length; diff --git a/queue-5.10/tpm-cap-the-number-of-pcr-banks.patch b/queue-5.10/tpm-cap-the-number-of-pcr-banks.patch new file mode 100644 index 0000000000..2d10e34af1 --- /dev/null +++ b/queue-5.10/tpm-cap-the-number-of-pcr-banks.patch @@ -0,0 +1,105 @@ +From stable+bounces-204158-greg=kroah.com@vger.kernel.org Tue Dec 30 01:38:53 2025 +From: Sasha Levin +Date: Mon, 29 Dec 2025 19:38:42 -0500 +Subject: tpm: Cap the number of PCR banks +To: stable@vger.kernel.org +Cc: Jarkko Sakkinen , Lai Yi , Jonathan McDowell , Roberto Sassu , Sasha Levin +Message-ID: <20251230003843.1889960-1-sashal@kernel.org> + +From: Jarkko Sakkinen + +[ Upstream commit faf07e611dfa464b201223a7253e9dc5ee0f3c9e ] + +tpm2_get_pcr_allocation() does not cap any upper limit for the number of +banks. Cap the limit to eight banks so that out of bounds values coming +from external I/O cause on only limited harm. + +Cc: stable@vger.kernel.org # v5.10+ +Fixes: bcfff8384f6c ("tpm: dynamically allocate the allocated_banks array") +Tested-by: Lai Yi +Reviewed-by: Jonathan McDowell +Reviewed-by: Roberto Sassu +Signed-off-by: Jarkko Sakkinen +[ added backward-compatible define for TPM_MAX_DIGEST_SIZE to support older ima_init.c code still using that macro name ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/char/tpm/tpm-chip.c | 1 - + drivers/char/tpm/tpm1-cmd.c | 5 ----- + drivers/char/tpm/tpm2-cmd.c | 8 +++----- + include/linux/tpm.h | 9 ++++++--- + 4 files changed, 9 insertions(+), 14 deletions(-) + +--- a/drivers/char/tpm/tpm-chip.c ++++ b/drivers/char/tpm/tpm-chip.c +@@ -269,7 +269,6 @@ static void tpm_dev_release(struct devic + + kfree(chip->work_space.context_buf); + kfree(chip->work_space.session_buf); +- kfree(chip->allocated_banks); + kfree(chip); + } + +--- a/drivers/char/tpm/tpm1-cmd.c ++++ b/drivers/char/tpm/tpm1-cmd.c +@@ -794,11 +794,6 @@ int tpm1_pm_suspend(struct tpm_chip *chi + */ + int tpm1_get_pcr_allocation(struct tpm_chip *chip) + { +- chip->allocated_banks = kcalloc(1, sizeof(*chip->allocated_banks), +- GFP_KERNEL); +- if (!chip->allocated_banks) +- return -ENOMEM; +- + chip->allocated_banks[0].alg_id = TPM_ALG_SHA1; + chip->allocated_banks[0].digest_size = hash_digest_size[HASH_ALGO_SHA1]; + chip->allocated_banks[0].crypto_id = HASH_ALGO_SHA1; +--- a/drivers/char/tpm/tpm2-cmd.c ++++ b/drivers/char/tpm/tpm2-cmd.c +@@ -574,11 +574,9 @@ ssize_t tpm2_get_pcr_allocation(struct t + + nr_possible_banks = be32_to_cpup( + (__be32 *)&buf.data[TPM_HEADER_SIZE + 5]); +- +- chip->allocated_banks = kcalloc(nr_possible_banks, +- sizeof(*chip->allocated_banks), +- GFP_KERNEL); +- if (!chip->allocated_banks) { ++ if (nr_possible_banks > TPM2_MAX_PCR_BANKS) { ++ pr_err("tpm: out of bank capacity: %u > %u\n", ++ nr_possible_banks, TPM2_MAX_PCR_BANKS); + rc = -ENOMEM; + goto out; + } +--- a/include/linux/tpm.h ++++ b/include/linux/tpm.h +@@ -25,7 +25,10 @@ + #include + + #define TPM_DIGEST_SIZE 20 /* Max TPM v1.2 PCR size */ +-#define TPM_MAX_DIGEST_SIZE SHA512_DIGEST_SIZE ++ ++#define TPM2_MAX_DIGEST_SIZE SHA512_DIGEST_SIZE ++#define TPM2_MAX_PCR_BANKS 8 ++#define TPM_MAX_DIGEST_SIZE TPM2_MAX_DIGEST_SIZE + + struct tpm_chip; + struct trusted_key_payload; +@@ -44,7 +47,7 @@ enum tpm_algorithms { + + struct tpm_digest { + u16 alg_id; +- u8 digest[TPM_MAX_DIGEST_SIZE]; ++ u8 digest[TPM2_MAX_DIGEST_SIZE]; + } __packed; + + struct tpm_bank_info { +@@ -150,7 +153,7 @@ struct tpm_chip { + unsigned int groups_cnt; + + u32 nr_allocated_banks; +- struct tpm_bank_info *allocated_banks; ++ struct tpm_bank_info allocated_banks[TPM2_MAX_PCR_BANKS]; + #ifdef CONFIG_ACPI + acpi_handle acpi_dev_handle; + char ppi_version[TPM_PPI_VERSION_LEN + 1]; diff --git a/queue-5.10/usb-dwc3-keep-susphy-enabled-during-exit-to-avoid-controller-faults.patch b/queue-5.10/usb-dwc3-keep-susphy-enabled-during-exit-to-avoid-controller-faults.patch new file mode 100644 index 0000000000..212020fa49 --- /dev/null +++ b/queue-5.10/usb-dwc3-keep-susphy-enabled-during-exit-to-avoid-controller-faults.patch @@ -0,0 +1,58 @@ +From stable+bounces-204239-greg=kroah.com@vger.kernel.org Tue Dec 30 16:58:39 2025 +From: Sasha Levin +Date: Tue, 30 Dec 2025 10:58:34 -0500 +Subject: usb: dwc3: keep susphy enabled during exit to avoid controller faults +To: stable@vger.kernel.org +Cc: Udipto Goswami , stable , Thinh Nguyen , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20251230155834.2291619-1-sashal@kernel.org> + +From: Udipto Goswami + +[ Upstream commit e1003aa7ec9eccdde4c926bd64ef42816ad55f25 ] + +On some platforms, switching USB roles from host to device can trigger +controller faults due to premature PHY power-down. This occurs when the +PHY is disabled too early during teardown, causing synchronization +issues between the PHY and controller. + +Keep susphy enabled during dwc3_host_exit() and dwc3_gadget_exit() +ensures the PHY remains in a low-power state capable of handling +required commands during role switch. + +Cc: stable +Fixes: 6d735722063a ("usb: dwc3: core: Prevent phy suspend during init") +Suggested-by: Thinh Nguyen +Signed-off-by: Udipto Goswami +Acked-by: Thinh Nguyen +Link: https://patch.msgid.link/20251126054221.120638-1-udipto.goswami@oss.qualcomm.com +Signed-off-by: Greg Kroah-Hartman +[ Adjust context ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc3/gadget.c | 2 +- + drivers/usb/dwc3/host.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -4109,7 +4109,7 @@ void dwc3_gadget_exit(struct dwc3 *dwc) + if (!dwc->gadget) + return; + +- dwc3_enable_susphy(dwc, false); ++ dwc3_enable_susphy(dwc, true); + usb_del_gadget(dwc->gadget); + dwc3_gadget_free_endpoints(dwc); + usb_put_gadget(dwc->gadget); +--- a/drivers/usb/dwc3/host.c ++++ b/drivers/usb/dwc3/host.c +@@ -155,7 +155,7 @@ err: + + void dwc3_host_exit(struct dwc3 *dwc) + { +- dwc3_enable_susphy(dwc, false); ++ dwc3_enable_susphy(dwc, true); + platform_device_unregister(dwc->xhci); + dwc->xhci = NULL; + } diff --git a/queue-5.10/usb-gadget-udc-fix-use-after-free-in-usb_gadget_state_work.patch b/queue-5.10/usb-gadget-udc-fix-use-after-free-in-usb_gadget_state_work.patch new file mode 100644 index 0000000000..8764ee2313 --- /dev/null +++ b/queue-5.10/usb-gadget-udc-fix-use-after-free-in-usb_gadget_state_work.patch @@ -0,0 +1,117 @@ +From stable+bounces-200373-greg=kroah.com@vger.kernel.org Mon Dec 8 22:06:27 2025 +From: Sasha Levin +Date: Mon, 8 Dec 2025 16:05:23 -0500 +Subject: usb: gadget: udc: fix use-after-free in usb_gadget_state_work +To: stable@vger.kernel.org +Cc: Jimmy Hu , stable , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20251208210523.401003-1-sashal@kernel.org> + +From: Jimmy Hu + +[ Upstream commit baeb66fbd4201d1c4325074e78b1f557dff89b5b ] + +A race condition during gadget teardown can lead to a use-after-free +in usb_gadget_state_work(), as reported by KASAN: + + BUG: KASAN: invalid-access in sysfs_notify+0x2c/0xd0 + Workqueue: events usb_gadget_state_work + +The fundamental race occurs because a concurrent event (e.g., an +interrupt) can call usb_gadget_set_state() and schedule gadget->work +at any time during the cleanup process in usb_del_gadget(). + +Commit 399a45e5237c ("usb: gadget: core: flush gadget workqueue after +device removal") attempted to fix this by moving flush_work() to after +device_del(). However, this does not fully solve the race, as a new +work item can still be scheduled *after* flush_work() completes but +before the gadget's memory is freed, leading to the same use-after-free. + +This patch fixes the race condition robustly by introducing a 'teardown' +flag and a 'state_lock' spinlock to the usb_gadget struct. The flag is +set during cleanup in usb_del_gadget() *before* calling flush_work() to +prevent any new work from being scheduled once cleanup has commenced. +The scheduling site, usb_gadget_set_state(), now checks this flag under +the lock before queueing the work, thus safely closing the race window. + +Fixes: 5702f75375aa9 ("usb: gadget: udc-core: move sysfs_notify() to a workqueue") +Cc: stable +Signed-off-by: Jimmy Hu +Link: https://patch.msgid.link/20251023054945.233861-1-hhhuuu@google.com +Signed-off-by: Greg Kroah-Hartman +[ Adjust context ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/udc/core.c | 17 ++++++++++++++++- + include/linux/usb/gadget.h | 5 +++++ + 2 files changed, 21 insertions(+), 1 deletion(-) + +--- a/drivers/usb/gadget/udc/core.c ++++ b/drivers/usb/gadget/udc/core.c +@@ -1037,8 +1037,13 @@ static void usb_gadget_state_work(struct + void usb_gadget_set_state(struct usb_gadget *gadget, + enum usb_device_state state) + { ++ unsigned long flags; ++ ++ spin_lock_irqsave(&gadget->state_lock, flags); + gadget->state = state; +- schedule_work(&gadget->work); ++ if (!gadget->teardown) ++ schedule_work(&gadget->work); ++ spin_unlock_irqrestore(&gadget->state_lock, flags); + } + EXPORT_SYMBOL_GPL(usb_gadget_set_state); + +@@ -1199,6 +1204,8 @@ void usb_initialize_gadget(struct device + void (*release)(struct device *dev)) + { + dev_set_name(&gadget->dev, "gadget"); ++ spin_lock_init(&gadget->state_lock); ++ gadget->teardown = false; + INIT_WORK(&gadget->work, usb_gadget_state_work); + gadget->dev.parent = parent; + +@@ -1376,6 +1383,7 @@ static void usb_gadget_remove_driver(str + void usb_del_gadget(struct usb_gadget *gadget) + { + struct usb_udc *udc = gadget->udc; ++ unsigned long flags; + + if (!udc) + return; +@@ -1394,6 +1402,13 @@ void usb_del_gadget(struct usb_gadget *g + mutex_unlock(&udc_lock); + + kobject_uevent(&udc->dev.kobj, KOBJ_REMOVE); ++ /* ++ * Set the teardown flag before flushing the work to prevent new work ++ * from being scheduled while we are cleaning up. ++ */ ++ spin_lock_irqsave(&gadget->state_lock, flags); ++ gadget->teardown = true; ++ spin_unlock_irqrestore(&gadget->state_lock, flags); + flush_work(&gadget->work); + device_unregister(&udc->dev); + device_del(&gadget->dev); +--- a/include/linux/usb/gadget.h ++++ b/include/linux/usb/gadget.h +@@ -341,6 +341,9 @@ struct usb_gadget_ops { + * @max_speed: Maximal speed the UDC can handle. UDC must support this + * and all slower speeds. + * @state: the state we are now (attached, suspended, configured, etc) ++ * @state_lock: Spinlock protecting the `state` and `teardown` members. ++ * @teardown: True if the device is undergoing teardown, used to prevent ++ * new work from being scheduled during cleanup. + * @name: Identifies the controller hardware type. Used in diagnostics + * and sometimes configuration. + * @dev: Driver model state for this abstract device. +@@ -408,6 +411,8 @@ struct usb_gadget { + enum usb_device_speed speed; + enum usb_device_speed max_speed; + enum usb_device_state state; ++ spinlock_t state_lock; ++ bool teardown; + const char *name; + struct device dev; + unsigned isoch_delay; diff --git a/queue-5.10/usb-ohci-nxp-fix-device-leak-on-probe-failure.patch b/queue-5.10/usb-ohci-nxp-fix-device-leak-on-probe-failure.patch new file mode 100644 index 0000000000..66c6818e9f --- /dev/null +++ b/queue-5.10/usb-ohci-nxp-fix-device-leak-on-probe-failure.patch @@ -0,0 +1,49 @@ +From stable+bounces-204218-greg=kroah.com@vger.kernel.org Tue Dec 30 14:41:30 2025 +From: Sasha Levin +Date: Tue, 30 Dec 2025 08:41:23 -0500 +Subject: usb: ohci-nxp: fix device leak on probe failure +To: stable@vger.kernel.org +Cc: Johan Hovold , Ma Ke , Alan Stern , Vladimir Zapolskiy , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20251230134123.2206998-2-sashal@kernel.org> + +From: Johan Hovold + +[ Upstream commit b4c61e542faf8c9131d69ecfc3ad6de96d1b2ab8 ] + +Make sure to drop the reference taken when looking up the PHY I2C device +during probe on probe failure (e.g. probe deferral) and on driver +unbind. + +Fixes: 73108aa90cbf ("USB: ohci-nxp: Use isp1301 driver") +Cc: stable@vger.kernel.org # 3.5 +Reported-by: Ma Ke +Link: https://lore.kernel.org/lkml/20251117013428.21840-1-make24@iscas.ac.cn/ +Signed-off-by: Johan Hovold +Acked-by: Alan Stern +Reviewed-by: Vladimir Zapolskiy +Link: https://patch.msgid.link/20251218153519.19453-4-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/ohci-nxp.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/usb/host/ohci-nxp.c ++++ b/drivers/usb/host/ohci-nxp.c +@@ -224,6 +224,7 @@ static int ohci_hcd_nxp_probe(struct pla + fail_resource: + usb_put_hcd(hcd); + fail_disable: ++ put_device(&isp1301_i2c_client->dev); + isp1301_i2c_client = NULL; + return ret; + } +@@ -235,6 +236,7 @@ static int ohci_hcd_nxp_remove(struct pl + usb_remove_hcd(hcd); + ohci_nxp_stop_hc(); + usb_put_hcd(hcd); ++ put_device(&isp1301_i2c_client->dev); + isp1301_i2c_client = NULL; + + return 0; diff --git a/queue-5.10/usb-ohci-nxp-use-helper-function-devm_clk_get_enabled.patch b/queue-5.10/usb-ohci-nxp-use-helper-function-devm_clk_get_enabled.patch new file mode 100644 index 0000000000..995b4a1ac2 --- /dev/null +++ b/queue-5.10/usb-ohci-nxp-use-helper-function-devm_clk_get_enabled.patch @@ -0,0 +1,93 @@ +From stable+bounces-204217-greg=kroah.com@vger.kernel.org Tue Dec 30 14:41:28 2025 +From: Sasha Levin +Date: Tue, 30 Dec 2025 08:41:22 -0500 +Subject: usb: ohci-nxp: Use helper function devm_clk_get_enabled() +To: stable@vger.kernel.org +Cc: Zhang Zekun , Alan Stern , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20251230134123.2206998-1-sashal@kernel.org> + +From: Zhang Zekun + +[ Upstream commit c146ede472717f352b7283a525bd9a1a2b15e2cf ] + +devm_clk_get() and clk_prepare_enable() can be replaced by helper +function devm_clk_get_enabled(). Let's use devm_clk_get_enabled() to +simplify code and avoid calling clk_disable_unprepare(). + +Signed-off-by: Zhang Zekun +Acked-by: Alan Stern +Link: https://lore.kernel.org/r/20240902123020.29267-3-zhangzekun11@huawei.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: b4c61e542faf ("usb: ohci-nxp: fix device leak on probe failure") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/ohci-nxp.c | 18 ++++-------------- + 1 file changed, 4 insertions(+), 14 deletions(-) + +--- a/drivers/usb/host/ohci-nxp.c ++++ b/drivers/usb/host/ohci-nxp.c +@@ -51,8 +51,6 @@ static struct hc_driver __read_mostly oh + + static struct i2c_client *isp1301_i2c_client; + +-static struct clk *usb_host_clk; +- + static void isp1301_configure_lpc32xx(void) + { + /* LPC32XX only supports DAT_SE0 USB mode */ +@@ -155,6 +153,7 @@ static int ohci_hcd_nxp_probe(struct pla + struct resource *res; + int ret = 0, irq; + struct device_node *isp1301_node; ++ struct clk *usb_host_clk; + + if (pdev->dev.of_node) { + isp1301_node = of_parse_phandle(pdev->dev.of_node, +@@ -180,26 +179,20 @@ static int ohci_hcd_nxp_probe(struct pla + } + + /* Enable USB host clock */ +- usb_host_clk = devm_clk_get(&pdev->dev, NULL); ++ usb_host_clk = devm_clk_get_enabled(&pdev->dev, NULL); + if (IS_ERR(usb_host_clk)) { +- dev_err(&pdev->dev, "failed to acquire USB OHCI clock\n"); ++ dev_err(&pdev->dev, "failed to acquire and start USB OHCI clock\n"); + ret = PTR_ERR(usb_host_clk); + goto fail_disable; + } + +- ret = clk_prepare_enable(usb_host_clk); +- if (ret < 0) { +- dev_err(&pdev->dev, "failed to start USB OHCI clock\n"); +- goto fail_disable; +- } +- + isp1301_configure(); + + hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); + if (!hcd) { + dev_err(&pdev->dev, "Failed to allocate HC buffer\n"); + ret = -ENOMEM; +- goto fail_hcd; ++ goto fail_disable; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +@@ -230,8 +223,6 @@ static int ohci_hcd_nxp_probe(struct pla + ohci_nxp_stop_hc(); + fail_resource: + usb_put_hcd(hcd); +-fail_hcd: +- clk_disable_unprepare(usb_host_clk); + fail_disable: + isp1301_i2c_client = NULL; + return ret; +@@ -244,7 +235,6 @@ static int ohci_hcd_nxp_remove(struct pl + usb_remove_hcd(hcd); + ohci_nxp_stop_hc(); + usb_put_hcd(hcd); +- clk_disable_unprepare(usb_host_clk); + isp1301_i2c_client = NULL; + + return 0; diff --git a/queue-5.10/xfs-fix-a-memory-leak-in-xfs_buf_item_init.patch b/queue-5.10/xfs-fix-a-memory-leak-in-xfs_buf_item_init.patch new file mode 100644 index 0000000000..1d2b360a5e --- /dev/null +++ b/queue-5.10/xfs-fix-a-memory-leak-in-xfs_buf_item_init.patch @@ -0,0 +1,38 @@ +From stable+bounces-204316-greg=kroah.com@vger.kernel.org Wed Dec 31 04:19:10 2025 +From: Sasha Levin +Date: Tue, 30 Dec 2025 22:19:04 -0500 +Subject: xfs: fix a memory leak in xfs_buf_item_init() +To: stable@vger.kernel.org +Cc: Haoxiang Li , Christoph Hellwig , Carlos Maiolino , Carlos Maiolino , Sasha Levin +Message-ID: <20251231031904.2685998-1-sashal@kernel.org> + +From: Haoxiang Li + +[ Upstream commit fc40459de82543b565ebc839dca8f7987f16f62e ] + +xfs_buf_item_get_format() may allocate memory for bip->bli_formats, +free the memory in the error path. + +Fixes: c3d5f0c2fb85 ("xfs: complain if anyone tries to create a too-large buffer log item") +Cc: stable@vger.kernel.org +Signed-off-by: Haoxiang Li +Reviewed-by: Christoph Hellwig +Reviewed-by: Carlos Maiolino +Signed-off-by: Carlos Maiolino +[ Adjust context ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/xfs_buf_item.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/fs/xfs/xfs_buf_item.c ++++ b/fs/xfs/xfs_buf_item.c +@@ -744,6 +744,7 @@ xfs_buf_item_init( + map_size = DIV_ROUND_UP(chunks, NBWORD); + + if (map_size > XFS_BLF_DATAMAP_SIZE) { ++ xfs_buf_item_free_format(bip); + kmem_cache_free(xfs_buf_item_zone, bip); + xfs_err(mp, + "buffer item dirty bitmap (%u uints) too small to reflect %u bytes!", diff --git a/queue-5.10/xhci-dbgtty-fix-device-unregister.patch b/queue-5.10/xhci-dbgtty-fix-device-unregister.patch new file mode 100644 index 0000000000..d95a31f79d --- /dev/null +++ b/queue-5.10/xhci-dbgtty-fix-device-unregister.patch @@ -0,0 +1,48 @@ +From stable+bounces-200349-greg=kroah.com@vger.kernel.org Mon Dec 8 14:01:46 2025 +From: Sasha Levin +Date: Mon, 8 Dec 2025 08:01:36 -0500 +Subject: xhci: dbgtty: fix device unregister +To: stable@vger.kernel.org +Cc: "Łukasz Bartosik" , stable , "Greg Kroah-Hartman" , "Sasha Levin" +Message-ID: <20251208130137.296454-1-sashal@kernel.org> + +From: Łukasz Bartosik + +[ Upstream commit 1f73b8b56cf35de29a433aee7bfff26cea98be3f ] + +When DbC is disconnected then xhci_dbc_tty_unregister_device() +is called. However if there is any user space process blocked +on write to DbC terminal device then it will never be signalled +and thus stay blocked indifinitely. + +This fix adds a tty_vhangup() call in xhci_dbc_tty_unregister_device(). +The tty_vhangup() wakes up any blocked writers and causes subsequent +write attempts to DbC terminal device to fail. + +Cc: stable +Fixes: dfba2174dc42 ("usb: xhci: Add DbC support in xHCI driver") +Signed-off-by: Łukasz Bartosik +Link: https://patch.msgid.link/20251119212910.1245694-1-ukaszb@google.com +Signed-off-by: Greg Kroah-Hartman +[ Adjust context ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/xhci-dbgtty.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/usb/host/xhci-dbgtty.c ++++ b/drivers/usb/host/xhci-dbgtty.c +@@ -468,6 +468,12 @@ static void xhci_dbc_tty_unregister_devi + + if (!port->registered) + return; ++ /* ++ * Hang up the TTY. This wakes up any blocked ++ * writers and causes subsequent writes to fail. ++ */ ++ tty_vhangup(port->port.tty); ++ + tty_unregister_device(dbc_tty_driver, 0); + xhci_dbc_tty_exit_port(port); + port->registered = false;