6.12.84-rc1 review
Greg Kroah-Hartman
maintainercover 6.12.84-rc1 review
This is the start of the stable review cycle for the 6.12.84 release. There are 35 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:21 +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.12.84-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.12.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 6.12.84-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()
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()
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()
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
Samuel Page <[email protected]>
fuse: reject oversized dirents in page cache
Chao Yu <[email protected]>
f2fs: fix to avoid memory leak in f2fs_rename()
Greg Kroah-Hartman <[email protected]>
fs/ntfs3: validate rec->used in journal-replay file record check
Wang Jie <[email protected]>
rxrpc: only handle RESPONSE during service challenge
Nathan Chancellor <[email protected]>
scripts/dtc: Remove unused dts_version in dtc-lexer.l
Namjae Jeon <[email protected]>
ksmbd: fix use-after-free in __ksmbd_close_fd() via durable scavenger
Max Boone <[email protected]>
mm/pagewalk: fix race between concurrent split and refault
Tamir Duberstein <[email protected]>
scripts: generate_rust_analyzer.py: define scripts
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
Miguel Ojeda <[email protected]>
rust: warn on bindgen < 0.69.5 and libclang >= 19.1
Felix Fietkau <[email protected]>
wifi: mac80211: always free skb on ieee80211_tx_prepare_skb() failure
Steven Chen <[email protected]>
ima: do not copy measurement list to kdump kernel
Steven Chen <[email protected]>
ima: verify if the segment size has changed
Koichiro Den <[email protected]>
PCI: endpoint: pci-epf-vntb: Remove duplicate resource teardown
Jianhui Zhou <[email protected]>
mm/userfaultfd: fix hugetlb fault mutex hash calculation
-------------
Diffstat:
Makefile | 4 +- 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 + drivers/net/wireless/ath/ath9k/channel.c | 6 +-- drivers/net/wireless/virtual/mac80211_hwsim.c | 1 - drivers/pci/endpoint/functions/pci-epf-vntb.c | 18 +------ fs/f2fs/compress.c | 14 +++-- fs/f2fs/namei.c | 1 + fs/fuse/control.c | 4 +- fs/fuse/dev.c | 3 ++ 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/mgmt/user_config.c | 6 --- fs/smb/server/smb2pdu.c | 2 + 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 | 41 +++++++++++---- include/linux/hugetlb.h | 17 ++++++ include/net/mac80211.h | 4 +- mm/pagewalk.c | 24 ++++++++- mm/userfaultfd.c | 2 +- net/mac80211/tx.c | 4 +- net/packet/af_packet.c | 21 +++++--- net/rxrpc/conn_event.c | 14 ++++- net/rxrpc/key.c | 4 ++ scripts/dtc/dtc-lexer.l | 3 -- scripts/generate_rust_analyzer.py | 14 ++++- scripts/rust_is_available.sh | 15 ++++++ .../rust_is_available_bindgen_libclang_concat.h | 3 ++ scripts/rust_is_available_test.py | 34 +++++++++++- security/integrity/ima/ima_kexec.c | 13 +++++ sound/usb/caiaq/device.c | 4 +- sound/usb/mixer.c | 7 +++ 39 files changed, 389 insertions(+), 109 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/35 mm/userfaultfd: fix hugetlb fault mutex hash calculation
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jianhui Zhou <[email protected]>
[ Upstream commit 0217c7fb4de4a40cee667eb21901f3204effe5ac ]
In mfill_atomic_hugetlb(), linear_page_index() is used to calculate the page index for hugetlb_fault_mutex_hash(). However, linear_page_index() returns the index in PAGE_SIZE units, while hugetlb_fault_mutex_hash() expects the index in huge page units. This mismatch means that different addresses within the same huge page can produce different hash values, leading to the use of different mutexes for the same huge page. This can cause races between faulting threads, which can corrupt the reservation map and trigger the BUG_ON in resv_map_release().
Fix this by introducing hugetlb_linear_page_index(), which returns the page index in huge page granularity, and using it in place of linear_page_index().
--- include/linux/hugetlb.h | 17 +++++++++++++++++ mm/userfaultfd.c | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-)
include/linux/hugetlb.h +17 -0
@@ -783,6 +783,23 @@ static inline unsigned huge_page_shift(struct hstate *h)return h->order +PAGE_SHIFT ; } +/** +* hugetlb_linear_page_index() - linear_page_index() but in hugetlb +* page size granularity. +* @vma: the hugetlb VMA +* @address: the virtual address within the VMA +* +* Return: the page offset within the mapping in huge page units. +*/ +static inline pgoff_t hugetlb_linear_page_index (struct vm_area_struct *vma, +unsigned long address) +{ +struct hstate *h =hstate_vma (vma); + +return ((address - vma->vm_start) >>huge_page_shift (h)) + + (vma->vm_pgoff >>huge_page_order (h)); +} +static inline bool hstate_is_gigantic (struct hstate *h) {return huge_page_order (h) >MAX_PAGE_ORDER ;
mm/userfaultfd.c +1 -1
@@ -573,7 +573,7 @@ static __always_inline ssize_t mfill_atomic_hugetlb(* in the case of shared pmds. fault mutex prevents * races with other faulting threads. */ - idx =linear_page_index (dst_vma, dst_addr); + idx =hugetlb_linear_page_index (dst_vma, dst_addr); mapping = dst_vma->vm_file->f_mapping; hash =hugetlb_fault_mutex_hash (mapping, idx);mutex_lock (&hugetlb_fault_mutex_table[hash]);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 2/35 PCI: endpoint: pci-epf-vntb: Remove duplicate resource teardown
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Koichiro Den <[email protected]>
[ Upstream commit 0da63230d3ec1ec5fcc443a2314233e95bfece54 ]
epf_ntb_epc_destroy() duplicates the teardown that the caller is supposed to perform later. This leads to an oops when .allow_link fails or when .drop_link is performed. The following is an example oops of the former case:
Unable to handle kernel paging request at virtual address dead000000000108 [...] [dead000000000108] address between user and kernel address ranges Internal error: Oops: 0000000096000044 [#1] SMP [...] Call trace: pci_epc_remove_epf+0x78/0xe0 (P) pci_primary_epc_epf_link+0x88/0xa8 configfs_symlink+0x1f4/0x5a0 vfs_symlink+0x134/0x1d8 do_symlinkat+0x88/0x138 __arm64_sys_symlinkat+0x74/0xe0 [...]
Remove the helper, and drop pci_epc_put(). EPC device refcounting is tied to the configfs EPC group lifetime, and pci_epc_put() in the .drop_link path is sufficient.
--- drivers/pci/endpoint/functions/pci-epf-vntb.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-)
drivers/pci/endpoint/functions/pci-epf-vntb.c +1 -17
@@ -662,18 +662,6 @@ static void epf_ntb_mw_bar_clear(struct epf_ntb *ntb, int num_mws) } } -/** -* epf_ntb_epc_destroy() - Cleanup NTB EPC interface -* @ntb: NTB device that facilitates communication between HOST and VHOST -* -* Wrapper for epf_ntb_epc_destroy_interface() to cleanup all the NTB interfaces -*/ -static void epf_ntb_epc_destroy (struct epf_ntb *ntb) -{ -pci_epc_remove_epf (ntb->epf->epc, ntb->epf,0 ); -pci_epc_put (ntb->epf->epc); -} -/** * epf_ntb_init_epc_bar() - Identify BARs to be used for each of the NTB * constructs (scratchpad region, doorbell, memorywindow)
@@ -1315,7 +1303,7 @@ static int epf_ntb_bind(struct pci_epf *epf) ret =epf_ntb_init_epc_bar (ntb);if (ret) {dev_err (dev,"Failed to create NTB EPC\n" ); - goto err_bar_init; +return ret; } ret =epf_ntb_config_spad_bar_alloc (ntb);
@@ -1355,9 +1343,6 @@ static int epf_ntb_bind(struct pci_epf *epf) err_bar_alloc:epf_ntb_config_spad_bar_free (ntb); -err_bar_init: -epf_ntb_epc_destroy (ntb); -return ret; }
@@ -1373,7 +1358,6 @@ static void epf_ntb_unbind(struct pci_epf *epf)epf_ntb_epc_cleanup (ntb);epf_ntb_config_spad_bar_free (ntb); -epf_ntb_epc_destroy (ntb);pci_unregister_driver (&vntb_pci_driver); }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 3/35 ima: verify if the segment size has changed
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Chen <[email protected]>
[ Upstream commit d0a00ce470e3ea19ba3b9f1c390aee739570a44a ]
kexec 'load' may be called multiple times. Free and realloc the buffer only if the segment_size is changed from the previous kexec 'load' call.
--- security/integrity/ima/ima_kexec.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
security/integrity/ima/ima_kexec.c +10 -0
@@ -34,6 +34,14 @@ static void ima_free_kexec_file_buf(struct seq_file *sf)static int ima_alloc_kexec_file_buf (size_t segment_size) { +/* +* kexec 'load' may be called multiple times. +* Free and realloc the buffer only if the segment_size is +* changed from the previous kexec 'load' call. +*/ +if (ima_kexec_file.buf && ima_kexec_file.size == segment_size) + goto out; +ima_free_kexec_file_buf (&ima_kexec_file);/* segment size can't change between kexec load and execute */
@@ -42,6 +50,8 @@ static int ima_alloc_kexec_file_buf(size_t segment_size)return -ENOMEM ; ima_kexec_file.size = segment_size; + +out: ima_kexec_file.read_pos =0 ; ima_kexec_file.count =sizeof (struct ima_kexec_hdr );/* reserved space */
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 4/35 ima: do not copy measurement list to kdump kernel
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Chen <[email protected]>
[ Upstream commit fe3aebf27dc1875b2a0d13431e2e8cf3cf350cca ]
Kdump kernel doesn't need IMA to do integrity measurement. Hence the measurement list in 1st kernel doesn't need to be copied to kdump kernel.
Here skip allocating buffer for measurement list copying if loading kdump kernel. Then there won't be the later handling related to ima_kexec_buffer.
--- security/integrity/ima/ima_kexec.c | 3 +++ 1 file changed, 3 insertions(+)
security/integrity/ima/ima_kexec.c +3 -0
@@ -129,6 +129,9 @@ void ima_add_kexec_buffer(struct kimage *image)size_t kexec_segment_size;int ret; +if (image->type ==KEXEC_TYPE_CRASH ) +return ; +/* * Reserve an extra half page of memory for additional measurements * added during the kexec load.
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 5/35 wifi: mac80211: always free skb on ieee80211_tx_prepare_skb() failure
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Fietkau <[email protected]>
[ Upstream commit d5ad6ab61cbd89afdb60881f6274f74328af3ee9 ]
ieee80211_tx_prepare_skb() has three error paths, but only two of them free the skb. The first error path (ieee80211_tx_prepare() returning TX_DROP) does not free it, while invoke_tx_handlers() failure and the fragmentation check both do.
Add kfree_skb() to the first error path so all three are consistent, and remove the now-redundant frees in callers (ath9k, mt76, mac80211_hwsim) to avoid double-free.
Document the skb ownership guarantee in the function's kdoc.
[ Exclude changes to drivers/net/wireless/mediatek/mt76/scan.c as this file is first
introduced by commit 31083e38548f("wifi: mt76: add code for emulating hardware scanning") after linux-6.14.]
--- drivers/net/wireless/ath/ath9k/channel.c | 6 ++---- drivers/net/wireless/virtual/mac80211_hwsim.c | 1 - include/net/mac80211.h | 4 +++- net/mac80211/tx.c | 4 +++- 4 files changed, 8 insertions(+), 7 deletions(-)
drivers/net/wireless/ath/ath9k/channel.c +2 -4
@@ -1011,7 +1011,7 @@ static void ath_scan_send_probe(struct ath_softc *sc,skb_set_queue_mapping (skb,IEEE80211_AC_VO );if (!ieee80211_tx_prepare_skb (sc->hw, vif, skb, band,NULL )) - goto error; +return ; txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO ];if (ath_tx_start (sc->hw, skb, &txctl))
@@ -1124,10 +1124,8 @@ ath_chanctx_send_vif_ps_frame(struct ath_softc *sc, struct ath_vif *avp, skb->priority =7 ;skb_set_queue_mapping (skb,IEEE80211_AC_VO ); -if (!ieee80211_tx_prepare_skb (sc->hw, vif, skb, band, &sta)) { -dev_kfree_skb_any (skb); +if (!ieee80211_tx_prepare_skb (sc->hw, vif, skb, band, &sta))return false; - }break ;default :return false;
drivers/net/wireless/virtual/mac80211_hwsim.c +0 -1
@@ -2977,7 +2977,6 @@ static void hw_scan_work(struct work_struct *work) hwsim->tmp_chan->band, NULL)) {rcu_read_unlock (); -kfree_skb (probe);continue ; }
include/net/mac80211.h +3 -1
@@ -7208,7 +7208,9 @@ void ieee80211_report_wowlan_wakeup(struct ieee80211_vif *vif,* @band: the band to transmit on * @sta: optional pointer to get the station to send the frame to * -* Return: %true if the skb was prepared, %false otherwise +* Return: %true if the skb was prepared, %false otherwise. +* On failure, the skb is freed by this function; callers must not +* free it again. * * Note: must be called under RCU lock */
net/mac80211/tx.c +3 -1
@@ -1897,8 +1897,10 @@ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,struct ieee80211_tx_data tx;struct sk_buff *skb2; -if (ieee80211_tx_prepare (sdata, &tx,NULL , skb) ==TX_DROP ) +if (ieee80211_tx_prepare (sdata, &tx,NULL , skb) ==TX_DROP ) { +kfree_skb (skb);return false; + } info->band = band; info->control.vif = vif;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 6/35 rust: warn on bindgen < 0.69.5 and libclang >= 19.1
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miguel Ojeda <[email protected]>
[ Upstream commit b2603f8ac8217bc59f5c7f248ac248423b9b99cb ]
When testing a clang upgrade with Rust Binder, Alice encountered [1] a build failure caused by bindgen not translating some symbols related to tracepoints. This was caused by commit 2e770edd8ce1 ("[libclang] Compute the right spelling location") changing the behavior of a function exposed by libclang. bindgen fixed the regression in commit 600f63895f73 ("Use clang_getFileLocation instead of clang_getSpellingLocation").
However, the regression fix is only available in bindgen versions 0.69.5 or later (it was backported for 0.69.x). This means that when older bindgen versions are used with new versions of libclang, bindgen may do the wrong thing, which could lead to a build failure.
Alice encountered the bug with some header files related to tracepoints, but it could also cause build failures in other circumstances. Thus, always emit a warning when using an old bindgen with a new libclang so that other people do not have to spend time chasing down the same bug.
However, testing just the version is inconvenient, since distributions do patch their packages without changing the version, so I reduced the issue into the following piece of code that can trigger the issue:
#define F(x) int x##x
F(foo);In particular, an unpatched bindgen will ignore the macro expansion and thus not provide a declaration for the exported int.
Thus add a build test to rust_is_available.sh using the code above (that is only triggered if the versions appear to be affected), following what we did for the 0.66.x issue.
Moreover, I checked the status in the major distributions we have instructions for:
- Fedora 41 was affected but is now OK, since it now ships bindgen 0.69.5.
Thanks Ben for the quick reply on the updates that were ongoing.
Fedora 40 and earlier are OK (older libclang, and they also now carry bindgen 0.69.5).
- Debian Sid was affected but is now OK, since they now ship a patched bindgen binary (0.66.1-7+b3). The issue was reported to Debian by email and then as a bug report [2].
Thanks NoisyCoil and Matthias for the quick replies. NoisyCoil handled the needed updates. Debian may upgrade to bindgen 0.70.x, too.
Debian Testing is OK (older libclang so far).
- Ubuntu non-LTS (oracular) is affected. The issue was reported to Ubuntu by email and then as a bug report [3].
Ubuntu LTS is not affected (older libclang so far).
- Arch Linux, Gentoo Linux and openSUSE should be OK (newer bindgen is provided). Nix as well (older libclang so far).
This issue was also added to our "live list" that tracks issues around distributions [4].
--- scripts/rust_is_available.sh | 15 ++++++++ ...ust_is_available_bindgen_libclang_concat.h | 3 ++ scripts/rust_is_available_test.py | 34 ++++++++++++++++++- 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 scripts/rust_is_available_bindgen_libclang_concat.h
scripts/rust_is_available.sh +15 -0
@@ -225,6 +225,21 @@ if [ "$bindgen_libclang_cversion" -lt "$bindgen_libclang_min_cversion" ]; then exit 1 fi +if [ "$bindgen_libclang_cversion" -ge 1900100 ] && + [ "$rust_bindings_generator_cversion" -lt 6905 ]; then + # Distributions may have patched the issue (e.g. Debian did). + if ! "$BINDGEN" $(dirname $0)/rust_is_available_bindgen_libclang_concat.h | grep -q foofoo; then + echo >&2 "***" + echo >&2 "*** Rust bindings generator '$BINDGEN' < 0.69.5 together with libclang >= 19.1" + echo >&2 "*** may not work due to a bug (https://github.com/rust-lang/rust-bindgen/pull/2824)," + echo >&2 "*** unless patched (like Debian's)." + echo >&2 "*** Your bindgen version: $rust_bindings_generator_version" + echo >&2 "*** Your libclang version: $bindgen_libclang_version" + echo >&2 "***" + warning=1 + fi +fi + # If the C compiler is Clang, then we can also check whether its version # matches the `libclang` version used by the Rust bindings generator. #
scripts/rust_is_available_bindgen_libclang_concat.h new file +3 -0
@@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#define F (x) int x##x +F (foo);
scripts/rust_is_available_test.py +33 -1
@@ -54,7 +54,7 @@ else: """) @classmethod - def generate_bindgen(cls, version_stdout, libclang_stderr, version_0_66_patched=False): + def generate_bindgen(cls, version_stdout, libclang_stderr, version_0_66_patched=False, libclang_concat_patched=False): if libclang_stderr is None: libclang_case = f"raise SystemExit({cls.bindgen_default_bindgen_libclang_failure_exit_code})" else:
@@ -65,12 +65,19 @@ else: else: version_0_66_case = "raise SystemExit(1)" + if libclang_concat_patched: + libclang_concat_case = "print('pub static mut foofoo: ::std::os::raw::c_int;')" + else: + libclang_concat_case = "pass" + return cls.generate_executable(f"""#!/usr/bin/env python3 import sys if "rust_is_available_bindgen_libclang.h" in " ".join(sys.argv): {libclang_case} elif "rust_is_available_bindgen_0_66.h" in " ".join(sys.argv): {version_0_66_case} +elif "rust_is_available_bindgen_libclang_concat.h" in " ".join(sys.argv): + {libclang_concat_case} else: print({repr(version_stdout)}) """)
@@ -268,6 +275,31 @@ else: result = self.run_script(self.Expected.FAILURE, { "BINDGEN": bindgen }) self.assertIn(f"libclang (used by the Rust bindings generator '{bindgen}') is too old.", result.stderr) + def test_bindgen_bad_libclang_concat(self): + for (bindgen_version, libclang_version, expected_not_patched) in ( + ("0.69.4", "18.0.0", self.Expected.SUCCESS), + ("0.69.4", "19.1.0", self.Expected.SUCCESS_WITH_WARNINGS), + ("0.69.4", "19.2.0", self.Expected.SUCCESS_WITH_WARNINGS), + + ("0.69.5", "18.0.0", self.Expected.SUCCESS), + ("0.69.5", "19.1.0", self.Expected.SUCCESS), + ("0.69.5", "19.2.0", self.Expected.SUCCESS), + + ("0.70.0", "18.0.0", self.Expected.SUCCESS), + ("0.70.0", "19.1.0", self.Expected.SUCCESS), + ("0.70.0", "19.2.0", self.Expected.SUCCESS), + ): + with self.subTest(bindgen_version=bindgen_version, libclang_version=libclang_version): + cc = self.generate_clang(f"clang version {libclang_version}") + libclang_stderr = f"scripts/rust_is_available_bindgen_libclang.h:2:9: warning: clang version {libclang_version} [-W#pragma-messages], err: false" + bindgen = self.generate_bindgen(f"bindgen {bindgen_version}", libclang_stderr) + result = self.run_script(expected_not_patched, { "BINDGEN": bindgen, "CC": cc }) + if expected_not_patched == self.Expected.SUCCESS_WITH_WARNINGS: + self.assertIn(f"Rust bindings generator '{bindgen}' < 0.69.5 together with libclang >= 19.1", result.stderr) + + bindgen = self.generate_bindgen(f"bindgen {bindgen_version}", libclang_stderr, libclang_concat_patched=True) + result = self.run_script(self.Expected.SUCCESS, { "BINDGEN": bindgen, "CC": cc }) + def test_clang_matches_bindgen_libclang_different_bindgen(self): bindgen = self.generate_bindgen_libclang("scripts/rust_is_available_bindgen_libclang.h:2:9: warning: clang version 999.0.0 [-W#pragma-messages], err: false") result = self.run_script(self.Expected.SUCCESS_WITH_WARNINGS, { "BINDGEN": bindgen })
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 7/35 net: ethernet: mtk_eth_soc: initialize PPE per-tag-layer MTU registers
In reply to Greg Kroah-Hartman6.12-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
@@ -3384,12 +3384,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;
@@ -3436,6 +3447,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 );
@@ -4129,6 +4144,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 ) {
@@ -4139,6 +4155,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 8/35 drm/amdgpu: replace PASID IDR with XArray
In reply to Greg Kroah-Hartman6.12-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,
@@ -653,7 +654,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 9/35 scripts: generate_rust_analyzer.py: define scripts
In reply to Greg Kroah-Hartman6.12-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
@@ -144,6 +144,18 @@ def generate_crates(srctree, objtree, sy append_crate_with_generated("uapi", ["core", "ffi"]) append_crate_with_generated("kernel", ["core", "macros", "build_error", "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()
@@ -160,7 +172,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 10/35 mm/pagewalk: fix race between concurrent split and refault
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Max Boone <[email protected]>
[ Upstream commit 9b25a6e3d243a8ce14eeaf74082c621a9944c776 ]
The splitting of a PUD entry in walk_pud_range() can race with a concurrent thread refaulting the PUD leaf entry causing it to try walking a PMD range that has disappeared.
An example and reproduction of this is to try reading numa_maps of a process while VFIO-PCI is setting up DMA (specifically the vfio_pin_pages_remote call) on a large BAR for that process.
This will trigger a kernel BUG:
vfio-pci 0000:03:00.0: enabling device (0000 -> 0002)
BUG: unable to handle page fault for address: ffffa23980000000 PGD 0 P4D 0 Oops: Oops: 0000 [#1] SMP NOPTI ... RIP: 0010:walk_pgd_range+0x3b5/0x7a0 Code: 8d 43 ff 48 89 44 24 28 4d 89 ce 4d 8d a7 00 00 20 00 48 8b 4c 24 28 49 81 e4 00 00 e0 ff 49 8d 44 24 ff 48 39 c8 4c 0f 43 e3 <49> f7 06 9f ff ff ff 75 3b 48 8b 44 24 20 48 8b 40 28 48 85 c0 74 RSP: 0018:ffffac23e1ecf808 EFLAGS: 00010287 RAX: 00007f44c01fffff RBX: 00007f4500000000 RCX: 00007f44ffffffff RDX: 0000000000000000 RSI: 000ffffffffff000 RDI: ffffffff93378fe0 RBP: ffffac23e1ecf918 R08: 0000000000000004 R09: ffffa23980000000 R10: 0000000000000020 R11: 0000000000000004 R12: 00007f44c0200000 R13: 00007f44c0000000 R14: ffffa23980000000 R15: 00007f44c0000000 FS: 00007fe884739580(0000) GS:ffff9b7d7a9c0000(0000)
knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: ffffa23980000000 CR3: 000000c0650e2005 CR4: 0000000000770ef0
PKRU: 55555554
Call Trace: <TASK> __walk_page_range+0x195/0x1b0 walk_page_vma+0x62/0xc0 show_numa_map+0x12b/0x3b0 seq_read_iter+0x297/0x440 seq_read+0x11d/0x140 vfs_read+0xc2/0x340 ksys_read+0x5f/0xe0 do_syscall_64+0x68/0x130 ? get_page_from_freelist+0x5c2/0x17e0 ? mas_store_prealloc+0x17e/0x360 ? vma_set_page_prot+0x4c/0xa0 ? __alloc_pages_noprof+0x14e/0x2d0 ? __mod_memcg_lruvec_state+0x8d/0x140 ? __lruvec_stat_mod_folio+0x76/0xb0 ? __folio_mod_stat+0x26/0x80 ? do_anonymous_page+0x705/0x900 ? __handle_mm_fault+0xa8d/0x1000 ? __count_memcg_events+0x53/0xf0 ? handle_mm_fault+0xa5/0x360 ? do_user_addr_fault+0x342/0x640 ? arch_exit_to_user_mode_prepare.constprop.0+0x16/0xa0 ? irqentry_exit_to_user_mode+0x24/0x100 entry_SYSCALL_64_after_hwframe+0x76/0x7e RIP: 0033:0x7fe88464f47e Code: c0 e9 b6 fe ff ff 50 48 8d 3d be 07 0b 00 e8 69 01 02 00 66 0f 1f
84 00 00 00 00 00 64 8b 04 25 18 00 00 00 85 c0 75 14 0f 05 <48> 3d 00
f0 ff ff 77 5a c3 66 0f 1f 84 00 00 00 00 00 48 83 ec 28
RSP: 002b:00007ffe6cd9a9b8 EFLAGS: 00000246 ORIG_RAX: 0000000000000000
RAX: ffffffffffffffda RBX: 0000000000020000 RCX: 00007fe88464f47e
RDX: 0000000000020000 RSI: 00007fe884543000 RDI: 0000000000000003
RBP: 00007fe884543000 R08: 00007fe884542010 R09: 0000000000000000
R10: fffffffffffffbc5 R11: 0000000000000246 R12: 0000000000000000
R13: 0000000000000003 R14: 0000000000020000 R15: 0000000000020000
</TASK>
Fix this by validating the PUD entry in walk_pmd_range() using a stable snapshot (pudp_get()). If the PUD is not present or is a leaf, retry the walk via ACTION_AGAIN instead of descending further. This mirrors the retry logic in walk_pte_range(), which lets walk_pmd_range() retry if the PTE is not being got by pte_offset_map_lock().
--- mm/pagewalk.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-)
mm/pagewalk.c +22 -2
@@ -78,12 +78,31 @@ static int walk_pte_range(pmd_t *pmd, unstatic int walk_pmd_range (pud_t *pud,unsigned long addr,unsigned long end,struct mm_walk *walk) { +pud_t pudval =pudp_get (pud);pmd_t *pmd;unsigned long next;const struct mm_walk_ops *ops = walk->ops;int err =0 ;int depth =real_depth (3 ); +/* +* For PTE handling, pte_offset_map_lock() takes care of checking +* whether there actually is a page table. But it also has to be +* very careful about concurrent page table reclaim. +* +* Similarly, we have to be careful here - a PUD entry that points +* to a PMD table cannot go away, so we can just walk it. But if +* it's something else, we need to ensure we didn't race something, +* so need to retry. +* +* A pertinent example of this is a PUD refault after PUD split - +* we will need to split again or risk accessing invalid memory. +*/ +if (!pud_present (pudval) ||pud_leaf (pudval)) { + walk->action =ACTION_AGAIN ; +return 0 ; + } + pmd =pmd_offset (pud, addr); do { again:
@@ -172,12 +191,13 @@ static int walk_pud_range(p4d_t *p4d, unif (walk->vma)split_huge_pud (walk->vma, pud, addr); -if (pud_none (*pud)) - goto again; err =walk_pmd_range (pud, addr, next, walk);if (err)break ; + +if (walk->action ==ACTION_AGAIN ) + goto again; }while (pud++, addr = next, addr != end);return err;
Greg Kroah-Hartman
maintainerPATCH 11/35 ksmbd: fix use-after-free in __ksmbd_close_fd() via durable scavenger
In reply to Greg Kroah-Hartman6.12-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().
--- 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 12/35 scripts/dtc: Remove unused dts_version in dtc-lexer.l
In reply to Greg Kroah-Hartman6.12-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 13/35 rxrpc: only handle RESPONSE during service challenge
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wang Jie <[email protected]>
[ Upstream commit c43ffdcfdbb5567b1f143556df8a04b4eeea041c ]
Only process RESPONSE packets while the service connection is still in RXRPC_CONN_SERVICE_CHALLENGING. Check that state under state_lock before running response verification and security initialization, then use a local secured flag to decide whether to queue the secured-connection work after the state transition. This keeps duplicate or late RESPONSE packets from re-running the setup path and removes the unlocked post-transition state test.
--- net/rxrpc/conn_event.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
net/rxrpc/conn_event.c +12 -2
@@ -233,6 +233,7 @@ static int rxrpc_process_event(struct rx struct sk_buff *skb) {struct rxrpc_skb_priv *sp =rxrpc_skb (skb); +bool secured = false;int ret;if (conn->state ==RXRPC_CONN_ABORTED )
@@ -245,6 +246,13 @@ static int rxrpc_process_event(struct rxreturn conn->security->respond_to_challenge (conn, skb);case RXRPC_PACKET_TYPE_RESPONSE : +spin_lock (&conn->state_lock); +if (conn->state !=RXRPC_CONN_SERVICE_CHALLENGING ) { +spin_unlock (&conn->state_lock); +return 0 ; + } +spin_unlock (&conn->state_lock); + ret = conn->security->verify_response (conn, skb);if (ret <0 )return ret;
@@ -255,11 +263,13 @@ static int rxrpc_process_event(struct rxreturn ret;spin_lock (&conn->state_lock); -if (conn->state ==RXRPC_CONN_SERVICE_CHALLENGING ) +if (conn->state ==RXRPC_CONN_SERVICE_CHALLENGING ) { conn->state =RXRPC_CONN_SERVICE ; + secured = true; + }spin_unlock (&conn->state_lock); -if (conn->state ==RXRPC_CONN_SERVICE ) { +if (secured) {/* Offload call state flipping to the I/O thread. As * we've already received the packet, put it on the * front of the queue.
Greg Kroah-Hartman
maintainerPATCH 14/35 fs/ntfs3: validate rec->used in journal-replay file record check
In reply to Greg Kroah-Hartman6.12-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 15/35 f2fs: fix to avoid memory leak in f2fs_rename()
In reply to Greg Kroah-Hartman6.12-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
@@ -940,6 +940,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 16/35 fuse: reject oversized dirents in page cache
In reply to Greg Kroah-Hartman6.12-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 17/35 fuse: Check for large folio with SPLICE_F_MOVE
In reply to Greg Kroah-Hartman6.12-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
@@ -871,6 +871,9 @@ static int fuse_try_move_page(struct fusfolio_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 18/35 fuse: quiet down complaints in fuse_conn_limit_write
In reply to Greg Kroah-Hartman6.12-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
@@ -120,7 +120,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,
@@ -162,7 +162,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 19/35 ksmbd: require minimum ACE size in smb_check_perm_dacl()
In reply to Greg Kroah-Hartman6.12-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 20/35 smb: server: fix active_num_conn leak on transport allocation failure
In reply to Greg Kroah-Hartman6.12-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
@@ -203,6 +203,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 21/35 smb: server: fix max_connections off-by-one in tcp accept path
In reply to Greg Kroah-Hartman6.12-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
@@ -297,7 +297,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 22/35 smb: client: require a full NFS mode SID before reading mode bits
In reply to Greg Kroah-Hartman6.12-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
@@ -832,6 +832,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 23/35 smb: client: fix OOB read in smb2_ioctl_query_info QUERY_INFO path
In reply to Greg Kroah-Hartman6.12-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
@@ -1782,6 +1782,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 24/35 ksmbd: validate response sizes in ipc_validate_msg()
In reply to Greg Kroah-Hartman6.12-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 25/35 ksmbd: validate num_aces and harden ACE walk in smb_inherit_dacl()
In reply to Greg Kroah-Hartman6.12-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 26/35 ksmbd: fix out-of-bounds write in smb2_get_ea() EA alignment
In reply to Greg Kroah-Hartman6.12-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
@@ -4833,6 +4833,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 27/35 ksmbd: use check_add_overflow() to prevent u16 DACL size overflow
In reply to Greg Kroah-Hartman6.12-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 28/35 f2fs: fix use-after-free of sbi in f2fs_compress_write_end_io()
In reply to Greg Kroah-Hartman6.12-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
@@ -1472,10 +1472,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]);
@@ -1485,6 +1485,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 29/35 ALSA: usb-audio: apply quirk for MOONDROP JU Jiu
In reply to Greg Kroah-Hartman6.12-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
@@ -1198,6 +1198,13 @@ static void volume_control_quirks(struct cval->min =-14208 ;/* 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 30/35 ALSA: caiaq: take a reference on the USB device in create_card()
In reply to Greg Kroah-Hartman6.12-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 31/35 net/packet: fix TOCTOU race on mmapd vnet_hdr in tpacket_snd()
In reply to Greg Kroah-Hartman6.12-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
@@ -2770,7 +2770,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 ;
@@ -2871,16 +2872,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,
@@ -2917,12 +2922,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 32/35 crypto: ccp: Dont attempt to copy CSR to userspace if PSP command failed
In reply to Greg Kroah-Hartman6.12-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
@@ -1541,7 +1541,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))) {
@@ -1549,6 +1552,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 33/35 crypto: ccp: Dont attempt to copy PDH cert to userspace if PSP command failed
In reply to Greg Kroah-Hartman6.12-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
@@ -1992,7 +1992,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;
@@ -2001,6 +2004,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 34/35 crypto: ccp: Dont attempt to copy ID to userspace if PSP command failed
In reply to Greg Kroah-Hartman6.12-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
@@ -1876,6 +1876,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 35/35 rxrpc: Fix missing validation of ticket length in non-XDR key preparsing
In reply to Greg Kroah-Hartman6.12-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
@@ -340,6 +340,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);
Am 24.04.2026 um 15:31 schrieb Greg Kroah-Hartman:
Quoted 4 lines
This is the start of the stable review cycle for the 6.12.84 release. There are 35 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]
Hi!
Quoted 4 lines
This is the start of the stable review cycle for the 6.12.84 release. There are 35 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.12.y
Best regards,
Pavel
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.12.84 release. There are 35 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:21 +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.12.84-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.12.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
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.12.84 release. There are 35 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.12.84 release. There are 35 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:21 +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.12.84-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.12.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.12.84 release. There are 35 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:21 +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.12.84-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.12.y
and the diffstat can be found below.thanks,
greg k-h
Tested on my Lenovo ThinkPad T14 Gen 1. Working well, no regressions observed.
Signature · 1 line
-Barry K. Nathan <[email protected]>
Build test summary:
- Tree: linux-stable-rc.git
- Branch: linux-6.12.y
- Head: 59f8529e7 Linux 6.12.84-rc1
- Arch: arm64
- Config: defconfig
- Toolchain: Ubuntu clang version 18.1.3 (1ubuntu1)
- Kernel release: 6.12.84-rc1-g59f8529e78a2
- Build target: Image modules dtbs
- Result: passed
No runtime testing was performed.
# Librecast Test Results
020/020 [ OK ] liblcrq
010/010 [ OK ] libmld
120/120 [ OK ] liblibrecast
CPU/kernel: Linux auntie 6.12.84-rc1-g59f8529e78a2 #1 SMP PREEMPT_DYNAMIC Sat Apr 25 07:20:43 -00 2026 x86_64 AMD Ryzen 9 9950X 16-Core Processor AuthenticAMD GNU/Linux
Quoted 8 lines · On Fri, 24 Apr 2026 15:31:07 +0200 Greg Kroah-Hartman…
This is the start of the stable review cycle for the 6.12.84 release. There are 35 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:21 +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.
I also talked to Benno and Gary about the Clippy warnings and they are OK with an #![allow], so we will do that.
Thanks!
Cheers,
Miguel
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.12.84 release. There are 35 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:21 +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.12.84-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.12.y
and the diffstat can be found below.thanks,
greg k-h
Built and booted successfully on RISC-V RV64 (HiFive Unmatched).
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.12.84 release. There are 35 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.
Hi Greg,
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.12.84 release. There are 35 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.
No problems seen on x86_64 and aarch64 with our testing.
Thanks,
Harshit