6.18.25-rc1 review
Greg Kroah-Hartman
maintainercover 6.18.25-rc1 review
This is the start of the stable review cycle for the 6.18.25 release. There are 55 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 26 Apr 2026 13:23:22 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.18.25-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.18.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 6.18.25-rc1
Anderson Nascimento <[email protected]>
rxrpc: Fix missing validation of ticket length in non-XDR key preparsing
Sean Christopherson <[email protected]>
crypto: ccp: Don't attempt to copy ID to userspace if PSP command failed
Sean Christopherson <[email protected]>
crypto: ccp: Don't attempt to copy PDH cert to userspace if PSP command failed
Sean Christopherson <[email protected]>
crypto: ccp: Don't attempt to copy CSR to userspace if PSP command failed
Bingquan Chen <[email protected]>
net/packet: fix TOCTOU race on mmap'd vnet_hdr in tpacket_snd()
Berk Cem Goksel <[email protected]>
ALSA: caiaq: take a reference on the USB device in create_card()
Eric Naim <[email protected]>
ALSA: hda/realtek: Add quirk for Legion S7 15IMH
Cryolitia PukNgae <[email protected]>
ALSA: usb-audio: apply quirk for MOONDROP JU Jiu
George Saad <[email protected]>
f2fs: fix use-after-free of sbi in f2fs_compress_write_end_io()
Jan Kara <[email protected]>
writeback: Fix use after free in inode_switch_wbs_work_fn()
DaeMyung Kang <[email protected]>
ksmbd: reset rcount per connection in ksmbd_conn_wait_idle_sess_id()
Tristan Madani <[email protected]>
ksmbd: use check_add_overflow() to prevent u16 DACL size overflow
Tristan Madani <[email protected]>
ksmbd: fix out-of-bounds write in smb2_get_ea() EA alignment
Michael Bommarito <[email protected]>
ksmbd: validate num_aces and harden ACE walk in smb_inherit_dacl()
Michael Bommarito <[email protected]>
ksmbd: validate response sizes in ipc_validate_msg()
Michael Bommarito <[email protected]>
smb: client: fix OOB read in smb2_ioctl_query_info QUERY_INFO path
Michael Bommarito <[email protected]>
smb: client: require a full NFS mode SID before reading mode bits
DaeMyung Kang <[email protected]>
smb: server: fix max_connections off-by-one in tcp accept path
Michael Bommarito <[email protected]>
smb: server: fix active_num_conn leak on transport allocation failure
Michael Bommarito <[email protected]>
ksmbd: require minimum ACE size in smb_check_perm_dacl()
Miklos Szeredi <[email protected]>
fuse: fuse_dev_ioctl_clone() should wait for device file to be initialized
Darrick J. Wong <[email protected]>
fuse: quiet down complaints in fuse_conn_limit_write
Bernd Schubert <[email protected]>
fuse: Check for large folio with SPLICE_F_MOVE
Miklos Szeredi <[email protected]>
fuse: abort on fatal signal during sync init
Samuel Page <[email protected]>
fuse: reject oversized dirents in page cache
Chao Yu <[email protected]>
f2fs: fix to avoid uninit-value access in f2fs_sanity_check_node_footer
Chao Yu <[email protected]>
f2fs: fix to avoid memory leak in f2fs_rename()
Yongpeng Yang <[email protected]>
f2fs: fix UAF caused by decrementing sbi->nr_pages[] in f2fs_write_end_io()
Chao Yu <[email protected]>
f2fs: fix to do sanity check on dcc->discard_cmd_cnt conditionally
Greg Kroah-Hartman <[email protected]>
fs/ntfs3: validate rec->used in journal-replay file record check
Nathan Chancellor <[email protected]>
scripts/dtc: Remove unused dts_version in dtc-lexer.l
Eric Biggers <[email protected]>
lib/crypto: tests: Drop the default to CRYPTO_SELFTESTS
Eric Biggers <[email protected]>
kunit: configs: Enable all crypto library tests in all_tests.config
Eric Biggers <[email protected]>
lib/crypto: tests: Introduce CRYPTO_LIB_ENABLE_ALL_FOR_KUNIT
Eric Biggers <[email protected]>
lib/crypto: tests: Add a .kunitconfig file
Eric Biggers <[email protected]>
kunit: configs: Enable all CRC tests in all_tests.config
Eric Biggers <[email protected]>
lib/crc: tests: Add a .kunitconfig file
Eric Biggers <[email protected]>
lib/crc: tests: Add CRC_ENABLE_ALL_FOR_KUNIT
Eric Biggers <[email protected]>
lib/crc: tests: Make crc_kunit test only the enabled CRC variants
Peter Zijlstra <[email protected]>
sched/debug: Fix avg_vruntime() usage
Catalin Marinas <[email protected]>
arm64: errata: Work around early CME DVMSync acknowledgement
Catalin Marinas <[email protected]>
arm64: cputype: Add C1-Pro definitions
Catalin Marinas <[email protected]>
arm64: tlb: Pass the corresponding mm to __tlbi_sync_s1ish()
Catalin Marinas <[email protected]>
arm64: tlb: Introduce __tlbi_sync_s1ish_{kernel,batch}() for TLB maintenance
Mark Rutland <[email protected]>
arm64: tlb: Optimize ARM64_WORKAROUND_REPEAT_TLBI
Mark Rutland <[email protected]>
arm64: tlb: Allow XZR argument to TLBI ops
Namjae Jeon <[email protected]>
ksmbd: validate owner of durable handle on reconnect
Namjae Jeon <[email protected]>
ksmbd: fix use-after-free in __ksmbd_close_fd() via durable scavenger
Tamir Duberstein <[email protected]>
scripts: generate_rust_analyzer.py: define scripts
Dudu Lu <[email protected]>
crypto: krb5enc - fix async decrypt skipping hash verification
Wesley Atwell <[email protected]>
crypto: krb5enc - fix sleepable flag handling in encrypt dispatch
Mikhail Gavrilov <[email protected]>
drm/amdgpu: replace PASID IDR with XArray
Daniel Golle <[email protected]>
net: ethernet: mtk_eth_soc: initialize PPE per-tag-layer MTU registers
Minhong He <[email protected]>
ipv6: add NULL checks for idev in SRv6 paths
Herbert Xu <[email protected]>
crypto: authencesn - Fix src offset when decrypting in-place
-------------
Diffstat:
Documentation/arch/arm64/silicon-errata.rst | 2 + Makefile | 4 +- arch/arm64/Kconfig | 12 +++ arch/arm64/include/asm/cpucaps.h | 2 + arch/arm64/include/asm/cputype.h | 2 + arch/arm64/include/asm/fpsimd.h | 21 ++++ arch/arm64/include/asm/tlbbatch.h | 10 +- arch/arm64/include/asm/tlbflush.h | 143 ++++++++++++++++++++++----- arch/arm64/kernel/cpu_errata.c | 30 ++++++ arch/arm64/kernel/entry-common.c | 3 + arch/arm64/kernel/fpsimd.c | 79 +++++++++++++++ arch/arm64/kernel/process.c | 36 +++++++ arch/arm64/kernel/sys_compat.c | 2 +- arch/arm64/kvm/hyp/nvhe/mm.c | 2 +- arch/arm64/kvm/hyp/nvhe/tlb.c | 8 +- arch/arm64/kvm/hyp/pgtable.c | 2 +- arch/arm64/kvm/hyp/vhe/tlb.c | 10 +- arch/arm64/tools/cpucaps | 1 + crypto/authencesn.c | 6 +- crypto/krb5enc.c | 51 ++++++---- drivers/crypto/ccp/sev-dev.c | 19 +++- drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c | 39 ++++---- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 22 ++++- drivers/net/ethernet/mediatek/mtk_ppe.c | 30 ++++++ drivers/net/ethernet/mediatek/mtk_ppe.h | 1 + fs/f2fs/compress.c | 14 ++- fs/f2fs/data.c | 7 +- fs/f2fs/f2fs.h | 2 +- fs/f2fs/namei.c | 1 + fs/f2fs/segment.c | 6 +- fs/f2fs/super.c | 11 ++- fs/fs-writeback.c | 36 +++---- fs/fuse/control.c | 4 +- fs/fuse/dev.c | 30 +++--- fs/fuse/fuse_i.h | 1 + fs/fuse/inode.c | 1 + fs/fuse/readdir.c | 4 + fs/ntfs3/fslog.c | 12 ++- fs/smb/client/cifsacl.c | 1 + fs/smb/client/smb2ops.c | 6 ++ fs/smb/server/connection.c | 5 +- fs/smb/server/mgmt/user_config.c | 6 -- fs/smb/server/mgmt/user_session.c | 7 +- fs/smb/server/oplock.c | 7 ++ fs/smb/server/oplock.h | 1 + fs/smb/server/smb2pdu.c | 5 +- fs/smb/server/smbacl.c | 61 +++++++++--- fs/smb/server/transport_ipc.c | 16 ++- fs/smb/server/transport_tcp.c | 4 +- fs/smb/server/vfs_cache.c | 128 ++++++++++++++++++++---- fs/smb/server/vfs_cache.h | 12 ++- kernel/sched/debug.c | 4 +- lib/crc/.kunitconfig | 3 + lib/crc/Kconfig | 21 ++-- lib/crc/tests/crc_kunit.c | 28 ++++-- lib/crypto/.kunitconfig | 11 +++ lib/crypto/tests/Kconfig | 32 ++++-- net/ipv6/exthdrs.c | 4 + net/ipv6/seg6_hmac.c | 2 + net/packet/af_packet.c | 21 ++-- net/rxrpc/key.c | 4 + scripts/dtc/dtc-lexer.l | 3 - scripts/generate_rust_analyzer.py | 14 ++- sound/hda/codecs/realtek/alc269.c | 1 + sound/usb/caiaq/device.c | 4 +- sound/usb/mixer.c | 7 ++ tools/testing/kunit/configs/all_tests.config | 4 + 67 files changed, 870 insertions(+), 218 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/55 crypto: authencesn - Fix src offset when decrypting in-place
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Herbert Xu <[email protected]>
commit 1f48ad3b19a9dfc947868edda0bb8e48e5b5a8fa upstream.
The src SG list offset wasn't set properly when decrypting in-place, fix it.
--- crypto/authencesn.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
crypto/authencesn.c +4 -2
@@ -228,9 +228,11 @@ static int crypto_authenc_esn_decrypt_ta decrypt: -if (src != dst) - src =scatterwalk_ffwd (areq_ctx->src, src, assoclen); dst =scatterwalk_ffwd (areq_ctx->dst, dst, assoclen); +if (req->src == req->dst) + src = dst; +else + src =scatterwalk_ffwd (areq_ctx->src, src, assoclen);skcipher_request_set_tfm (skreq, ctx->enc); skcipher_request_set_callback(skreq, flags,
Greg Kroah-Hartman
maintainerPATCH 2/55 ipv6: add NULL checks for idev in SRv6 paths
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Minhong He <[email protected]>
[ Upstream commit 06413793526251870e20402c39930804f14d59c0 ]
__in6_dev_get() can return NULL when the device has no IPv6 configuration (e.g. MTU < IPV6_MIN_MTU or after NETDEV_UNREGISTER).
Add NULL checks for idev returned by __in6_dev_get() in both seg6_hmac_validate_skb() and ipv6_srh_rcv() to prevent potential NULL pointer dereferences.
--- net/ipv6/exthdrs.c | 4 ++++ net/ipv6/seg6_hmac.c | 2 ++ 2 files changed, 6 insertions(+)
net/ipv6/exthdrs.c +4 -0
@@ -379,6 +379,10 @@ static int ipv6_srh_rcv(struct sk_buff *skb) hdr = (struct ipv6_sr_hdr *)skb_transport_header (skb); idev =__in6_dev_get (skb->dev); +if (!idev) { +kfree_skb (skb); +return -1 ; + } accept_seg6 =min (READ_ONCE (net->ipv6.devconf_all->seg6_enabled),READ_ONCE (idev->cnf.seg6_enabled));
net/ipv6/seg6_hmac.c +2 -0
@@ -184,6 +184,8 @@ bool seg6_hmac_validate_skb(struct sk_buff *skb)int require_hmac; idev =__in6_dev_get (skb->dev); +if (!idev) +return false; srh = (struct ipv6_sr_hdr *)skb_transport_header (skb);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 3/55 net: ethernet: mtk_eth_soc: initialize PPE per-tag-layer MTU registers
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Golle <[email protected]>
commit 2dddb34dd0d07b01fa770eca89480a4da4f13153 upstream.
The PPE enforces output frame size limits via per-tag-layer VLAN_MTU registers that the driver never initializes. The hardware defaults do not account for PPPoE overhead, causing the PPE to punt encapsulated frames back to the CPU instead of forwarding them.
Initialize the registers at PPE start and on MTU changes using the maximum GMAC MTU. This is a conservative approximation -- the actual per-PPE requirement depends on egress path, but using the global maximum ensures the limits are never too small.
--- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 22 ++++++++++++++- drivers/net/ethernet/mediatek/mtk_ppe.c | 30 +++++++++++++++++++++ drivers/net/ethernet/mediatek/mtk_ppe.h | 1 + 3 files changed, 52 insertions(+), 1 deletion(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +21 -1
@@ -3567,12 +3567,23 @@ static int mtk_device_event(struct notifier_block *n, unsigned long event, voidreturn NOTIFY_DONE ; } +static int mtk_max_gmac_mtu (struct mtk_eth *eth) +{ +int i, max_mtu =ETH_DATA_LEN ; + +for (i =0 ; i <ARRAY_SIZE (eth->netdev); i++) +if (eth->netdev[i] && eth->netdev[i]->mtu > max_mtu) + max_mtu = eth->netdev[i]->mtu; + +return max_mtu; +} +static int mtk_open (struct net_device *dev) {struct mtk_mac *mac =netdev_priv (dev);struct mtk_eth *eth = mac->hw;struct mtk_mac *target_mac; -int i, err, ppe_num; +int i, err, ppe_num, mtu; ppe_num = eth->soc->ppe_num;
@@ -3619,6 +3630,10 @@ static int mtk_open(struct net_device *dev)mtk_gdm_config (eth, target_mac->id, gdm_config); } + mtu =mtk_max_gmac_mtu (eth); +for (i =0 ; i <ARRAY_SIZE (eth->ppe); i++) +mtk_ppe_update_mtu (eth->ppe[i], mtu); +napi_enable (ð->tx_napi);napi_enable (ð->rx_napi);mtk_tx_irq_enable (eth,MTK_TX_DONE_INT );
@@ -4312,6 +4327,7 @@ static int mtk_change_mtu(struct net_device *dev, int new_mtu)int length = new_mtu +MTK_RX_ETH_HLEN ;struct mtk_mac *mac =netdev_priv (dev);struct mtk_eth *eth = mac->hw; +int max_mtu, i;if (rcu_access_pointer (eth->prog) && length >MTK_PP_MAX_BUF_SIZE ) {
@@ -4322,6 +4338,10 @@ static int mtk_change_mtu(struct net_device *dev, int new_mtu)mtk_set_mcr_max_rx (mac, length);WRITE_ONCE (dev->mtu, new_mtu); + max_mtu =mtk_max_gmac_mtu (eth); +for (i =0 ; i <ARRAY_SIZE (eth->ppe); i++) +mtk_ppe_update_mtu (eth->ppe[i], max_mtu); +return 0 ; }
drivers/net/ethernet/mediatek/mtk_ppe.c +30 -0
@@ -973,6 +973,36 @@ static void mtk_ppe_init_foe_table(struct mtk_ppe *ppe) } } +void mtk_ppe_update_mtu (struct mtk_ppe *ppe,int mtu) +{ +int base; +u32 val; + +if (!ppe) +return ; + +/* The PPE checks output frame size against per-tag-layer MTU limits, +* treating PPPoE and DSA tags just like 802.1Q VLAN tags. The Linux +* device MTU already accounts for PPPoE (PPPOE_SES_HLEN) and DSA tag +* overhead, but 802.1Q VLAN tags are handled transparently without +* being reflected by the lower device MTU being increased by 4. +* Use the maximum MTU across all GMAC interfaces so that PPE output +* frame limits are sufficiently high regardless of which port a flow +* egresses through. +*/ + base =ETH_HLEN + mtu; + + val =FIELD_PREP (MTK_PPE_VLAN_MTU0_NONE , base) | +FIELD_PREP (MTK_PPE_VLAN_MTU0_1TAG , base +VLAN_HLEN ); +ppe_w32 (ppe,MTK_PPE_VLAN_MTU0 , val); + + val =FIELD_PREP (MTK_PPE_VLAN_MTU1_2TAG , + base +2 *VLAN_HLEN ) | +FIELD_PREP (MTK_PPE_VLAN_MTU1_3TAG , + base +3 *VLAN_HLEN ); +ppe_w32 (ppe,MTK_PPE_VLAN_MTU1 , val); +} +void mtk_ppe_start (struct mtk_ppe *ppe) {u32 val;
drivers/net/ethernet/mediatek/mtk_ppe.h +1 -0
@@ -346,6 +346,7 @@ struct mtk_ppe {struct mtk_ppe *mtk_ppe_init (struct mtk_eth *eth,void __iomem *base,int index);void mtk_ppe_deinit (struct mtk_eth *eth); +void mtk_ppe_update_mtu (struct mtk_ppe *ppe,int mtu);void mtk_ppe_start (struct mtk_ppe *ppe);int mtk_ppe_stop (struct mtk_ppe *ppe);int mtk_ppe_prepare_reset (struct mtk_ppe *ppe);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 4/55 drm/amdgpu: replace PASID IDR with XArray
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikhail Gavrilov <[email protected]>
commit 3c863ff920b45fa7a9b7d4cb932f466488a87a58 upstream.
Replace the PASID IDR + spinlock with XArray as noted in the TODO left by commit ea56aa262570 ("drm/amdgpu: fix the idr allocation flags").
The IDR conversion still has an IRQ safety issue:amdgpu_pasid_free() can be called from hardirq context via the fence signal path, but amdgpu_pasid_idr_lock is taken with plain spin_lock() in process context, creating a potential deadlock:
CPU0
----
spin_lock(&amdgpu_pasid_idr_lock) // process context, IRQs on
<Interrupt>
spin_lock(&amdgpu_pasid_idr_lock) // deadlock
The hardirq call chain is:
sdma_v6_0_process_trap_irq
-> amdgpu_fence_process
-> dma_fence_signal
-> drm_sched_job_done
-> dma_fence_signal
-> amdgpu_pasid_free_cb
-> amdgpu_pasid_freeUse XArray with XA_FLAGS_LOCK_IRQ (all xa operations use IRQ-safe locking internally) and XA_FLAGS_ALLOC1 (zero is not a valid PASID). Both xa_alloc_cyclic() and xa_erase() then handle locking consistently, fixing the IRQ safety issue and removing the need for an explicit spinlock.
v8: squash in irq safe fix
--- drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c | 39 +++++++++++++++----------------- 1 file changed, 19 insertions(+), 20 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c +19 -20
@@ -22,7 +22,7 @@*/ #include "amdgpu_ids.h" -#include <linux/idr.h> +#include <linux/xarray.h> #include <linux/dma-fence-array.h>
@@ -40,8 +40,8 @@* VMs are looked up from the PASID per amdgpu_device. */ -static DEFINE_IDR (amdgpu_pasid_idr); -static DEFINE_SPINLOCK (amdgpu_pasid_idr_lock); +static DEFINE_XARRAY_FLAGS(amdgpu_pasid_xa, XA_FLAGS_LOCK_IRQ | XA_FLAGS_ALLOC1); +static u32 amdgpu_pasid_xa_next;/* Helper to free pasid from a fence callback */ struct amdgpu_pasid_cb {
@@ -62,36 +62,37 @@ struct amdgpu_pasid_cb {*/ int amdgpu_pasid_alloc (unsigned int bits) { -int pasid; +u32 pasid; +int r;if (bits ==0 )return -EINVAL ; -spin_lock (&amdgpu_pasid_idr_lock); -/* TODO: Need to replace the idr with an xarry, and then -* handle the internal locking with ATOMIC safe paths. -*/ - pasid =idr_alloc_cyclic (&amdgpu_pasid_idr,NULL ,1 , -1U << bits,GFP_ATOMIC ); -spin_unlock (&amdgpu_pasid_idr_lock); - -if (pasid >=0 ) -trace_amdgpu_pasid_allocated (pasid); + r =xa_alloc_cyclic_irq (&amdgpu_pasid_xa, &pasid,xa_mk_value (0 ), +XA_LIMIT (1 , (1U << bits) -1 ), + &amdgpu_pasid_xa_next,GFP_KERNEL ); +if (r <0 ) +return r; +trace_amdgpu_pasid_allocated (pasid);return pasid; }/** * amdgpu_pasid_free - Free a PASID * @pasid: PASID to free +* +* Called in IRQ context. */ void amdgpu_pasid_free (u32 pasid) { +unsigned long flags; +trace_amdgpu_pasid_freed (pasid); -spin_lock (&amdgpu_pasid_idr_lock); -idr_remove (&amdgpu_pasid_idr, pasid); -spin_unlock (&amdgpu_pasid_idr_lock); +xa_lock_irqsave (&amdgpu_pasid_xa, flags); +__xa_erase (&amdgpu_pasid_xa, pasid); +xa_unlock_irqrestore (&amdgpu_pasid_xa, flags); } static void amdgpu_pasid_free_cb(struct dma_fence *fence,
@@ -658,7 +659,5 @@ void amdgpu_vmid_mgr_fini(struct amdgpu_*/ void amdgpu_pasid_mgr_cleanup (void ) { -spin_lock (&amdgpu_pasid_idr_lock); -idr_destroy (&amdgpu_pasid_idr); -spin_unlock (&amdgpu_pasid_idr_lock); +xa_destroy (&amdgpu_pasid_xa); }
Greg Kroah-Hartman
maintainerPATCH 5/55 crypto: krb5enc - fix sleepable flag handling in encrypt dispatch
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wesley Atwell <[email protected]>
commit 2ef3bac16fb5e9eee4fb1d722578a79b751ea58a upstream.
krb5enc_encrypt_ahash_done() continues encryption from an ahash completion callback by calling krb5enc_dispatch_encrypt().
That helper takes a flags argument for this continuation path, but it ignored that argument and reused aead_request_flags(req) when setting up the skcipher subrequest callback. This can incorrectly preserve CRYPTO_TFM_REQ_MAY_SLEEP when the encrypt step is started from callback context.
Preserve the original request flags but clear CRYPTO_TFM_REQ_MAY_SLEEP for the callback continuation path, and use the caller-supplied flags when setting up the skcipher subrequest.
--- crypto/krb5enc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
crypto/krb5enc.c +3 -2
@@ -154,7 +154,7 @@ static int krb5enc_dispatch_encrypt(stru dst =scatterwalk_ffwd (areq_ctx->dst, req->dst, req->assoclen);skcipher_request_set_tfm (skreq, enc); -skcipher_request_set_callback (skreq,aead_request_flags (req), +skcipher_request_set_callback (skreq, flags, krb5enc_encrypt_done, req);skcipher_request_set_crypt (skreq, src, dst, req->cryptlen, req->iv);
@@ -192,7 +192,8 @@ static void krb5enc_encrypt_ahash_done(vkrb5enc_insert_checksum (req, ahreq->result); - err =krb5enc_dispatch_encrypt (req,0 ); + err =krb5enc_dispatch_encrypt (req, +aead_request_flags (req) & ~CRYPTO_TFM_REQ_MAY_SLEEP );if (err != -EINPROGRESS )aead_request_complete (req, err); }
Greg Kroah-Hartman
maintainerPATCH 6/55 crypto: krb5enc - fix async decrypt skipping hash verification
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dudu Lu <[email protected]>
commit 3bfbf5f0a99c991769ec562721285df7ab69240b upstream.
krb5enc_dispatch_decrypt() sets req->base.complete as the skcipher callback, which is the caller's own completion handler. When the skcipher completes asynchronously, this signals "done" to the caller without executing krb5enc_dispatch_decrypt_hash(), completely bypassing the integrity verification (hash check).
Compare with the encrypt path which correctly uses krb5enc_encrypt_done as an intermediate callback to chain into the hash computation on async completion.
Fix by adding krb5enc_decrypt_done as an intermediate callback that chains into krb5enc_dispatch_decrypt_hash() upon async skcipher completion, matching the encrypt path's callback pattern.
Also fix EBUSY/EINPROGRESS handling throughout: remove krb5enc_request_complete() which incorrectly swallowed EINPROGRESS notifications that must be passed up to callers waiting on backlogged requests, and add missing EBUSY checks in krb5enc_encrypt_ahash_done for the dispatch_encrypt return value.
Unset MAY_BACKLOG on the async completion path so the user won't see back-to-back EINPROGRESS notifications.
--- crypto/krb5enc.c | 52 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 21 deletions(-)
crypto/krb5enc.c +31 -21
@@ -39,12 +39,6 @@ struct krb5enc_request_ctx {char tail[]; }; -static void krb5enc_request_complete (struct aead_request *req,int err) -{ -if (err != -EINPROGRESS ) -aead_request_complete (req, err); -} -/** * crypto_krb5enc_extractkeys - Extract Ke and Ki keys from the key blob. * @keys: Where to put the key sizes and pointers
@@ -127,7 +121,7 @@ static void krb5enc_encrypt_done(void *d {struct aead_request *req = data; -krb5enc_request_complete (req, err); +aead_request_complete (req, err); }/*
@@ -188,14 +182,16 @@ static void krb5enc_encrypt_ahash_done(vstruct ahash_request *ahreq = (void *)(areq_ctx->tail + ictx->reqoff);if (err) -return krb5enc_request_complete (req, err); + goto out;krb5enc_insert_checksum (req, ahreq->result); - err =krb5enc_dispatch_encrypt (req, -aead_request_flags (req) & ~CRYPTO_TFM_REQ_MAY_SLEEP ); -if (err != -EINPROGRESS ) -aead_request_complete (req, err); + err =krb5enc_dispatch_encrypt (req,0 ); +if (err == -EINPROGRESS ) +return ; + +out: +aead_request_complete (req, err); }/*
@@ -265,17 +261,16 @@ static void krb5enc_decrypt_hash_done(vo {struct aead_request *req = data; -if (err) -return krb5enc_request_complete (req, err); - - err =krb5enc_verify_hash (req); -krb5enc_request_complete (req, err); +if (!err) + err =krb5enc_verify_hash (req); +aead_request_complete (req, err); }/* * Dispatch the hashing of the plaintext after we've done the decryption. */ -static int krb5enc_dispatch_decrypt_hash (struct aead_request *req) +static int krb5enc_dispatch_decrypt_hash (struct aead_request *req, +unsigned int flags) {struct crypto_aead *krb5enc =crypto_aead_reqtfm (req);struct aead_instance *inst =aead_alg_instance (krb5enc);
@@ -291,7 +286,7 @@ static int krb5enc_dispatch_decrypt_hashahash_request_set_tfm (ahreq, auth);ahash_request_set_crypt (ahreq, req->dst, hash, req->assoclen + req->cryptlen - authsize); -ahash_request_set_callback (ahreq,aead_request_flags (req), +ahash_request_set_callback (ahreq, flags, krb5enc_decrypt_hash_done, req); err =crypto_ahash_digest (ahreq);
@@ -301,6 +296,21 @@ static int krb5enc_dispatch_decrypt_hashreturn krb5enc_verify_hash (req); } +static void krb5enc_decrypt_done (void *data,int err) +{ +struct aead_request *req = data; + +if (err) + goto out; + + err =krb5enc_dispatch_decrypt_hash (req,0 ); +if (err == -EINPROGRESS ) +return ; + +out: +aead_request_complete (req, err); +} +/* * Dispatch the decryption of the ciphertext. */
@@ -324,7 +334,7 @@ static int krb5enc_dispatch_decrypt(struskcipher_request_set_tfm (skreq, ctx->enc);skcipher_request_set_callback (skreq,aead_request_flags (req), - req->base.complete, req->base.data); + krb5enc_decrypt_done, req);skcipher_request_set_crypt (skreq, src, dst, req->cryptlen - authsize, req->iv);
@@ -339,7 +349,7 @@ static int krb5enc_decrypt(struct aead_rif (err <0 )return err; -return krb5enc_dispatch_decrypt_hash (req); +return krb5enc_dispatch_decrypt_hash (req,aead_request_flags (req)); }static int krb5enc_init_tfm (struct crypto_aead *tfm)
Greg Kroah-Hartman
maintainerPATCH 7/55 scripts: generate_rust_analyzer.py: define scripts
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tamir Duberstein <[email protected]>
[ Upstream commit 36c619f6bd793493294becb10a02fea370b67a91 ]
Add IDE support for host-side scripts written in Rust. This support has been missing since these scripts were initially added in commit 9a8ff24ce584 ("scripts: add generate_rust_target.rs"), thus add it.
Change the existing instance of extension stripping to pathlib.Path.stem to maintain code consistency.
--- scripts/generate_rust_analyzer.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
scripts/generate_rust_analyzer.py +13 -1
@@ -166,6 +166,18 @@ def generate_crates(srctree, objtree, sy append_crate_with_generated("uapi", ["core", "ffi", "pin_init"]) append_crate_with_generated("kernel", ["core", "macros", "build_error", "pin_init", "ffi", "bindings", "uapi"]) + scripts = srctree / "scripts" + makefile = (scripts / "Makefile").read_text() + for path in scripts.glob("*.rs"): + name = path.stem + if f"{name}-rust" not in makefile: + continue + append_crate( + name, + path, + ["std"], + ) + def is_root_crate(build_file, target): try: contents = build_file.read_text()
@@ -182,7 +194,7 @@ def generate_crates(srctree, objtree, sy for folder in extra_dirs: for path in folder.rglob("*.rs"): logging.info("Checking %s", path) - name = path.name.replace(".rs", "") + name = path.stem # Skip those that are not crate roots. if not is_root_crate(path.parent / "Makefile", name) and \
Greg Kroah-Hartman
maintainerPATCH 8/55 ksmbd: fix use-after-free in __ksmbd_close_fd() via durable scavenger
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <[email protected]>
[ Upstream commit 235e32320a470fcd3998fb3774f2290a0eb302a1 ]
When a durable file handle survives session disconnect (TCP close without SMB2_LOGOFF), session_fd_check() sets fp->conn = NULL to preserve the handle for later reconnection. However, it did not clean up the byte-range locks on fp->lock_list.
Later, when the durable scavenger thread times out and calls __ksmbd_close_fd(NULL, fp), the lock cleanup loop did:
spin_lock(&fp->conn->llist_lock);
This caused a slab use-after-free because fp->conn was NULL and the original connection object had already been freed by ksmbd_tcp_disconnect().
The root cause is asymmetric cleanup: lock entries (smb_lock->clist) were left dangling on the freed conn->lock_list while fp->conn was nulled out.
To fix this issue properly, we need to handle the lifetime of smb_lock->clist across three paths:
- Safely skip clist deletion when list is empty and fp->conn is NULL.
- Remove the lock from the old connection's lock_list in session_fd_check()
- Re-add the lock to the new connection's lock_list in ksmbd_reopen_durable_fd().
Stable-dep-of: 49110a8ce654 ("ksmbd: validate owner of durable handle on reconnect")
--- fs/smb/server/vfs_cache.c | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-)
fs/smb/server/vfs_cache.c +30 -11
@@ -370,9 +370,11 @@ static void __ksmbd_close_fd(struct ksmb* there are not accesses to fp->lock_list. */ list_for_each_entry_safe (smb_lock, tmp_lock, &fp->lock_list, flist) { -spin_lock (&fp->conn->llist_lock); -list_del (&smb_lock->clist); -spin_unlock (&fp->conn->llist_lock); +if (!list_empty (&smb_lock->clist) && fp->conn) { +spin_lock (&fp->conn->llist_lock); +list_del (&smb_lock->clist); +spin_unlock (&fp->conn->llist_lock); + }list_del (&smb_lock->flist);locks_free_lock (smb_lock->fl);
@@ -902,6 +904,7 @@ static bool session_fd_check(struct ksmbstruct ksmbd_inode *ci;struct oplock_info *op;struct ksmbd_conn *conn; +struct ksmbd_lock *smb_lock, *tmp_lock;if (!is_reconnectable (fp))return false;
@@ -918,6 +921,12 @@ static bool session_fd_check(struct ksmb }up_write (&ci->m_lock); +list_for_each_entry_safe (smb_lock, tmp_lock, &fp->lock_list, flist) { +spin_lock (&fp->conn->llist_lock); +list_del_init (&smb_lock->clist); +spin_unlock (&fp->conn->llist_lock); + } + fp->conn =NULL ; fp->tcon =NULL ; fp->volatile_id =KSMBD_NO_FID ;
@@ -996,6 +1005,9 @@ int ksmbd_reopen_durable_fd(struct ksmbd {struct ksmbd_inode *ci;struct oplock_info *op; +struct ksmbd_conn *conn = work->conn; +struct ksmbd_lock *smb_lock; +unsigned int old_f_state;if (!fp->is_durable || fp->conn || fp->tcon) {pr_err ("Invalid durable fd [%p:%p]\n" , fp->conn, fp->tcon);
@@ -1007,9 +1019,23 @@ int ksmbd_reopen_durable_fd(struct ksmbdreturn -EBADF ; } - fp->conn = work->conn; + old_f_state = fp->f_state; + fp->f_state =FP_NEW ; +__open_id (&work->sess->file_table, fp,OPEN_ID_TYPE_VOLATILE_ID ); +if (!has_file_id (fp->volatile_id)) { + fp->f_state = old_f_state; +return -EBADF ; + } + + fp->conn = conn; fp->tcon = work->tcon; +list_for_each_entry (smb_lock, &fp->lock_list, flist) { +spin_lock (&conn->llist_lock); +list_add_tail (&smb_lock->clist, &conn->lock_list); +spin_unlock (&conn->llist_lock); + } + ci = fp->f_ci;down_write (&ci->m_lock);list_for_each_entry_rcu (op, &ci->m_op_list, op_entry) {
@@ -1020,13 +1046,6 @@ int ksmbd_reopen_durable_fd(struct ksmbd }up_write (&ci->m_lock); - fp->f_state =FP_NEW ; -__open_id (&work->sess->file_table, fp,OPEN_ID_TYPE_VOLATILE_ID ); -if (!has_file_id (fp->volatile_id)) { - fp->conn =NULL ; - fp->tcon =NULL ; -return -EBADF ; - }return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 9/55 ksmbd: validate owner of durable handle on reconnect
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <[email protected]>
[ Upstream commit 49110a8ce654bbe56bef7c5e44cce31f4b102b8a ]
Currently, ksmbd does not verify if the user attempting to reconnect to a durable handle is the same user who originally opened the file. This allows any authenticated user to hijack an orphaned durable handle by predicting or brute-forcing the persistent ID.
According to MS-SMB2, the server MUST verify that the SecurityContext of the reconnect request matches the SecurityContext associated with the existing open.
Add a durable_owner structure to ksmbd_file to store the original opener's UID, GID, and account name. and catpure the owner information when a file handle becomes orphaned. and implementing ksmbd_vfs_compare_durable_owner() to validate the identity of the requester during SMB2_CREATE (DHnC).
--- fs/smb/server/mgmt/user_session.c | 7 +-- fs/smb/server/oplock.c | 7 +++ fs/smb/server/oplock.h | 1 fs/smb/server/smb2pdu.c | 3 - fs/smb/server/vfs_cache.c | 87 ++++++++++++++++++++++++++++++++++---- fs/smb/server/vfs_cache.h | 12 ++++- 6 files changed, 102 insertions(+), 15 deletions(-)
fs/smb/server/mgmt/user_session.c +3 -4
@@ -161,11 +161,10 @@ void ksmbd_session_destroy(struct ksmbd_if (!sess)return ; +ksmbd_tree_conn_session_logoff (sess); +ksmbd_destroy_file_table (sess);if (sess->user)ksmbd_free_user (sess->user); - -ksmbd_tree_conn_session_logoff (sess); -ksmbd_destroy_file_table (&sess->file_table);ksmbd_launch_ksmbd_durable_scavenger ();ksmbd_session_rpc_clear_list (sess);free_channel_list (sess);
@@ -396,7 +395,7 @@ void destroy_previous_session(struct ksm goto out; } -ksmbd_destroy_file_table (&prev_sess->file_table); +ksmbd_destroy_file_table (prev_sess); prev_sess->state =SMB2_SESSION_EXPIRED ;ksmbd_all_conn_set_status (id,KSMBD_SESS_NEED_SETUP );ksmbd_launch_ksmbd_durable_scavenger ();
fs/smb/server/oplock.c +7 -0
@@ -1841,6 +1841,7 @@ int smb2_check_durable_oplock(struct ksmstruct ksmbd_share_config *share, struct ksmbd_file *fp, struct lease_ctx_info *lctx, + struct ksmbd_user *user, char *name) { struct oplock_info *opinfo = opinfo_get(fp);
@@ -1849,6 +1850,12 @@ int smb2_check_durable_oplock(struct ksmif (!opinfo)return 0 ; +if (ksmbd_vfs_compare_durable_owner (fp, user) == false) { +ksmbd_debug (SMB ,"Durable handle reconnect failed: owner mismatch\n" ); + ret = -EBADF ; + goto out; + } +if (opinfo->is_lease == false) {if (lctx) {pr_err ("create context include lease\n" );
fs/smb/server/oplock.h +1 -0
@@ -126,5 +126,6 @@ int smb2_check_durable_oplock(struct ksmstruct ksmbd_share_config *share, struct ksmbd_file *fp, struct lease_ctx_info *lctx, + struct ksmbd_user *user, char *name);#endif /* __KSMBD_OPLOCK_H */
fs/smb/server/smb2pdu.c +2 -1
@@ -3022,7 +3022,8 @@ int smb2_open(struct ksmbd_work *work) }if (dh_info.reconnected == true) { - rc =smb2_check_durable_oplock (conn, share, dh_info.fp, lc, name); + rc =smb2_check_durable_oplock (conn, share, dh_info.fp, + lc, sess->user, name);if (rc) {ksmbd_put_durable_fd (dh_info.fp); goto err_out2;
fs/smb/server/vfs_cache.c +78 -9
161 lines not on this page · raw message
fs/smb/server/vfs_cache.h +11 -1
@@ -68,6 +68,13 @@ enum {FP_CLOSED }; +/* Owner information for durable handle reconnect */ +struct durable_owner { +unsigned int uid; +unsigned int gid; +char *name; +}; +struct ksmbd_file {struct file *filp;u64 persistent_id;
@@ -114,6 +121,7 @@ struct ksmbd_file {bool is_resilient;bool is_posix_ctxt; +struct durable_owner owner; }; static inline void set_ctx_actor(struct dir_context *ctx,
@@ -140,7 +148,7 @@ static inline bool ksmbd_stream_fd(struc }int ksmbd_init_file_table (struct ksmbd_file_table *ft); -void ksmbd_destroy_file_table (struct ksmbd_file_table *ft); +void ksmbd_destroy_file_table (struct ksmbd_session *sess);int ksmbd_close_fd (struct ksmbd_work *work,u64 id);struct ksmbd_file *ksmbd_lookup_fd_fast (struct ksmbd_work *work,u64 id);struct ksmbd_file *ksmbd_lookup_foreign_fd (struct ksmbd_work *work,u64 id);
@@ -166,6 +174,8 @@ void ksmbd_free_global_file_table(void);void ksmbd_set_fd_limit (unsigned long limit);void ksmbd_update_fstate (struct ksmbd_file_table *ft,struct ksmbd_file *fp,unsigned int state); +bool ksmbd_vfs_compare_durable_owner (struct ksmbd_file *fp, +struct ksmbd_user *user);/* * INODE hash
Greg Kroah-Hartman
maintainerPATCH 10/55 arm64: tlb: Allow XZR argument to TLBI ops
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Rutland <[email protected]>
commit bfd9c931d19aa59fb8371d557774fa169b15db9a upstream.
The TLBI instruction accepts XZR as a register argument, and for TLBI operations with a register argument, there is no functional difference between using XZR or another GPR which contains zeroes. Operations without a register argument are encoded as if XZR were used.
Allow the __TLBI_1() macro to use XZR when a register argument is all zeroes.
Today this only results in a trivial code saving in __do_compat_cache_op()'s workaround for Neoverse-N1 erratum #1542419. In subsequent patches this pattern will be used more generally.
There should be no functional change as a result of this patch.
--- arch/arm64/include/asm/tlbflush.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/arm64/include/asm/tlbflush.h +3 -3
@@ -38,12 +38,12 @@ : : )#define __TLBI_1 (op, arg) asm (ARM64_ASM_PREAMBLE \ - "tlbi " #op ", %0\n" \ + "tlbi " #op ", %x0\n" \ ALTERNATIVE("nop\n nop", \ - "dsb ish\n tlbi " #op ", %0", \ + "dsb ish\n tlbi " #op ", %x0", \ ARM64_WORKAROUND_REPEAT_TLBI, \ CONFIG_ARM64_WORKAROUND_REPEAT_TLBI) \ - : : "r" (arg)) + : : "rZ" (arg))#define __TLBI_N (op, arg, n, ...) __TLBI_##n(op, arg)
Greg Kroah-Hartman
maintainerPATCH 11/55 arm64: tlb: Optimize ARM64_WORKAROUND_REPEAT_TLBI
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Rutland <[email protected]>
commit a8f78680ee6bf795086384e8aea159a52814f827 upstream.
The ARM64_WORKAROUND_REPEAT_TLBI workaround is used to mitigate several errata where broadcast TLBI;DSB sequences don't provide all the architecturally required synchronization. The workaround performs more work than necessary, and can have significant overhead. This patch optimizes the workaround, as explained below.
The workaround was originally added for Qualcomm Falkor erratum 1009 in commit:
d9ff80f83ecb ("arm64: Work around Falkor erratum 1009")
As noted in the message for that commit, the workaround is applied even in cases where it is not strictly necessary.
The workaround was later reused without changes for:
* Arm Cortex-A76 erratum #1286807
SDEN v33: https://developer.arm.com/documentation/SDEN-885749/33-0/
* Arm Cortex-A55 erratum #2441007
SDEN v16: https://developer.arm.com/documentation/SDEN-859338/1600/
* Arm Cortex-A510 erratum #2441009
SDEN v19: https://developer.arm.com/documentation/SDEN-1873351/1900/
The important details to note are as follows:
1. All relevant errata only affect the ordering and/or completion of memory accesses which have been translated by an invalidated TLB entry. The actual invalidation of TLB entries is unaffected.
2. The existing workaround is applied to both broadcast and local TLB invalidation, whereas for all relevant errata it is only necessary to apply a workaround for broadcast invalidation.
3. The existing workaround replaces every TLBI with a TLBI;DSB;TLBI sequence, whereas for all relevant errata it is only necessary to execute a single additional TLBI;DSB sequence after any number of TLBIs are completed by a DSB.
For example, for a sequence of batched TLBIs:
TLBI <op1>[, <arg1>]
TLBI <op2>[, <arg2>]
TLBI <op3>[, <arg3>]
DSB ISH... the existing workaround will expand this to:
TLBI <op1>[, <arg1>]
DSB ISH // additional
TLBI <op1>[, <arg1>] // additional
TLBI <op2>[, <arg2>]
DSB ISH // additional
TLBI <op2>[, <arg2>] // additional
TLBI <op3>[, <arg3>]
DSB ISH // additional
TLBI <op3>[, <arg3>] // additional
DSB ISH... whereas it is sufficient to have:
TLBI <op1>[, <arg1>]
TLBI <op2>[, <arg2>]
TLBI <op3>[, <arg3>]
DSB ISH
TLBI <opX>[, <argX>] // additional
DSB ISH // additionalUsing a single additional TBLI and DSB at the end of the sequence can have significantly lower overhead as each DSB which completes a TLBI must synchronize with other PEs in the system, with potential performance effects both locally and system-wide.
4. The existing workaround repeats each specific TLBI operation, whereas for all relevant errata it is sufficient for the additional TLBI to use *any* operation which will be broadcast, regardless of which translation regime or stage of translation the operation applies to.
For example, for a single TLBI:
TLBI ALLE2IS
DSB ISH
... the existing workaround will expand this to:
TLBI ALLE2IS
DSB ISH
TLBI ALLE2IS // additional
DSB ISH // additional
... whereas it is sufficient to have:
TLBI ALLE2IS
DSB ISH
TLBI VALE1IS, XZR // additional
DSB ISH // additional
As the additional TLBI doesn't have to match a specific earlier TLBI, the additional TLBI can be implemented in separate code, with no memory of the earlier TLBIs. The additional TLBI can also use a cheaper TLBI operation.
5. The existing workaround is applied to both Stage-1 and Stage-2 TLB invalidation, whereas for all relevant errata it is only necessary to apply a workaround for Stage-1 invalidation.
Architecturally, TLBI operations which invalidate only Stage-2 information (e.g. IPAS2E1IS) are not required to invalidate TLB entries which combine information from Stage-1 and Stage-2 translation table entries, and consequently may not complete memory accesses translated by those combined entries. In these cases, completion of memory accesses is only guaranteed after subsequent invalidation of Stage-1 information (e.g. VMALLE1IS).
Taking the above points into account, this patch reworks the workaround logic to reduce overhead:
* New __tlbi_sync_s1ish() and __tlbi_sync_s1ish_hyp() functions are added and used in place of any dsb(ish) which is used to complete broadcast Stage-1 TLB maintenance. When the ARM64_WORKAROUND_REPEAT_TLBI workaround is enabled, these helpers will execute an additional TLBI;DSB sequence.
For consistency, it might make sense to add __tlbi_sync_*() helpers for local and stage 2 maintenance. For now I've left those with open-coded dsb() to keep the diff small.
* The duplication of TLBIs in __TLBI_0() and __TLBI_1() is removed. This is no longer needed as the necessary synchronization will happen in __tlbi_sync_s1ish() or __tlbi_sync_s1ish_hyp().
* The additional TLBI operation is chosen to have minimal impact:
- __tlbi_sync_s1ish() uses "TLBI VALE1IS, XZR". This is only used at EL1 or at EL2 with {E2H,TGE}=={1,1}, where it will target an unused entry for the reserved ASID in the kernel's own translation regime, and have no adverse affect.
- __tlbi_sync_s1ish_hyp() uses "TLBI VALE2IS, XZR". This is only used in hyp code, where it will target an unused entry in the hyp code's TTBR0 mapping, and should have no adverse effect.
* As __TLBI_0() and __TLBI_1() no longer replace each TLBI with a TLBI;DSB;TLBI sequence, batching TLBIs is worthwhile, and there's no need for arch_tlbbatch_should_defer() to consider ARM64_WORKAROUND_REPEAT_TLBI.
When building defconfig with GCC 15.1.0, compared to v6.19-rc1, this patch saves ~1KiB of text, makes the vmlinux ~42KiB smaller, and makes the resulting Image 64KiB smaller:
| [mark@lakrids:~/src/linux]% size vmlinux-* | text data bss dec hex filename | 21179831 19660919 708216 41548966 279fca6 vmlinux-after | 21181075 19660903 708216 41550194 27a0172 vmlinux-before | [mark@lakrids:~/src/linux]% ls -l vmlinux-* | -rwxr-xr-x 1 mark mark 157771472 Feb 4 12:05 vmlinux-after | -rwxr-xr-x 1 mark mark 157815432 Feb 4 12:05 vmlinux-before | [mark@lakrids:~/src/linux]% ls -l Image-* | -rw-r--r-- 1 mark mark 41007616 Feb 4 12:05 Image-after | -rw-r--r-- 1 mark mark 41073152 Feb 4 12:05 Image-before
--- arch/arm64/include/asm/tlbflush.h | 59 ++++++++++++++++++++++---------------- arch/arm64/kernel/sys_compat.c | 2 - arch/arm64/kvm/hyp/nvhe/mm.c | 2 - arch/arm64/kvm/hyp/nvhe/tlb.c | 8 ++--- arch/arm64/kvm/hyp/pgtable.c | 2 - arch/arm64/kvm/hyp/vhe/tlb.c | 10 +++--- 6 files changed, 47 insertions(+), 36 deletions(-)
arch/arm64/include/asm/tlbflush.h +35 -24
@@ -31,18 +31,10 @@*/ #define __TLBI_0 (op, arg) asm (ARM64_ASM_PREAMBLE \ "tlbi " #op "\n" \ - ALTERNATIVE("nop\n nop", \ - "dsb ish\n tlbi " #op, \ - ARM64_WORKAROUND_REPEAT_TLBI, \ - CONFIG_ARM64_WORKAROUND_REPEAT_TLBI) \ : : )#define __TLBI_1 (op, arg) asm (ARM64_ASM_PREAMBLE \ "tlbi " #op ", %x0\n" \ - ALTERNATIVE("nop\n nop", \ - "dsb ish\n tlbi " #op ", %x0", \ - ARM64_WORKAROUND_REPEAT_TLBI, \ - CONFIG_ARM64_WORKAROUND_REPEAT_TLBI) \ : : "rZ" (arg))#define __TLBI_N (op, arg, n, ...) __TLBI_##n(op, arg)
@@ -181,6 +173,34 @@ static inline unsigned long get_trans_gr (__pages >> (5 * (scale) +1 )) -1 ; \ }) +#define __repeat_tlbi_sync(op, arg...) \ +do { \ + if (!alternative_has_cap_unlikely(ARM64_WORKAROUND_REPEAT_TLBI)) \ + break; \ + __tlbi(op, ##arg); \ + dsb(ish); \ +} while (0) + +/* +* Complete broadcast TLB maintenance issued by the host which invalidates +* stage 1 information in the host's own translation regime. +*/ +static inline void __tlbi_sync_s1ish (void ) +{ +dsb (ish); +__repeat_tlbi_sync (vale1is,0 ); +} + +/* +* Complete broadcast TLB maintenance issued by hyp code which invalidates +* stage 1 translation information in any translation regime. +*/ +static inline void __tlbi_sync_s1ish_hyp (void ) +{ +dsb (ish); +__repeat_tlbi_sync (vale2is,0 ); +} +/* * TLB Invalidation * ================
@@ -266,7 +286,7 @@ static inline void flush_tlb_all(void) {dsb (ishst);__tlbi (vmalle1is); -dsb (ish); +__tlbi_sync_s1ish ();isb (); }
@@ -278,7 +298,7 @@ static inline void flush_tlb_mm(struct m asid =__TLBI_VADDR (0 ,ASID (mm));__tlbi (aside1is, asid);__tlbi_user (aside1is, asid); -dsb (ish); +__tlbi_sync_s1ish ();mmu_notifier_arch_invalidate_secondary_tlbs (mm,0 ,-1UL ); }
@@ -305,20 +325,11 @@ static inline void flush_tlb_page(struct unsigned long uaddr) {flush_tlb_page_nosync (vma, uaddr); -dsb (ish); +__tlbi_sync_s1ish (); }static inline bool arch_tlbbatch_should_defer (struct mm_struct *mm) { -/* -* TLB flush deferral is not required on systems which are affected by -* ARM64_WORKAROUND_REPEAT_TLBI, as __tlbi()/__tlbi_user() implementation -* will have two consecutive TLBI instructions with a dsb(ish) in between -* defeating the purpose (i.e save overall 'dsb ish' cost). -*/ -if (alternative_has_cap_unlikely (ARM64_WORKAROUND_REPEAT_TLBI )) -return false; -return true; }
@@ -334,7 +345,7 @@ static inline bool arch_tlbbatch_should_*/ static inline void arch_tlbbatch_flush (struct arch_tlbflush_unmap_batch *batch) { -dsb (ish); +__tlbi_sync_s1ish (); }/*
@@ -469,7 +480,7 @@ static inline void __flush_tlb_range(str {__flush_tlb_range_nosync (vma->vm_mm, start, end, stride, last_level, tlb_level); -dsb (ish); +__tlbi_sync_s1ish (); } static inline void flush_tlb_range(struct vm_area_struct *vma,
@@ -501,7 +512,7 @@ static inline void flush_tlb_kernel_rangdsb (ishst);__flush_tlb_range_op (vaale1is, start, pages, stride,0 ,TLBI_TTL_UNKNOWN , false,lpa2_is_enabled ()); -dsb (ish); +__tlbi_sync_s1ish ();isb (); }
@@ -515,7 +526,7 @@ static inline void __flush_tlb_kernel_pgdsb (ishst);__tlbi (vaae1is, addr); -dsb (ish); +__tlbi_sync_s1ish ();isb (); }
arch/arm64/kernel/sys_compat.c +1 -1
@@ -37,7 +37,7 @@ __do_compat_cache_op(unsigned long start* We pick the reserved-ASID to minimise the impact. */ __tlbi (aside1is,__TLBI_VADDR (0 ,0 )); -dsb (ish); +__tlbi_sync_s1ish (); } ret =caches_clean_inval_user_pou (start, start + chunk);
arch/arm64/kvm/hyp/nvhe/mm.c +1 -1
@@ -271,7 +271,7 @@ static void fixmap_clear_slot(struct hyp*/ dsb (ishst);__tlbi_level (vale2is,__TLBI_VADDR (addr,0 ), level); -dsb (ish); +__tlbi_sync_s1ish_hyp ();isb (); }
arch/arm64/kvm/hyp/nvhe/tlb.c +4 -4
@@ -169,7 +169,7 @@ void __kvm_tlb_flush_vmid_ipa(struct kvm*/ dsb (ish);__tlbi (vmalle1is); -dsb (ish); +__tlbi_sync_s1ish_hyp ();isb ();exit_vmid_context (&cxt);
@@ -226,7 +226,7 @@ void __kvm_tlb_flush_vmid_range(struct kdsb (ish);__tlbi (vmalle1is); -dsb (ish); +__tlbi_sync_s1ish_hyp ();isb ();exit_vmid_context (&cxt);
@@ -240,7 +240,7 @@ void __kvm_tlb_flush_vmid(struct kvm_s2_enter_vmid_context (mmu, &cxt, false);__tlbi (vmalls12e1is); -dsb (ish); +__tlbi_sync_s1ish_hyp ();isb ();exit_vmid_context (&cxt);
@@ -266,5 +266,5 @@ void __kvm_flush_vm_context(void)/* Same remark as in enter_vmid_context() */ dsb (ish);__tlbi (alle1is); -dsb (ish); +__tlbi_sync_s1ish_hyp (); }
arch/arm64/kvm/hyp/pgtable.c +1 -1
@@ -483,7 +483,7 @@ static int hyp_unmap_walker(const struct *unmapped += granule; } -dsb (ish); +__tlbi_sync_s1ish_hyp ();isb (); mm_ops->put_page (ctx->ptep);
arch/arm64/kvm/hyp/vhe/tlb.c +5 -5
@@ -115,7 +115,7 @@ void __kvm_tlb_flush_vmid_ipa(struct kvm*/ dsb (ish);__tlbi (vmalle1is); -dsb (ish); +__tlbi_sync_s1ish_hyp ();isb ();exit_vmid_context (&cxt);
@@ -176,7 +176,7 @@ void __kvm_tlb_flush_vmid_range(struct kdsb (ish);__tlbi (vmalle1is); -dsb (ish); +__tlbi_sync_s1ish_hyp ();isb ();exit_vmid_context (&cxt);
@@ -192,7 +192,7 @@ void __kvm_tlb_flush_vmid(struct kvm_s2_enter_vmid_context (mmu, &cxt);__tlbi (vmalls12e1is); -dsb (ish); +__tlbi_sync_s1ish_hyp ();isb ();exit_vmid_context (&cxt);
@@ -217,7 +217,7 @@ void __kvm_flush_vm_context(void) {dsb (ishst);__tlbi (alle1is); -dsb (ish); +__tlbi_sync_s1ish_hyp (); }/*
@@ -358,7 +358,7 @@ int __kvm_tlbi_s1e2(struct kvm_s2_mmu *mdefault : ret = -EINVAL ; } -dsb (ish); +__tlbi_sync_s1ish_hyp ();isb ();if (mmu)
Greg Kroah-Hartman
maintainerPATCH 12/55 arm64: tlb: Introduce __tlbi_sync_s1ish_{kernel,batch}() for TLB maintenance
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Catalin Marinas <[email protected]>
commit 6bfbf574a39139da11af9fdf6e8d56fe1989cd3e upstream.
Add __tlbi_sync_s1ish_kernel() similar to __tlbi_sync_s1ish() and use it for kernel TLB maintenance. Also use this function in flush_tlb_all() which is only used in relation to kernel mappings. Subsequent patches can differentiate between workarounds that apply to user only or both user and kernel.
A subsequent patch will add mm_struct to __tlbi_sync_s1ish(). Since arch_tlbbatch_flush() is not specific to an mm, add a corresponding __tlbi_sync_s1ish_batch() helper.
--- arch/arm64/include/asm/tlbflush.h | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-)
arch/arm64/include/asm/tlbflush.h +16 -4
@@ -191,6 +191,18 @@ static inline void __tlbi_sync_s1ish(voi__repeat_tlbi_sync (vale1is,0 ); } +static inline void __tlbi_sync_s1ish_batch (void ) +{ +dsb (ish); +__repeat_tlbi_sync (vale1is,0 ); +} + +static inline void __tlbi_sync_s1ish_kernel (void ) +{ +dsb (ish); +__repeat_tlbi_sync (vale1is,0 ); +} +/* * Complete broadcast TLB maintenance issued by hyp code which invalidates * stage 1 translation information in any translation regime.
@@ -286,7 +298,7 @@ static inline void flush_tlb_all(void) {dsb (ishst);__tlbi (vmalle1is); -__tlbi_sync_s1ish (); +__tlbi_sync_s1ish_kernel ();isb (); }
@@ -345,7 +357,7 @@ static inline bool arch_tlbbatch_should_*/ static inline void arch_tlbbatch_flush (struct arch_tlbflush_unmap_batch *batch) { -__tlbi_sync_s1ish (); +__tlbi_sync_s1ish_batch (); }/*
@@ -512,7 +524,7 @@ static inline void flush_tlb_kernel_rangdsb (ishst);__flush_tlb_range_op (vaale1is, start, pages, stride,0 ,TLBI_TTL_UNKNOWN , false,lpa2_is_enabled ()); -__tlbi_sync_s1ish (); +__tlbi_sync_s1ish_kernel ();isb (); }
@@ -526,7 +538,7 @@ static inline void __flush_tlb_kernel_pgdsb (ishst);__tlbi (vaae1is, addr); -__tlbi_sync_s1ish (); +__tlbi_sync_s1ish_kernel ();isb (); }
Greg Kroah-Hartman
maintainerPATCH 13/55 arm64: tlb: Pass the corresponding mm to __tlbi_sync_s1ish()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Catalin Marinas <[email protected]>
commit d9fb08ba946a6190c371dcd9f9e465d0d52c5021 upstream.
The mm structure will be used for workarounds that need limiting to specific tasks.
--- arch/arm64/include/asm/tlbflush.h | 8 ++++---- arch/arm64/kernel/sys_compat.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-)
arch/arm64/include/asm/tlbflush.h +4 -4
@@ -185,7 +185,7 @@ do { \* Complete broadcast TLB maintenance issued by the host which invalidates * stage 1 information in the host's own translation regime. */ -static inline void __tlbi_sync_s1ish (void ) +static inline void __tlbi_sync_s1ish (struct mm_struct *mm) {dsb (ish);__repeat_tlbi_sync (vale1is,0 );
@@ -310,7 +310,7 @@ static inline void flush_tlb_mm(struct m asid =__TLBI_VADDR (0 ,ASID (mm));__tlbi (aside1is, asid);__tlbi_user (aside1is, asid); -__tlbi_sync_s1ish (); +__tlbi_sync_s1ish (mm);mmu_notifier_arch_invalidate_secondary_tlbs (mm,0 ,-1UL ); }
@@ -337,7 +337,7 @@ static inline void flush_tlb_page(struct unsigned long uaddr) {flush_tlb_page_nosync (vma, uaddr); -__tlbi_sync_s1ish (); +__tlbi_sync_s1ish (vma->vm_mm); }static inline bool arch_tlbbatch_should_defer (struct mm_struct *mm)
@@ -492,7 +492,7 @@ static inline void __flush_tlb_range(str {__flush_tlb_range_nosync (vma->vm_mm, start, end, stride, last_level, tlb_level); -__tlbi_sync_s1ish (); +__tlbi_sync_s1ish (vma->vm_mm); } static inline void flush_tlb_range(struct vm_area_struct *vma,
arch/arm64/kernel/sys_compat.c +1 -1
@@ -37,7 +37,7 @@ __do_compat_cache_op(unsigned long start* We pick the reserved-ASID to minimise the impact. */ __tlbi (aside1is,__TLBI_VADDR (0 ,0 )); -__tlbi_sync_s1ish (); +__tlbi_sync_s1ish (current->mm); } ret =caches_clean_inval_user_pou (start, start + chunk);
Greg Kroah-Hartman
maintainerPATCH 14/55 arm64: cputype: Add C1-Pro definitions
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Catalin Marinas <[email protected]>
commit 2c99561016c591f4c3d5ad7d22a61b8726e79735 upstream.
Add cputype definitions for C1-Pro. These will be used for errata detection in subsequent patches.
These values can be found in "Table A-303: MIDR_EL1 bit descriptions" in issue 07 of the C1-Pro TRM:
https://documentation-service.arm.com/static/6930126730f8f55a656570af
--- arch/arm64/include/asm/cputype.h | 2 ++ 1 file changed, 2 insertions(+)
arch/arm64/include/asm/cputype.h +2 -0
@@ -98,6 +98,7 @@#define ARM_CPU_PART_CORTEX_A725 0xD87#define ARM_CPU_PART_CORTEX_A720AE 0xD89#define ARM_CPU_PART_NEOVERSE_N3 0xD8E +#define ARM_CPU_PART_C1_PRO 0xD8B#define APM_CPU_PART_XGENE 0x000#define APM_CPU_VAR_POTENZA 0x00
@@ -189,6 +190,7 @@#define MIDR_CORTEX_A725 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A725)#define MIDR_CORTEX_A720AE MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A720AE)#define MIDR_NEOVERSE_N3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N3) +#define MIDR_C1_PRO MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_C1_PRO)#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)#define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)
Greg Kroah-Hartman
maintainerPATCH 15/55 arm64: errata: Work around early CME DVMSync acknowledgement
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Catalin Marinas <[email protected]>
commit 0baba94a9779c13c857f6efc55807e6a45b1d4e4 upstream.
C1-Pro acknowledges DVMSync messages before completing the SME/CME memory accesses. Work around this by issuing an IPI to the affected CPUs if they are running in EL0 with SME enabled.
Note that we avoid the local DSB in the IPI handler as the kernel runs with SCTLR_EL1.IESB=1. This is sufficient to complete SME memory accesses at EL0 on taking an exception to EL1. On the return to user path, no barrier is necessary either. See the comment in sme_set_active() and the more detailed explanation in the link below.
To avoid a potential IPI flood from malicious applications (e.g. madvise(MADV_PAGEOUT) in a tight loop), track where a process is active via mm_cpumask() and only interrupt those CPUs.
--- Documentation/arch/arm64/silicon-errata.rst | 2 arch/arm64/Kconfig | 12 ++++ arch/arm64/include/asm/cpucaps.h | 2 arch/arm64/include/asm/fpsimd.h | 21 +++++++ arch/arm64/include/asm/tlbbatch.h | 10 ++- arch/arm64/include/asm/tlbflush.h | 72 ++++++++++++++++++++++++- arch/arm64/kernel/cpu_errata.c | 30 ++++++++++ arch/arm64/kernel/entry-common.c | 3 + arch/arm64/kernel/fpsimd.c | 79 ++++++++++++++++++++++++++++ arch/arm64/kernel/process.c | 36 ++++++++++++ arch/arm64/tools/cpucaps | 1 11 files changed, 264 insertions(+), 4 deletions(-)
Documentation/arch/arm64/silicon-errata.rst +2 -0
@@ -202,6 +202,8 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-V3AE | #3312417 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | C1-Pro | #4193714 | ARM64_ERRATUM_4193714 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | MMU-500 | #841119,826419 | ARM_SMMU_MMU_500_CPRE_ERRATA| | | | #562869,1047329 | | +----------------+-----------------+-----------------+-----------------------------+
arch/arm64/Kconfig +12 -0
@@ -1154,6 +1154,18 @@ config ARM64_ERRATUM_3194386 If unsure, say Y. +config ARM64_ERRATUM_4193714 + bool "C1-Pro: 4193714: SME DVMSync early acknowledgement" + depends on ARM64_SME + default y + help + Enable workaround for C1-Pro acknowledging the DVMSync before + the SME memory accesses are complete. This will cause TLB + maintenance for processes using SME to also issue an IPI to + the affected CPUs. + + If unsure, say Y. + config CAVIUM_ERRATUM_22375 bool "Cavium erratum 22375, 24313" default y
arch/arm64/include/asm/cpucaps.h +2 -0
@@ -66,6 +66,8 @@ cpucap_is_possible(const unsigned int careturn IS_ENABLED (CONFIG_ARM64_WORKAROUND_REPEAT_TLBI );case ARM64_WORKAROUND_SPECULATIVE_SSBS :return IS_ENABLED (CONFIG_ARM64_ERRATUM_3194386 ); +case ARM64_WORKAROUND_4193714 : +return IS_ENABLED (CONFIG_ARM64_ERRATUM_4193714 );case ARM64_MPAM :/* * KVM MPAM support doesn't rely on the host kernel supporting MPAM.
arch/arm64/include/asm/fpsimd.h +21 -0
@@ -428,6 +428,24 @@ static inline size_t sme_state_size(stru return __sme_state_size(task_get_sme_vl(task)); } +void sme_enable_dvmsync (void ); +void sme_set_active (void ); +void sme_clear_active (void ); + +static inline void sme_enter_from_user_mode (void ) +{ +if (alternative_has_cap_unlikely (ARM64_WORKAROUND_4193714 ) && +test_thread_flag (TIF_SME )) +sme_clear_active (); +} + +static inline void sme_exit_to_user_mode (void ) +{ +if (alternative_has_cap_unlikely (ARM64_WORKAROUND_4193714 ) && +test_thread_flag (TIF_SME )) +sme_set_active (); +} +#else static inline void sme_user_disable (void ) {BUILD_BUG (); }
@@ -456,6 +474,9 @@ static inline size_t sme_state_size(stru return 0; } +static inline void sme_enter_from_user_mode (void ) { } +static inline void sme_exit_to_user_mode (void ) { } +#endif /* ! CONFIG_ARM64_SME */ /* For use by EFI runtime services calls only */
arch/arm64/include/asm/tlbbatch.h +8 -2
@@ -2,11 +2,17 @@#ifndef _ARCH_ARM64_TLBBATCH_H#define _ARCH_ARM64_TLBBATCH_H +#include <linux/cpumask.h> +struct arch_tlbflush_unmap_batch { +#ifdef CONFIG_ARM64_ERRATUM_4193714 /* -* For arm64, HW can do tlb shootdown, so we don't -* need to record cpumask for sending IPI +* Track CPUs that need SME DVMSync on completion of this batch. +* Otherwise, the arm64 HW can do tlb shootdown, so we don't need to +* record cpumask for sending IPI */ +cpumask_var_t cpumask; +#endif };#endif /* _ARCH_ARM64_TLBBATCH_H */
arch/arm64/include/asm/tlbflush.h +70 -2
101 lines not on this page · raw message
arch/arm64/kernel/cpu_errata.c +30 -0
@@ -11,6 +11,7 @@#include <asm/cpu.h> #include <asm/cputype.h> #include <asm/cpufeature.h> +#include <asm/fpsimd.h> #include <asm/kvm_asm.h> #include <asm/smp_plat.h>
@@ -551,6 +552,23 @@ static const struct midr_range erratum_s };#endif +#ifdef CONFIG_ARM64_ERRATUM_4193714 +static bool has_sme_dvmsync_erratum (const struct arm64_cpu_capabilities *entry, +int scope) +{ +if (!id_aa64pfr1_sme (read_sanitised_ftr_reg (SYS_ID_AA64PFR1_EL1 ))) +return false; + +return is_affected_midr_range (entry, scope); +} + +static void cpu_enable_sme_dvmsync (const struct arm64_cpu_capabilities *__unused) +{ +if (this_cpu_has_cap (ARM64_WORKAROUND_4193714 )) +sme_enable_dvmsync (); +} +#endif +#ifdef CONFIG_AMPERE_ERRATUM_AC03_CPU_38 static const struct midr_range erratum_ac03_cpu_38_list[] = { MIDR_ALL_VERSIONS(MIDR_AMPERE1),
@@ -870,6 +888,18 @@ const struct arm64_cpu_capabilities arm6 ERRATA_MIDR_RANGE_LIST(erratum_spec_ssbs_list), },#endif +#ifdef CONFIG_ARM64_ERRATUM_4193714 + { + .desc = "C1-Pro SME DVMSync early acknowledgement", + .capability = ARM64_WORKAROUND_4193714, + .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, + .matches = has_sme_dvmsync_erratum, + .cpu_enable = cpu_enable_sme_dvmsync, +/* C1-Pro r0p0 - r1p2 (the latter only when REVIDR_EL1[0]==0) */ + .midr_range =MIDR_RANGE (MIDR_C1_PRO ,0 ,0 ,1 ,2 ), +MIDR_FIXED (MIDR_CPU_VAR_REV (1 ,2 ),BIT (0 )), + }, +#endif #ifdef CONFIG_ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD { .desc = "ARM errata 2966298, 3117295",
arch/arm64/kernel/entry-common.c +3 -0
@@ -21,6 +21,7 @@#include <asm/daifflags.h> #include <asm/esr.h> #include <asm/exception.h> +#include <asm/fpsimd.h> #include <asm/irq_regs.h> #include <asm/kprobes.h> #include <asm/mmu.h>
@@ -84,6 +85,7 @@ static __always_inline void __enter_from {enter_from_user_mode (regs);mte_disable_tco_entry (current); +sme_enter_from_user_mode (); } static __always_inline void arm64_enter_from_user_mode(struct pt_regs *regs)
@@ -102,6 +104,7 @@ static __always_inline void arm64_exit_tlocal_irq_disable ();exit_to_user_mode_prepare (regs);local_daif_mask (); +sme_exit_to_user_mode ();mte_check_tfsr_exit ();exit_to_user_mode (); }
arch/arm64/kernel/fpsimd.c +79 -0
97 lines not on this page · raw message
arch/arm64/kernel/process.c +36 -0
@@ -26,6 +26,7 @@#include <linux/reboot.h> #include <linux/interrupt.h> #include <linux/init.h> +#include <linux/cpumask.h> #include <linux/cpu.h> #include <linux/elfcore.h> #include <linux/pm.h>
@@ -339,8 +340,41 @@ void flush_thread(void)flush_gcs (); } +#ifdef CONFIG_ARM64_ERRATUM_4193714 + +static void arch_dup_tlbbatch_mask (struct task_struct *dst) +{ +/* +* Clear the inherited cpumask with memset() to cover both cases where +* cpumask_var_t is a pointer or an array. It will be allocated lazily +* in sme_dvmsync_add_pending() if CPUMASK_OFFSTACK=y. +*/ +if (alternative_has_cap_unlikely (ARM64_WORKAROUND_4193714 )) +memset (&dst->tlb_ubc.arch.cpumask,0 , +sizeof (dst->tlb_ubc.arch.cpumask)); +} + +static void arch_release_tlbbatch_mask (struct task_struct *tsk) +{ +if (alternative_has_cap_unlikely (ARM64_WORKAROUND_4193714 )) +free_cpumask_var (tsk->tlb_ubc.arch.cpumask); +} + +#else + +static void arch_dup_tlbbatch_mask (struct task_struct *dst) +{ +} + +static void arch_release_tlbbatch_mask (struct task_struct *tsk) +{ +} + +#endif /* CONFIG_ARM64_ERRATUM_4193714 */ +void arch_release_task_struct (struct task_struct *tsk) { +arch_release_tlbbatch_mask (tsk);fpsimd_release_task (tsk); }
@@ -356,6 +390,8 @@ int arch_dup_task_struct(struct task_str *dst = *src; +arch_dup_tlbbatch_mask (dst); +/* * Drop stale reference to src's sve_state and convert dst to * non-streaming FPSIMD mode.
arch/arm64/tools/cpucaps +1 -0
@@ -101,6 +101,7 @@ WORKAROUND_2077057 WORKAROUND_2457168 WORKAROUND_2645198 WORKAROUND_2658417 +WORKAROUND_4193714 WORKAROUND_AMPERE_AC03_CPU_38 WORKAROUND_AMPERE_AC04_CPU_23 WORKAROUND_TRBE_OVERWRITE_FILL_MODE
Greg Kroah-Hartman
maintainerPATCH 16/55 sched/debug: Fix avg_vruntime() usage
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Zijlstra <[email protected]>
commit e08d007f9d813616ce7093600bc4fdb9c9d81d89 upstream.
John reported that stress-ng-yield could make his machine unhappy and managed to bisect it to commit b3d99f43c72b ("sched/fair: Fix zero_vruntime tracking").
The commit in question changes avg_vruntime() from a function that is a pure reader, to a function that updates variables. This turns an unlocked sched/debug usage of this function from a minor mistake into a data corruptor.
--- kernel/sched/debug.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
kernel/sched/debug.c +3 -1
@@ -798,6 +798,7 @@ static void print_rq(struct seq_file *m,void print_cfs_rq (struct seq_file *m,int cpu,struct cfs_rq *cfs_rq) {s64 left_vruntime =-1 , zero_vruntime, right_vruntime =-1 , left_deadline =-1 , spread; +u64 avruntime;struct sched_entity *last, *first, *root;struct rq *rq =cpu_rq (cpu);unsigned long flags;
@@ -821,6 +822,7 @@ void print_cfs_rq(struct seq_file *m, inif (last) right_vruntime = last->vruntime; zero_vruntime = cfs_rq->zero_vruntime; + avruntime =avg_vruntime (cfs_rq);raw_spin_rq_unlock_irqrestore (rq, flags); SEQ_printf(m, " .%-30s: %Ld.%06ld\n", "left_deadline",
@@ -830,7 +832,7 @@ void print_cfs_rq(struct seq_file *m, inSEQ_printf (m," .%-30s: %Ld.%06ld\n" ,"zero_vruntime" ,SPLIT_NS (zero_vruntime));SEQ_printf (m," .%-30s: %Ld.%06ld\n" ,"avg_vruntime" , -SPLIT_NS (avg_vruntime (cfs_rq))); +SPLIT_NS (avruntime));SEQ_printf (m," .%-30s: %Ld.%06ld\n" ,"right_vruntime" ,SPLIT_NS (right_vruntime)); spread = right_vruntime - left_vruntime;
Greg Kroah-Hartman
maintainerPATCH 17/55 lib/crc: tests: Make crc_kunit test only the enabled CRC variants
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <[email protected]>
commit 85c9f3a2b805eb96d899da7bcc38a16459aa3c16 upstream.
Like commit 4478e8eeb871 ("lib/crypto: tests: Depend on library options rather than selecting them") did with the crypto library tests, make crc_kunit depend on the code it tests rather than selecting it. This follows the standard convention for KUnit and fixes an issue where enabling KUNIT_ALL_TESTS enabled non-test code.
crc_kunit does differ from the crypto library tests in that it consolidates the tests for multiple CRC variants, with 5 kconfig options, into one KUnit suite. Since depending on *all* of these kconfig options would greatly restrict the ability to enable crc_kunit, instead just depend on *any* of these options. Update crc_kunit accordingly to test only the reachable code.
Alternatively we could split crc_kunit into 5 test suites. But keeping it as one is simpler for now.
--- lib/crc/Kconfig | 7 +------ lib/crc/tests/crc_kunit.c | 28 ++++++++++++++++++++++------ 2 files changed, 23 insertions(+), 12 deletions(-)
lib/crc/Kconfig +1 -6
@@ -99,13 +99,8 @@ config CRC_OPTIMIZATIONS config CRC_KUNIT_TEST tristate "KUnit tests for CRC functions" if !KUNIT_ALL_TESTS - depends on KUNIT + depends on KUNIT && (CRC7 || CRC16 || CRC_T10DIF || CRC32 || CRC64) default KUNIT_ALL_TESTS - select CRC7 - select CRC16 - select CRC_T10DIF - select CRC32 - select CRC64 help Unit tests for the CRC library functions.
lib/crc/tests/crc_kunit.c +22 -6
@@ -268,8 +268,7 @@ crc_benchmark(struct kunit *test, } } -/* crc7_be */ - +#if IS_REACHABLE (CONFIG_CRC7 )static u64 crc7_be_wrapper (u64 crc,const u8 *p,size_t len) {/*
@@ -294,9 +293,9 @@ static void crc7_be_benchmark(struct kun {crc_benchmark (test, crc7_be_wrapper); } +#endif /* CONFIG_CRC7 */ -/* crc16 */ - +#if IS_REACHABLE (CONFIG_CRC16 )static u64 crc16_wrapper (u64 crc,const u8 *p,size_t len) {return crc16 (crc, p, len);
@@ -318,9 +317,9 @@ static void crc16_benchmark(struct kunit {crc_benchmark (test, crc16_wrapper); } +#endif /* CONFIG_CRC16 */ -/* crc_t10dif */ - +#if IS_REACHABLE (CONFIG_CRC_T10DIF )static u64 crc_t10dif_wrapper (u64 crc,const u8 *p,size_t len) {return crc_t10dif_update (crc, p, len);
@@ -342,6 +341,9 @@ static void crc_t10dif_benchmark(struct {crc_benchmark (test, crc_t10dif_wrapper); } +#endif /* CONFIG_CRC_T10DIF */ + +#if IS_REACHABLE (CONFIG_CRC32 )/* crc32_le */
@@ -414,6 +416,9 @@ static void crc32c_benchmark(struct kuni {crc_benchmark (test, crc32c_wrapper); } +#endif /* CONFIG_CRC32 */ + +#if IS_REACHABLE (CONFIG_CRC64 )/* crc64_be */
@@ -463,24 +468,35 @@ static void crc64_nvme_benchmark(struct {crc_benchmark (test, crc64_nvme_wrapper); } +#endif /* CONFIG_CRC64 */ static struct kunit_case crc_test_cases[] = { +#if IS_REACHABLE(CONFIG_CRC7)KUNIT_CASE (crc7_be_test),KUNIT_CASE (crc7_be_benchmark), +#endif +#if IS_REACHABLE(CONFIG_CRC16)KUNIT_CASE (crc16_test),KUNIT_CASE (crc16_benchmark), +#endif +#if IS_REACHABLE(CONFIG_CRC_T10DIF)KUNIT_CASE (crc_t10dif_test),KUNIT_CASE (crc_t10dif_benchmark), +#endif +#if IS_REACHABLE(CONFIG_CRC32)KUNIT_CASE (crc32_le_test),KUNIT_CASE (crc32_le_benchmark),KUNIT_CASE (crc32_be_test),KUNIT_CASE (crc32_be_benchmark),KUNIT_CASE (crc32c_test),KUNIT_CASE (crc32c_benchmark), +#endif +#if IS_REACHABLE(CONFIG_CRC64)KUNIT_CASE (crc64_be_test),KUNIT_CASE (crc64_be_benchmark),KUNIT_CASE (crc64_nvme_test),KUNIT_CASE (crc64_nvme_benchmark), +#endif {}, };
Greg Kroah-Hartman
maintainerPATCH 18/55 lib/crc: tests: Add CRC_ENABLE_ALL_FOR_KUNIT
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <[email protected]>
commit cdf22aeaad8430905c3aa3b3d0f2686c65395c22 upstream.
Now that crc_kunit uses the standard "depends on" pattern, enabling the full set of CRC tests is a bit difficult, mainly due to CRC7 being rarely used. Add a kconfig option to make it easier. It is visible only when KUNIT, so hopefully the extra prompt won't be too annoying.
--- lib/crc/Kconfig | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
lib/crc/Kconfig +14 -0
@@ -107,6 +107,20 @@ config CRC_KUNIT_TEST This is intended to help people writing architecture-specific optimized versions. If unsure, say N. +config CRC_ENABLE_ALL_FOR_KUNIT + tristate "Enable all CRC functions for KUnit test" + depends on KUNIT + select CRC7 + select CRC16 + select CRC_T10DIF + select CRC32 + select CRC64 + help + Enable all CRC functions that have test code in CRC_KUNIT_TEST. + + Enable this only if you'd like the CRC KUnit test suite to test all + the CRC variants, even ones that wouldn't otherwise need to be built. + config CRC_BENCHMARK bool "Benchmark for the CRC functions" depends on CRC_KUNIT_TEST
Greg Kroah-Hartman
maintainerPATCH 19/55 lib/crc: tests: Add a .kunitconfig file
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <[email protected]>
commit c13cee2fc7f137dd25ed50c63eddcc578624f204 upstream.
Add a .kunitconfig file to the lib/crc/ directory so that the CRC library tests can be run more easily using kunit.py. Example with UML:
tools/testing/kunit/kunit.py run --kunitconfig=lib/crc
Example with QEMU:
tools/testing/kunit/kunit.py run --kunitconfig=lib/crc --arch=arm64 --make_options LLVM=1
--- lib/crc/.kunitconfig | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 lib/crc/.kunitconfig
lib/crc/.kunitconfig new file +3 -0
@@ -0,0 +1,3 @@ +CONFIG_KUNIT=y +CONFIG_CRC_ENABLE_ALL_FOR_KUNIT=y +CONFIG_CRC_KUNIT_TEST=y
Greg Kroah-Hartman
maintainerPATCH 20/55 kunit: configs: Enable all CRC tests in all_tests.config
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <[email protected]>
commit 44ff3791d6295f7b51dd2711aad6a03dd79aef22 upstream.
The new option CONFIG_CRC_ENABLE_ALL_FOR_KUNIT enables all the CRC code that has KUnit tests, causing CONFIG_KUNIT_ALL_TESTS to enable all these tests. Add this option to all_tests.config so that kunit.py will run them when passed the --alltests option.
--- tools/testing/kunit/configs/all_tests.config | 2 ++ 1 file changed, 2 insertions(+)
tools/testing/kunit/configs/all_tests.config +2 -0
@@ -46,6 +46,8 @@ CONFIG_AUDIT=y CONFIG_PRIME_NUMBERS=y +CONFIG_CRC_ENABLE_ALL_FOR_KUNIT=y + CONFIG_SECURITY=y CONFIG_SECURITY_APPARMOR=y CONFIG_SECURITY_LANDLOCK=y
Greg Kroah-Hartman
maintainerPATCH 21/55 lib/crypto: tests: Add a .kunitconfig file
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <[email protected]>
commit 20d6f07004d639967dcb00994d56ce6d16118e9e upstream.
Add a .kunitconfig file to the lib/crypto/ directory so that the crypto library tests can be run more easily using kunit.py. Example with UML:
tools/testing/kunit/kunit.py run --kunitconfig=lib/crypto
Example with QEMU:
tools/testing/kunit/kunit.py run --kunitconfig=lib/crypto --arch=arm64 --make_options LLVM=1
--- lib/crypto/.kunitconfig | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 lib/crypto/.kunitconfig
lib/crypto/.kunitconfig new file +23 -0
@@ -0,0 +1,23 @@ +CONFIG_KUNIT=y + +# These kconfig options select all the CONFIG_CRYPTO_LIB_* symbols that have a +# corresponding KUnit test. Those symbols cannot be directly enabled here, +# since they are hidden symbols. +CONFIG_CRYPTO=y +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y +CONFIG_INET=y +CONFIG_IPV6=y +CONFIG_NET=y +CONFIG_NETDEVICES=y +CONFIG_WIREGUARD=y + +CONFIG_CRYPTO_LIB_BLAKE2S_KUNIT_TEST=y +CONFIG_CRYPTO_LIB_CURVE25519_KUNIT_TEST=y +CONFIG_CRYPTO_LIB_MD5_KUNIT_TEST=y +CONFIG_CRYPTO_LIB_POLY1305_KUNIT_TEST=y +CONFIG_CRYPTO_LIB_SHA1_KUNIT_TEST=y +CONFIG_CRYPTO_LIB_SHA256_KUNIT_TEST=y +CONFIG_CRYPTO_LIB_SHA512_KUNIT_TEST=y
Greg Kroah-Hartman
maintainerPATCH 22/55 lib/crypto: tests: Introduce CRYPTO_LIB_ENABLE_ALL_FOR_KUNIT
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <[email protected]>
commit ed1767442d919f57aaf83d69c33853da2644d902 upstream.
For kunit.py to run all the crypto library tests when passed the --alltests option, tools/testing/kunit/configs/all_tests.config needs to enable options that satisfy the test dependencies.
This is the same as what lib/crypto/.kunitconfig already does. However, the strategy that lib/crypto/.kunitconfig currently uses to select all the hidden library options isn't going to scale up well when it needs to be repeated in two places.
Instead let's go ahead and introduce an option CRYPTO_LIB_ENABLE_ALL_FOR_KUNIT that depends on KUNIT and selects all the crypto library options that have corresponding KUnit tests.
Update lib/crypto/.kunitconfig to use this option.
--- lib/crypto/.kunitconfig | 14 +------------- lib/crypto/tests/Kconfig | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 13 deletions(-)
lib/crypto/.kunitconfig +1 -13
@@ -1,18 +1,6 @@ CONFIG_KUNIT=y -# These kconfig options select all the CONFIG_CRYPTO_LIB_* symbols that have a -# corresponding KUnit test. Those symbols cannot be directly enabled here, -# since they are hidden symbols. -CONFIG_CRYPTO=y -CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_SHA1=y -CONFIG_CRYPTO_SHA256=y -CONFIG_CRYPTO_SHA512=y -CONFIG_INET=y -CONFIG_IPV6=y -CONFIG_NET=y -CONFIG_NETDEVICES=y -CONFIG_WIREGUARD=y +CONFIG_CRYPTO_LIB_ENABLE_ALL_FOR_KUNIT=y CONFIG_CRYPTO_LIB_BLAKE2S_KUNIT_TEST=y CONFIG_CRYPTO_LIB_CURVE25519_KUNIT_TEST=y
lib/crypto/tests/Kconfig +18 -0
@@ -66,6 +66,24 @@ config CRYPTO_LIB_SHA512_KUNIT_TEST KUnit tests for the SHA-384 and SHA-512 cryptographic hash functions and their corresponding HMACs. +config CRYPTO_LIB_ENABLE_ALL_FOR_KUNIT + tristate "Enable all crypto library code for KUnit tests" + depends on KUNIT + select CRYPTO_LIB_CURVE25519 + select CRYPTO_LIB_MD5 + select CRYPTO_LIB_POLY1305 + select CRYPTO_LIB_SHA1 + select CRYPTO_LIB_SHA256 + select CRYPTO_LIB_SHA512 + help + Enable all the crypto library code that has KUnit tests. + + Enable this only if you'd like to test all the crypto library code, + even code that wouldn't otherwise need to be built. + + You'll still need to enable the tests themselves, either individually + or using KUNIT_ALL_TESTS. + config CRYPTO_LIB_BENCHMARK_VISIBLE bool
Greg Kroah-Hartman
maintainerPATCH 23/55 kunit: configs: Enable all crypto library tests in all_tests.config
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <[email protected]>
commit 8d547482231fef30d0d6440629b73560ad3e937c upstream.
The new option CONFIG_CRYPTO_LIB_ENABLE_ALL_FOR_KUNIT enables all the crypto library code that has KUnit tests, causing CONFIG_KUNIT_ALL_TESTS to enable all these tests. Add this option to all_tests.config so that kunit.py will run them when passed the --alltests option.
--- tools/testing/kunit/configs/all_tests.config | 2 ++ 1 file changed, 2 insertions(+)
tools/testing/kunit/configs/all_tests.config +2 -0
@@ -44,6 +44,8 @@ CONFIG_REGMAP_BUILD=y CONFIG_AUDIT=y +CONFIG_CRYPTO_LIB_ENABLE_ALL_FOR_KUNIT=y + CONFIG_PRIME_NUMBERS=y CONFIG_CRC_ENABLE_ALL_FOR_KUNIT=y
Greg Kroah-Hartman
maintainerPATCH 24/55 lib/crypto: tests: Drop the default to CRYPTO_SELFTESTS
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <[email protected]>
commit 6d80749becf8fc5ffa004194e578f79b558235ef upstream.
Defaulting the crypto KUnit tests to KUNIT_ALL_TESTS || CRYPTO_SELFTESTS instead of simply KUNIT_ALL_TESTS was originally intended to make it easy to enable all the crypto KUnit tests. This additional default is nonstandard for KUnit tests, though, and it can cause all the KUnit tests to be built-in unexpectedly if CRYPTO_SELFTESTS is set. It also constitutes a back-reference to crypto/ from lib/crypto/, which is something that we should be avoiding in order to get clean layering.
Now that we provide a lib/crypto/.kunitconfig file that enables all crypto KUnit tests, let's consider that to be the supported way to enable all these tests, and drop the default of CRYPTO_SELFTESTS.
--- lib/crypto/tests/Kconfig | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
lib/crypto/tests/Kconfig +7 -7
@@ -3,7 +3,7 @@ config CRYPTO_LIB_BLAKE2S_KUNIT_TEST tristate "KUnit tests for BLAKE2s" if !KUNIT_ALL_TESTS depends on KUNIT - default KUNIT_ALL_TESTS || CRYPTO_SELFTESTS + default KUNIT_ALL_TESTS select CRYPTO_LIB_BENCHMARK_VISIBLE # No need to depend on CRYPTO_LIB_BLAKE2S here, as that option doesn't # exist; the BLAKE2s code is always built-in for the /dev/random driver.
@@ -13,7 +13,7 @@ config CRYPTO_LIB_BLAKE2S_KUNIT_TEST config CRYPTO_LIB_CURVE25519_KUNIT_TEST tristate "KUnit tests for Curve25519" if !KUNIT_ALL_TESTS depends on KUNIT && CRYPTO_LIB_CURVE25519 - default KUNIT_ALL_TESTS || CRYPTO_SELFTESTS + default KUNIT_ALL_TESTS select CRYPTO_LIB_BENCHMARK_VISIBLE help KUnit tests for the Curve25519 Diffie-Hellman function.
@@ -21,7 +21,7 @@ config CRYPTO_LIB_CURVE25519_KUNIT_TEST config CRYPTO_LIB_MD5_KUNIT_TEST tristate "KUnit tests for MD5" if !KUNIT_ALL_TESTS depends on KUNIT && CRYPTO_LIB_MD5 - default KUNIT_ALL_TESTS || CRYPTO_SELFTESTS + default KUNIT_ALL_TESTS select CRYPTO_LIB_BENCHMARK_VISIBLE help KUnit tests for the MD5 cryptographic hash function and its
@@ -30,7 +30,7 @@ config CRYPTO_LIB_MD5_KUNIT_TEST config CRYPTO_LIB_POLY1305_KUNIT_TEST tristate "KUnit tests for Poly1305" if !KUNIT_ALL_TESTS depends on KUNIT && CRYPTO_LIB_POLY1305 - default KUNIT_ALL_TESTS || CRYPTO_SELFTESTS + default KUNIT_ALL_TESTS select CRYPTO_LIB_BENCHMARK_VISIBLE help KUnit tests for the Poly1305 library functions.
@@ -38,7 +38,7 @@ config CRYPTO_LIB_POLY1305_KUNIT_TEST config CRYPTO_LIB_SHA1_KUNIT_TEST tristate "KUnit tests for SHA-1" if !KUNIT_ALL_TESTS depends on KUNIT && CRYPTO_LIB_SHA1 - default KUNIT_ALL_TESTS || CRYPTO_SELFTESTS + default KUNIT_ALL_TESTS select CRYPTO_LIB_BENCHMARK_VISIBLE help KUnit tests for the SHA-1 cryptographic hash function and its
@@ -49,7 +49,7 @@ config CRYPTO_LIB_SHA1_KUNIT_TEST config CRYPTO_LIB_SHA256_KUNIT_TEST tristate "KUnit tests for SHA-224 and SHA-256" if !KUNIT_ALL_TESTS depends on KUNIT && CRYPTO_LIB_SHA256 - default KUNIT_ALL_TESTS || CRYPTO_SELFTESTS + default KUNIT_ALL_TESTS select CRYPTO_LIB_BENCHMARK_VISIBLE help KUnit tests for the SHA-224 and SHA-256 cryptographic hash functions
@@ -60,7 +60,7 @@ config CRYPTO_LIB_SHA256_KUNIT_TEST config CRYPTO_LIB_SHA512_KUNIT_TEST tristate "KUnit tests for SHA-384 and SHA-512" if !KUNIT_ALL_TESTS depends on KUNIT && CRYPTO_LIB_SHA512 - default KUNIT_ALL_TESTS || CRYPTO_SELFTESTS + default KUNIT_ALL_TESTS select CRYPTO_LIB_BENCHMARK_VISIBLE help KUnit tests for the SHA-384 and SHA-512 cryptographic hash functions
Greg Kroah-Hartman
maintainerPATCH 25/55 scripts/dtc: Remove unused dts_version in dtc-lexer.l
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nathan Chancellor <[email protected]>
This patch is for stable only. Commit 5a09df20872c ("scripts/dtc: Update to upstream version v1.7.2-69-g53373d135579") upstream applied it as part of a regular scripts/dtc sync, which may be unsuitable for older versions of stable where the warning it fixes is present.
A recent strengthening of -Wunused-but-set-variable (enabled with -Wall) in clang under a new subwarning, -Wunused-but-set-global, points out an unused static global variable in dtc-lexer.lex.c (compiled from dtc-lexer.l):
scripts/dtc/dtc-lexer.lex.c:641:12: warning: variable 'dts_version' set but not used [-Wunused-but-set-global]
641 | static int dts_version = 1;
| ^Remove it to clear up the warning, as it is truly unused.
---
This should apply cleanly to all supported stable branches.
--- scripts/dtc/dtc-lexer.l | 3 --- 1 file changed, 3 deletions(-)
scripts/dtc/dtc-lexer.l +0 -3
@@ -39,8 +39,6 @@ extern bool treesource_error; #define DPRINT(fmt, ...) do { } while (0) #endif -static int dts_version = 1; - #define BEGIN_DEFAULT() DPRINT("<V1>\n"); \ BEGIN(V1); \
@@ -101,7 +99,6 @@ static void PRINTF(1, 2) lexical_error(c <*>"/dts-v1/" { DPRINT("Keyword: /dts-v1/\n"); - dts_version = 1; BEGIN_DEFAULT(); return DT_V1; }
Greg Kroah-Hartman
maintainerPATCH 26/55 fs/ntfs3: validate rec->used in journal-replay file record check
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Greg Kroah-Hartman <[email protected]>
commit 0ca0485e4b2e837ebb6cbd4f2451aba665a03e4b upstream.
check_file_record() validates rec->total against the record size but never validates rec->used. The do_action() journal-replay handlers read rec->used from disk and use it to compute memmove lengths:
DeleteAttribute: memmove(attr, ..., used - asize - roff) CreateAttribute: memmove(..., attr, used - roff) change_attr_size: memmove(..., used - PtrOffset(rec, next))
When rec->used is smaller than the offset of a validated attribute, or larger than the record size, these subtractions can underflow allowing us to copy huge amounts of memory in to a 4kb buffer, generally considered a bad idea overall.
This requires a corrupted filesystem, which isn't a threat model the kernel really needs to worry about, but checking for such an obvious out-of-bounds value is good to keep things robust, especially on journal replay
Fix this up by bounding rec->used correctly.
This is much like commit b2bc7c44ed17 ("fs/ntfs3: Fix slab-out-of-bounds read in DeleteIndexEntryRoot") which checked different values in this same switch statement.
--- fs/ntfs3/fslog.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
fs/ntfs3/fslog.c +11 -1
@@ -2789,13 +2789,14 @@ static inline bool check_file_record(conu16 fn =le16_to_cpu (rec->rhdr.fix_num);u16 ao =le16_to_cpu (rec->attr_off);u32 rs = sbi->record_size; +u32 used =le32_to_cpu (rec->used);/* Check the file record header for consistency. */ if (rec->rhdr.sign !=NTFS_FILE_SIGNATURE || fo > (SECTOR_SIZE - ((rs >>SECTOR_SHIFT ) +1 ) *sizeof (short )) || (fn -1 ) *SECTOR_SIZE != rs || ao <MFTRECORD_FIXUP_OFFSET_1 || ao > sbi->record_size -SIZEOF_RESIDENT || !is_rec_inuse (rec) || -le32_to_cpu (rec->total) != rs) { +le32_to_cpu (rec->total) != rs || used > rs || used < ao) {return false; }
@@ -2807,6 +2808,15 @@ static inline bool check_file_record(conreturn false; } +/* +* The do_action() handlers compute memmove lengths as +* "rec->used - <offset of validated attr>", which underflows when +* rec->used is smaller than the attribute walk reached. At this +* point attr is the ATTR_END marker; rec->used must cover it. +*/ +if (used <PtrOffset (rec, attr) +sizeof (attr->type)) +return false; +return true; }
Greg Kroah-Hartman
maintainerPATCH 27/55 f2fs: fix to do sanity check on dcc->discard_cmd_cnt conditionally
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <[email protected]>
commit 6af249c996f7d73a3435f9e577956fa259347d18 upstream.
Syzbot reported a f2fs bug as below:
------------[ cut here ]------------
kernel BUG at fs/f2fs/segment.c:1900!
Oops: invalid opcode: 0000 [#1] SMP KASAN PTI
CPU: 1 UID: 0 PID: 6527 Comm: syz.5.110 Not tainted syzkaller #0 PREEMPT_{RT,(full)}
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2026
RIP: 0010:f2fs_issue_discard_timeout+0x59b/0x5a0 fs/f2fs/segment.c:1900
Code: d9 80 e1 07 80 c1 03 38 c1 0f 8c d6 fe ff ff 48 89 df e8 a8 5e fa fd e9 c9 fe ff ff e8 4e 46 94 fd 90 0f 0b e8 46 46 94 fd 90 <0f> 0b 0f 1f 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3
RSP: 0018:ffffc9000494f940 EFLAGS: 00010283
RAX: ffffffff843009ca RBX: 0000000000000001 RCX: 0000000000080000
RDX: ffffc9001ca78000 RSI: 00000000000029f3 RDI: 00000000000029f4
RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000
R10: dffffc0000000000 R11: ffffed100893a431 R12: 1ffff1100893a430
R13: 1ffff1100c2b702c R14: dffffc0000000000 R15: ffff8880449d2160
FS: 00007ffa35fed6c0(0000) GS:ffff88812643d000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f2b68634000 CR3: 0000000039f62000 CR4: 00000000003526f0
Call Trace:
<TASK>
__f2fs_remount fs/f2fs/super.c:2960 [inline]
f2fs_reconfigure+0x108a/0x1710 fs/f2fs/super.c:5443
reconfigure_super+0x227/0x8a0 fs/super.c:1080
do_remount fs/namespace.c:3391 [inline]
path_mount+0xdc5/0x10e0 fs/namespace.c:4151
do_mount fs/namespace.c:4172 [inline]
__do_sys_mount fs/namespace.c:4361 [inline]
__se_sys_mount+0x31d/0x420 fs/namespace.c:4338
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7ffa37dbda0aThe root cause is there will be race condition in between f2fs_ioc_fitrim() and f2fs_remount():
- f2fs_remount - f2fs_ioc_fitrim
- f2fs_issue_discard_timeout
- __issue_discard_cmd
- __drop_discard_cmd
- __wait_all_discard_cmd
- f2fs_trim_fs
- f2fs_write_checkpoint
- f2fs_clear_prefree_segments
- f2fs_issue_discard
- __issue_discard_async
- __queue_discard_cmd
- __update_discard_tree_range
- __insert_discard_cmd
- __create_discard_cmd
: atomic_inc(&dcc->discard_cmd_cnt);
- sanity check on dcc->discard_cmd_cnt (expect discard_cmd_cnt to be zero)
This will only happen when fitrim races w/ remount rw, if we remount to readonly filesystem, remount will wait until mnt_pcp.mnt_writers to zero, that means fitrim is not in process at that time.
--- fs/f2fs/f2fs.h | 2 +- fs/f2fs/segment.c | 6 +++--- fs/f2fs/super.c | 11 ++++++++--- 3 files changed, 12 insertions(+), 7 deletions(-)
fs/f2fs/f2fs.h +1 -1
@@ -3930,7 +3930,7 @@ bool f2fs_is_checkpointed_data(struct f2int f2fs_start_discard_thread (struct f2fs_sb_info *sbi);void f2fs_drop_discard_cmd (struct f2fs_sb_info *sbi);void f2fs_stop_discard_thread (struct f2fs_sb_info *sbi); -bool f2fs_issue_discard_timeout (struct f2fs_sb_info *sbi); +bool f2fs_issue_discard_timeout (struct f2fs_sb_info *sbi,bool need_check);void f2fs_clear_prefree_segments (struct f2fs_sb_info *sbi,struct cp_control *cpc);void f2fs_dirty_to_prefree (struct f2fs_sb_info *sbi);
fs/f2fs/segment.c +3 -3
@@ -1895,7 +1895,7 @@ void f2fs_stop_discard_thread(struct f2f* * Return true if issued all discard cmd or no discard cmd need issue, otherwise return false. */ -bool f2fs_issue_discard_timeout (struct f2fs_sb_info *sbi) +bool f2fs_issue_discard_timeout (struct f2fs_sb_info *sbi,bool need_check) {struct discard_cmd_control *dcc =SM_I (sbi)->dcc_info;struct discard_policy dpolicy;
@@ -1912,7 +1912,7 @@ bool f2fs_issue_discard_timeout(struct f/* just to make sure there is no pending discard commands */ __wait_all_discard_cmd (sbi,NULL ); -f2fs_bug_on (sbi,atomic_read (&dcc->discard_cmd_cnt)); +f2fs_bug_on (sbi, need_check &&atomic_read (&dcc->discard_cmd_cnt));return !dropped; }
@@ -2382,7 +2382,7 @@ static void destroy_discard_cmd_control(* Recovery can cache discard commands, so in error path of * fill_super(), it needs to give a chance to handle them. */ -f2fs_issue_discard_timeout (sbi); +f2fs_issue_discard_timeout (sbi, true);kfree (dcc);SM_I (sbi)->dcc_info =NULL ;
fs/f2fs/super.c +8 -3
@@ -1961,7 +1961,7 @@ static void f2fs_put_super(struct super_ }/* be sure to wait for any on-going discard commands */ - done =f2fs_issue_discard_timeout (sbi); + done =f2fs_issue_discard_timeout (sbi, true);if (f2fs_realtime_discard_enable (sbi) && !sbi->discard_blks && done) {struct cp_control cpc = { .reason =CP_UMOUNT |CP_TRIMMED ,
@@ -2104,7 +2104,7 @@ static int f2fs_unfreeze(struct super_bl* will recover after removal of snapshot. */ if (test_opt (sbi,DISCARD ) && !f2fs_hw_support_discard (sbi)) -f2fs_issue_discard_timeout (sbi); +f2fs_issue_discard_timeout (sbi, true);clear_sbi_flag (F2FS_SB (sb),SBI_IS_FREEZING );return 0 ;
@@ -2884,7 +2884,12 @@ static int __f2fs_remount(struct fs_cont need_stop_discard = true; }else {f2fs_stop_discard_thread (sbi); -f2fs_issue_discard_timeout (sbi); +/* +* f2fs_ioc_fitrim() won't race w/ "remount ro" +* so it's safe to check discard_cmd_cnt in +* f2fs_issue_discard_timeout(). +*/ +f2fs_issue_discard_timeout (sbi, flags &SB_RDONLY ); need_restart_discard = true; } }
Greg Kroah-Hartman
maintainerPATCH 28/55 f2fs: fix UAF caused by decrementing sbi->nr_pages[] in f2fs_write_end_io()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yongpeng Yang <[email protected]>
commit 2d9c4a4ed4eef1f82c5b16b037aee8bad819fd53 upstream.
The xfstests case "generic/107" and syzbot have both reported a NULL pointer dereference.
The concurrent scenario that triggers the panic is as follows:
F2FS_WB_CP_DATA write callback umount
- f2fs_write_checkpoint
- f2fs_wait_on_all_pages(sbi, F2FS_WB_CP_DATA)
- blk_mq_end_request
- bio_endio
- f2fs_write_end_io
: dec_page_count(sbi, F2FS_WB_CP_DATA)
: wake_up(&sbi->cp_wait)
- kill_f2fs_super
- kill_block_super
- f2fs_put_super
: iput(sbi->node_inode)
: sbi->node_inode = NULL
: f2fs_in_warm_node_list
- is_node_folio // sbi->node_inode is NULL and panic
The root cause is that f2fs_put_super() calls iput(sbi->node_inode) and sets sbi->node_inode to NULL after sbi->nr_pages[F2FS_WB_CP_DATA] is decremented to zero. As a result, f2fs_in_warm_node_list() may dereference a NULL node_inode when checking whether a folio belongs to the node inode, leading to a panic.
This patch fixes the issue by calling f2fs_in_warm_node_list() before decrementing sbi->nr_pages[F2FS_WB_CP_DATA], thus preventing the use-after-free condition.
--- fs/f2fs/data.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/f2fs/data.c +2 -2
@@ -363,6 +363,8 @@ static void f2fs_write_end_io(struct bio folio->index, NODE_TYPE_REGULAR, true);f2fs_bug_on (sbi, folio->index !=nid_of_node (folio)); } +if (f2fs_in_warm_node_list (sbi, folio)) +f2fs_del_fsync_node_entry (sbi, folio);dec_page_count (sbi, type);
@@ -374,8 +376,6 @@ static void f2fs_write_end_io(struct bio wq_has_sleeper(&sbi->cp_wait))wake_up (&sbi->cp_wait); -if (f2fs_in_warm_node_list (sbi, folio)) -f2fs_del_fsync_node_entry (sbi, folio);folio_clear_f2fs_gcing (folio);folio_end_writeback (folio); }
Greg Kroah-Hartman
maintainerPATCH 29/55 f2fs: fix to avoid memory leak in f2fs_rename()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <[email protected]>
commit 3cf11e6f36c170050c12171dd6fd3142711478fc upstream.
syzbot reported a f2fs bug as below:
BUG: memory leak
unreferenced object 0xffff888127f70830 (size 16):
comm "syz.0.23", pid 6144, jiffies 4294943712
hex dump (first 16 bytes):
3c af 57 72 5b e6 8f ad 6e 8e fd 33 42 39 03 ff <.Wr[...n..3B9..
backtrace (crc 925f8a80):
kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
slab_post_alloc_hook mm/slub.c:4520 [inline]
slab_alloc_node mm/slub.c:4844 [inline]
__do_kmalloc_node mm/slub.c:5237 [inline]
__kmalloc_noprof+0x3bd/0x560 mm/slub.c:5250
kmalloc_noprof include/linux/slab.h:954 [inline]
fscrypt_setup_filename+0x15e/0x3b0 fs/crypto/fname.c:364
f2fs_setup_filename+0x52/0xb0 fs/f2fs/dir.c:143
f2fs_rename+0x159/0xca0 fs/f2fs/namei.c:961
f2fs_rename2+0xd5/0xf20 fs/f2fs/namei.c:1308
vfs_rename+0x7ff/0x1250 fs/namei.c:6026
filename_renameat2+0x4f4/0x660 fs/namei.c:6144
__do_sys_renameat2 fs/namei.c:6173 [inline]
__se_sys_renameat2 fs/namei.c:6168 [inline]
__x64_sys_renameat2+0x59/0x80 fs/namei.c:6168
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7fThe root cause is in commit 40b2d55e0452 ("f2fs: fix to create selinux label during whiteout initialization"), we added a call to f2fs_setup_filename() without a matching call to f2fs_free_filename(), fix it.
--- fs/f2fs/namei.c | 1 + 1 file changed, 1 insertion(+)
fs/f2fs/namei.c +1 -0
@@ -949,6 +949,7 @@ static int f2fs_rename(struct mnt_idmapreturn err; err =f2fs_create_whiteout (idmap, old_dir, &whiteout, &fname); +f2fs_free_filename (&fname);if (err)return err; }
Greg Kroah-Hartman
maintainerPATCH 30/55 f2fs: fix to avoid uninit-value access in f2fs_sanity_check_node_footer
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <[email protected]>
commit 7b9161a605e91d0987e2596a245dc1f21621b23f upstream.
syzbot reported a f2fs bug as below:
BUG: KMSAN: uninit-value in f2fs_sanity_check_node_footer+0x374/0xa20 fs/f2fs/node.c:1520 f2fs_sanity_check_node_footer+0x374/0xa20 fs/f2fs/node.c:1520 f2fs_finish_read_bio+0xe1e/0x1d60 fs/f2fs/data.c:177 f2fs_read_end_io+0x6ab/0x2220 fs/f2fs/data.c:-1 bio_endio+0x1006/0x1160 block/bio.c:1792 submit_bio_noacct+0x533/0x2960 block/blk-core.c:891 submit_bio+0x57a/0x620 block/blk-core.c:926 blk_crypto_submit_bio include/linux/blk-crypto.h:203 [inline] f2fs_submit_read_bio+0x12c/0x360 fs/f2fs/data.c:557 f2fs_submit_page_bio+0xee2/0x1450 fs/f2fs/data.c:775 read_node_folio+0x384/0x4b0 fs/f2fs/node.c:1481 __get_node_folio+0x5db/0x15d0 fs/f2fs/node.c:1576 f2fs_get_inode_folio+0x40/0x50 fs/f2fs/node.c:1623 do_read_inode fs/f2fs/inode.c:425 [inline] f2fs_iget+0x1209/0x9380 fs/f2fs/inode.c:596 f2fs_fill_super+0x8f5a/0xb2e0 fs/f2fs/super.c:5184 get_tree_bdev_flags+0x6e6/0x920 fs/super.c:1694 get_tree_bdev+0x38/0x50 fs/super.c:1717 f2fs_get_tree+0x35/0x40 fs/f2fs/super.c:5436 vfs_get_tree+0xb3/0x5d0 fs/super.c:1754 fc_mount fs/namespace.c:1193 [inline] do_new_mount_fc fs/namespace.c:3763 [inline] do_new_mount+0x885/0x1dd0 fs/namespace.c:3839 path_mount+0x7a2/0x20b0 fs/namespace.c:4159 do_mount fs/namespace.c:4172 [inline] __do_sys_mount fs/namespace.c:4361 [inline] __se_sys_mount+0x704/0x7f0 fs/namespace.c:4338 __x64_sys_mount+0xe4/0x150 fs/namespace.c:4338 x64_sys_call+0x39f0/0x3ea0 arch/x86/include/generated/asm/syscalls_64.h:166 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0x134/0xf80 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f
The root cause is: in f2fs_finish_read_bio(), we may access uninit data in folio if we failed to read the data from device into folio, let's add a check condition to avoid such issue.
--- fs/f2fs/data.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/f2fs/data.c +2 -1
@@ -152,7 +152,8 @@ static void f2fs_finish_read_bio(structdec_page_count (F2FS_F_SB (folio),__read_io_type (folio)); -if (F2FS_F_SB (folio)->node_inode &&is_node_folio (folio) && +if (bio->bi_status ==BLK_STS_OK && +F2FS_F_SB (folio)->node_inode &&is_node_folio (folio) &&f2fs_sanity_check_node_footer (F2FS_F_SB (folio), folio, folio->index,NODE_TYPE_REGULAR , true)) bio->bi_status =BLK_STS_IOERR ;
Greg Kroah-Hartman
maintainerPATCH 31/55 fuse: reject oversized dirents in page cache
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Samuel Page <[email protected]>
commit 51a8de6c50bf947c8f534cd73da4c8f0a13e7bed upstream.
fuse_add_dirent_to_cache() computes a serialized dirent size from the server-controlled namelen field and copies the dirent into a single page-cache page. The existing logic only checks whether the dirent fits in the remaining space of the current page and advances to a fresh page if not. It never checks whether the dirent itself exceeds PAGE_SIZE.
As a result, a malicious FUSE server can return a dirent with namelen=4095, producing a serialized record size of 4120 bytes. On 4 KiB page systems this causes memcpy() to overflow the cache page by 24 bytes into the following kernel page.
Reject dirents that cannot fit in a single page before copying them into the readdir cache.
--- fs/fuse/readdir.c | 4 ++++ 1 file changed, 4 insertions(+)
fs/fuse/readdir.c +4 -0
@@ -41,6 +41,10 @@ static void fuse_add_dirent_to_cache(strunsigned int offset;void *addr; +/* Dirent doesn't fit in readdir cache page? Skip caching. */ +if (reclen >PAGE_SIZE ) +return ; +spin_lock (&fi->rdc.lock);/* * Is cache already completed? Or this entry does not go at the end of
Greg Kroah-Hartman
maintainerPATCH 32/55 fuse: abort on fatal signal during sync init
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miklos Szeredi <[email protected]>
commit 204aa22a686bfee48daca7db620c1e017615f2ff upstream.
When sync init is used and the server exits for some reason (error, crash) while processing FUSE_INIT, the filesystem creation will hang. The reason is that while all other threads will exit, the mounting thread (or process) will keep the device fd open, which will prevent an abort from happening.
This is a regression from the async mount case, where the mount was done first, and the FUSE_INIT processing afterwards, in which case there's no such recursive syscall keeping the fd open.
--- fs/fuse/dev.c | 8 +++++++- fs/fuse/fuse_i.h | 1 + fs/fuse/inode.c | 1 + 3 files changed, 9 insertions(+), 1 deletion(-)
fs/fuse/dev.c +7 -1
@@ -570,6 +570,11 @@ static void request_wait_answer(struct fif (!err)return ; +if (req->args->abort_on_kill) { +fuse_abort_conn (fc); +return ; + } +if (test_bit (FR_URING , &req->flags)) removed =fuse_uring_remove_pending_req (req);else
@@ -676,7 +681,8 @@ ssize_t __fuse_simple_request(struct mntfuse_force_creds (req);__set_bit (FR_WAITING , &req->flags); -__set_bit (FR_FORCE , &req->flags); +if (!args->abort_on_kill) +__set_bit (FR_FORCE , &req->flags); }else {WARN_ON (args->nocreds); req =fuse_get_req (idmap, fm, false);
fs/fuse/fuse_i.h +1 -0
@@ -333,6 +333,7 @@ struct fuse_args { bool is_ext:1; bool is_pinned:1; bool invalidate_vmap:1; + bool abort_on_kill:1;struct fuse_in_arg in_args[4 ];struct fuse_arg out_args[2 ];void (*end)(struct fuse_mount *fm,struct fuse_args *args,int error);
fs/fuse/inode.c +1 -0
@@ -1548,6 +1548,7 @@ int fuse_send_init(struct fuse_mount *fmint err;if (fm->fc->sync_init) { + ia->args.abort_on_kill = true; err =fuse_simple_request (fm, &ia->args);/* Ignore size of init reply */ if (err >0 )
Greg Kroah-Hartman
maintainerPATCH 33/55 fuse: Check for large folio with SPLICE_F_MOVE
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernd Schubert <[email protected]>
commit 59ba47b6be9cd0146ef9a55c6e32e337e11e7625 upstream.
xfstest generic/074 and generic/075 complain result in kernel warning messages / page dumps.
This is easily reproducible (on 6.19) with CONFIG_TRANSPARENT_HUGEPAGE_SHMEM_HUGE_ALWAYS=y CONFIG_TRANSPARENT_HUGEPAGE_TMPFS_HUGE_ALWAYS=y
This just adds a test for large folios fuse_try_move_folio with the same page copy fallback, but to avoid the warnings from fuse_check_folio().
--- fs/fuse/dev.c | 3 +++ 1 file changed, 3 insertions(+)
fs/fuse/dev.c +3 -0
@@ -1017,6 +1017,9 @@ static int fuse_try_move_folio(struct fufolio_clear_uptodate (newfolio);folio_clear_mappedtodisk (newfolio); +if (folio_test_large (newfolio)) + goto out_fallback_unlock; +if (fuse_check_folio (newfolio) !=0 ) goto out_fallback_unlock;
Greg Kroah-Hartman
maintainerPATCH 34/55 fuse: quiet down complaints in fuse_conn_limit_write
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <[email protected]>
commit 129a45f9755a89f573c6a513a6b9e3d234ce89b0 upstream.
gcc 15 complains about an uninitialized variable val that is passed by reference into fuse_conn_limit_write:
control.c: In function ‘fuse_conn_congestion_threshold_write’:
include/asm-generic/rwonce.h:55:37: warning: ‘val’ may be used uninitialized [-Wmaybe-uninitialized]
55 | *(volatile typeof(x) *)&(x) = (val); \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~
include/asm-generic/rwonce.h:61:9: note: in expansion of macro ‘__WRITE_ONCE’
61 | __WRITE_ONCE(x, val); \
| ^~~~~~~~~~~~
control.c:178:9: note: in expansion of macro ‘WRITE_ONCE’
178 | WRITE_ONCE(fc->congestion_threshold, val);
| ^~~~~~~~~~ control.c:166:18: note: ‘val’ was declared here
166 | unsigned val;
| ^~~
Unfortunately there's enough macro spew involved in kstrtoul_from_user that I think gcc gives up on its analysis and sprays the above warning. AFAICT it's not actually a bug, but we could just zero-initialize the variable to enable using -Wmaybe-uninitialized to find real problems.
Previously we would use some weird uninitialized_var annotation to quiet down the warnings, so clearly this code has been like this for quite some time.
--- fs/fuse/control.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/fuse/control.c +2 -2
@@ -121,7 +121,7 @@ static ssize_t fuse_conn_max_background_const char __user *buf, size_t count, loff_t *ppos) { - unsigned val; + unsigned int val = 0;ssize_t ret; ret = fuse_conn_limit_write(file, buf, count, ppos, &val,
@@ -163,7 +163,7 @@ static ssize_t fuse_conn_congestion_threconst char __user *buf, size_t count, loff_t *ppos) { - unsigned val; + unsigned int val = 0;struct fuse_conn *fc;ssize_t ret;
Greg Kroah-Hartman
maintainerPATCH 35/55 fuse: fuse_dev_ioctl_clone() should wait for device file to be initialized
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miklos Szeredi <[email protected]>
commit da6fcc6dbddbef80e603d2f0c1554a9f2ac03742 upstream.
Use fuse_get_dev() not __fuse_get_dev() on the old fd, since in the case of synchronous INIT the caller will want to wait for the device file to be available for cloning, just like I/O wants to wait instead of returning an error.
--- fs/fuse/dev.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-)
fs/fuse/dev.c +8 -11
@@ -2599,9 +2599,8 @@ static int fuse_device_clone(struct fusestatic long fuse_dev_ioctl_clone (struct file *file,__u32 __user *argp) { -int res;int oldfd; -struct fuse_dev *fud =NULL ; +struct fuse_dev *fud;if (get_user (oldfd, argp))return -EFAULT ;
@@ -2614,17 +2613,15 @@ static long fuse_dev_ioctl_clone(struct* Check against file->f_op because CUSE * uses the same ioctl handler. */ -if (fd_file (f)->f_op == file->f_op) - fud =__fuse_get_dev (fd_file (f)); +if (fd_file (f)->f_op != file->f_op) +return -EINVAL ; - res = -EINVAL ; -if (fud) { -mutex_lock (&fuse_mutex); - res =fuse_device_clone (fud->fc, file); -mutex_unlock (&fuse_mutex); - } + fud =fuse_get_dev (fd_file (f)); +if (IS_ERR (fud)) +return PTR_ERR (fud); -return res; +guard (mutex)(&fuse_mutex); +return fuse_device_clone (fud->fc, file); } static long fuse_dev_ioctl_backing_open(struct file *file,
Greg Kroah-Hartman
maintainerPATCH 36/55 ksmbd: require minimum ACE size in smb_check_perm_dacl()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Bommarito <[email protected]>
commit d07b26f39246a82399661936dd0c853983cfade7 upstream.
Both ACE-walk loops in smb_check_perm_dacl() only guard against an under-sized remaining buffer, not against an ACE whose declared ace->size is smaller than the struct it claims to describe:
if (offsetof(struct smb_ace, access_req) > aces_size)
break;
ace_size = le16_to_cpu(ace->size);
if (ace_size > aces_size)
break;The first check only requires the 4-byte ACE header to be in bounds; it does not require access_req (4 bytes at offset 4) to be readable. An attacker who has set a crafted DACL on a file they own can declare ace->size == 4 with aces_size == 4, pass both checks, and then
granted |= le32_to_cpu(ace->access_req); /* upper loop */
compare_sids(&sid, &ace->sid); /* lower loop */
reads access_req at offset 4 (OOB by up to 4 bytes) and ace->sid at offset 8 (OOB by up to CIFS_SID_BASE_SIZE + SID_MAX_SUB_AUTHORITIES
* 4 bytes).
Tighten both loops to require
ace_size >= offsetof(struct smb_ace, sid) + CIFS_SID_BASE_SIZE
which is the smallest valid on-wire ACE layout (4-byte header + 4-byte access_req + 8-byte sid base with zero sub-auths). Also reject ACEs whose sid.num_subauth exceeds SID_MAX_SUB_AUTHORITIES before letting compare_sids() dereference sub_auth[] entries.
parse_sec_desc() already enforces an equivalent check (lines 441-448); smb_check_perm_dacl() simply grew weaker validation over time.
Reachability: authenticated SMB client with permission to set an ACL on a file. On a subsequent CREATE against that file, the kernel walks the stored DACL via smb_check_perm_dacl() and triggers the OOB read. Not pre-auth, and the OOB read is not reflected to the attacker, but KASAN reports and kernel state corruption are possible.
--- fs/smb/server/smbacl.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-)
fs/smb/server/smbacl.c +13 -4
@@ -1342,10 +1342,13 @@ int smb_check_perm_dacl(struct ksmbd_con ace = (struct smb_ace *)((char *)pdacl +sizeof (struct smb_acl )); aces_size = acl_size -sizeof (struct smb_acl );for (i =0 ; i <le16_to_cpu (pdacl->num_aces); i++) { -if (offsetof(struct smb_ace , access_req) > aces_size) +if (offsetof(struct smb_ace , sid) + + aces_size <CIFS_SID_BASE_SIZE )break ; ace_size =le16_to_cpu (ace->size); -if (ace_size > aces_size) +if (ace_size > aces_size || + ace_size < offsetof(struct smb_ace , sid) + +CIFS_SID_BASE_SIZE )break ; aces_size -= ace_size; granted |=le32_to_cpu (ace->access_req);
@@ -1363,13 +1366,19 @@ int smb_check_perm_dacl(struct ksmbd_con ace = (struct smb_ace *)((char *)pdacl +sizeof (struct smb_acl )); aces_size = acl_size -sizeof (struct smb_acl );for (i =0 ; i <le16_to_cpu (pdacl->num_aces); i++) { -if (offsetof(struct smb_ace , access_req) > aces_size) +if (offsetof(struct smb_ace , sid) + + aces_size <CIFS_SID_BASE_SIZE )break ; ace_size =le16_to_cpu (ace->size); -if (ace_size > aces_size) +if (ace_size > aces_size || + ace_size < offsetof(struct smb_ace , sid) + +CIFS_SID_BASE_SIZE )break ; aces_size -= ace_size; +if (ace->sid.num_subauth >SID_MAX_SUB_AUTHORITIES ) +break ; +if (!compare_sids (&sid, &ace->sid) || !compare_sids (&sid_unix_NFS_mode, &ace->sid)) { found =1 ;
Greg Kroah-Hartman
maintainerPATCH 37/55 smb: server: fix active_num_conn leak on transport allocation failure
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Bommarito <[email protected]>
commit 6551300dc452ac16a855a83dbd1e74899542d3b3 upstream.
Commit 77ffbcac4e56 ("smb: server: fix leak of active_num_conn in ksmbd_tcp_new_connection()") addressed the kthread_run() failure path. The earlier alloc_transport() == NULL path in the same function has the same leak, is reachable pre-authentication via any TCP connect to port 445, and was empirically reproduced on UML (ARCH=um, v7.0-rc7): a small number of forced allocation failures were sufficient to put ksmbd into a state where every subsequent connection attempt was rejected for the remainder of the boot.
ksmbd_kthread_fn() increments active_num_conn before calling ksmbd_tcp_new_connection() and discards the return value, so when alloc_transport() returns NULL the socket is released and -ENOMEM returned without decrementing the counter. Each such failure permanently consumes one slot from the max_connections pool; once cumulative failures reach the cap, atomic_inc_return() hits the threshold on every subsequent accept and every new connection is rejected. The counter is only reset by module reload.
An unauthenticated remote attacker can drive the server toward the memory pressure that makes alloc_transport() fail by holding open connections with large RFC1002 lengths up to MAX_STREAM_PROT_LEN (0x00FFFFFF); natural transient allocation failures on a loaded host produce the same drift more slowly.
Mirror the existing rollback pattern in ksmbd_kthread_fn(): on the alloc_transport() failure path, decrement active_num_conn gated on server_conf.max_connections.
Repro details: with the patch reverted, forced alloc_transport() NULL returns leaked counter slots and subsequent connection attempts -- including legitimate connects issued after the forced-fail window had closed -- were all rejected with "Limit the maximum number of connections". With this patch applied, the same connect sequence produces no rejections and the counter cycles cleanly between zero and one on every accept.
--- fs/smb/server/transport_tcp.c | 2 ++ 1 file changed, 2 insertions(+)
fs/smb/server/transport_tcp.c +2 -0
@@ -197,6 +197,8 @@ static int ksmbd_tcp_new_connection(stru t =alloc_transport (client_sk);if (!t) {sock_release (client_sk); +if (server_conf.max_connections) +atomic_dec (&active_num_conn);return -ENOMEM ; }
Greg Kroah-Hartman
maintainerPATCH 38/55 smb: server: fix max_connections off-by-one in tcp accept path
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: DaeMyung Kang <[email protected]>
commit ce23158bfe584bd90d1918f279fdf9de57802012 upstream.
The global max_connections check in ksmbd's TCP accept path counts the newly accepted connection with atomic_inc_return(), but then rejects the connection when the result is greater than or equal to server_conf.max_connections.
That makes the effective limit one smaller than configured. For example:
- max_connections=1 rejects the first connection
- max_connections=2 allows only one connection
The per-IP limit in the same function uses <= correctly because it counts only pre-existing connections. The global limit instead checks the post-increment total, so it should reject only when that total exceeds the configured maximum.
Fix this by changing the comparison from >= to >, so exactly max_connections simultaneous connections are allowed and the next one is rejected. This matches the documented meaning of max_connections in fs/smb/server/ksmbd_netlink.h as the "Number of maximum simultaneous connections".
--- fs/smb/server/transport_tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/smb/server/transport_tcp.c +1 -1
@@ -301,7 +301,7 @@ static int ksmbd_kthread_fn(void *p) skip_max_ip_conns_limit:if (server_conf.max_connections && -atomic_inc_return (&active_num_conn) >= server_conf.max_connections) { +atomic_inc_return (&active_num_conn) > server_conf.max_connections) {pr_info_ratelimited ("Limit the maximum number of connections(%u)\n" ,atomic_read (&active_num_conn));atomic_dec (&active_num_conn);
Greg Kroah-Hartman
maintainerPATCH 39/55 smb: client: require a full NFS mode SID before reading mode bits
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Bommarito <[email protected]>
commit 2757ad3e4b6f9e0fed4c7739594e702abc5cab21 upstream.
parse_dacl() treats an ACE SID matching sid_unix_NFS_mode as an NFS mode SID and reads sid.sub_auth[2] to recover the mode bits.
That assumes the ACE carries three subauthorities, but compare_sids() only compares min(a, b) subauthorities. A malicious server can return an ACE with num_subauth = 2 and sub_auth[] = {88, 3}, which still matches sid_unix_NFS_mode and then drives the sub_auth[2] read four bytes past the end of the ACE.
Require num_subauth >= 3 before treating the ACE as an NFS mode SID. This keeps the fix local to the special-SID mode path without changing compare_sids() semantics for the rest of cifsacl.
--- fs/smb/client/cifsacl.c | 1 + 1 file changed, 1 insertion(+)
fs/smb/client/cifsacl.c +1 -0
@@ -831,6 +831,7 @@ static void parse_dacl(struct smb_acl *pdump_ace (ppace[i], end_of_acl);#endif if (mode_from_special_sid && + ppace[i]->sid.num_subauth >=3 && (compare_sids (&(ppace[i]->sid), &sid_unix_NFS_mode) ==0 )) {/*
Greg Kroah-Hartman
maintainerPATCH 40/55 smb: client: fix OOB read in smb2_ioctl_query_info QUERY_INFO path
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Bommarito <[email protected]>
commit a58c5af19ff0d6f44f6e9fe31e33a2c92223f77e upstream.
smb2_ioctl_query_info() has two response-copy branches: PASSTHRU_FSCTL and the default QUERY_INFO path. The QUERY_INFO branch clamps qi.input_buffer_length to the server-reported OutputBufferLength and then copies qi.input_buffer_length bytes from qi_rsp->Buffer to userspace, but it never verifies that the flexible-array payload actually fits within rsp_iov[1].iov_len.
A malicious server can return OutputBufferLength larger than the actual QUERY_INFO response, causing copy_to_user() to walk past the response buffer and expose adjacent kernel heap to userspace.
Guard the QUERY_INFO copy with a bounds check on the actual Buffer payload. Use struct_size(qi_rsp, Buffer, qi.input_buffer_length) rather than an open-coded addition so the guard cannot overflow on 32-bit builds.
--- fs/smb/client/smb2ops.c | 6 ++++++ 1 file changed, 6 insertions(+)
fs/smb/client/smb2ops.c +6 -0
@@ -1775,6 +1775,12 @@ replay_again: qi_rsp = (struct smb2_query_info_rsp *)rsp_iov[1 ].iov_base;if (le32_to_cpu (qi_rsp->OutputBufferLength) < qi.input_buffer_length) qi.input_buffer_length =le32_to_cpu (qi_rsp->OutputBufferLength); +if (qi.input_buffer_length >0 && +struct_size (qi_rsp, Buffer, qi.input_buffer_length) > + rsp_iov[1 ].iov_len) { + rc = -EFAULT ; + goto out; + }if (copy_to_user (&pqi->input_buffer_length, &qi.input_buffer_length,sizeof (qi.input_buffer_length))) {
Greg Kroah-Hartman
maintainerPATCH 41/55 ksmbd: validate response sizes in ipc_validate_msg()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Bommarito <[email protected]>
commit d6a6aa81eac2c9bff66dc6e191179cb69a14426b upstream.
ipc_validate_msg() computes the expected message size for each response type by adding (or multiplying) attacker-controlled fields from the daemon response to a fixed struct size in unsigned int arithmetic. Three cases can overflow:
KSMBD_EVENT_RPC_REQUEST:
msg_sz = sizeof(struct ksmbd_rpc_command) + resp->payload_sz;
KSMBD_EVENT_SHARE_CONFIG_REQUEST:
msg_sz = sizeof(struct ksmbd_share_config_response) +
resp->payload_sz;
KSMBD_EVENT_LOGIN_REQUEST_EXT:
msg_sz = sizeof(struct ksmbd_login_response_ext) +
resp->ngroups * sizeof(gid_t);resp->payload_sz is __u32 and resp->ngroups is __s32. Each addition can wrap in unsigned int; the multiplication by sizeof(gid_t) mixes signed and size_t, so a negative ngroups is converted to SIZE_MAX before the multiply. A wrapped value of msg_sz that happens to equal entry->msg_sz bypasses the size check on the next line, and downstream consumers (smb2pdu.c:6742 memcpy using rpc_resp->payload_sz, kmemdup in ksmbd_alloc_user using resp_ext->ngroups) then trust the unverified length.
Use check_add_overflow() on the RPC_REQUEST and SHARE_CONFIG_REQUEST paths to detect integer overflow without constraining functional payload size; userspace ksmbd-tools grows NDR responses in 4096-byte chunks for calls like NetShareEnumAll, so a hard transport cap is unworkable on the response side. For LOGIN_REQUEST_EXT, reject resp->ngroups outside the signed [0, NGROUPS_MAX] range up front and report the error from ipc_validate_msg() so it fires at the IPC boundary; with that bound the subsequent multiplication and addition stay well below UINT_MAX. The now-redundant ngroups check and pr_err in ksmbd_alloc_user() are removed.
This is the response-side analogue of aab98e2dbd64 ("ksmbd: fix integer overflows on 32 bit systems"), which hardened the request side.
--- fs/smb/server/mgmt/user_config.c | 6 ------ fs/smb/server/transport_ipc.c | 16 +++++++++++++--- 2 files changed, 13 insertions(+), 9 deletions(-)
fs/smb/server/mgmt/user_config.c +0 -6
@@ -56,12 +56,6 @@ struct ksmbd_user *ksmbd_alloc_user(stru goto err_free;if (resp_ext) { -if (resp_ext->ngroups >NGROUPS_MAX ) { -pr_err ("ngroups(%u) from login response exceeds max groups(%d)\n" , - resp_ext->ngroups,NGROUPS_MAX ); - goto err_free; - } - user->sgid =kmemdup (resp_ext->____payload, resp_ext->ngroups *sizeof (gid_t),KSMBD_DEFAULT_GFP );
fs/smb/server/transport_ipc.c +13 -3
@@ -13,6 +13,7 @@#include <net/genetlink.h> #include <linux/socket.h> #include <linux/workqueue.h> +#include <linux/overflow.h> #include "vfs_cache.h" #include "transport_ipc.h"
@@ -497,7 +498,9 @@ static int ipc_validate_msg(struct ipc_m {struct ksmbd_rpc_command *resp = entry->response; - msg_sz =sizeof (struct ksmbd_rpc_command ) + resp->payload_sz; +if (check_add_overflow (sizeof (struct ksmbd_rpc_command ), + resp->payload_sz, &msg_sz)) +return -EINVAL ;break ; }case KSMBD_EVENT_SPNEGO_AUTHEN_REQUEST :
@@ -516,8 +519,9 @@ static int ipc_validate_msg(struct ipc_mif (resp->payload_sz < resp->veto_list_sz)return -EINVAL ; - msg_sz =sizeof (struct ksmbd_share_config_response ) + - resp->payload_sz; +if (check_add_overflow (sizeof (struct ksmbd_share_config_response ), + resp->payload_sz, &msg_sz)) +return -EINVAL ; }break ; }
@@ -526,6 +530,12 @@ static int ipc_validate_msg(struct ipc_mstruct ksmbd_login_response_ext *resp = entry->response;if (resp->ngroups) { +if (resp->ngroups <0 || + resp->ngroups >NGROUPS_MAX ) { +pr_err ("ngroups(%d) from login response exceeds max groups(%d)\n" , + resp->ngroups,NGROUPS_MAX ); +return -EINVAL ; + } msg_sz =sizeof (struct ksmbd_login_response_ext ) + resp->ngroups *sizeof (gid_t); }
Greg Kroah-Hartman
maintainerPATCH 42/55 ksmbd: validate num_aces and harden ACE walk in smb_inherit_dacl()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Bommarito <[email protected]>
commit 3e4e2ea2a781018ed5d75f969e3e5606beb66e48 upstream.
smb_inherit_dacl() trusts the on-disk num_aces value from the parent directory's DACL xattr and uses it to size a heap allocation:
aces_base = kmalloc(sizeof(struct smb_ace) * num_aces * 2, ...);
num_aces is a u16 read from le16_to_cpu(parent_pdacl->num_aces) without checking that it is consistent with the declared pdacl_size. An authenticated client whose parent directory's security.NTACL is tampered (e.g. via offline xattr corruption or a concurrent path that bypasses parse_dacl()) can present num_aces = 65535 with minimal actual ACE data. This causes a ~8 MB allocation (not kzalloc, so uninitialized) that the subsequent loop only partially populates, and may also overflow the three-way size_t multiply on 32-bit kernels.
Additionally, the ACE walk loop uses the weaker offsetof(struct smb_ace, access_req) minimum size check rather than the minimum valid on-wire ACE size, and does not reject ACEs whose declared size is below the minimum.
Reproduced on UML + KASAN + LOCKDEP against the real ksmbd code path. A legitimate mount.cifs client creates a parent directory over SMB (ksmbd writes a valid security.NTACL xattr), then the NTACL blob on the backing filesystem is rewritten to set num_aces = 0xFFFF while keeping the posix_acl_hash bytes intact so ksmbd_vfs_get_sd_xattr()'s hash check still passes. A subsequent SMB2 CREATE of a child under that parent drives smb2_open() into smb_inherit_dacl() (share has "vfs objects = acl_xattr" set), which fails the page allocator:
WARNING: mm/page_alloc.c:5226 at __alloc_frozen_pages_noprof+0x46c/0x9c0 Workqueue: ksmbd-io handle_ksmbd_work __alloc_frozen_pages_noprof+0x46c/0x9c0 ___kmalloc_large_node+0x68/0x130 __kmalloc_large_node_noprof+0x24/0x70 __kmalloc_noprof+0x4c9/0x690 smb_inherit_dacl+0x394/0x2430 smb2_open+0x595d/0xabe0 handle_ksmbd_work+0x3d3/0x1140
With the patch applied the added guard rejects the tampered value with -EINVAL before any large allocation runs, smb2_open() falls back to smb2_create_sd_buffer(), and the child is created with a default SD. No warning, no splat.
Fix by:
1. Validating num_aces against pdacl_size using the same formula applied in parse_dacl().
2. Replacing the raw kmalloc(sizeof * num_aces * 2) with kmalloc_array(num_aces * 2, sizeof(...)) for overflow-safe allocation.
3. Tightening the per-ACE loop guard to require the minimum valid ACE size (offsetof(smb_ace, sid) + CIFS_SID_BASE_SIZE) and rejecting under-sized ACEs, matching the hardening in smb_check_perm_dacl() and parse_dacl().
v1 -> v2:
- Replace the synthetic test-module splat in the changelog with a real-path UML + KASAN reproduction driven through mount.cifs and SMB2 CREATE; Namjae flagged the kcifs3_test_inherit_dacl_old name in v1 since it does not exist in ksmbd.
- Drop the commit-hash citation from the code comment per Namjae's review; keep the parse_dacl() pointer.
--- fs/smb/server/smbacl.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-)
fs/smb/server/smbacl.c +23 -5
@@ -1106,8 +1106,24 @@ int smb_inherit_dacl(struct ksmbd_conn * goto free_parent_pntsd; } - aces_base =kmalloc (sizeof (struct smb_ace ) * num_aces *2 , -KSMBD_DEFAULT_GFP ); + aces_size = pdacl_size -sizeof (struct smb_acl ); + +/* +* Validate num_aces against the DACL payload before allocating. +* Each ACE must be at least as large as its fixed-size header +* (up to the SID base), so num_aces cannot exceed the payload +* divided by the minimum ACE size. This mirrors the existing +* check in parse_dacl(). +*/ +if (num_aces > aces_size / (offsetof(struct smb_ace , sid) + + offsetof(struct smb_sid , sub_auth) + +sizeof (__le16))) { + rc = -EINVAL ; + goto free_parent_pntsd; + } + + aces_base =kmalloc_array (num_aces *2 ,sizeof (struct smb_ace ), +KSMBD_DEFAULT_GFP );if (!aces_base) { rc = -ENOMEM ; goto free_parent_pntsd;
@@ -1116,7 +1132,6 @@ int smb_inherit_dacl(struct ksmbd_conn * aces = (struct smb_ace *)aces_base; parent_aces = (struct smb_ace *)((char *)parent_pdacl +sizeof (struct smb_acl )); - aces_size = acl_len -sizeof (struct smb_acl );if (pntsd_type &DACL_AUTO_INHERITED ) inherited_flags =INHERITED_ACE ;
@@ -1124,11 +1139,14 @@ int smb_inherit_dacl(struct ksmbd_conn *for (i =0 ; i < num_aces; i++) {int pace_size; -if (offsetof(struct smb_ace , access_req) > aces_size) +if (aces_size < offsetof(struct smb_ace , sid) + +CIFS_SID_BASE_SIZE )break ; pace_size =le16_to_cpu (parent_aces->size); -if (pace_size > aces_size) +if (pace_size > aces_size || + pace_size < offsetof(struct smb_ace , sid) + +CIFS_SID_BASE_SIZE )break ; aces_size -= pace_size;
Greg Kroah-Hartman
maintainerPATCH 43/55 ksmbd: fix out-of-bounds write in smb2_get_ea() EA alignment
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tristan Madani <[email protected]>
commit 30010c952077a1c89ecdd71fc4d574c75a8f5617 upstream.
smb2_get_ea() applies 4-byte alignment padding via memset() after writing each EA entry. The bounds check on buf_free_len is performed before the value memcpy, but the alignment memset fires unconditionally afterward with no check on remaining space.
When the EA value exactly fills the remaining buffer (buf_free_len == 0 after value subtraction), the alignment memset writes 1-3 NUL bytes past the buf_free_len boundary. In compound requests where the response buffer is shared across commands, the first command (e.g., READ) can consume most of the buffer, leaving a tight remainder for the QUERY_INFO EA response. The alignment memset then overwrites past the physical kvmalloc allocation into adjacent kernel heap memory.
Add a bounds check before the alignment memset to ensure buf_free_len can accommodate the padding bytes.
This is the same bug pattern fixed by commit beef2634f81f ("ksmbd: fix potencial OOB in get_file_all_info() for compound requests") and commit fda9522ed6af ("ksmbd: fix OOB write in QUERY_INFO for compound requests"), both of which added bounds checks before unconditional writes in QUERY_INFO response handlers.
--- fs/smb/server/smb2pdu.c | 2 ++ 1 file changed, 2 insertions(+)
fs/smb/server/smb2pdu.c +2 -0
@@ -4831,6 +4831,8 @@ static int smb2_get_ea(struct ksmbd_work/* align next xattr entry at 4 byte bundary */ alignment_bytes = ((next_offset +3 ) & ~3 ) - next_offset;if (alignment_bytes) { +if (buf_free_len < alignment_bytes) +break ;memset (ptr,'\0' , alignment_bytes); ptr += alignment_bytes; next_offset += alignment_bytes;
Greg Kroah-Hartman
maintainerPATCH 44/55 ksmbd: use check_add_overflow() to prevent u16 DACL size overflow
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tristan Madani <[email protected]>
commit 299f962c0b02d048fb45d248b4da493d03f3175d upstream.
set_posix_acl_entries_dacl() and set_ntacl_dacl() accumulate ACE sizes in u16 variables. When a file has many POSIX ACL entries, the accumulated size can wrap past 65535, causing the pointer arithmetic (char *)pndace + *size to land within already-written ACEs. Subsequent writes then overwrite earlier entries, and pndacl->size gets a truncated value.
Use check_add_overflow() at each accumulation point to detect the wrap before it corrupts the buffer, consistent with existing check_mul_overflow() usage elsewhere in smbacl.c.
--- fs/smb/server/smbacl.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
fs/smb/server/smbacl.c +12 -4
@@ -596,6 +596,7 @@ static void set_posix_acl_entries_dacl(sstruct smb_sid *sid;struct smb_ace *ntace;int i, j; +u16 ace_sz;if (!fattr->cf_acls) goto posix_default_acl;
@@ -640,8 +641,10 @@ static void set_posix_acl_entries_dacl(s flags =0x03 ; ntace = (struct smb_ace *)((char *)pndace + *size); - *size +=fill_ace_for_sid (ntace, sid,ACCESS_ALLOWED , flags, + ace_sz =fill_ace_for_sid (ntace, sid,ACCESS_ALLOWED , flags, pace->e_perm,0777 ); +if (check_add_overflow (*size, ace_sz, size)) +break ; (*num_aces)++;if (pace->e_tag ==ACL_USER ) ntace->access_req |=
@@ -650,8 +653,10 @@ static void set_posix_acl_entries_dacl(sif (S_ISDIR (fattr->cf_mode) && (pace->e_tag ==ACL_USER || pace->e_tag ==ACL_GROUP )) { ntace = (struct smb_ace *)((char *)pndace + *size); - *size +=fill_ace_for_sid (ntace, sid,ACCESS_ALLOWED , + ace_sz =fill_ace_for_sid (ntace, sid,ACCESS_ALLOWED ,0x03 , pace->e_perm,0777 ); +if (check_add_overflow (*size, ace_sz, size)) +break ; (*num_aces)++;if (pace->e_tag ==ACL_USER ) ntace->access_req |=
@@ -691,8 +696,10 @@ posix_default_acl: } ntace = (struct smb_ace *)((char *)pndace + *size); - *size +=fill_ace_for_sid (ntace, sid,ACCESS_ALLOWED ,0x0b , + ace_sz =fill_ace_for_sid (ntace, sid,ACCESS_ALLOWED ,0x0b , pace->e_perm,0777 ); +if (check_add_overflow (*size, ace_sz, size)) +break ; (*num_aces)++;if (pace->e_tag ==ACL_USER ) ntace->access_req |=
@@ -728,7 +735,8 @@ static void set_ntacl_dacl(struct mnt_idbreak ;memcpy ((char *)pndace + size, ntace, nt_ace_size); - size += nt_ace_size; +if (check_add_overflow (size, nt_ace_size, &size)) +break ; aces_size -= nt_ace_size; ntace = (struct smb_ace *)((char *)ntace + nt_ace_size); num_aces++;
Greg Kroah-Hartman
maintainerPATCH 45/55 ksmbd: reset rcount per connection in ksmbd_conn_wait_idle_sess_id()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: DaeMyung Kang <[email protected]>
commit def036ef87f8641c1c525d5ae17438d7a1006491 upstream.
rcount is intended to be connection-specific: 2 for curr_conn, 1 for every other connection sharing the same session. However, it is initialised only once before the hash iteration and is never reset. After the loop visits curr_conn, later sibling connections are also checked against rcount == 2, so a sibling with req_running == 1 is incorrectly treated as idle. This makes the outcome depend on the hash iteration order: whether a given sibling is checked against the loose (< 2) or the strict (< 1) threshold is decided by whether it happens to be visited before or after curr_conn.
The function's contract is "wait until every connection sharing this session is idle" so that destroy_previous_session() can safely tear the session down. The latched rcount violates that contract and reopens the teardown race window the wait logic was meant to close:destroy_previous_session() may proceed before sibling channels have actually quiesced, overlapping session teardown with in-flight work on those connections.
Recompute rcount inside the loop so each connection is compared against its own threshold regardless of iteration order.
This is a code-inspection fix for an iteration-order-dependent logic error; a targeted reproducer would require SMB3 multichannel with in-flight work on a sibling channel landing after curr_conn in hash order, which is not something that can be triggered reliably.
--- fs/smb/server/connection.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
fs/smb/server/connection.c +2 -3
@@ -180,7 +180,7 @@ int ksmbd_conn_wait_idle_sess_id(struct {struct ksmbd_conn *conn;int rc, retry_count =0 , max_timeout =120 ; -int rcount =1 , bkt; +int rcount, bkt; retry_idle:if (retry_count >= max_timeout)
@@ -189,8 +189,7 @@ retry_idle:down_read (&conn_list_lock);hash_for_each (conn_list, bkt, conn, hlist) {if (conn->binding ||xa_load (&conn->sessions, sess_id)) { -if (conn == curr_conn) - rcount =2 ; + rcount = (conn == curr_conn) ?2 :1 ;if (atomic_read (&conn->req_running) >= rcount) { rc = wait_event_timeout(conn->req_running_q, atomic_read(&conn->req_running) < rcount,
Greg Kroah-Hartman
maintainerPATCH 46/55 writeback: Fix use after free in inode_switch_wbs_work_fn()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Kara <[email protected]>
commit 6689f01d6740cf358932b3e97ee968c6099800d9 upstream.
inode_switch_wbs_work_fn() has a loop like:
wb_get(new_wb);
while (1) {
list = llist_del_all(&new_wb->switch_wbs_ctxs);
/* Nothing to do? */
if (!list)
break;
... process the items ...
}Now adding of items to the list looks like:
wb_queue_isw()
if (llist_add(&isw->list, &wb->switch_wbs_ctxs))
queue_work(isw_wq, &wb->switch_work);
Because inode_switch_wbs_work_fn() loops when processing isw items, it can happen that wb->switch_work is pending while wb->switch_wbs_ctxs is empty. This is a problem because in that case wb can get freed (no isw items -> no wb reference) while the work is still pending causing use-after-free issues.
We cannot just fix this by cancelling work when freeing wb because that could still trigger problematic 0 -> 1 transitions on wb refcount due to wb_get() in inode_switch_wbs_work_fn(). It could be all handled with more careful code but that seems unnecessarily complex so let's avoid that until it is proven that the looping actually brings practical benefit. Just remove the loop from inode_switch_wbs_work_fn() instead. That way when wb_queue_isw() queues work, we are guaranteed we have added the first item to wb->switch_wbs_ctxs and nobody is going to remove it (and drop the wb reference it holds) until the queued work runs.
--- fs/fs-writeback.c | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-)
fs/fs-writeback.c +19 -17
@@ -558,28 +558,30 @@ void inode_switch_wbs_work_fn(struct worstruct inode_switch_wbs_context *isw, *next_isw;struct llist_node *list; + list =llist_del_all (&new_wb->switch_wbs_ctxs);/* -* Grab out reference to wb so that it cannot get freed under us +* Nothing to do? That would be a problem as references held by isw +* items protect wb from freeing... +*/ +if (WARN_ON_ONCE (!list)) +return ; + +/* +* Grab our reference to wb so that it cannot get freed under us * after we process all the isw items. */ wb_get (new_wb); -while (1 ) { - list =llist_del_all (&new_wb->switch_wbs_ctxs); -/* Nothing to do? */ -if (!list) -break ; -/* -* In addition to synchronizing among switchers, I_WB_SWITCH -* tells the RCU protected stat update paths to grab the i_page -* lock so that stat transfer can synchronize against them. -* Let's continue after I_WB_SWITCH is guaranteed to be -* visible. -*/ -synchronize_rcu (); +/* +* In addition to synchronizing among switchers, I_WB_SWITCH +* tells the RCU protected stat update paths to grab the i_page +* lock so that stat transfer can synchronize against them. +* Let's continue after I_WB_SWITCH is guaranteed to be +* visible. +*/ +synchronize_rcu (); -llist_for_each_entry_safe (isw, next_isw, list, list) -process_inode_switch_wbs (new_wb, isw); - } +llist_for_each_entry_safe (isw, next_isw, list, list) +process_inode_switch_wbs (new_wb, isw);wb_put (new_wb); }
Greg Kroah-Hartman
maintainerPATCH 47/55 f2fs: fix use-after-free of sbi in f2fs_compress_write_end_io()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: George Saad <[email protected]>
commit 39d4ee19c1e7d753dd655aebee632271b171f43a upstream.
In f2fs_compress_write_end_io(), dec_page_count(sbi, type) can bring the F2FS_WB_CP_DATA counter to zero, unblocking f2fs_wait_on_all_pages() in f2fs_put_super() on a concurrent unmount CPU. The unmount path then proceeds to call f2fs_destroy_page_array_cache(sbi), which destroys sbi->page_array_slab via kmem_cache_destroy(), and eventually kfree(sbi). Meanwhile, the bio completion callback is still executing:
when it reaches page_array_free(sbi, ...), it dereferences sbi->page_array_slab — a destroyed slab cache — to call kmem_cache_free(), causing a use-after-free.
This is the same class of bug as CVE-2026-23234 (which fixed the equivalent race in f2fs_write_end_io() in data.c), but in the compressed writeback completion path that was not covered by that fix.
Fix this by moving dec_page_count() to after page_array_free(), so that all sbi accesses complete before the counter decrement that can unblock unmount. For non-last folios (where atomic_dec_return on cic->pending_pages is nonzero), dec_page_count is called immediately before returning — page_array_free is not reached on this path, so there is no post-decrement sbi access. For the last folio, page_array_free runs while the F2FS_WB_CP_DATA counter is still nonzero (this folio has not yet decremented it), keeping sbi alive, and dec_page_count runs as the final operation.
--- fs/f2fs/compress.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
fs/f2fs/compress.c +11 -3
@@ -1489,10 +1489,10 @@ void f2fs_compress_write_end_io(struct bf2fs_compress_free_page (page); -dec_page_count (sbi, type); - -if (atomic_dec_return (&cic->pending_pages)) +if (atomic_dec_return (&cic->pending_pages)) { +dec_page_count (sbi, type);return ; + }for (i =0 ; i < cic->nr_rpages; i++) {WARN_ON (!cic->rpages[i]);
@@ -1502,6 +1502,14 @@ void f2fs_compress_write_end_io(struct bpage_array_free (sbi, cic->rpages, cic->nr_rpages);kmem_cache_free (cic_entry_slab, cic); + +/* +* Make sure dec_page_count() is the last access to sbi. +* Once it drops the F2FS_WB_CP_DATA counter to zero, the +* unmount thread can proceed to destroy sbi and +* sbi->page_array_slab. +*/ +dec_page_count (sbi, type); } static int f2fs_write_raw_pages(struct compress_ctx *cc,
Greg Kroah-Hartman
maintainerPATCH 48/55 ALSA: usb-audio: apply quirk for MOONDROP JU Jiu
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cryolitia PukNgae <[email protected]>
commit 4513d3e0bbc0585b86ccf2631902593ff97e88f5 upstream.
It(ID 31b2:0111 JU Jiu) reports a MIN value -12800 for volume control, but will mute when setting it less than -10880.
Thanks to my girlfriend Kagura for reporting this issue.
--- sound/usb/mixer.c | 7 +++++++ 1 file changed, 7 insertions(+)
sound/usb/mixer.c +7 -0
@@ -1204,6 +1204,13 @@ static void volume_control_quirks(struct cval->min =-11264 ;/* Mute under it */ }break ; +case USB_ID (0x31b2 ,0x0111 ):/* MOONDROP JU Jiu */ +if (!strcmp (kctl->id.name,"PCM Playback Volume" )) { +usb_audio_info (chip, +"set volume quirk for MOONDROP JU Jiu\n" ); + cval->min =-10880 ;/* Mute under it */ + } +break ; } }
Greg Kroah-Hartman
maintainerPATCH 49/55 ALSA: hda/realtek: Add quirk for Legion S7 15IMH
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Naim <[email protected]>
commit 67f4c61a73e9b17dc9593bf27badc6785ecadd78 upstream.
Fix speaker output on the Lenovo Legion S7 15IMH05.
--- sound/hda/codecs/realtek/alc269.c | 1 + 1 file changed, 1 insertion(+)
sound/hda/codecs/realtek/alc269.c +1 -0
@@ -7392,6 +7392,7 @@ static const struct hda_quirk alc269_fixSND_PCI_QUIRK (0x17aa ,0x3801 ,"Lenovo Yoga9 14IAP7" ,ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN ),HDA_CODEC_QUIRK (0x17aa ,0x3802 ,"DuetITL 2021" ,ALC287_FIXUP_YOGA7_14ITL_SPEAKERS ),SND_PCI_QUIRK (0x17aa ,0x3802 ,"Lenovo Yoga Pro 9 14IRP8" ,ALC287_FIXUP_TAS2781_I2C ), +SND_PCI_QUIRK (0x17aa ,0x3811 ,"Legion S7 15IMH05" ,ALC287_FIXUP_LEGION_15IMHG05_SPEAKERS ),SND_PCI_QUIRK (0x17aa ,0x3813 ,"Legion 7i 15IMHG05" ,ALC287_FIXUP_LEGION_15IMHG05_SPEAKERS ),SND_PCI_QUIRK (0x17aa ,0x3818 ,"Lenovo C940 / Yoga Duet 7" ,ALC298_FIXUP_LENOVO_C940_DUET7 ), SND_PCI_QUIRK(0x17aa, 0x3819, "Lenovo 13s Gen2 ITL", ALC287_FIXUP_13S_GEN2_SPEAKERS),
Greg Kroah-Hartman
maintainerPATCH 50/55 ALSA: caiaq: take a reference on the USB device in create_card()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Berk Cem Goksel <[email protected]>
commit 80bb50e2d459213cccff3111d5ef98ed4238c0d5 upstream.
The caiaq driver stores a pointer to the parent USB device in cdev->chip.dev but never takes a reference on it. The card's private_free callback, snd_usb_caiaq_card_free(), can run asynchronously via snd_card_free_when_closed() after the USB device has already been disconnected and freed, so any access to cdev->chip.dev in that path dereferences a freed usb_device.
On top of the refcounting issue, the current card_free implementation calls usb_reset_device(cdev->chip.dev). A reset in a free callback is inappropriate: the device is going away, the call takes the device lock in a teardown context, and the reset races with the disconnect path that the callback is already cleaning up after.
Take a reference on the USB device in create_card() with usb_get_dev(), drop it with usb_put_dev() in the free callback, and remove the usb_reset_device() call.
--- sound/usb/caiaq/device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
sound/usb/caiaq/device.c +2 -2
@@ -384,7 +384,7 @@ static void card_free(struct snd_card *csnd_usb_caiaq_input_free (cdev);#endif snd_usb_caiaq_audio_free (cdev); -usb_reset_device (cdev->chip.dev); +usb_put_dev (cdev->chip.dev); } static int create_card(struct usb_device *usb_dev,
@@ -410,7 +410,7 @@ static int create_card(struct usb_devicereturn err; cdev =caiaqdev (card); - cdev->chip.dev = usb_dev; + cdev->chip.dev =usb_get_dev (usb_dev); cdev->chip.card = card; cdev->chip.usb_id =USB_ID (le16_to_cpu (usb_dev->descriptor.idVendor),le16_to_cpu (usb_dev->descriptor.idProduct));
Greg Kroah-Hartman
maintainerPATCH 51/55 net/packet: fix TOCTOU race on mmapd vnet_hdr in tpacket_snd()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bingquan Chen <[email protected]>
commit 2c054e17d9d41f1020376806c7f750834ced4dc5 upstream.
In tpacket_snd(), when PACKET_VNET_HDR is enabled, vnet_hdr points directly into the mmap'd TX ring buffer shared with userspace. The kernel validates the header via __packet_snd_vnet_parse() but then re-reads all fields later in virtio_net_hdr_to_skb(). A concurrent userspace thread can modify the vnet_hdr fields between validation and use, bypassing all safety checks.
The non-TPACKET path (packet_snd()) already correctly copies vnet_hdr to a stack-local variable. All other vnet_hdr consumers in the kernel (tun.c, tap.c, virtio_net.c) also use stack copies. The TPACKET TX path is the only caller of virtio_net_hdr_to_skb() that reads directly from user-controlled shared memory.
Fix this by copying vnet_hdr from the mmap'd ring buffer to a stack-local variable before validation and use, consistent with the approach used in packet_snd() and all other callers.
--- net/packet/af_packet.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-)
net/packet/af_packet.c +13 -8
@@ -2717,7 +2717,8 @@ static int tpacket_snd(struct packet_soc {struct sk_buff *skb =NULL ;struct net_device *dev; -struct virtio_net_hdr *vnet_hdr =NULL ; +struct virtio_net_hdr vnet_hdr; +bool has_vnet_hdr = false;struct sockcm_cookie sockc;__be16 proto;int err, reserve =0 ;
@@ -2818,16 +2819,20 @@ static int tpacket_snd(struct packet_soc hlen =LL_RESERVED_SPACE (dev); tlen = dev->needed_tailroom;if (vnet_hdr_sz) { - vnet_hdr = data; data += vnet_hdr_sz; tp_len -= vnet_hdr_sz; -if (tp_len <0 || -__packet_snd_vnet_parse (vnet_hdr, tp_len)) { +if (tp_len <0 ) { + tp_len = -EINVAL ; + goto tpacket_error; + } +memcpy (&vnet_hdr, data - vnet_hdr_sz,sizeof (vnet_hdr)); +if (__packet_snd_vnet_parse (&vnet_hdr, tp_len)) { tp_len = -EINVAL ; goto tpacket_error; } copylen =__virtio16_to_cpu (vio_le (), - vnet_hdr->hdr_len); + vnet_hdr.hdr_len); + has_vnet_hdr = true; } copylen =max_t (int, copylen, dev->hard_header_len); skb = sock_alloc_send_skb(&po->sk,
@@ -2864,12 +2869,12 @@ tpacket_error: } } -if (vnet_hdr_sz) { -if (virtio_net_hdr_to_skb (skb, vnet_hdr,vio_le ())) { +if (has_vnet_hdr) { +if (virtio_net_hdr_to_skb (skb, &vnet_hdr,vio_le ())) { tp_len = -EINVAL ; goto tpacket_error; } -virtio_net_hdr_set_proto (skb, vnet_hdr); +virtio_net_hdr_set_proto (skb, &vnet_hdr); } skb->destructor = tpacket_destruct_skb;
Greg Kroah-Hartman
maintainerPATCH 52/55 crypto: ccp: Dont attempt to copy CSR to userspace if PSP command failed
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <[email protected]>
commit abe4a6d6f606113251868c2c4a06ba904bb41eed upstream.
When retrieving the PEK CSR, don't attempt to copy the blob to userspace if the firmware command failed. If the failure was due to an invalid length, i.e. the userspace buffer+length was too small, copying the number of bytes _firmware_ requires will overflow the kernel-allocated buffer and leak data to userspace.
BUG: KASAN: slab-out-of-bounds in instrument_copy_to_user ../include/linux/instrumented.h:129 [inline] BUG: KASAN: slab-out-of-bounds in _inline_copy_to_user ../include/linux/uaccess.h:205 [inline] BUG: KASAN: slab-out-of-bounds in _copy_to_user+0x66/0xa0 ../lib/usercopy.c:26 Read of size 2084 at addr ffff898144612e20 by task syz.9.219/21405 CPU: 14 UID: 0 PID: 21405 Comm: syz.9.219 Tainted: G U O 7.0.0-smp-DEV #28 PREEMPTLAZY Tainted: [U]=USER, [O]=OOT_MODULE Hardware name: Google, Inc. Arcadia_IT_80/Arcadia_IT_80, BIOS 12.62.0-0 11/19/2025 Call Trace: <TASK> dump_stack_lvl+0xc5/0x110 ../lib/dump_stack.c:120 print_address_description ../mm/kasan/report.c:378 [inline] print_report+0xbc/0x260 ../mm/kasan/report.c:482 kasan_report+0xa2/0xe0 ../mm/kasan/report.c:595 check_region_inline ../mm/kasan/generic.c:-1 [inline] kasan_check_range+0x264/0x2c0 ../mm/kasan/generic.c:200 instrument_copy_to_user ../include/linux/instrumented.h:129 [inline] _inline_copy_to_user ../include/linux/uaccess.h:205 [inline] _copy_to_user+0x66/0xa0 ../lib/usercopy.c:26 copy_to_user ../include/linux/uaccess.h:236 [inline] sev_ioctl_do_pek_csr+0x31f/0x590 ../drivers/crypto/ccp/sev-dev.c:1872 sev_ioctl+0x3a4/0x490 ../drivers/crypto/ccp/sev-dev.c:2562 vfs_ioctl ../fs/ioctl.c:51 [inline] __do_sys_ioctl ../fs/ioctl.c:597 [inline] __se_sys_ioctl+0x11d/0x1b0 ../fs/ioctl.c:583 do_syscall_x64 ../arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xe0/0x800 ../arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x76/0x7e </TASK>
WARN if the driver says the command succeeded, but the firmware error code says otherwise, as __sev_do_cmd_locked() is expected to return -EIO on any firwmware error.
--- drivers/crypto/ccp/sev-dev.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/crypto/ccp/sev-dev.c +7 -1
@@ -1833,7 +1833,10 @@ cmd: ret =__sev_do_cmd_locked (SEV_CMD_PEK_CSR , &data, &argp->error); -/* If we query the CSR length, FW responded with expected data. */ +/* +* Firmware will returns the length of the CSR blob (either the minimum +* required length or the actual length written), return it to the user. +*/ input.length = data.len;if (copy_to_user ((void __user *)argp->data, &input,sizeof (input))) {
@@ -1841,6 +1844,9 @@ cmd: goto e_free_blob; } +if (ret ||WARN_ON_ONCE (argp->error)) + goto e_free_blob; +if (blob) {if (copy_to_user (input_address, blob, input.length)) ret = -EFAULT ;
Greg Kroah-Hartman
maintainerPATCH 53/55 crypto: ccp: Dont attempt to copy PDH cert to userspace if PSP command failed
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <[email protected]>
commit e76239fed3cffd6d304d8ca3ce23984fd24f57d3 upstream.
When retrieving the PDH cert, don't attempt to copy the blobs to userspace if the firmware command failed. If the failure was due to an invalid length, i.e. the userspace buffer+length was too small, copying the number of bytes _firmware_ requires will overflow the kernel-allocated buffer and leak data to userspace.
BUG: KASAN: slab-out-of-bounds in instrument_copy_to_user ../include/linux/instrumented.h:129 [inline] BUG: KASAN: slab-out-of-bounds in _inline_copy_to_user ../include/linux/uaccess.h:205 [inline] BUG: KASAN: slab-out-of-bounds in _copy_to_user+0x66/0xa0 ../lib/usercopy.c:26 Read of size 2084 at addr ffff8885c4ab8aa0 by task syz.0.186/21033 CPU: 51 UID: 0 PID: 21033 Comm: syz.0.186 Tainted: G U O 7.0.0-smp-DEV #28 PREEMPTLAZY Tainted: [U]=USER, [O]=OOT_MODULE Hardware name: Google, Inc. Arcadia_IT_80/Arcadia_IT_80, BIOS 34.84.12-0 11/17/2025 Call Trace: <TASK> dump_stack_lvl+0xc5/0x110 ../lib/dump_stack.c:120 print_address_description ../mm/kasan/report.c:378 [inline] print_report+0xbc/0x260 ../mm/kasan/report.c:482 kasan_report+0xa2/0xe0 ../mm/kasan/report.c:595 check_region_inline ../mm/kasan/generic.c:-1 [inline] kasan_check_range+0x264/0x2c0 ../mm/kasan/generic.c:200 instrument_copy_to_user ../include/linux/instrumented.h:129 [inline] _inline_copy_to_user ../include/linux/uaccess.h:205 [inline] _copy_to_user+0x66/0xa0 ../lib/usercopy.c:26 copy_to_user ../include/linux/uaccess.h:236 [inline] sev_ioctl_do_pdh_export+0x3d3/0x7c0 ../drivers/crypto/ccp/sev-dev.c:2347 sev_ioctl+0x2a2/0x490 ../drivers/crypto/ccp/sev-dev.c:2568 vfs_ioctl ../fs/ioctl.c:51 [inline] __do_sys_ioctl ../fs/ioctl.c:597 [inline] __se_sys_ioctl+0x11d/0x1b0 ../fs/ioctl.c:583 do_syscall_x64 ../arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xe0/0x800 ../arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x76/0x7e </TASK>
WARN if the driver says the command succeeded, but the firmware error code says otherwise, as __sev_do_cmd_locked() is expected to return -EIO on any firwmware error.
--- drivers/crypto/ccp/sev-dev.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/crypto/ccp/sev-dev.c +7 -1
@@ -2313,7 +2313,10 @@ cmd: ret =__sev_do_cmd_locked (SEV_CMD_PDH_CERT_EXPORT , &data, &argp->error); -/* If we query the length, FW responded with expected data. */ +/* +* Firmware will return the length of the blobs (either the minimum +* required length or the actual length written), return 'em to the user. +*/ input.cert_chain_len = data.cert_chain_len; input.pdh_cert_len = data.pdh_cert_len;
@@ -2322,6 +2325,9 @@ cmd: goto e_free_cert; } +if (ret ||WARN_ON_ONCE (argp->error)) + goto e_free_cert; +if (pdh_blob) {if (copy_to_user (input_pdh_cert_address, pdh_blob, input.pdh_cert_len)) {
Greg Kroah-Hartman
maintainerPATCH 54/55 crypto: ccp: Dont attempt to copy ID to userspace if PSP command failed
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <[email protected]>
commit 4f685dbfa87c546e51d9dc6cab379d20f275e114 upstream.
When retrieving the ID for the CPU, don't attempt to copy the ID blob to userspace if the firmware command failed. If the failure was due to an invalid length, i.e. the userspace buffer+length was too small, copying the number of bytes _firmware_ requires will overflow the kernel-allocated buffer and leak data to userspace.
BUG: KASAN: slab-out-of-bounds in instrument_copy_to_user ../include/linux/instrumented.h:129 [inline] BUG: KASAN: slab-out-of-bounds in _inline_copy_to_user ../include/linux/uaccess.h:205 [inline] BUG: KASAN: slab-out-of-bounds in _copy_to_user+0x66/0xa0 ../lib/usercopy.c:26 Read of size 64 at addr ffff8881867f5960 by task syz.0.906/24388 CPU: 130 UID: 0 PID: 24388 Comm: syz.0.906 Tainted: G U O 7.0.0-smp-DEV #28 PREEMPTLAZY Tainted: [U]=USER, [O]=OOT_MODULE Hardware name: Google, Inc. Arcadia_IT_80/Arcadia_IT_80, BIOS 12.62.0-0 11/19/2025 Call Trace: <TASK> dump_stack_lvl+0xc5/0x110 ../lib/dump_stack.c:120 print_address_description ../mm/kasan/report.c:378 [inline] print_report+0xbc/0x260 ../mm/kasan/report.c:482 kasan_report+0xa2/0xe0 ../mm/kasan/report.c:595 check_region_inline ../mm/kasan/generic.c:-1 [inline] kasan_check_range+0x264/0x2c0 ../mm/kasan/generic.c:200 instrument_copy_to_user ../include/linux/instrumented.h:129 [inline] _inline_copy_to_user ../include/linux/uaccess.h:205 [inline] _copy_to_user+0x66/0xa0 ../lib/usercopy.c:26 copy_to_user ../include/linux/uaccess.h:236 [inline] sev_ioctl_do_get_id2+0x361/0x490 ../drivers/crypto/ccp/sev-dev.c:2222 sev_ioctl+0x25f/0x490 ../drivers/crypto/ccp/sev-dev.c:2575 vfs_ioctl ../fs/ioctl.c:51 [inline] __do_sys_ioctl ../fs/ioctl.c:597 [inline] __se_sys_ioctl+0x11d/0x1b0 ../fs/ioctl.c:583 do_syscall_x64 ../arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xe0/0x800 ../arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x76/0x7e </TASK>
WARN if the driver says the command succeeded, but the firmware error code says otherwise, as __sev_do_cmd_locked() is expected to return -EIO on any firwmware error.
--- drivers/crypto/ccp/sev-dev.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/crypto/ccp/sev-dev.c +3 -0
@@ -2197,6 +2197,9 @@ static int sev_ioctl_do_get_id2(struct s goto e_free; } +if (ret ||WARN_ON_ONCE (argp->error)) + goto e_free; +if (id_blob) {if (copy_to_user (input_address, id_blob, data.len)) { ret = -EFAULT ;
Greg Kroah-Hartman
maintainerPATCH 55/55 rxrpc: Fix missing validation of ticket length in non-XDR key preparsing
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Anderson Nascimento <[email protected]>
commit ac33733b10b484d666f97688561670afd5861383 upstream.
In rxrpc_preparse(), there are two paths for parsing key payloads: the XDR path (for large payloads) and the non-XDR path (for payloads <= 28 bytes). While the XDR path (rxrpc_preparse_xdr_rxkad()) correctly validates the ticket length against AFSTOKEN_RK_TIX_MAX, the non-XDR path fails to do so.
This allows an unprivileged user to provide a very large ticket length. When this key is later read via rxrpc_read(), the total token size (toksize) calculation results in a value that exceeds AFSTOKEN_LENGTH_MAX, triggering a WARN_ON().
[ 2001.302904] WARNING: CPU: 2 PID: 2108 at net/rxrpc/key.c:778 rxrpc_read+0x109/0x5c0 [rxrpc]
Fix this by adding a check in the non-XDR parsing path of rxrpc_preparse() to ensure the ticket length does not exceed AFSTOKEN_RK_TIX_MAX, bringing it into parity with the XDR parsing logic.
--- net/rxrpc/key.c | 4 ++++ 1 file changed, 4 insertions(+)
net/rxrpc/key.c +4 -0
@@ -502,6 +502,10 @@ static int rxrpc_preparse(struct key_preif (v1->security_index !=RXRPC_SECURITY_RXKAD ) goto error; + ret = -EKEYREJECTED ; +if (v1->ticket_length >AFSTOKEN_RK_TIX_MAX ) + goto error; + plen =sizeof (*token->kad) + v1->ticket_length; prep->quotalen += plen +sizeof (*token);
Hi!
Quoted 4 lines
This is the start of the stable review cycle for the 6.18.25 release. There are 55 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
CIP testing did not find any problems here:
https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/tree/linux-6.18.y
Best regards,
Pavel
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.18.25 release. There are 55 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 26 Apr 2026 13:23:22 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.18.25-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.18.y
and the diffstat can be found below.thanks,
greg k-h
On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels, build tested on BMIPS_GENERIC:
Signature · 1 line
Florian
Am 24.04.2026 um 15:30 schrieb Greg Kroah-Hartman:
Quoted 4 lines
This is the start of the stable review cycle for the 6.18.25 release. There are 55 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Builds, boots and works on my 2-socket Ivy Bridge Xeon E5-2697 v2 server. No dmesg oddities or regressions found.
Beste Grüße,
Peter Schneider
Signature · 8 lines
Climb the mountain not to plant your flag, but to embrace the challenge, enjoy the air and behold the view. Climb it so you can see the world, not so the world can see you. -- David McCullough Jr. OpenPGP: 0xA3828BD796CCE11A8CADE8866E3A92C92C3FF244 Download: https://www.peters-netzplatz.de/download/pschneider1968_pub.asc https://keys.mailvelope.com/pks/lookup?op=get&[email protected] https://keys.mailvelope.com/pks/lookup?op=get&[email protected]
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.18.25 release. There are 55 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.18.25 release. There are 55 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 26 Apr 2026 13:23:22 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.18.25-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.18.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
# Librecast Test Results
020/020 [ OK ] liblcrq
010/010 [ OK ] libmld
120/120 [ OK ] liblibrecast
CPU/kernel: Linux auntie 6.18.25-rc1-g2bba374400df #1 SMP PREEMPT_DYNAMIC Sat Apr 25 07:23:55 -00 2026 x86_64 AMD Ryzen 9 9950X 16-Core Processor AuthenticAMD GNU/Linux
Quoted 8 lines · On Fri, 24 Apr 2026 15:30:39 +0200 Greg Kroah-Hartman…
This is the start of the stable review cycle for the 6.18.25 release. There are 55 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 26 Apr 2026 13:23:22 +0000. Anything received after that time might be too late.
Boot-tested under QEMU for Rust x86_64, arm64 and riscv64; built-tested for loongarch64:
The UML issue is now gone.
Thanks!
Cheers,
Miguel
Build tested in our x86,arm64,loongarch,riscv config successfully without error.
BRs
Wentao Guan
defconfigs:
https://gist.github.com/opsiff/a840ae9e3d6857f5b7bacb9cdc49f8e9
Log:
strings vmlinux-* | grep "Linux version 6.18.25-rc1"
Linux version 6.18.25-rc1-g2bba374400df (guanwentao@uos-PC) (aarch64-linux-gnu-gcc-12 (Deepin 12.3.0-17deepin8) 12.3.0, GNU ld (GNU Binutils for Deepin) 2.41) # SMP PREEMPT_DYNAMIC Linux version 6.18.25-rc1-g2bba374400df (guanwentao@uos-PC) (aarch64-linux-gnu-gcc-12 (Deepin 12.3.0-17deepin8) 12.3.0, GNU ld (GNU Binutils for Deepin) 2.41) #2 SMP PREEMPT_DYNAMIC Sun Apr 26 00:40:28 CST 2026 Linux version 6.18.25-rc1-g2bba374400df (guanwentao@uos-PC) (loongarch64-linux-gnu-gcc-12 (Deepin 12.3.0-17deepin8) 12.3.0, GNU ld (GNU Binutils for Deepin) 2.41) # SMP PREEMPT_DYNAMIC Linux version 6.18.25-rc1-g2bba374400df (guanwentao@uos-PC) (loongarch64-linux-gnu-gcc-12 (Deepin 12.3.0-17deepin8) 12.3.0, GNU ld (GNU Binutils for Deepin) 2.41) #3 SMP PREEMPT_DYNAMIC Sun Apr 26 01:03:19 CST 2026 Linux version 6.18.25-rc1+ (guanwentao@uos-PC) (riscv64-linux-gnu-gcc-12 (Deepin 12.3.0-17deepin8) 12.3.0, GNU ld (GNU Binutils for Deepin) 2.41) # SMP PREEMPT
Linux version 6.18.25-rc1+ (guanwentao@uos-PC) (riscv64-linux-gnu-gcc-12 (Deepin 12.3.0-17deepin8) 12.3.0, GNU ld (GNU Binutils for Deepin) 2.41) #4 SMP PREEMPT Sun Apr 26 01:28:01 CST 2026 Linux version 6.18.25-rc1-g2bba374400df (guanwentao@uos-PC) (gcc (Deepin 12.3.0-17deepin15) 12.3.0, GNU ld (GNU Binutils for Deepin) 2.41) # SMP PREEMPT_DYNAMIC
Linux version 6.18.25-rc1-g2bba374400df (guanwentao@uos-PC) (gcc (Deepin 12.3.0-17deepin15) 12.3.0, GNU ld (GNU Binutils for Deepin) 2.41) #1 SMP PREEMPT_DYNAMIC Sun Apr 26 00:14:25 CST 2026
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.18.25 release. There are 55 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 26 Apr 2026 13:23:22 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.18.25-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.18.y
and the diffstat can be found below.thanks,
greg k-h
Built and booted successfully on RISC-V RV64 (HiFive Unmatched).
Quoted 15 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.18.25 release. There are 55 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 26 Apr 2026 13:23:22 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.18.25-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.18.y
and the diffstat can be found below.
Quoted 5 lines
thanks,
greg k-h
-------------
I tested kernel version 6.18.25-rc1 by building and booting it in a virtual environment on both x86_64 and arm64 architectures.
Build and boot testing was performed on version 6.18.25-rc1 using the default configuration on both x86_64 and arm64 architectures in a virtual environment. The kernel built and booted successfully, and no dmesg regressions were observed.
kernel version: 6.18.25-rc1
Configurations: x86_64_defconfig, defconfig
Architectures: arm64, x86_64
Kernel Source: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
Commit: 2bba374400df741071c2c40c53e8d4b8254899f2
Regards,
Dileep Malepu
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.18.25 release. There are 55 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 26 Apr 2026 13:23:22 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.18.25-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.18.y
and the diffstat can be found below.thanks,
greg k-h
Tested on 2 amd64 laptops and 1 arm64 virtual machine. Working well, no regressions observed.
Signature · 1 line
-Barry K. Nathan <[email protected]>