Skip to contentSkip to conversation

6.18.39-rc1 review

PATCH In review Greg Kroah-Hartman 10 participants 490 messages Jul 16 – Jul 17 Stable branch Page 1 of 4

lore
Share & tools
lore

Greg Kroah-Hartman

author maintainer
#0 lore raw

cover 6.18.39-rc1 review

This is the start of the stable review cycle for the 6.18.39 release. There are 480 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 Sat, 18 Jul 2026 13:30:01 +0000. Anything received after that time might be too late.

The whole patch series can be found in one patch at:

	https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.18.39-rc1.gz

or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.18.y
and the diffstat can be found below.

thanks,

greg k-h

-------------
Pseudo-Shortlog of commits:

Greg Kroah-Hartman <[email protected]>

    Linux 6.18.39-rc1

Zhaoyang Huang <[email protected]>
Revert "f2fs: remove non-uptodate folio from the page cache in move_data_block"

Luiz Augusto von Dentz <[email protected]>

    Bluetooth: 6lowpan: Fix using chan->conn as indication to no remote netdev

Mikhail Gavrilov <[email protected]>
timekeeping: Register default clocksource before taking tk_core.lock

Neill Kapron <[email protected]>

    usb: gadget: f_fs: Initialize epfile->in early to fix endpoint direction checks

Adam Li <[email protected]>
sched/fair: Only update stats for allowed CPUs when looking for dst group

Joanne Koong <[email protected]>
fuse-uring: remove request-less entries from ent_w_req_queue to fix NULL deref

Bernd Schubert <[email protected]>
fuse-uring: make a fuse_req on SQE commit only findable after memcpy

Bernd Schubert <[email protected]>

    fuse-uring: Avoid queue->stopped races and set/read that value under lock

Bernd Schubert <[email protected]>
fuse-uring: Avoid use-after-free in fuse_uring_async_stop_queues

Chris Mason <[email protected]>
fuse-uring: end fuse_req on io-uring cancel task work

Joanne Koong <[email protected]>
fuse-uring: fix moving cancelled entry to ent_in_userspace list

Chris Mason <[email protected]>

    fuse-uring: fix data races on ring->ready

Chris Mason <[email protected]>
fuse-uring: fix EFAULT clobber in fuse_uring_commit

Ji'an Zhou <[email protected]>
fuse: clear intr_entry in fuse_resend and fuse_remove_pending_req

Joanne Koong <[email protected]>
fuse: fix io-uring background queue dispatch on request completion

Joanne Koong <[email protected]>
fuse: re-lock request before returning from fuse_ref_folio()

Alberto Ruiz <[email protected]>
fuse: fix device node leak in cuse_process_init_reply()

Samuel Moelius <[email protected]>
fuse: avoid 32-bit prune notification count wrap

Matthew R. Ochs <[email protected]>
fuse: back uncached readdir buffers with pages

Michael Bommarito <[email protected]>
RDMA/siw: bound Read Response placement to the RREAD length

Maher Sanalla <[email protected]>
RDMA/core: Fix broadcast address falsely detected as local

Zhenhao Wan <[email protected]>
RDMA/rtrs-srv: Bound RDMA-Write length to chunk size in rdma_write_sg

Dmitry Torokhov <[email protected]>
Input: maplecontrol - set driver data before registering input device

Dmitry Torokhov <[email protected]>
Input: maplemouse - set driver data before registering input device

Dmitry Torokhov <[email protected]>
Input: maple_keyb - set driver data before registering input device

Dmitry Torokhov <[email protected]>
Input: mms114 - fix multi-touch slot corruption

Florian Fuchs <[email protected]>
Input: maplemouse - fix NULL pointer dereference in open()

Xu Rao <[email protected]>
Input: gscps2 - advance receive buffer write index

Bryam Vargas <[email protected]>
Input: mms114 - reject an oversized device packet size

Bryam Vargas <[email protected]>
Input: touchwin - reset the packet index on every complete packet

Kris Bahnsen <[email protected]>
Input: ads7846 - don't use scratch for tx_buf when clearing register

Dmitry Torokhov <[email protected]>
Input: mms114 - fix touch indexing for MMS134S and MMS136

Bryam Vargas <[email protected]>
Input: iforce - bound the device-reported force-feedback effect index

Bryam Vargas <[email protected]>
Input: goodix - clamp the device-reported contact count

Ranjan Kumar <[email protected]>
Input: elan_i2c - prevent division by zero and arithmetic underflow

Bryam Vargas <[email protected]>
Input: synaptics-rmi4 - bound the F30 keymap to the GPIO/LED count

Bryam Vargas <[email protected]>
Input: synaptics-rmi4 - bound the F3A keymap to the GPIO count

Haoxiang Li <[email protected]>
Input: synaptics-rmi4 - unregister function handlers on physical driver registration failure

Mingyu Wang <[email protected]>
i2c: i801: fix hardware state machine corruption in error path

Carlos Song <[email protected]>
i2c: imx-lpi2c: mark I2C adapter when hardware is powered down

Guillermo Rodríguez <[email protected]>
i2c: stm32f7: truncate clock period instead of rounding it

Haoxiang Li <[email protected]>
i2c: davinci: Unregister cpufreq notifier on probe failure

Andy Shevchenko <[email protected]>
i2c: mpc: Fix timeout calculations

Johan Hovold <[email protected]>
i2c: core: fix adapter deregistration race

Johan Hovold <[email protected]>
i2c: core: fix adapter debugfs creation

Johan Hovold <[email protected]>
i2c: core: fix NULL-deref on adapter registration failure

Johan Hovold <[email protected]>
i2c: core: fix irq domain leak on adapter registration failure

Johan Hovold <[email protected]>
i2c: core: fix adapter probe deferral loop

Sebastian Alba Vives <[email protected]>
fpga: dfl-afu: validate DMA mapping length in afu_dma_map_region()

Mikhail Gavrilov <[email protected]>
dma-buf/udmabuf: skip redundant cpu sync to fix cacheline EEXIST warning

Mikhail Gavrilov <[email protected]>
udmabuf: fix DMA direction mismatch in release_udmabuf()

Oliver Upton <[email protected]>
KVM: arm64: Don't leak PFN when kvm_translate_vncr() races MMU notifier

Sean Christopherson <[email protected]>
KVM: x86: Add dedicated API for getting mask of accelerated x2APIC MSRs

Sean Christopherson <[email protected]>
KVM: x86: Ensure vendor's exit handler runs before fastpath userspace exits

Xuanqing Shi <[email protected]>
KVM: VMX: Handle bad values on proxied writes to LBR MSRs

Sean Christopherson <[email protected]>
KVM: VMX: Refresh GUEST_PENDING_DBG_EXCEPTIONS.BS on all injected #DBs

Sean Christopherson <[email protected]>
KVM: SVM: Only disable x2AVIC WRMSR interception for MSRs that are accelerated

Sean Christopherson <[email protected]>
KVM: SVM: Disable x2AVIC RDMSR interception for MSRs KVM actually supports

Hyunwoo Kim <[email protected]>
KVM: arm64: Clear __hyp_running_vcpu when flushing the pKVM hyp vCPU

Zeng Chi <[email protected]>
LoongArch: KVM: Add missing slots_lock for device register/unregister

Marc Zyngier <[email protected]>
KVM: arm64: nv: Avoid dereferencing NULL VNCR pseudo-TLB

Mickaël Salaün <[email protected]>
selftests/landlock: Filter dealloc records in audit_count_records()

Mickaël Salaün <[email protected]>
landlock: Set audit_net.sk for socket access checks

Ricardo Robaina <[email protected]>
audit: fix removal of dangling executable rules

Nicolin Chen <[email protected]>
iommufd: Set upper bounds on cache invalidation entry_num and entry_len

Nicolin Chen <[email protected]>
iommufd: Avoid partial fault group delivery in iommufd_fault_fops_read()

Nicolin Chen <[email protected]>
iommufd: Break the loop on failure in iommufd_fault_fops_read()

Nicolin Chen <[email protected]>
iommufd: Reject invalid read count in iommufd_fault_fops_read()

Nicolin Chen <[email protected]>
iommufd: Reject invalid read count in iommufd_veventq_fops_read()

Nicolin Chen <[email protected]>
iommufd: Rewind header length in done if iommufd_veventq_fops_read() fails

Nicolin Chen <[email protected]>
iommufd: Set veventq_depth upper bound

Nicolin Chen <[email protected]>
iommufd: Fix data_len byte-count vs element-count mismatch

Kai Aizen <[email protected]>
iommufd: Use sizeof(*hdr) instead of sizeof(hdr) in veventq read

Weinan Liu <[email protected]>
iommu/amd: Don't split flush for amd_iommu_domain_flush_all()

Lu Baolu <[email protected]>
iommu/vt-d: Avoid WARNING in sva unbind path

Eric Biggers <[email protected]>
crypto: loongson - Remove broken and unused loongson-rng

Zenghui Yu <[email protected]>
selftests/mm: pagemap_ioctl: use the correct page size for transact_test()

Pedro Falcato <[email protected]>
mm: do file ownership checks with the proper mount idmap

Ketan <[email protected]>
mm: page_ext: add count limit to page_ext_iter_next to prevent invalid PFN access

David Hildenbrand (Arm) <[email protected]>
selftests: mm: fix and speedup "droppable" test

Anthony Yznaga <[email protected]>
mm: fix mmap errno value when MAP_DROPPABLE is not supported

Vivian Wang <[email protected]>
riscv: mm: Unconditionally sfence.vma for spurious fault

Vivian Wang <[email protected]>
riscv: mm: Define DIRECT_MAP_PHYSMEM_END

Koichiro Den <[email protected]>
NTB: epf: Fix request_irq() unwind in ntb_epf_init_isr()

Bryam Vargas <[email protected]>
exfat: bound uniname advance in exfat_find_dir_entry()

Andrii Kuchmenko <[email protected]>
module: decompress: check return value of module_extend_max_pages()

Gabriele Monaco <[email protected]>
rqspinlock: Fix order in raw_res_spin_(un)lock_irq to allow schedule

Benjamin Coddington <[email protected]>
NFSv4: include MAY_WRITE in open permission mask for O_TRUNC

Ricardo Robaina <[email protected]>
audit: fix potential integer overflow in audit_log_n_hex()

Huihui Huang <[email protected]>
tracing: Prevent out-of-bounds read in glob matching

Lee Jia Jie <[email protected]>
perf/aux: Fix page UAF in map_range()

Johan Hovold <[email protected]>
i2c: core: fix hang on adapter registration failure

Wentao Liang <[email protected]>
regulator: scmi: fix of_node refcount leak in scmi_regulator_probe()

Janne Grunau <[email protected]>
watchdog: apple: Add "apple,t8103-wdt" compatible

Vasily Khoruzhick <[email protected]>
EDAC/i10nm: Don't fail probing if ADXL is missing

David Hildenbrand (Arm) <[email protected]>
x86/mm: Fix freeing of PMD-sized vmemmap pages

Carlos Song <[email protected]>
spi: fsl-lpspi: terminate the RX channel on TX prepare failure path

Carlos Song <[email protected]>
spi: fsl-lpspi: replace dmaengine_terminate_all() with dmaengine_terminate_sync()

Mark Rutland <[email protected]>
arm64: fpsimd: Fix type mismatch in sme_{save,load}_state()

Paul Louvel <[email protected]>
crypto: talitos/hash - fix SEC2 64k - 1 ahash request limitation

Paul Louvel <[email protected]>
crypto: talitos/hash - remove useless wrapper

Paul Louvel <[email protected]>
crypto: talitos/hash - rename first_desc/last_desc to first_request/last_request

Paul Louvel <[email protected]>
crypto: talitos/hash - drop workqueue mechanism for SEC1

Paul Louvel <[email protected]>
crypto: talitos/hash - use descriptor chaining for SEC1 instead of workqueue

Paul Louvel <[email protected]>
crypto: talitos/hash - prepare SEC1 descriptor chaining, remove additional descriptor

Paul Louvel <[email protected]>
crypto: talitos - move code in current_desc_hdr() into a standalone function

Paul Louvel <[email protected]>
crypto: talitos - move dma mapping code in talitos_submit() into a standalone dma_map_request() function

Paul Louvel <[email protected]>
crypto: talitos - move dma unmapping code in flush_channel() into a standalone dma_unmap_request() function

Paul Louvel <[email protected]>
crypto: talitos - add chaining of arbitrary number of descriptor for the SEC1

Paul Louvel <[email protected]>
crypto: talitos - use dma_sync_single_for_cpu() before reading descriptor header

Ahsan Atta <[email protected]>
crypto: qat - factor out AER reset helpers

Giovanni Cabiddu <[email protected]>
crypto: qat - validate RSA CRT component lengths

Ahsan Atta <[email protected]>
crypto: qat - skip restart for down devices

Ahsan Atta <[email protected]>
crypto: qat - protect service table iterations with service_lock

Ahsan Atta <[email protected]>
crypto: qat - notify fatal error before AER reset preparation

Ahsan Atta <[email protected]>
crypto: qat - keep VFs enabled during reset

Ahsan Atta <[email protected]>
crypto: qat - handle sysfs-triggered reset callbacks

Ahsan Atta <[email protected]>
crypto: qat - centralize bus master enable

Eric Biggers <[email protected]>
crypto: drbg - Fix the fips_enabled priority boost

Eric Biggers <[email protected]>
crypto: drbg - Fix drbg_max_addtl() on 64-bit kernels

Eric Biggers <[email protected]>
crypto: drbg - Fix returning success on failure in CTR_DRBG

Tycho Andersen (AMD) <[email protected]>
crypto: ccp - Do not initialize SNP for ioctl(SNP_CONFIG)

Tycho Andersen (AMD) <[email protected]>
crypto: ccp - Do not initialize SNP for ioctl(SNP_VLEK_LOAD)

Tycho Andersen (AMD) <[email protected]>
crypto: ccp - Do not initialize SNP for ioctl(SNP_COMMIT)

Tycho Andersen (AMD) <[email protected]>
crypto: ccp - Do not initialize SNP for SEV ioctls

Eric Biggers <[email protected]>
crypto: loongson - Select CRYPTO_RNG

Wentao Liang <[email protected]>
crypto: tegra - fix refcount leak in tegra_se_host1x_submit()

Ruijie Li <[email protected]>
crypto: pcrypt - restore callback for non-parallel fallback

Eric Biggers <[email protected]>
crypto: hisi-trng - Remove crypto_rng interface

Anastasia Tishchenko <[email protected]>
crypto: ecc - Fix carry overflow in vli multiplication

Eric Biggers <[email protected]>
crypto: crypto4xx - Remove insecure and unused rng_alg

Xiaonan Zhao <[email protected]>
crypto: chacha20poly1305 - validate poly1305 template argument

Thorsten Blum <[email protected]>
crypto: caam - use print_hex_dump_devel to guard key hex dumps again

Thorsten Blum <[email protected]>
crypto: caam - use print_hex_dump_devel to guard key hex dumps

Eric Biggers <[email protected]>
crypto: af_alg - Remove zero-copy support from skcipher and aead

Bryam Vargas <[email protected]>
isofs: bound Rock Ridge symlink components to the SL record

Bryam Vargas <[email protected]>
partitions: aix: bound the pp_count scan to the ppe array

Qu Wenruo <[email protected]>
btrfs: do not trim a device which is not writeable

Qu Wenruo <[email protected]>
btrfs: check and set EXTENT_DELALLOC_NEW before clearing EXTENT_DELALLOC

Tianchu Chen <[email protected]>
nvmet-auth: validate reply message payload bounds against transfer length

Bryam Vargas <[email protected]>
nvmet: fix pre-auth out-of-bounds heap read in Discovery Get Log Page

Achkinazi, Igor <[email protected]>
nvme-multipath: set BIO_REMAPPED on bios remapped to per-path namespace disks

Mikulas Patocka <[email protected]>
dm-ioctl: report an error if a device has no table

Wentao Liang <[email protected]>
block: partitions: fix of_node refcount leak in of_partition()

Wentao Liang <[email protected]>
nvme: target: rdma: fix ndev refcount leak on queue connect

Thorsten Blum <[email protected]>
crypto: atmel-sha204a - drop hwrng quality reduction for ATSHA204A

Wentao Liang <[email protected]>
hwrng: jh7110 - fix refcount leak in starfive_trng_read()

Bryam Vargas <[email protected]>
udf: validate sparing table length as an entry count, not a byte count

Bryam Vargas <[email protected]>
udf: validate VAT header length against the VAT inode size

Michael Bommarito <[email protected]>
udf: validate free block extents against the partition length

Pawan Gupta <[email protected]>
bpf: Prefer dirty packs for eBPF allocations

Pawan Gupta <[email protected]>
bpf: Prefer packs that won't trigger an IBPB flush on allocation

Pawan Gupta <[email protected]>
bpf: Skip redundant IBPB in pack allocator

Pawan Gupta <[email protected]>
bpf: Restrict JIT predictor flush to cBPF

Pawan Gupta <[email protected]>
x86/bugs: Enable IBPB flush on BPF JIT allocation

Pawan Gupta <[email protected]>
bpf: Support for hardening against JIT spraying

Alice Ryhl <[email protected]>
rust_binder: fix BINDER_GET_EXTENDED_ERROR

Alice Ryhl <[email protected]>
rust_binder: introduce TransactionInfo

Reinette Chatre <[email protected]>
x86,fs/resctrl: Prevent out-of-bounds access while offlining CPU when SNC enabled

Baolin Wang <[email protected]>
mm: shmem: fix potential livelock issue for shmem direct swapin

Chao Shi <[email protected]>
block: skip sync_blockdev() on surprise removal in bdev_mark_dead()

Paul Cercueil <[email protected]>
usb: gadget: f_fs: Fix DMA fence leak

Paul Menzel <[email protected]>
usb: typec: ucsi: cancel pending work on system suspend

Fan Wu <[email protected]>
usb: typec: ucsi: ccg: Fix use-after-free of ucsi on remove

Madhu M <[email protected]>
usb: typec: ucsi: Pass full DP config payload in SET_NEW_CAM for DP alt mode

Andrei Kuchynski <[email protected]>
usb: typec: ucsi: Invert DisplayPort role assignment

Badhri Jagan Sridharan <[email protected]>
usb: typec: tcpm: Validate SVID index in svdm_consume_modes()

Andy Yan <[email protected]>
usb: typec: tcpm: Fix VDM type for Enter Mode commands

Shuangpeng Bai <[email protected]>
usb: typec: class: drop PD lookup reference

Myeonghun Pak <[email protected]>
usb: typec: anx7411: use devm_pm_runtime_enable()

Sam Day <[email protected]>
usbip: vudc: fix NULL deref in vep_dequeue()

Yichong Chen <[email protected]>
usbip: tools: support SuperSpeedPlus devices

Xu Rao <[email protected]>
USB: usb-storage: ene_ub6250: restore media-ready check

Johan Hovold <[email protected]>
USB: ulpi: fix memory leak on registration failure

Johan Hovold <[email protected]>
USB: serial: digi_acceleport: fix write buffer corruption

Johan Hovold <[email protected]>
USB: serial: digi_acceleport: fix hard lockup on disconnect

Johan Hovold <[email protected]>
USB: serial: digi_acceleport: fix broken rx after throttle

Fabio Porcedda <[email protected]>
USB: serial: option: add Telit Cinterion FE990D50 compositions

Johan Hovold <[email protected]>
USB: serial: keyspan_pda: fix information leak

Haoxiang Li <[email protected]>
usb: mtu3: unmap request DMA on queue failure

Myeonghun Pak <[email protected]>
USB: misc: uss720: unregister parport on probe failure

HE WEI (ギカク) <[email protected]>
usb: misc: usbio: bound bulk IN response length to the received transfer

Xu Rao <[email protected]>
USB: storage: include US_FL_NO_SAME in quirks mask

Myeonghun Pak <[email protected]>
usb: sl811-hcd: disable controller wakeup on remove

Johan Hovold <[email protected]>
USB: legousbtower: fix use-after-free on disconnect race

Erich E. Hoover <[email protected]>
USB: quirks: add NO_LPM for the Samsung T5 EVO Portable SSD

Johan Hovold <[email protected]>
USB: iowarrior: fix use-after-free on disconnect

Johan Hovold <[email protected]>
USB: ldusb: fix use-after-free on disconnect race

Johan Hovold <[email protected]>
USB: idmouse: fix use-after-free on disconnect race

Xu Rao <[email protected]>
usb: gadget: f_printer: take kref only for successful open

Jimmy Hu <[email protected]>
usb: gadget: udc: Fix use-after-free in gadget_match_driver

Maoyi Xie <[email protected]>
usb: gadget: composite: fix dead empty check in the USB_DT_OTG handler

Dawei Feng <[email protected]>
usb: free iso schedules on failed submit

WenTao Liang <[email protected]>
usb: dwc3: meson-g12a: fix refcount leak in dwc3_meson_g12a_resume()

Rodrigo Lugathe da Conceição Alves <[email protected]>
USB: core: add USB_QUIRK_NO_LPM for VIA Labs USB 2.0 hub

Haoxiang Li <[email protected]>
usb: cdnsp: fix stream context array leak in cdnsp_alloc_stream_info()

Jared Baldridge <[email protected]>
usb: cdc_acm: Add quirk for Uniden BC125AT scanner

Maoyi Xie <[email protected]>
net: usb: kalmia: bound RX frame length in kalmia_rx_fixup()

Paul Moses <[email protected]>
bpf: Validate BTF repeated field counts before expansion

Dawei Feng <[email protected]>
bpf: Restore sysctl new-value from 1 to 0

Zhao Zhang <[email protected]>
bpf: Reject fragmented frames in devmap

Dawei Feng <[email protected]>
xfs: fix memory leak in xfs_dqinode_metadir_create()

Yingjie Gao <[email protected]>
xfs: fix exchmaps reservation limit check

Darrick J. Wong <[email protected]>
xfs: fix pointer arithmetic error on 32-bit systems

Alexey Nepomnyashih <[email protected]>
xfs: fix unreachable BIGTIME check in dquot flush validation

Yingjie Gao <[email protected]>
xfs: release dquot buffer after dqflush failure

Yousef Alhouseen <[email protected]>
xfs: use null daddr for unset first bad log block

Andy Shevchenko <[email protected]>
serial: 8250_mid: Disable DMA for selected platforms

Louis-Alexis Eyraud <[email protected]>
media: mtk-jpeg: cancel workqueue on release for supported platforms only

Deepanshu Kartikey <[email protected]>
nilfs2: reject CLEAN_SEGMENTS ioctl with out-of-range segment numbers

Tristan Madani <[email protected]>
hfs/hfsplus: zero-initialize buffer in hfs_bnode_read

Srinivas Pandruvada <[email protected]>
HID: sensor-hub: Add sensor_hub_input_attr_read_values() for multi-byte reads

Maoyi Xie <[email protected]>
HID: lg-g15: cancel pending work on remove to fix a use-after-free

Manish Khadka <[email protected]>
HID: appleir: fix UAF on pending key_up_timer in remove()

Trung Nguyen <[email protected]>
HID: multitouch: fix out-of-bounds bit access on mt_io_flags

Manish Khadka <[email protected]>
HID: letsketch: fix UAF on inrange_timer at driver unbind

Jinmo Yang <[email protected]>
HID: wacom: use GFP_ATOMIC in wacom_wac_queue_flush()

Jinmo Yang <[email protected]>
HID: wacom: fix slab-out-of-bounds write in wacom_wac_queue_insert

Oleg Makarenko <[email protected]>
HID: pidff: Use correct effect type in effect update

Myeonghun Pak <[email protected]>
HID: wacom: stop hardware after post-start probe failures

Carlos Llamas <[email protected]>
HID: uhid: convert to hid_safe_input_report()

Tianchu Chen <[email protected]>
HID: hid-goodix-spi: validate report size to prevent stack buffer overflow

Yichong Chen <[email protected]>
tools/mm/slabinfo: fix total_objects attribute name

Xuewen Wang <[email protected]>
tools/mm/slabinfo: Fix trace disable logic inversion

Vlastimil Babka (SUSE) <[email protected]>
mm/slab: do not limit zeroing to orig_size when only red zoning is enabled

Lukas Wunner <[email protected]>
X.509: Fix validation of ASN.1 certificate header

Robin Murphy <[email protected]>
perf/arm-cmn: Fix DVM node events

Heiko Carstens <[email protected]>
s390: Revert support for DCACHE_WORD_ACCESS

Kartik Rajput <[email protected]>
clocksource/drivers/timer-tegra186: Fix support for multiple watchdog instances

Thomas Gleixner <[email protected]>
time/jiffies: Register jiffies clocksource before usage

WenTao Liang <[email protected]>
posix-cpu-timers: Fix pid refcount leak in do_cpu_nanosleep() error path

Yuho Choi <[email protected]>
cpufreq: pcc: fix use-after-free and double free in _OSC evaluation

Tianxiang Chen <[email protected]>
cpufreq: Fix hotplug-suspend race during reboot

Steven Rostedt <[email protected]>
sched/rt: Have RT_PUSH_IPI be default off for non PREEMPT_RT

Fushuai Wang <[email protected]>

    cpufreq: intel_pstate: Sync policy->cur during CPU offline

Zide Chen <[email protected]>
perf/x86/intel/uncore: Defer ADL global PMON enable to enable_box()

John Hubbard <[email protected]>
libfs: set SB_I_NOEXEC and SB_I_NODEV by default in init_pseudo()

Guangshuo Li <[email protected]>
firmware_loader: fix device reference leak in firmware_upload_register()

Guangshuo Li <[email protected]>
cpufreq: qcom-cpufreq-hw: Fix possible double free

Abdun Nihaal <[email protected]>
OPP: of: Fix potential memory leak in opp_parse_supplies()

Baokun Li <[email protected]>
writeback: fix race between cgroup_writeback_umount() and inode_switch_wbs()

Norbert Manthey <[email protected]>
smb: client: mask server-provided mode to 07777 in modefromsid

Xu Rao <[email protected]>
smb: client: fix atime clamp check in read completion

Zihan Xi <[email protected]>
smb: client: harden POSIX SID length parsing

Zihan Xi <[email protected]>
smb: client: use unaligned reads in parse_posix_ctxt()

Haoxiang Li <[email protected]>
smb: client: Fix next buffer leak in receive_encrypted_standard()

Henrique Carvalho <[email protected]>
smb: client: fix double-free in SMB2_close() replay

Henrique Carvalho <[email protected]>
smb: client: fix double-free in SMB2_open() replay

Zhao Zhang <[email protected]>
smb: client: fix double-free in SMB2_flush() replay

Henrique Carvalho <[email protected]>
smb: client: fix change notify replay double-free

Henrique Carvalho <[email protected]>
smb: client: fix double-free in SMB2_ioctl() replay

Henrique Carvalho <[email protected]>
smb: client: fix query_info() replay double-free

Henrique Carvalho <[email protected]>
smb: client: fix query directory replay double-free

Namjae Jeon <[email protected]>
ksmbd: use opener credentials for ADS I/O

Namjae Jeon <[email protected]>
ksmbd: use opener credentials for delete-on-close

Gil Portnoy <[email protected]>
ksmbd: add per-handle permission check to FILE_LINK_INFORMATION

Gil Portnoy <[email protected]>
ksmbd: enforce FILE_READ_ATTRIBUTES on SMB_FIND_FILE_POSIX_INFORMATION

Namjae Jeon <[email protected]>
ksmbd: run set info with opener credentials

Gil Portnoy <[email protected]>
ksmbd: add a WRITE_DAC/WRITE_OWNER check to SMB2 SET_INFO SECURITY

Namjae Jeon <[email protected]>
ksmbd: require source read access for duplicate extents

Davide Ornaghi <[email protected]>
ksmbd: fix UAF of struct file_lock in SMB2_LOCK deferred-lock cancellation

Namjae Jeon <[email protected]>
ksmbd: serialize QUERY_DIRECTORY requests per file

Gil Portnoy <[email protected]>
ksmbd: add a permission check for FSCTL_SET_ZERO_DATA

Gil Portnoy <[email protected]>
ksmbd: add permission checks for FSCTL_DUPLICATE_EXTENTS_TO_FILE

Dan Carpenter <[email protected]>
smb/client: Fix error code in smb2_aead_req_alloc()

Michael Bommarito <[email protected]>
smb: client: resolve SWN tcon from live registrations

Junrui Luo <[email protected]>
coresight: ultrasoc-smb: Fix OOB write in smb_sync_perf_buffer()

Deepanshu Kartikey <[email protected]>
fs/ntfs3: fix missing run load for vcn0 in attr_data_get_block_locked()

Konstantin Komarov <[email protected]>
fs/ntfs3: zero-fill folios beyond i_valid in ntfs_read_folio()

Konstantin Komarov <[email protected]>
fs/ntfs3: fsync files by syncing parent inodes

Konstantin Komarov <[email protected]>
fs/ntfs3: rename ni_readpage_cmpr into ni_read_folio_cmpr

Lu Baolu <[email protected]>
iommu/vt-d: Fix race condition during PASID entry replacement

Muhammad Bilal <[email protected]>
Bluetooth: L2CAP: validate option length before reading conf opt value

Runyu Xiao <[email protected]>

    Bluetooth: L2CAP: cancel pending_rx_work before taking conn->lock

Muhammad Bilal <[email protected]>
Bluetooth: ISO: avoid NULL deref of conn in iso_conn_big_sync()

Pauli Virtanen <[email protected]>
Bluetooth: hci_uart: clear HCI_UART_SENDING when write_work is canceled

Siwei Zhang <[email protected]>
Bluetooth: hci_conn: Fix null ptr deref in hci_abort_conn()

Yousef Alhouseen <[email protected]>
Bluetooth: fix UAF in bt_accept_dequeue()

Maoyi Xie <[email protected]>
Bluetooth: btnxpuart: Fix out-of-bounds firmware read in nxp_recv_fw_req_v3()

Yousef Alhouseen <[email protected]>
Bluetooth: bnep: pin L2CAP connection during netdev registration

Sergey Senozhatsky <[email protected]>
Bluetooth: btmtksdio: fix infinite loop in btmtksdio_txrx_work()

Adrian Bente <[email protected]>
netfilter: flowtable: fix offloaded ct timeout never being extended

Xiang Mei <[email protected]>
netfilter: ebtables: terminate table name before find_table_lock()

Florian Westphal <[email protected]>
netfilter: ebtables: module names must be null-terminated

Florian Westphal <[email protected]>
netfilter: ebtables: zero chainstack array

Florian Westphal <[email protected]>
netfilter: handle unreadable frags

Pratham Gupta <[email protected]>
netfilter: ctnetlink: use nf_ct_exp_net() in expectation dump

Zijiang Huang <[email protected]>
mm/swap: add cond_resched() in swap_reclaim_full_clusters to prevent softlockup

Jose Fernandez (Anthropic) <[email protected]>
mm: swap_cgroup: fix NULL deref in lookup_swap_cgroup_id on swapless host

Qi Zheng <[email protected]>
mm: shrinker: fix NULL pointer dereference in debugfs

Qi Zheng <[email protected]>
mm: shrinker: fix shrinker_info teardown race with expansion

Shakeel Butt <[email protected]>
mm/shrinker: do not hold RCU lock in shrinker_debugfs_count_show()

Andrei Kuchynski <[email protected]>
mfd: cros_ec: Delay dev_set_drvdata() until probe success

Wyatt Feng <[email protected]>
net: ipv4: bound TCP reordering sysctl writes and MTU probe sizes

Yuyang Huang <[email protected]>
ipv4: igmp: remove multicast group from hash table on device destruction

Breno Leitao <[email protected]>
netpoll: fix a use-after-free on shutdown path

Michael Wigham <[email protected]>
io_uring/rw: preserve partial result for iopoll

Runyu Xiao <[email protected]>
io_uring/io-wq: re-check IO_WQ_BIT_EXIT for each linked work item

Vasileios Almpanis <[email protected]>
io_uring/nop: fix file reference leak with IOSQE_FIXED_FILE

Runyu Xiao <[email protected]>
gpio: sch: use raw_spinlock_t in the irq startup path

Runyu Xiao <[email protected]>
gpio: eic-sprd: use raw_spinlock_t in the irq startup path

Koichiro Den <[email protected]>
NTB: epf: Avoid calling pci_irq_vector() from hardirq context

Yunpeng Tian <[email protected]>
fs/ntfs3: validate Dirty Page Table capacity in log_replay copy_lcns

Thomas Gleixner <[email protected]>
debugobjects: Plug race against a concurrent OOM disable

Runyu Xiao <[email protected]>
coresight: etb10: restore atomic_t for shared reading state

Samuel Page <[email protected]>
Bluetooth: MGMT: Fix UAF of hci_conn_params in add_device_complete

Marco Elver <[email protected]>
Bluetooth: L2CAP: Fix UAF in channel timeout by holding conn ref

Chi Wang <[email protected]>
audit: Fix data races of skb_queue_len() readers on audit_queue

Zijing Yin <[email protected]>
net: af_key: initialize alg_key_len for IPComp states

Gil Portnoy <[email protected]>
ksmbd: fix use-after-free of a deferred file_lock on SMB2_CLOSE then SMB2_CANCEL

Michael Bommarito <[email protected]>
crypto: krb5 - filter out async aead implementations at alloc

Dawei Feng <[email protected]>
crypto: amlogic - avoid double cleanup in meson_crypto_probe()

Alexandru Hossu <[email protected]>
staging: rtl8723bs: fix OOB write in HT_caps_handler()

Alexandru Hossu <[email protected]>
staging: rtl8723bs: fix OOB reads in is_ap_in_tkip() IE loop

Alexandru Hossu <[email protected]>
staging: rtl8723bs: fix OOB reads in IE loops in issue_assocreq() and join_cmd_hdl()

Alexandru Hossu <[email protected]>
staging: rtl8723bs: fix OOB read in update_beacon_info() IE loop

Alexandru Hossu <[email protected]>
staging: rtl8723bs: fix OOB read in OnAssocRsp() IE loop

Alexandru Hossu <[email protected]>
staging: rtl8723bs: fix WEP length underflow and OOB read in OnAuth()

Alexandru Hossu <[email protected]>
staging: rtl8723bs: fix heap buffer overflow in rtw_cfg80211_set_wpa_ie()

Alexandru Hossu <[email protected]>
staging: media: ipu7: fix double-free and use-after-free in error paths

Arnd Bergmann <[email protected]>
staging: media: atomisp: reduce load_primary_binaries() stack usage

Ricardo Ribalda <[email protected]>
media: staging: ipu3-imgu: Add range check for imgu_css_cfg_acc_stripe

Hao-Qun Huang <[email protected]>
staging: vme_user: fix location monitor leak in tsi148 bridge

Hao-Qun Huang <[email protected]>
staging: vme_user: fix location monitor leak in fake bridge

Shoichiro Miyamoto <[email protected]>
smb: client: restrict implied bcc[0] exemption to responses without data area

Michael Tautschnig <[email protected]>
staging: vme_user: bound slave read/write to the kern_buf size

Samuel Page <[email protected]>
tipc: fix out-of-bounds read in broadcast Gap ACK blocks

Yizhou Zhao <[email protected]>
6lowpan: fix NHC entry use-after-free on error path

Cen Zhang <[email protected]>
usb: misc: usbio: fix disconnect UAF in client teardown

Runyu Xiao <[email protected]>
usb: dwc3: run gadget disconnect from sleepable suspend context

Alan Stern <[email protected]>
USB: chaoskey: Fix slab-use-after-free in chaoskey_release()

Michael Bommarito <[email protected]>
hwrng: virtio: clamp device-reported used.len at copy_data()

Johan Hovold <[email protected]>
virtio-mmio: fix device release warning on module unload

Ammar Faizi <[email protected]>
virtio_pci: fix vq info pointer lookup via wrong index

Xiang Mei <[email protected]>
netfilter: ipset: fix race between dump and ip_set_list resize

SeongJae Park <[email protected]>
mm/damon/ops-common: handle extreme intervals in damon_hot_score()

Michael Bommarito <[email protected]>
tcp: restore RCU grace period in tcp_ao_destroy_sock

Marco Nenciarini <[email protected]>
PCI/IOV: Skip VF Resizable BAR restore on read error

Yadu M G <[email protected]>
PCI: qcom: Initialize DWC MSI lock for firmware-managed ECAM hosts

Manivannan Sadhasivam <[email protected]>
PCI: mediatek: Fix IRQ domain leak when port fails to enable

Richard Zhu <[email protected]>
PCI: imx6: Fix IMX6SX_GPR12_PCIE_TEST_POWERDOWN handling

Ratheesh Kannoth <[email protected]>
PCI: host-common: Request bus reassignment when not probe-only

Maciej W. Rozycki <[email protected]>
PCI: Always lift 2.5GT/s restriction in PCIe failed link retraining

Mahesh Vaidya <[email protected]>
PCI: altera: Fix resource leaks on probe failure

Mahesh Vaidya <[email protected]>
PCI: altera: Do not dispose parent IRQ mapping

Ziyao Li <[email protected]>
PCI: loongson: Override PCIe bridge supported speeds for Loongson-3C6000 series

Myeonghun Pak <[email protected]>
usb: typec: tcpci_rt1711h: unregister TCPCI port with devres

Xu Rao <[email protected]>
xhci: sideband: fix ring sg table pages leak

胡连勤 <[email protected]>
usb: xhci: Fix sleep in atomic context in xhci_free_streams()

Alice Ryhl <[email protected]>
rust_binder: clear freeze listener on node removal

Keshav Verma <[email protected]>
rust_binder: synchronize Rust Binder stats with freeze commands

Keshav Verma <[email protected]>
rust_binder: reject context manager self-transaction

Hyunwoo Kim <[email protected]>
rust_binder: use a u64 stride when cleaning up the offsets array

Carlos Llamas <[email protected]>
binder: fix UAF in binder_free_transaction()

Carlos Llamas <[email protected]>
binder: fix UAF in binder_thread_release()

Johan Hovold <[email protected]>
Bluetooth: btusb: fix wakeup source leak on probe failure

Johan Hovold <[email protected]>
Bluetooth: btusb: fix use-after-free on marvell probe failure

Johan Hovold <[email protected]>
Bluetooth: btusb: fix use-after-free on registration failure

Zenm Chen <[email protected]>
Bluetooth: btusb: Add USB ID 2c4e:0128 for Mercusys MA60XNB

Alex Williamson <[email protected]>
vfio: Remove device debugfs before releasing devres

Junrui Luo <[email protected]>
vfio: prevent infinite loop in vfio_mig_get_next_state() on blocked arc

Alex Williamson <[email protected]>
vfio/pci: Fix racy bitfields and tighten struct layout

Alex Williamson <[email protected]>
vfio/pci: Release the VGA arbiter client on register_device() failure

Alex Williamson <[email protected]>
vfio/pci: Latch disable_idle_d3 per device

Raghavendra Rao Ananta <[email protected]>
vfio/pci: Use a private flag to prevent power state change with VFs

Cássio Gabriel <[email protected]>
ALSA: usb-audio: Update US-16x08 EQ/comp shadow state after successful writes

Cássio Gabriel <[email protected]>
ALSA: usb-audio: Update Babyface Pro control caches only after successful writes

Cássio Gabriel <[email protected]>
ALSA: usb-audio: Roll back quirk control caches on write errors

Cássio Gabriel <[email protected]>
ALSA: usb-audio: Propagate US-16x08 write errors in route/mix EQ-switch put callbacks

Cássio Gabriel <[email protected]>
ALSA: usb-audio: Propagate errors in scarlett_ctl_enum_put()

Darvell Long <[email protected]>
ALSA: usb-audio: avoid kobject path lookup in DualSense match

WenTao Liang <[email protected]>
ALSA: us144mkii: capture_urb_complete: redundant usb_anchor_urb corrupts anchor list on each resubmission

HyeongJun An <[email protected]>
ALSA: seq: Fix uninitialised heap leak in snd_seq_event_dup()

Zhao Dongdong <[email protected]>
ALSA: ice1712: check snd_ctl_new1() return value

Aaron Erhardt <[email protected]>
ALSA: hda/realtek: Fix noisy mic for Clevo V6xxAW

Huacai Chen <[email protected]>
ALSA: hda/hdmi: Use 'AC_PINSENSE_ELDV' to detect pinsense for Loongson

Cameron Graham <[email protected]>
ALSA: hda/hdmi: Add force-connect quirk for HP EliteDesk 800 G5 Mini

Cássio Gabriel <[email protected]>
ALSA: hda/cs35l41: Fix firmware load work teardown

Zhao Dongdong <[email protected]>
ALSA: gus: check snd_ctl_new1() return value

Maoyi Xie <[email protected]>
ALSA: firewire: isight: bound the sample count to the packet payload

Geoffrey D. Bennett <[email protected]>
ALSA: FCP: Add Focusrite ISA C8X support

Zhao Dongdong <[email protected]>
ALSA: es1938: check snd_ctl_new1() return value

Cássio Gabriel <[email protected]>
ALSA: compress: Fix task creation error unwind

Zhao Dongdong <[email protected]>
ALSA: cmipci: check snd_ctl_new1() return value

Maoyi Xie <[email protected]>
ALSA: caiaq: fix out-of-bounds read in the Traktor Kontrol S4 input parser

Zhao Dongdong <[email protected]>
ALSA: aoa: check snd_ctl_new1() return value

Zhao Dongdong <[email protected]>
ALSA: ymfpci: check snd_ctl_new1() return value

Cássio Gabriel <[email protected]>
ALSA: virtio: Validate control metadata from the device

Cássio Gabriel <[email protected]>
ALSA: virtio: Add missing 384 kHz PCM rate mapping

HyeongJun An <[email protected]>
ALSA: usx2y: us144mkii: fix work UAF on disconnect

Stepan Ionichev <[email protected]>
iio: temperature: tmp006: use devm_iio_trigger_register

Liviu Stan <[email protected]>
iio: temperature: ltc2983: Fix reinit_completion() called after conversion start

Liviu Stan <[email protected]>
iio: temperature: ltc2983: Fix n_wires default bypassing rotation check

Pengpeng Hou <[email protected]>
iio: temperature: Build mlx90635 with CONFIG_MLX90635

Stepan Ionichev <[email protected]>
iio: resolver: ad2s1210: notify trigger and clear state on fault read error

Stepan Ionichev <[email protected]>

    iio: proximity: vl53l0x: notify trigger and clear IRQ on error paths

Biren Pandya <[email protected]>
iio: pressure: mpl115: fix runtime PM leak on read error

David Carlier <[email protected]>
iio: pressure: bmp280: zero-init bmp580 trigger handler buffer

Andy Shevchenko <[email protected]>
iio: magnetometer: ak8975: Add missed pm_runtime_put_autosuspend() call

Javier Carrasco <[email protected]>
iio: light: veml6030: fix channel type when pushing events

Stepan Ionichev <[email protected]>
iio: light: tsl2591: return actual error from probe IRQ failure

Joshua Crofts <[email protected]>
iio: light: opt3001: fix missing state reset on timeout

Biren Pandya <[email protected]>
iio: light: gp2ap002: fix runtime PM leak on read error

Alexander A. Klimov <[email protected]>
iio: light: al3320a: read both ALS ADC registers again

Joshua Crofts <[email protected]>
iio: light: al3320a: add missing REGMAP_I2C to Kconfig

Alexander A. Klimov <[email protected]>
iio: light: al3010: read both ALS ADC registers again

Vidhu Sarwal <[email protected]>
iio: light: al3010: fix incorrect scale for the highest gain range

Joshua Crofts <[email protected]>
iio: light: al3010: add missing REGMAP_I2C to Kconfig

Joshua Crofts <[email protected]>
iio: light: al3000a: add missing REGMAP_I2C to Kconfig

Andreas Kempe <[email protected]>
iio: imu: st_lsm6dsx: deselect shub page before reading whoami

Jean-Baptiste Maneyrol <[email protected]>
iio: imu: inv_icm42600: fix timestamping by limiting FIFO reading

Jean-Baptiste Maneyrol <[email protected]>
iio: imu: inv_icm42600: fix timestamp clock period by using lower value

Runyu Xiao <[email protected]>
iio: imu: bmi160: add IRQF_NO_THREAD to data-ready trigger IRQ

Runyu Xiao <[email protected]>
iio: imu: adis: add IRQF_NO_THREAD to non-FIFO trigger IRQ

Stepan Ionichev <[email protected]>
iio: gyro: bmg160: wait full startup time after mode change at probe

Stepan Ionichev <[email protected]>
iio: gyro: bmg160: bail out when bandwidth/filter is not in table

Lars-Peter Clausen <[email protected]>
iio: event: Fix event FIFO reset race

Dan Carpenter <[email protected]>
iio: dac: ad3552r-hs: fix uninitialized data ni ad3552r_hs_write_data_source()

Dan Carpenter <[email protected]>
iio: core: fix uninitialized data in debugfs

Herman van Hazendonk <[email protected]>
iio: common: st_sensors: honour channel endianness in read_axis_data

Maxwell Doose <[email protected]>
iio: chemical: scd30: Cleanup initializations and fix sign-extension bug

Dan Carpenter <[email protected]>
iio: backend: fix uninitialized data in debugfs

Pengpeng Hou <[email protected]>
iio: adc: ti-ads124s08: Return reset GPIO lookup errors

Guangshuo Li <[email protected]>
iio: adc: ti-ads1119: fix PM reference leak in buffer preenable

Maxwell Doose <[email protected]>
iio: adc: spear: Initialize completion before requesting IRQ

Maxwell Doose <[email protected]>
iio: adc: lpc32xx: Initialize completion before requesting IRQ

Radu Sabau <[email protected]>
iio: adc: ad_sigma_delta: fix CS held asserted and state leaks

Radu Sabau <[email protected]>
iio: adc: ad_sigma_delta: fix clear_pending_event for registerless devices

Joshua Crofts <[email protected]>
iio: adc: ad7779: add missing 'select IIO_TRIGGERED_BUFFER' to Kconfig

Jonathan Cameron <[email protected]>

    iio: adc: ad7768-1: Select GPIOLIB

Samuel Moelius <[email protected]>
iio: adc: ad7380: select REGMAP

Biren Pandya <[email protected]>
iio: accel: kxsd9: fix runtime PM imbalance on write_raw() error

Bryam Vargas <[email protected]>
iio: accel: bmc150: clamp the device-reported FIFO frame count

Griffin Kroah-Hartman <[email protected]>
usb: gadget: function: rndis: add length check for header

Griffin Kroah-Hartman <[email protected]>
usb: gadget: function: rndis: add length check to response query

Eric Biggers <[email protected]>
fscrypt: Replace mk_users keyring with simple list

Eric Biggers <[email protected]>
fscrypt: Fix key setup in edge case with multiple data unit sizes

Alice Ryhl <[email protected]>
rust: kasan: KASAN+RUST requires clang

Taeyang Lee <[email protected]>
perf/core: Detach event groups during remove_on_exec

Sebastian Andrzej Siewior <[email protected]>
futex/requeue: Revert "Prevent NULL pointer dereference in remove_waiter() on self-deadlock""

Alice Ryhl <[email protected]>
rust: Kbuild: set frame-pointer llvm module flag for CONFIG_FRAME_POINTER

Gary Guo <[email protected]>
rust: doctest: fix incorrect pattern in replacement

Haoze Xie <[email protected]>
rust: block: fix GenDisk cleanup paths

Miguel Ojeda <[email protected]>
rust: cpufreq: clean new clippy::map_or_identity lint for Rust 1.98.0

Huacai Chen <[email protected]>
LoongArch: Add PIO for early access before ACPI PCI root register

HyeongJun An <[email protected]>
platform/x86: intel-hid: Protect ACPI notify handler against recursion

Rafael J. Wysocki <[email protected]>
ACPI: NFIT: core: Fix possible NULL pointer dereference

Jeremy Linton <[email protected]>
ACPI: CPPC: Suppress UBSAN warning caused by field misuse

Carlos López <[email protected]>
KVM: x86: Unconditionally recompute CR8 intercept on PPR update

Sean Christopherson <[email protected]>
KVM: VMX: Grab vmcs12 on CR8 interception update iff vCPU is in guest mode

Sean Christopherson <[email protected]>
KVM: x86: Move update_cr8_intercept() to lapic.c

Florian Fainelli <[email protected]>
perf trace beauty fcntl: Fix build with older kernel headers

Randy Dunlap <[email protected]>
slab: recognize @GFP parameter as optional in kernel-doc

Linus Torvalds <[email protected]>
default_gfp(): avoid using the "newfangled" __VA_OPT__ trick

Linus Torvalds <[email protected]>
add default_gfp() helper macro and use it in the new *alloc_obj() helpers

Kees Cook <[email protected]>
slab: Introduce kmalloc_flex() and family

Pedro Falcato <[email protected]>
mm/khugepaged: write all dirty file folios when collapsing

NeilBrown <[email protected]>
nfsd: change nfs4_client_to_reclaim() to allocate data

NeilBrown <[email protected]>
nfsd: move name lookup out of nfsd4_list_rec_dir()

Xingquan Liu <[email protected]>
net/sched: dualpi2: fix GSO backlog accounting

Mingyu Wang <[email protected]>
fbdev: fbcon: fix out-of-bounds read in err_out of fbcon_do_set_font()

Chao Yu <[email protected]>
f2fs: fix to do sanity check on f2fs_get_node_folio_ra()

Chao Yu <[email protected]>
f2fs: detect more inconsistent cases in sanity_check_node_footer()

YH Lin <[email protected]>
f2fs: optimize trace_f2fs_write_checkpoint with enums

Chao Yu <[email protected]>
f2fs: introduce f2fs_schedule_timeout()

Chao Yu <[email protected]>
f2fs: use memalloc_retry_wait() as much as possible

Keshav Verma <[email protected]>
f2fs: fix listxattr handling of corrupted xattr entries

Chao Yu <[email protected]>
f2fs: fix potential deadlock in gc_merge path of f2fs_balance_fs()

Ruipeng Qi <[email protected]>
f2fs: fix potential deadlock in f2fs_balance_fs()

Bryam Vargas <[email protected]>
f2fs: bound i_inline_xattr_size for non-inline-xattr inodes

Chao Yu <[email protected]>
f2fs: atomic: fix UAF issue on f2fs_inode_info.atomic_inode

Yongpeng Yang <[email protected]>
f2fs: remove non-uptodate folio from the page cache in move_data_block

Bartosz Golaszewski <[email protected]>
device property: initialize the remaining fields of fwnode_handle in fwnode_init()

Kiryl Shutsemau <[email protected]>
userfaultfd: gate must_wait writability check on pte_present()

Miguel Ojeda <[email protected]>
rust: str: clean unused import for Rust >= 1.98

Miguel Ojeda <[email protected]>
rust: str: use the "kernel vertical" imports style

Chris Mason <[email protected]>
nfsd: release layout stid on setlease failure

Olga Kornievskaia <[email protected]>
nfsd: update mtime/ctime on COPY in presence of delegated attributes

Olga Kornievskaia <[email protected]>
nfsd: update mtime/ctime on CLONE in presense of delegated attributes

Daniel Borkmann <[email protected]>
bpf, arm64: Reject out-of-range B.cond targets

-------------

Diffstat:

 Documentation/crypto/userspace-if.rst              |  31 +-
 Documentation/process/deprecated.rst               |   7 +
 MAINTAINERS                                        |   1 -
 Makefile                                           |   7 +-
 arch/arm64/kernel/entry-fpsimd.S                   |   8 +-
 arch/arm64/kvm/hyp/nvhe/hyp-main.c                 |   3 +
 arch/arm64/kvm/nested.c                            |  40 +-
 arch/arm64/lib/insn.c                              |   2 +
 arch/arm64/net/bpf_jit_comp.c                      |   4 +-
 arch/loongarch/include/asm/acpi.h                  |   2 +
 arch/loongarch/kernel/acpi.c                       |  28 +
 arch/loongarch/kernel/setup.c                      |   2 +
 arch/loongarch/kvm/intc/eiointc.c                  |   6 +
 arch/loongarch/kvm/intc/ipi.c                      |   2 +
 arch/loongarch/kvm/intc/pch_pic.c                  |   2 +
 arch/loongarch/net/bpf_jit.c                       |   2 +-
 arch/loongarch/pci/acpi.c                          |   2 +
 arch/powerpc/net/bpf_jit_comp.c                    |   4 +-
 arch/riscv/include/asm/pgtable.h                   |  10 +
 arch/riscv/kernel/entry.S                          |   7 +-
 arch/riscv/net/bpf_jit_comp64.c                    |   2 +-
 arch/riscv/net/bpf_jit_core.c                      |   3 +-
 arch/s390/Kconfig                                  |   1 -
 arch/s390/include/asm/asm-extable.h                |   4 -
 arch/s390/include/asm/word-at-a-time.h             |  22 -
 arch/s390/mm/extable.c                             |  18 -
 arch/x86/events/intel/uncore_snb.c                 |   7 -
 arch/x86/include/asm/nospec-branch.h               |   4 +
 arch/x86/kernel/cpu/bugs.c                         |  50 +-
 arch/x86/kernel/cpu/resctrl/monitor.c              |   8 +-
 arch/x86/kvm/lapic.c                               |  49 +-
 arch/x86/kvm/lapic.h                               |   3 +-
 arch/x86/kvm/svm/avic.c                            |  47 +-
 arch/x86/kvm/svm/svm.c                             |   3 +
 arch/x86/kvm/vmx/pmu_intel.c                       |   6 +-
 arch/x86/kvm/vmx/vmx.c                             |  44 +-
 arch/x86/kvm/x86.c                                 |  38 +-
 arch/x86/mm/init_64.c                              |  40 +-
 arch/x86/net/bpf_jit_comp.c                        |   5 +-
 block/bdev.c                                       |   8 +-
 block/partitions/aix.c                             |   9 +
 block/partitions/of.c                              |   5 +-
 crypto/af_alg.c                                    |  69 +--
 crypto/algif_aead.c                                |   8 +-
 crypto/asymmetric_keys/x509_loader.c               |   2 +-
 crypto/chacha20poly1305.c                          |  11 +-
 crypto/drbg.c                                      |   4 +-
 crypto/ecc.c                                       |  31 +-
 crypto/krb5/krb5_api.c                             |   2 +-
 crypto/pcrypt.c                                    |   4 +
 drivers/acpi/cppc_acpi.c                           |  11 +-
 drivers/acpi/nfit/core.c                           |   3 +
 drivers/android/binder.c                           |  19 +-
 drivers/android/binder/allocation.rs               |   8 +-
 drivers/android/binder/error.rs                    |  23 +-
 drivers/android/binder/freeze.rs                   |  11 +-
 drivers/android/binder/node.rs                     |  10 +-
 drivers/android/binder/process.rs                  |  33 +-
 drivers/android/binder/rust_binder_events.c        |   7 +-
 drivers/android/binder/stats.rs                    |   4 +-
 drivers/android/binder/thread.rs                   | 237 +++++----
 drivers/android/binder/transaction.rs              |  96 ++--
 drivers/base/firmware_loader/sysfs_upload.c        |   8 +-
 drivers/bluetooth/btmtksdio.c                      |   2 +-
 drivers/bluetooth/btnxpuart.c                      |   6 +
 drivers/bluetooth/btusb.c                          |  39 +-
 drivers/bluetooth/hci_ldisc.c                      |  14 +-
 drivers/char/hw_random/jh7110-trng.c               |  13 +-
 drivers/char/hw_random/virtio-rng.c                |  23 +-
 drivers/clocksource/timer-tegra186.c               |   3 +-
 drivers/cpufreq/cpufreq.c                          |   2 +
 drivers/cpufreq/intel_pstate.c                     |   6 +-
 drivers/cpufreq/pcc-cpufreq.c                      |   2 +
 drivers/cpufreq/qcom-cpufreq-hw.c                  |   1 -
 drivers/crypto/Kconfig                             |   1 -
 drivers/crypto/Makefile                            |   1 -
 drivers/crypto/amcc/crypto4xx_core.c               |  88 ----
 drivers/crypto/amcc/crypto4xx_core.h               |   4 -
 drivers/crypto/amcc/crypto4xx_reg_def.h            |  11 -
 drivers/crypto/amlogic/amlogic-gxl-core.c          |   2 +-
 drivers/crypto/atmel-sha204a.c                     |  19 +-
 drivers/crypto/caam/caamalg.c                      |  12 +-
 drivers/crypto/caam/caamalg_qi.c                   |  12 +-
 drivers/crypto/caam/caamalg_qi2.c                  |  12 +-
 drivers/crypto/caam/caamhash.c                     |   4 +-
 drivers/crypto/caam/key_gen.c                      |   4 +-
 drivers/crypto/ccp/sev-dev.c                       |  70 +--
 drivers/crypto/hisilicon/Kconfig                   |   1 -
 drivers/crypto/hisilicon/trng/trng.c               | 296 +----------
 drivers/crypto/intel/qat/qat_420xx/adf_drv.c       |   2 -
 drivers/crypto/intel/qat/qat_4xxx/adf_drv.c        |   2 -
 drivers/crypto/intel/qat/qat_6xxx/adf_drv.c        |   2 -
 drivers/crypto/intel/qat/qat_c3xxx/adf_drv.c       |   1 -
 drivers/crypto/intel/qat/qat_c3xxxvf/adf_drv.c     |   1 -
 drivers/crypto/intel/qat/qat_c62x/adf_drv.c        |   1 -
 drivers/crypto/intel/qat/qat_c62xvf/adf_drv.c      |   1 -
 drivers/crypto/intel/qat/qat_common/adf_aer.c      | 102 ++--
 .../crypto/intel/qat/qat_common/adf_common_drv.h   |   1 +
 drivers/crypto/intel/qat/qat_common/adf_init.c     |  18 +
 drivers/crypto/intel/qat/qat_common/adf_sriov.c    |  12 +-
 .../crypto/intel/qat/qat_common/qat_asym_algs.c    |  10 +-
 drivers/crypto/intel/qat/qat_dh895xcc/adf_drv.c    |   1 -
 drivers/crypto/intel/qat/qat_dh895xccvf/adf_drv.c  |   1 -
 drivers/crypto/loongson/Kconfig                    |   5 -
 drivers/crypto/loongson/Makefile                   |   1 -
 drivers/crypto/loongson/loongson-rng.c             | 209 --------
 drivers/crypto/talitos.c                           | 561 +++++++++++----------
 drivers/crypto/talitos.h                           |  12 +
 drivers/crypto/tegra/tegra-se-main.c               |   2 +-
 drivers/dma-buf/udmabuf.c                          |   9 +-
 drivers/edac/i10nm_base.c                          |  14 +-
 drivers/fpga/dfl-afu-main.c                        |   3 +
 drivers/gpio/gpio-eic-sprd.c                       |   8 +-
 drivers/gpio/gpio-sch.c                            |  32 +-
 drivers/hid/hid-appleir.c                          |  45 +-
 drivers/hid/hid-goodix-spi.c                       |   3 +
 drivers/hid/hid-letsketch.c                        |  36 +-
 drivers/hid/hid-lg-g15.c                           |  16 +
 drivers/hid/hid-multitouch.c                       |  32 +-
 drivers/hid/hid-sensor-hub.c                       |  77 ++-
 drivers/hid/uhid.c                                 |   8 +-
 drivers/hid/usbhid/hid-pidff.c                     |   2 +-
 drivers/hid/wacom_sys.c                            |  20 +-
 drivers/hwtracing/coresight/coresight-etb10.c      |   6 +-
 drivers/hwtracing/coresight/ultrasoc-smb.c         |   1 +
 drivers/i2c/busses/i2c-davinci.c                   |   4 +-
 drivers/i2c/busses/i2c-i801.c                      |   2 +-
 drivers/i2c/busses/i2c-imx-lpi2c.c                 |  15 +-
 drivers/i2c/busses/i2c-mpc.c                       |   2 +-
 drivers/i2c/busses/i2c-stm32f7.c                   |   9 +-
 drivers/i2c/i2c-core-base.c                        |  81 +--
 drivers/iio/accel/bmc150-accel-core.c              |   2 +
 drivers/iio/accel/kxsd9.c                          |   5 +-
 drivers/iio/adc/Kconfig                            |   3 +
 drivers/iio/adc/ad_sigma_delta.c                   |  39 +-
 drivers/iio/adc/lpc32xx_adc.c                      |   4 +-
 drivers/iio/adc/spear_adc.c                        |   3 +-
 drivers/iio/adc/ti-ads1119.c                       |   6 +-
 drivers/iio/adc/ti-ads124s08.c                     |   3 +-
 drivers/iio/chemical/scd30_core.c                  |  19 +-
 drivers/iio/common/st_sensors/st_sensors_core.c    |  23 +-
 drivers/iio/dac/ad3552r-hs.c                       |   2 +-
 drivers/iio/gyro/bmg160_core.c                     |  16 +-
 drivers/iio/imu/adis_trigger.c                     |   2 +-
 drivers/iio/imu/bmi160/bmi160_core.c               |   3 +-
 drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c  |   4 +-
 drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c |   9 +-
 drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h |   1 +
 drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c   |   4 +-
 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c       |  21 +-
 drivers/iio/industrialio-backend.c                 |   2 +-
 drivers/iio/industrialio-core.c                    |   2 +-
 drivers/iio/industrialio-event.c                   |   5 +-
 drivers/iio/light/Kconfig                          |   3 +
 drivers/iio/light/al3010.c                         |  10 +-
 drivers/iio/light/al3320a.c                        |   8 +-
 drivers/iio/light/gp2ap002.c                       |   2 +-
 drivers/iio/light/opt3001.c                        |   6 +-
 drivers/iio/light/tsl2591.c                        |   6 +-
 drivers/iio/light/veml6030.c                       |   8 +-
 drivers/iio/magnetometer/ak8975.c                  |   1 +
 drivers/iio/pressure/bmp280-core.c                 |   2 +-
 drivers/iio/pressure/mpl115.c                      |   4 +-
 drivers/iio/proximity/vl53l0x-i2c.c                |   7 +-
 drivers/iio/resolver/ad2s1210.c                    |   2 +-
 drivers/iio/temperature/Makefile                   |   2 +-
 drivers/iio/temperature/ltc2983.c                  |   5 +-
 drivers/iio/temperature/tmp006.c                   |   2 +-
 drivers/infiniband/core/addr.c                     |   2 +-
 drivers/infiniband/sw/siw/siw_qp_rx.c              |   9 +
 drivers/infiniband/ulp/rtrs/rtrs-srv.c             |   5 +-
 drivers/input/joystick/iforce/iforce-packets.c     |  18 +-
 drivers/input/joystick/maplecontrol.c              |   3 +-
 drivers/input/keyboard/maple_keyb.c                |   4 +-
 drivers/input/mouse/elan_i2c_core.c                |  36 +-
 drivers/input/mouse/maplemouse.c                   |   9 +-
 drivers/input/rmi4/rmi_bus.c                       |   4 +-
 drivers/input/rmi4/rmi_f30.c                       |   2 +-
 drivers/input/rmi4/rmi_f3a.c                       |   2 +-
 drivers/input/serio/gscps2.c                       |   1 +
 drivers/input/touchscreen/ads7846.c                |   5 +-
 drivers/input/touchscreen/goodix.c                 |   3 +-
 drivers/input/touchscreen/mms114.c                 |  26 +-
 drivers/input/touchscreen/touchwin.c               |  15 +-
 drivers/iommu/amd/iommu.c                          |   3 +-
 drivers/iommu/intel/iommu.c                        |  29 +-
 drivers/iommu/intel/iommu.h                        |  11 +
 drivers/iommu/intel/nested.c                       |   9 +-
 drivers/iommu/intel/pasid.c                        | 190 -------
 drivers/iommu/intel/pasid.h                        |  14 -
 drivers/iommu/intel/svm.c                          |  12 +-
 drivers/iommu/iommufd/eventq.c                     |  26 +-
 drivers/iommu/iommufd/hw_pagetable.c               |  11 +-
 drivers/iommu/iommufd/iommufd_private.h            |   2 +-
 drivers/md/dm-ioctl.c                              |   5 +-
 .../media/platform/mediatek/jpeg/mtk_jpeg_core.c   |   3 +-
 drivers/mfd/cros_ec_dev.c                          |   3 +-
 drivers/net/usb/kalmia.c                           |   8 +
 drivers/ntb/hw/epf/ntb_hw_epf.c                    |  14 +-
 drivers/nvme/host/multipath.c                      |   6 +
 drivers/nvme/target/discovery.c                    |  23 +-
 drivers/nvme/target/fabrics-cmd-auth.c             |  15 +-
 drivers/nvme/target/rdma.c                         |   6 +-
 drivers/opp/of.c                                   |   3 +-
 drivers/pci/controller/dwc/pci-imx6.c              |  12 +-
 drivers/pci/controller/dwc/pcie-qcom.c             |   6 +
 drivers/pci/controller/pci-host-common.c           |   4 +
 drivers/pci/controller/pci-loongson.c              |  36 ++
 drivers/pci/controller/pcie-altera.c               |  36 +-
 drivers/pci/controller/pcie-mediatek.c             |  65 ++-
 drivers/pci/iov.c                                  |   6 +
 drivers/pci/quirks.c                               |  51 +-
 drivers/perf/arm-cmn.c                             |  23 +-
 drivers/platform/x86/intel/hid.c                   |   9 +
 drivers/regulator/scmi-regulator.c                 |   4 +-
 drivers/spi/spi-fsl-lpspi.c                        |  18 +-
 drivers/staging/media/atomisp/pci/sh_css.c         |   6 +-
 drivers/staging/media/ipu3/ipu3-css-params.c       |   8 +-
 drivers/staging/media/ipu7/ipu7.c                  |  22 +-
 drivers/staging/rtl8723bs/core/rtw_mlme_ext.c      |  20 +-
 drivers/staging/rtl8723bs/core/rtw_wlan_util.c     |  23 +-
 drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c  |   8 +
 drivers/staging/vme_user/vme_fake.c                |   8 +
 drivers/staging/vme_user/vme_tsi148.c              |   8 +
 drivers/staging/vme_user/vme_user.c                |  22 +
 drivers/tty/serial/8250/8250_mid.c                 |  13 +-
 drivers/usb/cdns3/cdnsp-mem.c                      |   2 +
 drivers/usb/class/cdc-acm.c                        |   3 +
 drivers/usb/common/ulpi.c                          |  23 +-
 drivers/usb/core/quirks.c                          |   6 +
 drivers/usb/dwc3/dwc3-meson-g12a.c                 |  14 +-
 drivers/usb/dwc3/gadget.c                          |  43 +-
 drivers/usb/fotg210/fotg210-hcd.c                  |   6 +-
 drivers/usb/gadget/composite.c                     |   5 +-
 drivers/usb/gadget/function/f_fs.c                 |   3 +-
 drivers/usb/gadget/function/f_printer.c            |   3 +-
 drivers/usb/gadget/function/rndis.c                |  20 +-
 drivers/usb/gadget/udc/core.c                      |  29 +-
 drivers/usb/host/ehci-sched.c                      |  11 +-
 drivers/usb/host/sl811-hcd.c                       |   1 +
 drivers/usb/host/xhci-sideband.c                   |   2 +
 drivers/usb/host/xhci.c                            |  11 +-
 drivers/usb/misc/chaoskey.c                        |   1 -
 drivers/usb/misc/idmouse.c                         |  45 +-
 drivers/usb/misc/iowarrior.c                       |   4 +-
 drivers/usb/misc/ldusb.c                           |  38 +-
 drivers/usb/misc/legousbtower.c                    |  37 +-
 drivers/usb/misc/usbio.c                           |   8 +-
 drivers/usb/misc/uss720.c                          |   5 +-
 drivers/usb/mtu3/mtu3_gadget.c                     |   1 +
 drivers/usb/serial/digi_acceleport.c               |  43 +-
 drivers/usb/serial/keyspan_pda.c                   |   2 +-
 drivers/usb/serial/option.c                        |  16 +
 drivers/usb/storage/ene_ub6250.c                   |   3 +-
 drivers/usb/storage/usb.c                          |   2 +-
 drivers/usb/typec/anx7411.c                        |   4 +-
 drivers/usb/typec/class.c                          |   1 +
 drivers/usb/typec/tcpm/tcpci_rt1711h.c             |  13 +-
 drivers/usb/typec/tcpm/tcpm.c                      |   9 +-
 drivers/usb/typec/ucsi/displayport.c               |   7 +-
 drivers/usb/typec/ucsi/ucsi.c                      |  20 +
 drivers/usb/typec/ucsi/ucsi.h                      |   1 +
 drivers/usb/typec/ucsi/ucsi_acpi.c                 |  10 +-
 drivers/usb/typec/ucsi/ucsi_ccg.c                  |   2 +-
 drivers/usb/usbip/vudc.h                           |   1 -
 drivers/usb/usbip/vudc_dev.c                       |   4 +-
 drivers/vfio/debugfs.c                             |   1 +
 drivers/vfio/pci/vfio_pci_core.c                   |  37 +-
 drivers/vfio/vfio_main.c                           |  11 +-
 drivers/video/fbdev/core/fbcon.c                   |   7 +
 drivers/virtio/virtio_mmio.c                       |  26 +-
 drivers/virtio/virtio_pci_common.c                 |  10 +-
 drivers/watchdog/apple_wdt.c                       |   1 +
 fs/btrfs/btrfs_inode.h                             |   2 +
 fs/btrfs/extent-tree.c                             |  12 +-
 fs/btrfs/file.c                                    |  25 +-
 fs/btrfs/inode.c                                   |  61 ++-
 fs/btrfs/reflink.c                                 |   4 +-
 fs/crypto/fscrypt_private.h                        |  84 +--
 fs/crypto/inline_crypt.c                           |   8 +-
 fs/crypto/keyring.c                                | 239 ++++-----
 fs/crypto/keysetup.c                               | 118 +++--
 fs/exfat/dir.c                                     |  13 +-
 fs/f2fs/checkpoint.c                               |  10 +-
 fs/f2fs/compress.c                                 |   4 +-
 fs/f2fs/data.c                                     |  33 +-
 fs/f2fs/f2fs.h                                     |  30 +-
 fs/f2fs/gc.c                                       |  50 +-
 fs/f2fs/inode.c                                    |  17 +-
 fs/f2fs/node.c                                     |  21 +-
 fs/f2fs/segment.c                                  |  14 +-
 fs/f2fs/super.c                                    |   4 +-
 fs/f2fs/xattr.c                                    |   6 +-
 fs/fs-writeback.c                                  |  31 +-
 fs/fuse/cuse.c                                     |   4 +-
 fs/fuse/dev.c                                      |  54 +-
 fs/fuse/dev_uring.c                                |  93 ++--
 fs/fuse/dev_uring_i.h                              |  10 +-
 fs/fuse/fuse_dev_i.h                               |   1 +
 fs/fuse/notify.c                                   | 434 ++++++++++++++++
 fs/fuse/readdir.c                                  |  85 +++-
 fs/hfs/bnode.c                                     |   2 +
 fs/hfsplus/bnode.c                                 |   2 +
 fs/isofs/rock.c                                    |  11 +
 fs/libfs.c                                         |   1 +
 fs/nfs/dir.c                                       |   2 +
 fs/nfsd/nfs4layouts.c                              |   4 +-
 fs/nfsd/nfs4proc.c                                 |  14 +-
 fs/nfsd/nfs4recover.c                              | 119 ++---
 fs/nfsd/nfs4state.c                                |  66 ++-
 fs/nfsd/state.h                                    |   1 +
 fs/nfsd/xdr4.h                                     |   1 +
 fs/nilfs2/segment.c                                |  22 +
 fs/ntfs3/attrib.c                                  |  14 +
 fs/ntfs3/dir.c                                     |   2 +-
 fs/ntfs3/file.c                                    |  30 +-
 fs/ntfs3/frecord.c                                 |  59 ++-
 fs/ntfs3/fslog.c                                   |  20 +-
 fs/ntfs3/inode.c                                   |  15 +-
 fs/ntfs3/ntfs_fs.h                                 |   4 +-
 fs/resctrl/monitor.c                               |  37 +-
 fs/smb/client/cifs_swn.c                           | 316 ++++++++++--
 fs/smb/client/cifsacl.c                            |   2 +-
 fs/smb/client/file.c                               |   2 +-
 fs/smb/client/smb2misc.c                           |  32 +-
 fs/smb/client/smb2ops.c                            |  18 +-
 fs/smb/client/smb2pdu.c                            |  22 +-
 fs/smb/client/trace.h                              |   2 +
 fs/smb/server/smb2pdu.c                            | 101 ++--
 fs/smb/server/vfs.c                                |  18 +-
 fs/smb/server/vfs_cache.c                          |   5 +
 fs/smb/server/vfs_cache.h                          |   2 +
 fs/udf/balloc.c                                    |   5 +-
 fs/udf/super.c                                     |  11 +-
 fs/userfaultfd.c                                   |  14 +-
 fs/xfs/libxfs/xfs_bmap_btree.h                     |   2 +-
 fs/xfs/libxfs/xfs_dquot_buf.c                      |  14 +-
 fs/xfs/libxfs/xfs_exchmaps.c                       |   2 +-
 fs/xfs/xfs_dquot.c                                 |  16 +-
 fs/xfs/xfs_log_recover.c                           |   6 +-
 fs/xfs/xfs_qm.c                                    |   5 +-
 include/asm-generic/rqspinlock.h                   |  14 +-
 include/crypto/drbg.h                              |  18 +-
 include/linux/damon.h                              |   8 +-
 include/linux/filter.h                             |  15 +-
 include/linux/fs.h                                 |   5 +
 include/linux/fwnode.h                             |   2 +
 include/linux/gfp.h                                |   4 +
 include/linux/glob.h                               |   1 +
 include/linux/hid-sensor-hub.h                     |  25 +
 include/linux/page_ext.h                           |  19 +-
 include/linux/slab.h                               |  78 ++-
 include/linux/vfio_pci_core.h                      |  15 +-
 include/net/bluetooth/hci_core.h                   |   1 +
 include/net/bluetooth/l2cap.h                      |   1 +
 include/net/tcp_ao.h                               |   1 +
 include/sound/hda_codec.h                          |   1 +
 include/trace/events/f2fs.h                        |  19 +-
 init/Kconfig                                       |   1 +
 io_uring/io-wq.c                                   |   2 +-
 io_uring/nop.c                                     |   8 +-
 io_uring/rw.c                                      |  12 +-
 kernel/audit.c                                     |  21 +-
 kernel/audit_fsnotify.c                            |   4 -
 kernel/bpf/btf.c                                   |   9 +-
 kernel/bpf/cgroup.c                                |   2 +-
 kernel/bpf/core.c                                  |  68 ++-
 kernel/bpf/devmap.c                                |   7 +
 kernel/bpf/dispatcher.c                            |   2 +-
 kernel/events/core.c                               |  19 +-
 kernel/futex/requeue.c                             |   6 -
 kernel/module/decompress.c                         |   2 +
 kernel/sched/fair.c                                |   2 +-
 kernel/sched/features.h                            |   8 +
 kernel/time/jiffies.c                              |  11 +-
 kernel/time/posix-cpu-timers.c                     |   1 +
 kernel/time/timekeeping.c                          |   7 +-
 kernel/trace/trace_events_filter.c                 |   6 +-
 lib/debugobjects.c                                 |  17 +
 lib/glob.c                                         |  31 +-
 mm/damon/ops-common.c                              |   1 +
 mm/filemap.c                                       |   2 +-
 mm/khugepaged.c                                    |  41 +-
 mm/madvise.c                                       |   3 +-
 mm/mincore.c                                       |   3 +-
 mm/mmap.c                                          |   2 +-
 mm/shmem.c                                         |  14 +-
 mm/shrinker.c                                      |  13 +-
 mm/shrinker_debug.c                                |  14 +-
 mm/slub.c                                          |  18 +-
 mm/swap_cgroup.c                                   |   2 +
 mm/swapfile.c                                      |   1 +
 net/6lowpan/nhc.c                                  |   2 +-
 net/bluetooth/6lowpan.c                            |  18 +-
 net/bluetooth/af_bluetooth.c                       |  17 +-
 net/bluetooth/bnep/core.c                          |  27 +-
 net/bluetooth/hci_conn.c                           |  21 +-
 net/bluetooth/hci_sync.c                           | 137 ++++-
 net/bluetooth/iso.c                                |  13 +-
 net/bluetooth/l2cap_core.c                         |  80 +--
 net/bluetooth/l2cap_sock.c                         |   4 +-
 net/bluetooth/mgmt.c                               |   3 +
 net/bridge/netfilter/ebtables.c                    |  12 +-
 net/core/netpoll.c                                 |   9 +-
 net/ipv4/igmp.c                                    |   1 +
 net/ipv4/sysctl_net_ipv4.c                         |  10 +-
 net/ipv4/tcp_ao.c                                  |   5 +-
 net/ipv4/tcp_output.c                              |   4 +-
 net/ipv6/netfilter/nf_conntrack_reasm.c            |   2 +-
 net/key/af_key.c                                   |   1 +
 net/netfilter/ipset/ip_set_core.c                  |   8 +-
 net/netfilter/nf_conntrack_netlink.c               |   2 +-
 net/netfilter/nf_flow_table_core.c                 |  13 +-
 net/netfilter/nfnetlink_log.c                      |  26 +-
 net/netfilter/nfnetlink_queue.c                    |  16 +-
 net/netfilter/xt_u32.c                             |  16 +-
 net/sched/sch_dualpi2.c                            |  11 +-
 net/tipc/bcast.c                                   |  22 +-
 net/tipc/bcast.h                                   |   2 +-
 net/tipc/node.c                                    |  15 +-
 rust/kernel/block/mq/gen_disk.rs                   |  20 +-
 rust/kernel/cpufreq.rs                             |   2 +-
 rust/kernel/str.rs                                 |  24 +-
 rust/kernel/uaccess.rs                             |   3 +
 scripts/rustdoc_test_builder.rs                    |  16 +-
 security/landlock/net.c                            |   1 +
 sound/aoa/fabrics/layout.c                         |   6 +
 sound/core/compress_offload.c                      |  13 +-
 sound/core/seq/seq_memory.c                        |   2 +-
 sound/firewire/isight.c                            |   3 +-
 sound/hda/codecs/hdmi/hdmi.c                       |   9 +-
 sound/hda/codecs/realtek/alc269.c                  |   1 +
 sound/hda/codecs/side-codecs/cs35l41_hda.c         |  77 ++-
 sound/hda/codecs/side-codecs/cs35l41_hda.h         |   5 +
 sound/hda/common/jack.c                            |   6 +
 sound/isa/gus/gus_pcm.c                            |   2 +
 sound/pci/cmipci.c                                 |   6 +
 sound/pci/es1938.c                                 |   2 +
 sound/pci/ice1712/aureon.c                         |   2 +
 sound/pci/ice1712/ice1712.c                        |   8 +
 sound/pci/ice1712/ice1724.c                        |   6 +
 sound/pci/ymfpci/ymfpci_main.c                     |   6 +
 sound/usb/caiaq/input.c                            |   2 +-
 sound/usb/mixer_quirks.c                           | 102 ++--
 sound/usb/mixer_scarlett.c                         |   4 +-
 sound/usb/mixer_us16x08.c                          | 127 +++--
 sound/usb/usx2y/us144mkii.c                        |  17 +-
 sound/usb/usx2y/us144mkii_capture.c                |   2 +-
 sound/virtio/virtio_kctl.c                         |  50 ++
 sound/virtio/virtio_pcm.c                          |   3 +-
 sound/virtio/virtio_pcm_ops.c                      |   3 +-
 tools/mm/slabinfo.c                                |   6 +-
 tools/perf/trace/beauty/fcntl.c                    |  16 +
 tools/testing/selftests/landlock/audit.h           |  39 +-
 tools/testing/selftests/landlock/audit_test.c      |   2 +
 tools/testing/selftests/landlock/net_test.c        |  62 +++
 tools/testing/selftests/landlock/ptrace_test.c     |   1 +
 .../selftests/landlock/scoped_abstract_unix_test.c |   1 +
 tools/testing/selftests/mm/droppable.c             |  48 +-
 tools/testing/selftests/mm/pagemap_ioctl.c         |  12 +-
 tools/usb/usbip/libsrc/usbip_common.c              |   2 +
 tools/usb/usbip/libsrc/usbip_device_driver.c       |   4 +
 tools/usb/usbip/libsrc/vhci_driver.c               |   1 +
 463 files changed, 5755 insertions(+), 3449 deletions(-)
author maintainer
#1 lore raw

PATCH 1/480 bpf, arm64: Reject out-of-range B.cond targets

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Daniel Borkmann <[email protected]>

commit 48d83d94930eb4db4c93d2de44838b9455cff626 upstream.

aarch64_insn_gen_cond_branch_imm() calls label_imm_common() to compute a 19-bit signed byte offset for a conditional branch, but unlike its siblings aarch64_insn_gen_branch_imm() and aarch64_insn_gen_comp_branch_imm(), it does not check whether label_imm_common() returned its out-of-range sentinel (range) before feeding the value to aarch64_insn_encode_immediate().

aarch64_insn_encode_immediate() unconditionally masks the value with the 19-bit field mask, so an offset that was rejected by label_imm_common() gets silently truncated. With the sentinel value SZ_1M, the resulting field ends up with bit 18 (the sign bit of the 19-bit signed displacement) set, and the CPU decodes it as a ~1 MiB *backward* branch, producing an incorrectly targeted B.cond instruction. For code-gen locations like the emit_bpf_tail_call() this function is the only barrier between an overflowing displacement and a silently miscompiled branch.

Fix it by returning AARCH64_BREAK_FAULT when the offset is out of range, so callers see a loud failure instead of a silently misencoded branch. validate_code() scans the generated image for any AARCH64_BREAK_FAULT and then lets the JIT fail.

Fixes 345e0d35ecdd ("arm64: introduce aarch64_insn_gen_cond_branch_imm()")
Fixes c94ae4f7c5ec ("arm64: insn: remove BUG_ON from codegen")
---
 arch/arm64/lib/insn.c | 2 ++
 1 file changed, 2 insertions(+)
arch/arm64/lib/insn.c +2 -0
index 4e298baddc2e56..e9e9a70ac155c8 100644
@@ -338,6 +338,8 @@ u32 aarch64_insn_gen_cond_branch_imm(unsigned long pc, unsigned long addr,
 	long offset;
 
 	offset = label_imm_common(pc, addr, SZ_1M);
+	if (offset >= SZ_1M)
+		return AARCH64_BREAK_FAULT;
 
 	insn = aarch64_insn_get_bcond_value();
 
Signature · 1 line
2.53.0
author maintainer
#2 lore raw

PATCH 2/480 nfsd: update mtime/ctime on CLONE in presense of delegated attributes

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Olga Kornievskaia <[email protected]>

commit 2863bac7f49c4acd80a048ce52506a2b9c8db015 upstream.

When delegated attributes are given on open, the file is opened with NOCMTIME and modifying operations do not update mtime/ctime as to not get out-of-sync with the client's delegated view. However, for CLONE operation, the server should update its view of mtime/ctime and reflect that in any GETATTR queries.

Fixes e5e9b24ab8fa ("nfsd: freeze c/mtime updates with outstanding WRITE_ATTRS delegation")
[ cel: 9be4b7e74eb7 and 3daab3112f03 are missing from linux-6.18.y ]
---
 fs/nfsd/nfs4proc.c  |  3 +++
 fs/nfsd/nfs4state.c | 44 +++++++++++++++++++++++++++++---------------
 fs/nfsd/state.h     |  1 +
 3 files changed, 33 insertions(+), 15 deletions(-)
fs/nfsd/nfs4proc.c +3 -0
index 9d876f9d98be20..5bfe49502a06f4 100644
@@ -1350,6 +1350,9 @@ nfsd4_clone(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 			dst, clone->cl_dst_pos, clone->cl_count,
 			EX_ISSYNC(cstate->current_fh.fh_export));
 
+	if (!status && (READ_ONCE(dst->nf_file->f_mode) & FMODE_NOCMTIME) != 0)
+		nfsd_update_cmtime_attr(dst->nf_file, 0);
+
 	nfsd_file_put(dst);
 	nfsd_file_put(src);
 out:
fs/nfsd/nfs4state.c +29 -15

59 lines not on this page · raw message

fs/nfsd/state.h +1 -0
index aaf513ed910459..2eed2c5b3cd0c2 100644
@@ -831,6 +831,7 @@ extern void nfsd4_shutdown_callback(struct nfs4_client *);
 extern void nfsd4_shutdown_copy(struct nfs4_client *clp);
 void nfsd4_async_copy_reaper(struct nfsd_net *nn);
 bool nfsd4_has_active_async_copies(struct nfs4_client *clp);
+void nfsd_update_cmtime_attr(struct file *f, unsigned int flags);
 extern struct nfs4_client_reclaim *nfs4_client_to_reclaim(struct xdr_netobj name,
 				struct xdr_netobj princhash, struct nfsd_net *nn);
 extern bool nfs4_has_reclaimed_state(struct xdr_netobj name, struct nfsd_net *nn);
Signature · 1 line
2.53.0
author maintainer
#3 lore raw

PATCH 3/480 nfsd: update mtime/ctime on COPY in presence of delegated attributes

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Olga Kornievskaia <[email protected]>

commit 4183cf383b6faec17a0882b84cd2d901dba62b16 upstream.

When delegated attributes are given on open, the file is opened with NOCMTIME and modifying operations do not update mtime/ctime as to not get out-of-sync with the client's delegated view. However, for COPY operation, the server should update its view of mtime/ctime and reflect that in any GETATTR queries.

Fixes e5e9b24ab8fa ("nfsd: freeze c/mtime updates with outstanding WRITE_ATTRS delegation")
---
 fs/nfsd/nfs4proc.c | 11 ++++++++++-
 fs/nfsd/xdr4.h     |  1 +
 2 files changed, 11 insertions(+), 1 deletion(-)
fs/nfsd/nfs4proc.c +10 -1
index 5bfe49502a06f4..98086d217aa220 100644
@@ -1956,8 +1956,10 @@ static int nfsd4_do_async_copy(void *data)
 
 	set_bit(NFSD4_COPY_F_COMPLETED, &copy->cp_flags);
 	trace_nfsd_copy_async_done(copy);
-	nfsd4_send_cb_offload(copy);
 	atomic_dec(&copy->cp_nn->pending_async_copies);
+	if (copy->cp_res.wr_bytes_written > 0 && copy->attr_update)
+		nfsd_update_cmtime_attr(copy->nf_dst->nf_file, 0);
+	nfsd4_send_cb_offload(copy);
 	return 0;
 }
 
@@ -2017,6 +2019,9 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 		memcpy(&result->cb_stateid, &copy->cp_stateid.cs_stid,
 			sizeof(result->cb_stateid));
 		dup_copy_fields(copy, async_copy);
+		if ((READ_ONCE(copy->nf_dst->nf_file->f_mode) &
+			       FMODE_NOCMTIME) != 0)
+			async_copy->attr_update = true;
 		memcpy(async_copy->cp_cb_offload.co_referring_sessionid.data,
 		       cstate->session->se_sessionid.data,
 		       NFS4_MAX_SESSIONID_LEN);
@@ -2035,6 +2040,10 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	} else {
 		status = nfsd4_do_copy(copy, copy->nf_src->nf_file,
 				       copy->nf_dst->nf_file, true);
+		if ((READ_ONCE(copy->nf_dst->nf_file->f_mode) &
+			       FMODE_NOCMTIME) != 0 &&
+				copy->cp_res.wr_bytes_written > 0)
+			nfsd_update_cmtime_attr(copy->nf_dst->nf_file, 0);
 	}
 out:
 	trace_nfsd_copy_done(copy, status);
fs/nfsd/xdr4.h +1 -0
index 1ce8e12ae3354c..d0ef5e7f10778f 100644
@@ -745,6 +745,7 @@ struct nfsd4_copy {
 
 	struct nfsd_file        *nf_src;
 	struct nfsd_file        *nf_dst;
+	bool			attr_update;
 
 	copy_stateid_t		cp_stateid;
 
Signature · 1 line
2.53.0
author maintainer
#4 lore raw

PATCH 4/480 nfsd: release layout stid on setlease failure

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chris Mason <[email protected]>

commit 30d55c8aabb261bc3f427d6b9aae7ef6206063f9 upstream.

nfs4_alloc_stid() publishes the new stid into cl->cl_stateids via idr_alloc_cyclic() under cl_lock before returning to nfsd4_alloc_layout_stateid(). When nfsd4_layout_setlease() then fails, the error path frees the layout stateid directly with kmem_cache_free() without ever calling idr_remove(), leaving the IDR slot pointing at freed slab memory. Any subsequent IDR walker (states_show, client teardown) dereferences the dangling pointer.

The correct teardown for an IDR-published stid is nfs4_put_stid(), which removes the IDR slot under cl_lock, dispatches sc_free (nfsd4_free_layout_stateid) to release ls->ls_file via nfsd4_close_layout(), and drops the nfs4_file reference in its tail.

A second issue blocks that switch: nfsd4_free_layout_stateid() unconditionally inspects ls->ls_fence_work via delayed_work_pending() under ls_lock, but INIT_DELAYED_WORK(&ls->ls_fence_work, ...) currently runs only after the setlease call. On the setlease-failure path the destructor would touch an uninitialized delayed_work.

    nfsd4_alloc_layout_stateid()
      nfs4_alloc_stid()           /* idr_alloc_cyclic under cl_lock */
      nfsd4_layout_setlease()     /* fails */
        nfs4_put_stid()
          nfsd4_free_layout_stateid()
            delayed_work_pending(&ls->ls_fence_work)  /* needs INIT */
            nfsd4_close_layout()  /* nfsd_file_put(ls->ls_file) */
          put_nfs4_file()

Fix by hoisting the ls_fenced / ls_fence_delay / INIT_DELAYED_WORK initialization above the nfsd4_layout_setlease() call, and replace the manual nfsd_file_put + put_nfs4_file + kmem_cache_free cleanup with a single nfs4_put_stid(stp).

Fixes c5c707f96fc9 ("nfsd: implement pNFS layout recalls")
Assisted-by kres (claude-opus-4-7)
[ cel: drop fence_work init hoist absent from 6.18.y ]
---
 fs/nfsd/nfs4layouts.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)
fs/nfsd/nfs4layouts.c +1 -3
index 683bd1130afe29..62762e43f810b3 100644
@@ -256,9 +256,7 @@ nfsd4_alloc_layout_stateid(struct nfsd4_compound_state *cstate,
 	BUG_ON(!ls->ls_file);
 
 	if (nfsd4_layout_setlease(ls)) {
-		nfsd_file_put(ls->ls_file);
-		put_nfs4_file(fp);
-		kmem_cache_free(nfs4_layout_stateid_cache, ls);
+		nfs4_put_stid(stp);
 		return NULL;
 	}
 
Signature · 1 line
2.53.0
author maintainer
#5 lore raw

PATCH 5/480 rust: str: use the "kernel vertical" imports style

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Miguel Ojeda <[email protected]>

[ Upstream commit 724a93a9f6033800b02a3530dbcb464638448e7f ]

Convert the imports to use the "kernel vertical" imports style [1].

No functional changes intended.

Stable-dep-of: 3fff4271809b ("rust: str: clean unused import for Rust >= 1.98")

---
 rust/kernel/str.rs | 25 ++++++++++++++++++++-----
 1 file changed, 20 insertions(+), 5 deletions(-)
rust/kernel/str.rs +20 -5
index 8992fedabaf0f7..3a276bc32962d9 100644
@@ -3,14 +3,29 @@
 //! String representations.
 
 use crate::{
-    alloc::{flags::*, AllocError, KVec},
-    error::{to_result, Result},
-    fmt::{self, Write},
-    prelude::*,
+    alloc::{
+        flags::*,
+        AllocError,
+        KVec, //
+    },
+    error::{
+        to_result,
+        Result, //
+    },
+    fmt::{
+        self,
+        Write, //
+    },
+    prelude::*, //
 };
 use core::{
     marker::PhantomData,
-    ops::{self, Deref, DerefMut, Index},
+    ops::{
+        self,
+        Deref,
+        DerefMut,
+        Index, //
+    }, //
 };
 
 /// Byte string without UTF-8 validity guarantee.
Signature · 1 line
2.53.0
author maintainer
#6 lore raw

PATCH 6/480 rust: str: clean unused import for Rust >= 1.98

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Miguel Ojeda <[email protected]>

[ Upstream commit 3fff4271809b57182c4011811e96556bdd4cb2f9 ]

Starting with Rust 1.98.0 (expected 2026-08-20), the compiler has changed how the resolution algorithm works [1] in upstream commit c4d84db5f184 ("Resolver: Batched import resolution."), and it now spots:

    error: unused import: `flags::*`
     --> rust/kernel/str.rs:7:9
      |
    7 |         flags::*,
      |         ^^^^^^^^
      |
      = note: `-D unused-imports` implied by `-D warnings`
      = help: to override `-D warnings` add `#[allow(unused_imports)]`

It happens to not be needed because the prelude::* already provides the flags.

Thus clean it up.

---
 rust/kernel/str.rs | 1 -
 1 file changed, 1 deletion(-)
rust/kernel/str.rs +0 -1
index 3a276bc32962d9..22cefbc9852360 100644
@@ -4,7 +4,6 @@
 
 use crate::{
     alloc::{
-        flags::*,
         AllocError,
         KVec, //
     },
Signature · 1 line
2.53.0
author maintainer
#7 lore raw

PATCH 7/480 userfaultfd: gate must_wait writability check on pte_present()

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Kiryl Shutsemau <[email protected]>

[ Upstream commit 8e80af52db652fbc41320eee45a4f73bc029faf2 ]

userfaultfd_must_wait() and userfaultfd_huge_must_wait() read the PTE without taking the page table lock and then apply pte_write() / huge_pte_write() to it. Those accessors decode bits from the present encoding only; on a swap or migration entry they read the offset bits that happen to share the same position and return an undefined result.

The intent of the check is "is this fault still WP-blocked?". A non-marker swap entry means the page is in transit -- the userfault context the original fault delivered against is no longer the same, and the swap-in or migration completion path will re-deliver a fresh fault if userspace still needs to handle it. Worst case under the current code the garbage write bit says "wait", and the thread stays asleep until a UFFDIO_WAKE that may never arrive.

Gate the writability check on pte_present() so the lockless re-check only inspects present-PTE bits when the entry is actually present. The non-present, non-marker case returns "don't wait" and lets the fault path retry.

Fixes 369cd2121be4 ("userfaultfd: hugetlbfs: userfaultfd_huge_must_wait for hugepmd ranges")
Fixes 63b2d4174c4a ("userfaultfd: wp: add the writeprotect API to userfaultfd ioctl")
Cc David Hildenbrand <[email protected]>
Cc Michal Hocko <[email protected]>
Cc Mike Rapoport <[email protected]>
Cc Peter Xu <[email protected]>
Cc Suren Baghdasaryan <[email protected]>
Cc Vlastimil Babka <[email protected]>
Cc Balbir Singh <[email protected]>

[ kas: apply to fs/userfaultfd.c and fold the pte_present()/
huge_pte_present() gate into the existing writability checks; this tree predates the marker/return-style refactor of these functions ]

---
 fs/userfaultfd.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)
fs/userfaultfd.c +12 -2
index a67afdbbf77af1..7e40eb9131bd70 100644
@@ -251,7 +251,12 @@ static inline bool userfaultfd_huge_must_wait(struct userfaultfd_ctx *ctx,
 	 */
 	if (huge_pte_none_mostly(pte))
 		ret = true;
-	if (!huge_pte_write(pte) && (reason & VM_UFFD_WP))
+	/*
+	 * Gate the writability check on pte_present(): huge_pte_write() on a
+	 * non-present migration entry decodes random offset bits. The
+	 * migration completion path re-delivers the fault if still needed.
+	 */
+	if (pte_present(pte) && !huge_pte_write(pte) && (reason & VM_UFFD_WP))
 		ret = true;
 out:
 	return ret;
@@ -326,7 +331,12 @@ static inline bool userfaultfd_must_wait(struct userfaultfd_ctx *ctx,
 	ptent = ptep_get(pte);
 	if (pte_none_mostly(ptent))
 		ret = true;
-	if (!pte_write(ptent) && (reason & VM_UFFD_WP))
+	/*
+	 * Gate the writability check on pte_present(): pte_write() on a
+	 * non-present swap/migration entry decodes random offset bits. The
+	 * page-in path re-delivers the fault if it still needs userspace.
+	 */
+	if (pte_present(ptent) && !pte_write(ptent) && (reason & VM_UFFD_WP))
 		ret = true;
 	pte_unmap(pte);
 
Signature · 1 line
2.53.0
author maintainer
#8 lore raw

PATCH 8/480 device property: initialize the remaining fields of fwnode_handle in fwnode_init()

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Bartosz Golaszewski <[email protected]>

[ Upstream commit 7eba000621fff223dd7bab484d48918c7c77a307 ]

If a firmware node is allocated on the stack (for instance: temporary software node whose life-time we control) or on the heap - but using a non-zeroing allocation function - and initialized using fwnode_init(), its secondary pointer will contain uninitialized memory which likely will be neither NULL nor IS_ERR() and so may end up being dereferenced (for example: in dev_to_swnode()). Set fwnode->secondary to NULL on initialization. While at it: initialize the remaining fields of struct fwnode_handle too just to be sure.

---
 include/linux/fwnode.h |    2 ++
 1 file changed, 2 insertions(+)
include/linux/fwnode.h +2 -0
@@ -210,8 +210,10 @@ static inline void fwnode_init(struct fw
 {
 	fwnode->secondary = NULL;
 	fwnode->ops = ops;
+	fwnode->dev = NULL;
 	INIT_LIST_HEAD(&fwnode->consumers);
 	INIT_LIST_HEAD(&fwnode->suppliers);
+	fwnode->flags = 0;
 }
 
 static inline void fwnode_set_flag(struct fwnode_handle *fwnode,
author maintainer
#9 lore raw

PATCH 9/480 f2fs: remove non-uptodate folio from the page cache in move_data_block

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Yongpeng Yang <[email protected]>

[ Upstream commit 9609dd704725a40cd63d915f2ab6c44248a44598 ]

During data movement, move_data_block acquires file folio without triggering a file read. Such folio are typically not uptodate, they need to be removed from the page cache after gc complete. This patch marks folio with the PG_dropbehind flag and uses folio_end_dropbehind to remove folio from the page cache.

Stable-dep-of: e0288584baa5 ("f2fs: atomic: fix UAF issue on f2fs_inode_info.atomic_inode")

---
 fs/f2fs/gc.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
fs/f2fs/gc.c +5 -1
@@ -1456,7 +1456,11 @@ up_out:
 put_out:
 	f2fs_put_dnode(&dn);
 out:
-	f2fs_folio_put(folio, true);
+	if (!folio_test_uptodate(folio))
+		__folio_set_dropbehind(folio);
+	folio_unlock(folio);
+	folio_end_dropbehind(folio);
+	folio_put(folio);
 	return err;
 }
 
author maintainer
#10 lore raw

PATCH 10/480 f2fs: atomic: fix UAF issue on f2fs_inode_info.atomic_inode

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chao Yu <[email protected]>

[ Upstream commit e0288584baa5dc41df4a829a023c4c1b33fe53d7 ]

- ioctl(F2FS_IOC_GARBAGE_COLLECT_RANGE) - shrink
- f2fs_gc
- gc_data_segment
- ra_data_block(cow_inode)
- mapping = F2FS_I(inode)->atomic_inode->i_mapping
: f2fs_is_cow_file(cow_inode) is true
- f2fs_evict_inode(atomic_inode)
- clear_inode_flag(fi->cow_inode, FI_COW_FILE)
- F2FS_I(fi->cow_inode)->atomic_inode = NULL
...
- truncate_inode_pages_final(atomic_inode)
- f2fs_grab_cache_folio(mapping)
: create folio in atomic_inode->mapping
- clear_inode(atomic_inode)
- BUG_ON(atomic_inode->i_data.nrpages)

We need to add a reference on fi->atomic_inode before using its mapping field during garbage collection, otherwise, it will cause UAF issue.

Cc Daeho Jeong <[email protected]>
Cc Sunmin Jeong <[email protected]>
Fixes 3db1de0e582c ("f2fs: change the current atomic write way")
Fixes f18d00769336 ("f2fs: use meta inode for GC of COW file")
---
 fs/f2fs/gc.c    |   50 ++++++++++++++++++++++++++++++++++++++++++--------
 fs/f2fs/inode.c |   11 ++++++++---
 2 files changed, 50 insertions(+), 11 deletions(-)
fs/f2fs/gc.c +42 -8
@@ -1208,8 +1208,8 @@ static bool is_alive(struct f2fs_sb_info
 static int ra_data_block(struct inode *inode, pgoff_t index)
 {
 	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
-	struct address_space *mapping = f2fs_is_cow_file(inode) ?
-				F2FS_I(inode)->atomic_inode->i_mapping : inode->i_mapping;
+	struct address_space *mapping = inode->i_mapping;
+	struct inode *atomic_inode = NULL;
 	struct dnode_of_data dn;
 	struct folio *folio, *efolio;
 	struct f2fs_io_info fio = {
@@ -1224,9 +1224,22 @@ static int ra_data_block(struct inode *i
 	};
 	int err = 0;
 
+	f2fs_down_read(&F2FS_I(inode)->i_sem);
+	if (f2fs_is_cow_file(inode)) {
+		atomic_inode = igrab(F2FS_I(inode)->atomic_inode);
+		if (!atomic_inode) {
+			f2fs_up_read(&F2FS_I(inode)->i_sem);
+			return -EBUSY;
+		}
+		mapping = atomic_inode->i_mapping;
+	}
+	f2fs_up_read(&F2FS_I(inode)->i_sem);
+
 	folio = f2fs_grab_cache_folio(mapping, index, true);
-	if (IS_ERR(folio))
-		return PTR_ERR(folio);
+	if (IS_ERR(folio)) {
+		err = PTR_ERR(folio);
+		goto out_iput;
+	}
 
 	if (f2fs_lookup_read_extent_cache_block(inode, index,
 						&dn.data_blkaddr)) {
@@ -1287,11 +1300,16 @@ got_it:
 	f2fs_update_iostat(sbi, inode, FS_DATA_READ_IO, F2FS_BLKSIZE);
 	f2fs_update_iostat(sbi, NULL, FS_GDATA_READ_IO, F2FS_BLKSIZE);
 
+	if (atomic_inode)
+		iput(atomic_inode);
 	return 0;
 put_encrypted_page:
 	f2fs_put_page(fio.encrypted_page, 1);
 put_folio:
 	f2fs_folio_put(folio, true);
+out_iput:
+	if (atomic_inode)
+		iput(atomic_inode);
 	return err;
 }
 
@@ -1302,8 +1320,8 @@ put_folio:
 static int move_data_block(struct inode *inode, block_t bidx,
 				int gc_type, unsigned int segno, int off)
 {
-	struct address_space *mapping = f2fs_is_cow_file(inode) ?
-				F2FS_I(inode)->atomic_inode->i_mapping : inode->i_mapping;
+	struct address_space *mapping = inode->i_mapping;
+	struct inode *atomic_inode = NULL;
 	struct f2fs_io_info fio = {
 		.sbi = F2FS_I_SB(inode),
 		.ino = inode->i_ino,
@@ -1325,10 +1343,23 @@ static int move_data_block(struct inode
 				(fio.sbi->gc_mode != GC_URGENT_HIGH) ?
 				CURSEG_ALL_DATA_ATGC : CURSEG_COLD_DATA;
 
+	f2fs_down_read(&F2FS_I(inode)->i_sem);
+	if (f2fs_is_cow_file(inode)) {
+		atomic_inode = igrab(F2FS_I(inode)->atomic_inode);
+		if (!atomic_inode) {
+			f2fs_up_read(&F2FS_I(inode)->i_sem);
+			return -EBUSY;
+		}
+		mapping = atomic_inode->i_mapping;
+	}
+	f2fs_up_read(&F2FS_I(inode)->i_sem);
+
 	/* do not read out */
 	folio = f2fs_grab_cache_folio(mapping, bidx, false);
-	if (IS_ERR(folio))
-		return PTR_ERR(folio);
+	if (IS_ERR(folio)) {
+		err = PTR_ERR(folio);
+		goto out_iput;
+	}
 
 	if (!check_valid_map(F2FS_I_SB(inode), segno, off)) {
 		err = -ENOENT;
@@ -1461,6 +1492,9 @@ out:
 	folio_unlock(folio);
 	folio_end_dropbehind(folio);
 	folio_put(folio);
+out_iput:
+	if (atomic_inode)
+		iput(atomic_inode);
 	return err;
 }
 
fs/f2fs/inode.c +8 -3
@@ -853,10 +853,15 @@ void f2fs_evict_inode(struct inode *inod
 	f2fs_abort_atomic_write(inode, true);
 
 	if (fi->cow_inode && f2fs_is_cow_file(fi->cow_inode)) {
-		clear_inode_flag(fi->cow_inode, FI_COW_FILE);
-		F2FS_I(fi->cow_inode)->atomic_inode = NULL;
-		iput(fi->cow_inode);
+		struct inode *cow_inode = fi->cow_inode;
+
+		f2fs_down_write(&F2FS_I(cow_inode)->i_sem);
+		clear_inode_flag(cow_inode, FI_COW_FILE);
+		F2FS_I(cow_inode)->atomic_inode = NULL;
 		fi->cow_inode = NULL;
+		f2fs_up_write(&F2FS_I(cow_inode)->i_sem);
+
+		iput(cow_inode);
 	}
 
 	trace_f2fs_evict_inode(inode);
author maintainer
#11 lore raw

PATCH 11/480 f2fs: bound i_inline_xattr_size for non-inline-xattr inodes

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Bryam Vargas <[email protected]>

[ Upstream commit 378acf3cf19b6af6cba55e8dd1154c4e1504bae8 ]

When the flexible_inline_xattr feature is enabled, do_read_inode() loads the on-disk i_inline_xattr_size unconditionally:

	if (f2fs_sb_has_flexible_inline_xattr(sbi))
		fi->i_inline_xattr_size = le16_to_cpu(ri->i_inline_xattr_size);

but sanity_check_inode() only range-checks it when the inode also has the FI_INLINE_XATTR flag set. An inode that carries an inline dentry or inline data but not FI_INLINE_XATTR -- the normal layout for an inline directory -- therefore keeps a fully attacker-controlled i_inline_xattr_size from a crafted image.

get_inline_xattr_addrs() returns that value with no flag gating, so it feeds the inode geometry:

MAX_INLINE_DATA() = 4 * (CUR_ADDRS_PER_INODE - i_inline_xattr_size - 1) NR_INLINE_DENTRY() = MAX_INLINE_DATA() * BITS_PER_BYTE / (...)
addrs_per_page() = CUR_ADDRS_PER_INODE - i_inline_xattr_size

A large i_inline_xattr_size drives MAX_INLINE_DATA() and NR_INLINE_DENTRY() negative, so make_dentry_ptr_inline() sets d->max (int) to a negative value. The inline directory walk then compares an unsigned long bit_pos against that negative d->max, which is promoted to a huge unsigned bound, and reads far past the inline area:

	while (bit_pos < d->max)		/* fs/f2fs/dir.c */
		... test_bit_le(bit_pos, d->bitmap) / d->dentry[bit_pos] ...

Mounting a crafted image and reading such a directory triggers an out-of-bounds read in f2fs_fill_dentries(); the same underflow also corrupts ADDRS_PER_INODE for regular files.

Validate i_inline_xattr_size against MAX_INLINE_XATTR_SIZE whenever the flexible_inline_xattr feature is enabled -- i.e. whenever the value is loaded from disk and consumed -- and keep the lower MIN_INLINE_XATTR_SIZE bound gated on inodes that actually carry an inline xattr, so legitimate inodes with i_inline_xattr_size == 0 are still accepted.

Fixes 6afc662e68b5 ("f2fs: support flexible inline xattr size")
---
 fs/f2fs/inode.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
fs/f2fs/inode.c +3 -3
@@ -318,9 +318,9 @@ static bool sanity_check_inode(struct in
 	}
 
 	if (f2fs_sb_has_flexible_inline_xattr(sbi) &&
-		f2fs_has_inline_xattr(inode) &&
-		(fi->i_inline_xattr_size < MIN_INLINE_XATTR_SIZE ||
-		fi->i_inline_xattr_size > MAX_INLINE_XATTR_SIZE)) {
+		(fi->i_inline_xattr_size > MAX_INLINE_XATTR_SIZE ||
+		(f2fs_has_inline_xattr(inode) &&
+		fi->i_inline_xattr_size < MIN_INLINE_XATTR_SIZE))) {
 		f2fs_warn(sbi, "%s: inode (ino=%lx) has corrupted i_inline_xattr_size: %d, min: %zu, max: %lu",
 			  __func__, inode->i_ino, fi->i_inline_xattr_size,
 			  MIN_INLINE_XATTR_SIZE, MAX_INLINE_XATTR_SIZE);
author maintainer
#12 lore raw

PATCH 12/480 f2fs: fix potential deadlock in f2fs_balance_fs()

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Ruipeng Qi <[email protected]>

[ Upstream commit dd3114870771562036fdcf5abe813956f36d224d ]

When the f2fs filesystem space is nearly exhausted, we encounter deadlock issues as below:

INFO: task A:1890 blocked for more than 120 seconds.
      Tainted: G           O       6.12.41-g3fe07ddf05ab #1
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
task:A    state:D stack:0     pid:1890  tgid:1626  ppid:1153   flags:0x00000204
Call trace:
 __switch_to+0xf4/0x158
 __schedule+0x27c/0x908
 schedule+0x3c/0x118
 io_schedule+0x44/0x68
 folio_wait_bit_common+0x174/0x370
 folio_wait_bit+0x20/0x38
 folio_wait_writeback+0x54/0xc8
 truncate_inode_partial_folio+0x70/0x1e0
 truncate_inode_pages_range+0x1b0/0x450
 truncate_pagecache+0x54/0x88
 f2fs_file_write_iter+0x3e8/0xb80
 do_iter_readv_writev+0xf0/0x1e0
 vfs_writev+0x138/0x2c8
 do_writev+0x88/0x130
 __arm64_sys_writev+0x28/0x40
 invoke_syscall+0x50/0x120
 el0_svc_common.constprop.0+0xc8/0xf0
 do_el0_svc+0x24/0x38
 el0_svc+0x30/0xf8
 el0t_64_sync_handler+0x120/0x130
 el0t_64_sync+0x190/0x198

INFO: task kworker/u8:11:2680853 blocked for more than 120 seconds.
      Tainted: G           O       6.12.41-g3fe07ddf05ab #1
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
task:kworker/u8:11   state:D stack:0     pid:2680853 tgid:2680853 ppid:2      flags:0x00000208
Workqueue: writeback wb_workfn (flush-254:0)
Call trace:
 __switch_to+0xf4/0x158
 __schedule+0x27c/0x908
 schedule+0x3c/0x118
 io_schedule+0x44/0x68
 folio_wait_bit_common+0x174/0x370
 __filemap_get_folio+0x214/0x348
 pagecache_get_page+0x20/0x70
 f2fs_get_read_data_page+0x150/0x3e8
 f2fs_get_lock_data_page+0x2c/0x160
 move_data_page+0x50/0x478
 do_garbage_collect+0xd38/0x1528
 f2fs_gc+0x240/0x7e0
 f2fs_balance_fs+0x1a0/0x208
 f2fs_write_single_data_page+0x6e4/0x730
 f2fs_write_cache_pages+0x378/0x9b0
 f2fs_write_data_pages+0x2e4/0x388
 do_writepages+0x8c/0x2c8
 __writeback_single_inode+0x4c/0x498
 writeback_sb_inodes+0x234/0x4a8
 __writeback_inodes_wb+0x58/0x118
 wb_writeback+0x2f8/0x3c0
 wb_workfn+0x2c4/0x508
 process_one_work+0x180/0x408
 worker_thread+0x258/0x368
 kthread+0x118/0x128
 ret_from_fork+0x10/0x200

INFO: task kworker/u8:8:2641297 blocked for more than 120 seconds.
      Tainted: G           O       6.12.41-g3fe07ddf05ab #1
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
task:kworker/u8:8    state:D stack:0     pid:2641297 tgid:2641297 ppid:2      flags:0x00000208
Workqueue: writeback wb_workfn (flush-254:0)
Call trace:
 __switch_to+0xf4/0x158
 __schedule+0x27c/0x908
 rt_mutex_schedule+0x30/0x60
 __rt_mutex_slowlock_locked.constprop.0+0x460/0x8a8
 rwbase_write_lock+0x24c/0x378
 down_write+0x1c/0x30
 f2fs_balance_fs+0x184/0x208
 f2fs_write_inode+0xf4/0x328
 __writeback_single_inode+0x370/0x498
 writeback_sb_inodes+0x234/0x4a8
 __writeback_inodes_wb+0x58/0x118
 wb_writeback+0x2f8/0x3c0
 wb_workfn+0x2c4/0x508
 process_one_work+0x180/0x408
 worker_thread+0x258/0x368
 kthread+0x118/0x128
 ret_from_fork+0x10/0x20

INFO: task B:1902 blocked for more than 120 seconds.
      Tainted: G           O       6.12.41-g3fe07ddf05ab #1
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
task:B     state:D stack:0     pid:1902  tgid:1626  ppid:1153   flags:0x0000020c
Call trace:
 __switch_to+0xf4/0x158
 __schedule+0x27c/0x908
 rt_mutex_schedule+0x30/0x60
 __rt_mutex_slowlock_locked.constprop.0+0x460/0x8a8
 rwbase_write_lock+0x24c/0x378
 down_write+0x1c/0x30
 f2fs_balance_fs+0x184/0x208
 f2fs_map_blocks+0x94c/0x1110
 f2fs_file_write_iter+0x228/0xb80
 do_iter_readv_writev+0xf0/0x1e0
 vfs_writev+0x138/0x2c8
 do_writev+0x88/0x130
 __arm64_sys_writev+0x28/0x40
 invoke_syscall+0x50/0x120
 el0_svc_common.constprop.0+0xc8/0xf0
 do_el0_svc+0x24/0x38
 el0_svc+0x30/0xf8
 el0t_64_sync_handler+0x120/0x130
 el0t_64_sync+0x190/0x198

INFO: task sync:2769849 blocked for more than 120 seconds.
      Tainted: G           O       6.12.41-g3fe07ddf05ab #1
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
task:sync            state:D stack:0     pid:2769849 tgid:2769849 ppid:736    flags:0x0000020c
Call trace:
 __switch_to+0xf4/0x158
 __schedule+0x27c/0x908
 schedule+0x3c/0x118
 wb_wait_for_completion+0xb0/0xe8
 sync_inodes_sb+0xc8/0x2b0
 sync_inodes_one_sb+0x24/0x38
 iterate_supers+0xa8/0x138
 ksys_sync+0x54/0xc8
 __arm64_sys_sync+0x18/0x30
 invoke_syscall+0x50/0x120
 el0_svc_common.constprop.0+0xc8/0xf0
 do_el0_svc+0x24/0x38
 el0_svc+0x30/0xf8
 el0t_64_sync_handler+0x120/0x130
 el0t_64_sync+0x190/0x198

The root cause is a potential deadlock between the following tasks:

kworker/u8:11 Thread A
- f2fs_write_single_data_page
- f2fs_do_write_data_page
- folio_start_writeback(X)
- f2fs_outplace_write_data
- bio_add_folio(X)
- folio_unlock(X)
- truncate_inode_pages_range
- __filemap_get_folio(X, FGP_LOCK)
- truncate_inode_partial_folio(X)
- folio_wait_writeback(X)
- f2fs_balance_fs
- f2fs_gc
- do_garbage_collect
- move_data_page
- f2fs_get_lock_data_page
- __filemap_get_folio(X, FGP_LOCK)

Both threads try to access folio X. Thread A holds the lock but waits for writeback, while kworker waits for the lock. This causes a deadlock.

Other threads also enter D state, waiting for locks such as gc_lock and writepages.

OPU/IPU DATA folio are all affected by this issue. To avoid such potential deadlocks, always commit these cached folios before triggering f2fs_gc() in f2fs_balance_fs().

Stable-dep-of: 8b4468ec023d ("f2fs: fix potential deadlock in gc_merge path of f2fs_balance_fs()")

---
 fs/f2fs/data.c    |   29 +++++++++++++++++++++++++++++
 fs/f2fs/f2fs.h    |    1 +
 fs/f2fs/segment.c |    8 ++++++++
 3 files changed, 38 insertions(+)
fs/f2fs/data.c +29 -0
@@ -898,6 +898,35 @@ void f2fs_submit_merged_ipu_write(struct
 	}
 }
 
+void f2fs_submit_all_merged_ipu_writes(struct f2fs_sb_info *sbi)
+{
+	struct bio_entry *be, *tmp;
+	struct f2fs_bio_info *io;
+	enum temp_type temp;
+
+	for (temp = HOT; temp < NR_TEMP_TYPE; temp++) {
+		LIST_HEAD(list);
+
+		io = sbi->write_io[DATA] + temp;
+
+		/* A lockless list_empty() check is safe here: any bios from
+		 * other kworkers that we miss will be submitted by those
+		 * kworkers accordingly.
+		 */
+		if (list_empty(&io->bio_list))
+			continue;
+
+		f2fs_down_write(&io->bio_list_lock);
+		list_splice_init(&io->bio_list, &list);
+		f2fs_up_write(&io->bio_list_lock);
+
+		list_for_each_entry_safe(be, tmp, &list, list) {
+			f2fs_submit_write_bio(sbi, be->bio, DATA);
+			del_bio_entry(be);
+		}
+	}
+}
+
 int f2fs_merge_page_bio(struct f2fs_io_info *fio)
 {
 	struct bio *bio = *fio->bio;
fs/f2fs/f2fs.h +1 -0
@@ -4084,6 +4084,7 @@ void f2fs_submit_merged_write_cond(struc
 				nid_t ino, enum page_type type);
 void f2fs_submit_merged_ipu_write(struct f2fs_sb_info *sbi,
 					struct bio **bio, struct folio *folio);
+void f2fs_submit_all_merged_ipu_writes(struct f2fs_sb_info *sbi);
 void f2fs_flush_merged_writes(struct f2fs_sb_info *sbi);
 int f2fs_submit_page_bio(struct f2fs_io_info *fio);
 int f2fs_merge_page_bio(struct f2fs_io_info *fio);
fs/f2fs/segment.c +8 -0
@@ -461,6 +461,14 @@ void f2fs_balance_fs(struct f2fs_sb_info
 			.should_migrate_blocks = false,
 			.err_gc_skipped = false,
 			.nr_free_secs = 1 };
+
+		/*
+		 * Submit all cached OPU/IPU DATA bios before triggering
+		 * foreground GC to avoid potential deadlocks.
+		 */
+		f2fs_submit_merged_write(sbi, DATA);
+		f2fs_submit_all_merged_ipu_writes(sbi);
+
 		f2fs_down_write(&sbi->gc_lock);
 		stat_inc_gc_call_count(sbi, FOREGROUND);
 		f2fs_gc(sbi, &gc_control);
author maintainer
#13 lore raw

PATCH 13/480 f2fs: fix potential deadlock in gc_merge path of f2fs_balance_fs()

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chao Yu <[email protected]>

[ Upstream commit 8b4468ec023d0d1b4669dfb867588997cc03a06b ]

When we mount device w/ gc_merge mount option, we may suffer below potential deadlock:

Kworker GC trehad Truncator
- f2fs_write_cache_pages
- f2fs_write_single_data_page
- f2fs_do_write_data_page
- folio_start_writeback --- set writeback flag on folio
- f2fs_outplace_write_data
: cached folio in internal bio cache
- f2fs_balance_fs
- wake_up(gc_thread)
: wake up gc thread to run foreground GC
- finish_wait(fggc_wq)
: wait on the waitqueue --- wait on GC thread to finish the work
- truncate_inode_pages_range
- __filemap_get_folio(, FGP_LOCK) --- lock folio
- truncate_inode_partial_folio
- folio_wait_writeback --- wait on writeback being cleared
- do_garbage_collect
- move_data_page
- f2fs_get_lock_data_folio
- lock on folio --- blocked on folio's lock

In order to avoid such deadlock, let's call below functions to commit cached bios in GC_MERGE path of f2fs_balance_fs() as the same as we did in NOGC_MERGE path.
- f2fs_submit_merged_write(sbi, DATA);
- f2fs_submit_all_merged_ipu_writes(sbi);

Fixes 351df4b20115 ("f2fs: add segment operations")
Cc Ruipeng Qi <[email protected]>

Reported: Sandeep Dhavale <[email protected]>

---
 fs/f2fs/segment.c |   14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
fs/f2fs/segment.c +7 -7
@@ -443,6 +443,13 @@ void f2fs_balance_fs(struct f2fs_sb_info
 	if (has_enough_free_secs(sbi, 0, 0))
 		return;
 
+	/*
+	 * Submit all cached OPU/IPU DATA bios before triggering
+	 * foreground GC to avoid potential deadlocks.
+	 */
+	f2fs_submit_merged_write(sbi, DATA);
+	f2fs_submit_all_merged_ipu_writes(sbi);
+
 	if (test_opt(sbi, GC_MERGE) && sbi->gc_thread &&
 				sbi->gc_thread->f2fs_gc_task) {
 		DEFINE_WAIT(wait);
@@ -462,13 +469,6 @@ void f2fs_balance_fs(struct f2fs_sb_info
 			.err_gc_skipped = false,
 			.nr_free_secs = 1 };
 
-		/*
-		 * Submit all cached OPU/IPU DATA bios before triggering
-		 * foreground GC to avoid potential deadlocks.
-		 */
-		f2fs_submit_merged_write(sbi, DATA);
-		f2fs_submit_all_merged_ipu_writes(sbi);
-
 		f2fs_down_write(&sbi->gc_lock);
 		stat_inc_gc_call_count(sbi, FOREGROUND);
 		f2fs_gc(sbi, &gc_control);
author maintainer
#14 lore raw

PATCH 14/480 f2fs: fix listxattr handling of corrupted xattr entries

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Keshav Verma <[email protected]>

[ Upstream commit 5ef5bc304f23c3fe255d4936472378dcb74d0e94 ]

Validate the xattr entry before reading its fields in f2fs_listxattr(). Return -EFSCORRUPTED when the entry is outside the valid xattr storage area instead of returning a successful partial result.

Fixes 688078e7f36c ("f2fs: fix to avoid memory leakage in f2fs_listxattr")
---
 fs/f2fs/xattr.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
fs/f2fs/xattr.c +3 -3
@@ -581,8 +581,6 @@ ssize_t f2fs_listxattr(struct dentry *de
 		size_t prefix_len;
 		size_t size;
 
-		prefix = f2fs_xattr_prefix(entry->e_name_index, dentry);
-
 		if ((void *)(entry) + sizeof(__u32) > last_base_addr ||
 			(void *)XATTR_NEXT_ENTRY(entry) > last_base_addr) {
 			f2fs_err(F2FS_I_SB(inode), "list inode (%lu) has corrupted xattr",
@@ -590,9 +588,11 @@ ssize_t f2fs_listxattr(struct dentry *de
 			set_sbi_flag(F2FS_I_SB(inode), SBI_NEED_FSCK);
 			f2fs_handle_error(F2FS_I_SB(inode),
 						ERROR_CORRUPTED_XATTR);
-			break;
+			error = -EFSCORRUPTED;
+			goto cleanup;
 		}
 
+		prefix = f2fs_xattr_prefix(entry->e_name_index, dentry);
 		if (!prefix)
 			continue;
 
author maintainer
#15 lore raw

PATCH 15/480 f2fs: use memalloc_retry_wait() as much as possible

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chao Yu <[email protected]>

[ Upstream commit 30a8496694f1a93328e5d7f19206380346918b5a ]

memalloc_retry_wait() is recommended in memory allocation retry logic, use it as much as possible.

Stable-dep-of: 8712353ed80f ("f2fs: fix to do sanity check on f2fs_get_node_folio_ra()")

---
 fs/f2fs/segment.c |    2 +-
 fs/f2fs/super.c   |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
fs/f2fs/segment.c +1 -1
@@ -234,7 +234,7 @@ retry:
 	err = f2fs_get_dnode_of_data(&dn, index, ALLOC_NODE);
 	if (err) {
 		if (err == -ENOMEM) {
-			f2fs_io_schedule_timeout(DEFAULT_IO_TIMEOUT);
+			memalloc_retry_wait(GFP_NOFS);
 			goto retry;
 		}
 		return err;
fs/f2fs/super.c +1 -1
@@ -3128,7 +3128,7 @@ retry:
 							&folio, &fsdata);
 		if (unlikely(err)) {
 			if (err == -ENOMEM) {
-				f2fs_io_schedule_timeout(DEFAULT_IO_TIMEOUT);
+				memalloc_retry_wait(GFP_NOFS);
 				goto retry;
 			}
 			set_sbi_flag(F2FS_SB(sb), SBI_QUOTA_NEED_REPAIR);
author maintainer
#16 lore raw

PATCH 16/480 f2fs: introduce f2fs_schedule_timeout()

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chao Yu <[email protected]>

[ Upstream commit 76e780d88c771921ea643fb8a6c8d0b08c17cb7b ]

In f2fs retry logic, we will call f2fs_io_schedule_timeout() to sleep as uninterruptible state (waiting for IO) for a while, however, in several paths below, we are not blocked by IO:
- f2fs_write_single_data_page() return -EAGAIN due to racing on cp_rwsem.
- f2fs_flush_device_cache() failed to submit preflush command.
- __issue_discard_cmd_range() sleeps periodically in between two in batch discard submissions.

So, in order to reveal state of task more accurate, let's introduce f2fs_schedule_timeout() and call it in above paths in where we are waiting for non-IO reasons.

Then we can get real reason of uninterruptible sleep for a thread in tracepoint, perfetto, etc.

Stable-dep-of: 8712353ed80f ("f2fs: fix to do sanity check on f2fs_get_node_folio_ra()")

---
 fs/f2fs/checkpoint.c |    4 ++--
 fs/f2fs/compress.c   |    4 ++--
 fs/f2fs/data.c       |    4 ++--
 fs/f2fs/f2fs.h       |   22 +++++++++++++++-------
 fs/f2fs/segment.c    |    4 ++--
 fs/f2fs/super.c      |    2 +-
 6 files changed, 24 insertions(+), 16 deletions(-)
fs/f2fs/checkpoint.c +2 -2
@@ -1330,7 +1330,7 @@ void f2fs_wait_on_all_pages(struct f2fs_
 			f2fs_submit_merged_write(sbi, DATA);
 
 		prepare_to_wait(&sbi->cp_wait, &wait, TASK_UNINTERRUPTIBLE);
-		io_schedule_timeout(DEFAULT_IO_TIMEOUT);
+		io_schedule_timeout(DEFAULT_SCHEDULE_TIMEOUT);
 	}
 	finish_wait(&sbi->cp_wait, &wait);
 }
@@ -1986,7 +1986,7 @@ void f2fs_flush_ckpt_thread(struct f2fs_
 
 	/* Let's wait for the previous dispatched checkpoint. */
 	while (atomic_read(&cprc->queued_ckpt))
-		io_schedule_timeout(DEFAULT_IO_TIMEOUT);
+		io_schedule_timeout(DEFAULT_SCHEDULE_TIMEOUT);
 }
 
 void f2fs_init_ckpt_req_control(struct f2fs_sb_info *sbi)
fs/f2fs/compress.c +2 -2
@@ -1057,7 +1057,7 @@ static void cancel_cluster_writeback(str
 		f2fs_submit_merged_write(F2FS_I_SB(cc->inode), DATA);
 		while (atomic_read(&cic->pending_pages) !=
 					(cc->valid_nr_cpages - submitted + 1))
-			f2fs_io_schedule_timeout(DEFAULT_IO_TIMEOUT);
+			f2fs_io_schedule_timeout(DEFAULT_SCHEDULE_TIMEOUT);
 	}
 
 	/* Cancel writeback and stay locked. */
@@ -1582,7 +1582,7 @@ continue_unlock:
 				 */
 				if (IS_NOQUOTA(cc->inode))
 					goto out;
-				f2fs_io_schedule_timeout(DEFAULT_IO_TIMEOUT);
+				f2fs_schedule_timeout(DEFAULT_SCHEDULE_TIMEOUT);
 				goto retry_write;
 			}
 			goto out;
fs/f2fs/data.c +2 -2
@@ -3214,8 +3214,8 @@ result:
 				} else if (ret == -EAGAIN) {
 					ret = 0;
 					if (wbc->sync_mode == WB_SYNC_ALL) {
-						f2fs_io_schedule_timeout(
-							DEFAULT_IO_TIMEOUT);
+						f2fs_schedule_timeout(
+							DEFAULT_SCHEDULE_TIMEOUT);
 						goto retry_write;
 					}
 					goto next;
fs/f2fs/f2fs.h +15 -7
@@ -665,8 +665,8 @@ enum {
 
 #define DEFAULT_RETRY_IO_COUNT	8	/* maximum retry read IO or flush count */
 
-/* congestion wait timeout value, default: 20ms */
-#define	DEFAULT_IO_TIMEOUT	(msecs_to_jiffies(20))
+/* IO/non-IO congestion wait timeout value, default: 20ms */
+#define	DEFAULT_SCHEDULE_TIMEOUT	(msecs_to_jiffies(20))
 
 /* timeout value injected, default: 1000ms */
 #define DEFAULT_FAULT_TIMEOUT	(msecs_to_jiffies(1000))
@@ -4940,22 +4940,30 @@ static inline bool f2fs_block_unit_disca
 	return F2FS_OPTION(sbi).discard_unit == DISCARD_UNIT_BLOCK;
 }
 
-static inline void f2fs_io_schedule_timeout(long timeout)
+static inline void __f2fs_schedule_timeout(long timeout, bool io)
 {
 	set_current_state(TASK_UNINTERRUPTIBLE);
-	io_schedule_timeout(timeout);
+	if (io)
+		io_schedule_timeout(timeout);
+	else
+		schedule_timeout(timeout);
 }
 
+#define f2fs_io_schedule_timeout(timeout)		\
+			__f2fs_schedule_timeout(timeout, true)
+#define f2fs_schedule_timeout(timeout)			\
+			__f2fs_schedule_timeout(timeout, false)
+
 static inline void f2fs_io_schedule_timeout_killable(long timeout)
 {
 	while (timeout) {
 		if (fatal_signal_pending(current))
 			return;
 		set_current_state(TASK_UNINTERRUPTIBLE);
-		io_schedule_timeout(DEFAULT_IO_TIMEOUT);
-		if (timeout <= DEFAULT_IO_TIMEOUT)
+		io_schedule_timeout(DEFAULT_SCHEDULE_TIMEOUT);
+		if (timeout <= DEFAULT_SCHEDULE_TIMEOUT)
 			return;
-		timeout -= DEFAULT_IO_TIMEOUT;
+		timeout -= DEFAULT_SCHEDULE_TIMEOUT;
 	}
 }
 
fs/f2fs/segment.c +2 -2
@@ -758,7 +758,7 @@ int f2fs_flush_device_cache(struct f2fs_
 		do {
 			ret = __submit_flush_wait(sbi, FDEV(i).bdev);
 			if (ret)
-				f2fs_io_schedule_timeout(DEFAULT_IO_TIMEOUT);
+				f2fs_schedule_timeout(DEFAULT_SCHEDULE_TIMEOUT);
 		} while (ret && --count);
 
 		if (ret) {
@@ -3480,7 +3480,7 @@ next:
 			blk_finish_plug(&plug);
 			mutex_unlock(&dcc->cmd_lock);
 			trimmed += __wait_all_discard_cmd(sbi, NULL);
-			f2fs_io_schedule_timeout(DEFAULT_IO_TIMEOUT);
+			f2fs_schedule_timeout(DEFAULT_SCHEDULE_TIMEOUT);
 			goto next;
 		}
 skip:
fs/f2fs/super.c +1 -1
@@ -2656,7 +2656,7 @@ static int f2fs_enable_checkpoint(struct
 	/* we should flush all the data to keep data consistency */
 	while (get_pages(sbi, F2FS_DIRTY_DATA)) {
 		writeback_inodes_sb_nr(sbi->sb, nr_pages, WB_REASON_SYNC);
-		f2fs_io_schedule_timeout(DEFAULT_IO_TIMEOUT);
+		f2fs_io_schedule_timeout(DEFAULT_SCHEDULE_TIMEOUT);
 
 		if (f2fs_time_over(sbi, ENABLE_TIME))
 			break;
author maintainer
#17 lore raw

PATCH 17/480 f2fs: optimize trace_f2fs_write_checkpoint with enums

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: YH Lin <[email protected]>

[ Upstream commit 8d1cb17aca466b361cca17834b8bb1cf3e3d1818 ]

This patch optimizes the tracepoint by replacing these hardcoded strings with a new enumeration f2fs_cp_phase.

1.Defines enum f2fs_cp_phase with values for each checkpoint phase. 2.Updates trace_f2fs_write_checkpoint to accept a u16 phase argument instead of a string pointer.
3.Uses __print_symbolic in TP_printk to convert the enum values back to their corresponding strings for human-readable trace output.

This change reduces the storage overhead for each trace event by replacing a variable-length string with a 2-byte integer, while maintaining the same readable output in ftrace.

Stable-dep-of: 8712353ed80f ("f2fs: fix to do sanity check on f2fs_get_node_folio_ra()")

---
 fs/f2fs/checkpoint.c        |    6 +++---
 fs/f2fs/f2fs.h              |    6 ++++++
 include/trace/events/f2fs.h |   19 ++++++++++++++-----
 3 files changed, 23 insertions(+), 8 deletions(-)
fs/f2fs/checkpoint.c +3 -3
@@ -1685,7 +1685,7 @@ int f2fs_write_checkpoint(struct f2fs_sb
 		goto out;
 	}
 
-	trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, "start block_ops");
+	trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, CP_PHASE_START_BLOCK_OPS);
 
 	err = block_operations(sbi);
 	if (err)
@@ -1693,7 +1693,7 @@ int f2fs_write_checkpoint(struct f2fs_sb
 
 	stat_cp_time(cpc, CP_TIME_OP_LOCK);
 
-	trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, "finish block_ops");
+	trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, CP_PHASE_FINISH_BLOCK_OPS);
 
 	f2fs_flush_merged_writes(sbi);
 
@@ -1759,7 +1759,7 @@ stop:
 
 	/* update CP_TIME to trigger checkpoint periodically */
 	f2fs_update_time(sbi, CP_TIME);
-	trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, "finish checkpoint");
+	trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, CP_PHASE_FINISH_CHECKPOINT);
 out:
 	if (cpc->reason != CP_RESIZE)
 		f2fs_up_write(&sbi->cp_global_sem);
fs/f2fs/f2fs.h +6 -0
@@ -319,6 +319,12 @@ struct cp_control {
 	struct cp_stats stats;
 };
 
+enum f2fs_cp_phase {
+	CP_PHASE_START_BLOCK_OPS,
+	CP_PHASE_FINISH_BLOCK_OPS,
+	CP_PHASE_FINISH_CHECKPOINT,
+};
+
 /*
  * indicate meta/data type
  */
include/trace/events/f2fs.h +14 -5
@@ -50,6 +50,9 @@ TRACE_DEFINE_ENUM(CP_PAUSE);
 TRACE_DEFINE_ENUM(CP_RESIZE);
 TRACE_DEFINE_ENUM(EX_READ);
 TRACE_DEFINE_ENUM(EX_BLOCK_AGE);
+TRACE_DEFINE_ENUM(CP_PHASE_START_BLOCK_OPS);
+TRACE_DEFINE_ENUM(CP_PHASE_FINISH_BLOCK_OPS);
+TRACE_DEFINE_ENUM(CP_PHASE_FINISH_CHECKPOINT);
 
 #define show_block_type(type)						\
 	__print_symbolic(type,						\
@@ -175,6 +178,12 @@ TRACE_DEFINE_ENUM(EX_BLOCK_AGE);
 #define S_ALL_PERM	(S_ISUID | S_ISGID | S_ISVTX |	\
 			S_IRWXU | S_IRWXG | S_IRWXO)
 
+#define show_cp_phase(phase)					\
+	__print_symbolic(phase,						\
+		{ CP_PHASE_START_BLOCK_OPS,		"start block_ops" },			\
+		{ CP_PHASE_FINISH_BLOCK_OPS,	"finish block_ops" },			\
+		{ CP_PHASE_FINISH_CHECKPOINT,	"finish checkpoint" })
+
 struct f2fs_sb_info;
 struct f2fs_io_info;
 struct extent_info;
@@ -1541,26 +1550,26 @@ TRACE_EVENT(f2fs_readpages,
 
 TRACE_EVENT(f2fs_write_checkpoint,
 
-	TP_PROTO(struct super_block *sb, int reason, const char *msg),
+	TP_PROTO(struct super_block *sb, int reason, u16 phase),
 
-	TP_ARGS(sb, reason, msg),
+	TP_ARGS(sb, reason, phase),
 
 	TP_STRUCT__entry(
 		__field(dev_t,	dev)
 		__field(int,	reason)
-		__string(dest_msg, msg)
+		__field(u16, phase)
 	),
 
 	TP_fast_assign(
 		__entry->dev		= sb->s_dev;
 		__entry->reason		= reason;
-		__assign_str(dest_msg);
+		__entry->phase		= phase;
 	),
 
 	TP_printk("dev = (%d,%d), checkpoint for %s, state = %s",
 		show_dev(__entry->dev),
 		show_cpreason(__entry->reason),
-		__get_str(dest_msg))
+		show_cp_phase(__entry->phase))
 );
 
 DECLARE_EVENT_CLASS(f2fs_discard,
author maintainer
#18 lore raw

PATCH 18/480 f2fs: detect more inconsistent cases in sanity_check_node_footer()

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chao Yu <[email protected]>

[ Upstream commit 93ffb6c28ff180560d2d7313ac106efcd9e012b8 ]

Let's enhance sanity_check_node_footer() to detect more inconsistent cases as below:

Node Type Node Footer Info
=================== =============================
NODE_TYPE_REGULAR inode = true and xnode = true
NODE_TYPE_INODE inode = false or xnode = true
NODE_TYPE_XATTR inode = true or xnode = false
NODE_TYPE_NON_INODE inode = false

Stable-dep-of: 8712353ed80f ("f2fs: fix to do sanity check on f2fs_get_node_folio_ra()")

---
 fs/f2fs/node.c |   15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)
fs/f2fs/node.c +12 -3
@@ -1504,20 +1504,29 @@ int f2fs_sanity_check_node_footer(struct
 					struct folio *folio, pgoff_t nid,
 					enum node_type ntype, bool in_irq)
 {
+	bool is_inode, is_xnode;
+
 	if (unlikely(nid != nid_of_node(folio)))
 		goto out_err;
 
+	is_inode = IS_INODE(folio);
+	is_xnode = f2fs_has_xattr_block(ofs_of_node(folio));
+
 	switch (ntype) {
+	case NODE_TYPE_REGULAR:
+		if (is_inode && is_xnode)
+			goto out_err;
+		break;
 	case NODE_TYPE_INODE:
-		if (!IS_INODE(folio))
+		if (!is_inode || is_xnode)
 			goto out_err;
 		break;
 	case NODE_TYPE_XATTR:
-		if (!f2fs_has_xattr_block(ofs_of_node(folio)))
+		if (is_inode || !is_xnode)
 			goto out_err;
 		break;
 	case NODE_TYPE_NON_INODE:
-		if (IS_INODE(folio))
+		if (is_inode)
 			goto out_err;
 		break;
 	default:
author maintainer
#19 lore raw

PATCH 19/480 f2fs: fix to do sanity check on f2fs_get_node_folio_ra()

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chao Yu <[email protected]>

[ Upstream commit 8712353ed80f87271d732297567dcdbe4b84e8c7 ]

kernel BUG at fs/f2fs/file.c:845!

Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI
CPU: 0 UID: 0 PID: 5336 Comm: syz.0.0 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
RIP: 0010:f2fs_do_truncate_blocks+0x1115/0x1140 fs/f2fs/file.c:845
Code: fc fc 90 0f 0b e8 8b 9d 9a fd 90 0f 0b e8 83 9d 9a fd 48 89 df 48 c7 c6 60 d1 1a 8c e8 54 f1 fc fc 90 0f 0b e8 6c 9d 9a fd 90 <0f> 0b e8 64 9d 9a fd 90 0f 0b 90 e9 93 fd ff ff e8 56 9d 9a fd 90
RSP: 0018:ffffc9000e4474c0 EFLAGS: 00010283
RAX: ffffffff842b1d34 RBX: 0000000000000003 RCX: 0000000000100000
RDX: ffffc9000f03a000 RSI: 0000000000035503 RDI: 0000000000035504
RBP: ffffc9000e447608 R08: ffff8880123b0000 R09: 0000000000000002
R10: 00000000fffffffe R11: 0000000000000002 R12: 0000000000000001
R13: 0000000000000000 R14: 1ffff92001c88ea0 R15: 00000000ffff039c
FS:  00007f7e02ee36c0(0000) GS:ffff88808c887000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007ff0305c4000 CR3: 0000000012d4c000 CR4: 0000000000352ef0
Call Trace:
 <TASK>
 f2fs_truncate_blocks+0x10a/0x300 fs/f2fs/file.c:882
 f2fs_truncate+0x471/0x7c0 fs/f2fs/file.c:940
 f2fs_evict_inode+0xa3f/0x1ac0 fs/f2fs/inode.c:907
 evict+0x61e/0xb10 fs/inode.c:841
 f2fs_fill_super+0x5f43/0x78f0 fs/f2fs/super.c:5224
 get_tree_bdev_flags+0x431/0x4f0 fs/super.c:1694
 vfs_get_tree+0x92/0x2a0 fs/super.c:1754
 fc_mount fs/namespace.c:1193 [inline]
 do_new_mount_fc fs/namespace.c:3758 [inline]
 do_new_mount+0x341/0xd30 fs/namespace.c:3834
 do_mount fs/namespace.c:4167 [inline]
 __do_sys_mount fs/namespace.c:4383 [inline]
 __se_sys_mount+0x31d/0x420 fs/namespace.c:4360
 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
 do_syscall_64+0x15f/0xf80 arch/x86/entry/syscall_64.c:94
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
	count = ADDRS_PER_PAGE(dn.node_folio, inode);

	count -= dn.ofs_in_node;
	f2fs_bug_on(sbi, count < 0);

The fuzz test will trigger above bug_on in f2fs.

The root cause should be: in the corrupted inode, there is a direct node which has the same ino and nid in its footer, so in f2fs_do_truncate_blocks(), after f2fs_get_dnode_of_data() finds such dnode:
1) ADDRS_PER_PAGE(dn.node_folio, inode) will return 923
2) once dn.ofs_in_node points to addr[923, 1017]
Then it will trigger the system panic.

Let's introduce NODE_TYPE_NON_IXNODE to indicate current node should not be an inode or xattr node, and then use it in below path to detect inconsistent node chain in inode mapping table:

- f2fs_do_truncate_blocks
- f2fs_get_dnode_of_data
- f2fs_get_node_folio_ra
- __get_node_folio
- f2fs_sanity_check_node_footer
- case NODE_TYPE_NON_IXNODE -> check whether it is inode|xnode

---
 fs/f2fs/f2fs.h |    1 +
 fs/f2fs/node.c |    6 +++++-
 2 files changed, 6 insertions(+), 1 deletion(-)
fs/f2fs/f2fs.h +1 -0
@@ -1533,6 +1533,7 @@ enum node_type {
 	NODE_TYPE_INODE,
 	NODE_TYPE_XATTR,
 	NODE_TYPE_NON_INODE,
+	NODE_TYPE_NON_IXNODE,	/* non inode and xnode */
 };
 
 
fs/f2fs/node.c +5 -1
@@ -1529,6 +1529,10 @@ int f2fs_sanity_check_node_footer(struct
 		if (is_inode)
 			goto out_err;
 		break;
+	case NODE_TYPE_NON_IXNODE:
+		if (is_inode || is_xnode)
+			goto out_err;
+		break;
 	default:
 		break;
 	}
@@ -1622,7 +1626,7 @@ static struct folio *f2fs_get_node_folio
 	struct f2fs_sb_info *sbi = F2FS_F_SB(parent);
 	nid_t nid = get_nid(parent, start, false);
 
-	return __get_node_folio(sbi, nid, parent, start, NODE_TYPE_REGULAR);
+	return __get_node_folio(sbi, nid, parent, start, NODE_TYPE_NON_IXNODE);
 }
 
 static void flush_inline_data(struct f2fs_sb_info *sbi, nid_t ino)
author maintainer
#20 lore raw

PATCH 20/480 fbdev: fbcon: fix out-of-bounds read in err_out of fbcon_do_set_font()

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mingyu Wang <[email protected]>

[ Upstream commit 8fdc8c2057eea08d40ce2c8eed41ff9e451c65c2 ]

When fbcon_do_set_font() fails (e.g., due to a memory allocation failure inside vc_resize() under heavy memory pressure), it jumps to the err_out label to roll back the console state. However, the current rollback logic forgets to restore the hi_font state, leading to a severe state machine corruption.

Earlier in the function, set_vc_hi_font() might be called to change vc->vc_hi_font_mask and mutate the screen buffer. If vc_resize() subsequently fails, the err_out path restores vc_font.charcount but entirely skips rolling back the vc_hi_font_mask and the screen buffer.

This mismatch leaves the terminal in a desynchronized state. Because vc_hi_font_mask remains set, the VT subsystem will still accept character indices greater than 255 from userspace and write them to the screen buffer. Subsequent rendering calls (e.g., fbcon_putcs()) will then use these inflated indices to access the reverted, 256-character font array, leading to a deterministic out-of-bounds read and potential kernel memory disclosure.

Fix this by adding the missing rollback logic for the hi_font mask and screen buffer in the error path.

Fixes a5a923038d70 ("fbdev: fbcon: Properly revert changes when vc_resize() failed")
[ Adjust context ]
---
 drivers/video/fbdev/core/fbcon.c |    7 +++++++
 1 file changed, 7 insertions(+)
drivers/video/fbdev/core/fbcon.c +7 -0
@@ -2422,6 +2422,7 @@ static int fbcon_do_set_font(struct vc_d
 	struct fbcon_display *p = &fb_display[vc->vc_num];
 	int resize, ret, old_userfont, old_width, old_height, old_charcount;
 	u8 *old_data = vc->vc_font.data;
+	unsigned short old_hi_font_mask = vc->vc_hi_font_mask;
 
 	resize = (w != vc->vc_font.width) || (h != vc->vc_font.height);
 	vc->vc_font.data = (void *)(p->fontdata = data);
@@ -2475,6 +2476,12 @@ err_out:
 	vc->vc_font.height = old_height;
 	vc->vc_font.charcount = old_charcount;
 
+	/* Restore the hi_font state and screen buffer */
+	if (old_hi_font_mask && !vc->vc_hi_font_mask)
+		set_vc_hi_font(vc, true);
+	else if (!old_hi_font_mask && vc->vc_hi_font_mask)
+		set_vc_hi_font(vc, false);
+
 	return ret;
 }
 
author maintainer
#21 lore raw

PATCH 21/480 net/sched: dualpi2: fix GSO backlog accounting

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Xingquan Liu <[email protected]>

commit 05ed733b65ab977dd931e7f7ac0f62fdb81205c2 upstream.

When DualPI2 splits a GSO skb into N segments, it propagates N additional packets to its parent before returning NET_XMIT_SUCCESS. The parent then accounts for the original skb once more, leaving its qlen one larger than the number of packets actually queued.

With QFQ as the parent, after all real packets are dequeued, QFQ still has a non-zero qlen while its in-service aggregate has no active classes. qfq_choose_next_agg() returns NULL and qfq_dequeue() passes the result to qfq_peek_skb(), causing a NULL pointer dereference.

Follow the same pattern used by tbf_segment() and taprio: count only successfully queued segments, propagate the difference between the original skb and those segments, and return NET_XMIT_SUCCESS whenever at least one segment was queued.

---
 net/sched/sch_dualpi2.c |   11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)
net/sched/sch_dualpi2.c +5 -6
@@ -463,7 +463,7 @@ static int dualpi2_qdisc_enqueue(struct
 		if (IS_ERR_OR_NULL(nskb))
 			return qdisc_drop(skb, sch, to_free);
 
-		cnt = 1;
+		cnt = 0;
 		byte_len = 0;
 		orig_len = qdisc_pkt_len(skb);
 		skb_list_walk_safe(nskb, nskb, next) {
@@ -489,16 +489,15 @@ static int dualpi2_qdisc_enqueue(struct
 				byte_len += nskb->len;
 			}
 		}
-		if (cnt > 1) {
+		if (cnt > 0) {
 			/* The caller will add the original skb stats to its
 			 * backlog, compensate this if any nskb is enqueued.
 			 */
-			--cnt;
-			byte_len -= orig_len;
+			qdisc_tree_reduce_backlog(sch, 1 - cnt,
+						  orig_len - byte_len);
 		}
-		qdisc_tree_reduce_backlog(sch, -cnt, -byte_len);
 		consume_skb(skb);
-		return err;
+		return cnt > 0 ? NET_XMIT_SUCCESS : err;
 	}
 	return dualpi2_enqueue_skb(skb, sch, to_free);
 }
author maintainer
#22 lore raw

PATCH 22/480 nfsd: move name lookup out of nfsd4_list_rec_dir()

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: NeilBrown <[email protected]>

[ Upstream commit 89bd77cf436bf25e448817a662ebf76515f22863 ]

nfsd4_list_rec_dir() is called with two different callbacks. One of the callbacks uses vfs_rmdir() to remove the directory. The other doesn't use the dentry at all, just the name.

As only one callback needs the dentry, this patch moves the lookup into that callback. This prepares of changes to how directory operations are locked.

Stable-dep-of: 4552f4e3f2c9 ("nfsd: change nfs4_client_to_reclaim() to allocate data")

---
 fs/nfsd/nfs4recover.c | 54 +++++++++++++++++++++----------------------
 1 file changed, 26 insertions(+), 28 deletions(-)
fs/nfsd/nfs4recover.c +26 -28
index 3ea4b8a8616315..8ab0b26c1f91ab 100644
@@ -237,7 +237,7 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
 	nfs4_reset_creds(original_cred);
 }
 
-typedef int (recdir_func)(struct dentry *, struct dentry *, struct nfsd_net *);
+typedef int (recdir_func)(struct dentry *, char *, struct nfsd_net *);
 
 struct name_list {
 	char name[HEXDIR_LEN];
@@ -291,24 +291,14 @@ nfsd4_list_rec_dir(recdir_func *f, struct nfsd_net *nn)
 	}
 
 	status = iterate_dir(nn->rec_file, &ctx.ctx);
-	inode_lock_nested(d_inode(dir), I_MUTEX_PARENT);
 
 	list_for_each_entry_safe(entry, tmp, &ctx.names, list) {
-		if (!status) {
-			struct dentry *dentry;
-			dentry = lookup_one(&nop_mnt_idmap,
-					    &QSTR(entry->name), dir);
-			if (IS_ERR(dentry)) {
-				status = PTR_ERR(dentry);
-				break;
-			}
-			status = f(dir, dentry, nn);
-			dput(dentry);
-		}
+		if (!status)
+			status = f(dir, entry->name, nn);
+
 		list_del(&entry->list);
 		kfree(entry);
 	}
-	inode_unlock(d_inode(dir));
 	nfs4_reset_creds(original_cred);
 
 	list_for_each_entry_safe(entry, tmp, &ctx.names, list) {
@@ -406,18 +396,19 @@ nfsd4_remove_clid_dir(struct nfs4_client *clp)
 }
 
 static int
-purge_old(struct dentry *parent, struct dentry *child, struct nfsd_net *nn)
+purge_old(struct dentry *parent, char *cname, struct nfsd_net *nn)
 {
 	int status;
+	struct dentry *child;
 	struct xdr_netobj name;
 
-	if (child->d_name.len != HEXDIR_LEN - 1) {
-		printk("%s: illegal name %pd in recovery directory\n",
-				__func__, child);
+	if (strlen(cname) != HEXDIR_LEN - 1) {
+		printk("%s: illegal name %s in recovery directory\n",
+				__func__, cname);
 		/* Keep trying; maybe the others are OK: */
 		return 0;
 	}
-	name.data = kmemdup_nul(child->d_name.name, child->d_name.len, GFP_KERNEL);
+	name.data = kstrdup(cname, GFP_KERNEL);
 	if (!name.data) {
 		dprintk("%s: failed to allocate memory for name.data!\n",
 			__func__);
@@ -427,10 +418,17 @@ purge_old(struct dentry *parent, struct dentry *child, struct nfsd_net *nn)
 	if (nfs4_has_reclaimed_state(name, nn))
 		goto out_free;
 
-	status = vfs_rmdir(&nop_mnt_idmap, d_inode(parent), child);
-	if (status)
-		printk("failed to remove client recovery directory %pd\n",
-				child);
+	inode_lock_nested(d_inode(parent), I_MUTEX_PARENT);
+	child = lookup_one(&nop_mnt_idmap, &QSTR(cname), parent);
+	if (!IS_ERR(child)) {
+		status = vfs_rmdir(&nop_mnt_idmap, d_inode(parent), child);
+		if (status)
+			printk("failed to remove client recovery directory %pd\n",
+			       child);
+		dput(child);
+	}
+	inode_unlock(d_inode(parent));
+
 out_free:
 	kfree(name.data);
 out:
@@ -461,18 +459,18 @@ nfsd4_recdir_purge_old(struct nfsd_net *nn)
 }
 
 static int
-load_recdir(struct dentry *parent, struct dentry *child, struct nfsd_net *nn)
+load_recdir(struct dentry *parent, char *cname, struct nfsd_net *nn)
 {
 	struct xdr_netobj name;
 	struct xdr_netobj princhash = { .len = 0, .data = NULL };
 
-	if (child->d_name.len != HEXDIR_LEN - 1) {
-		printk("%s: illegal name %pd in recovery directory\n",
-				__func__, child);
+	if (strlen(cname) != HEXDIR_LEN - 1) {
+		printk("%s: illegal name %s in recovery directory\n",
+				__func__, cname);
 		/* Keep trying; maybe the others are OK: */
 		return 0;
 	}
-	name.data = kmemdup_nul(child->d_name.name, child->d_name.len, GFP_KERNEL);
+	name.data = kstrdup(cname, GFP_KERNEL);
 	if (!name.data) {
 		dprintk("%s: failed to allocate memory for name.data!\n",
 			__func__);
Signature · 1 line
2.53.0
author maintainer
#23 lore raw

PATCH 23/480 nfsd: change nfs4_client_to_reclaim() to allocate data

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: NeilBrown <[email protected]>

[ Upstream commit 4552f4e3f2c96597914f07b060d5c5db84420ddd ]

The calling convention for nfs4_client_to_reclaim() is clumsy in that the caller needs to free memory if the function fails. It is much cleaner if the function frees its own memory.

This patch changes nfs4_client_to_reclaim() to re-allocate the .data fields to be stored in the newly allocated struct nfs4_client_reclaim, and to free everything on failure.

__cld_pipe_inprogress_downcall() needs to allocate the data anyway to copy it from user-space, so now that data is allocated twice. I think that is a small price to pay for a cleaner interface.

---
 fs/nfsd/nfs4recover.c | 67 +++++++++++++++----------------------------
 fs/nfsd/nfs4state.c   | 22 ++++++++++++--
 2 files changed, 42 insertions(+), 47 deletions(-)
fs/nfsd/nfs4recover.c +23 -44
index 8ab0b26c1f91ab..8c5b5b8a5c880a 100644
@@ -147,24 +147,13 @@ legacy_recdir_name_error(struct nfs4_client *clp, int error)
 
 static void
 __nfsd4_create_reclaim_record_grace(struct nfs4_client *clp,
-		const char *dname, int len, struct nfsd_net *nn)
+				    char *dname, struct nfsd_net *nn)
 {
-	struct xdr_netobj name;
+	struct xdr_netobj name = { .len = strlen(dname), .data = dname };
 	struct xdr_netobj princhash = { .len = 0, .data = NULL };
 	struct nfs4_client_reclaim *crp;
 
-	name.data = kmemdup(dname, len, GFP_KERNEL);
-	if (!name.data) {
-		dprintk("%s: failed to allocate memory for name.data!\n",
-			__func__);
-		return;
-	}
-	name.len = len;
 	crp = nfs4_client_to_reclaim(name, princhash, nn);
-	if (!crp) {
-		kfree(name.data);
-		return;
-	}
 	crp->cr_clp = clp;
 }
 
@@ -223,8 +212,7 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
 	inode_unlock(d_inode(dir));
 	if (status == 0) {
 		if (nn->in_grace)
-			__nfsd4_create_reclaim_record_grace(clp, dname,
-					HEXDIR_LEN, nn);
+			__nfsd4_create_reclaim_record_grace(clp, dname, nn);
 		vfs_fsync(nn->rec_file, 0);
 	} else {
 		printk(KERN_ERR "NFSD: failed to write recovery record"
@@ -461,7 +449,7 @@ nfsd4_recdir_purge_old(struct nfsd_net *nn)
 static int
 load_recdir(struct dentry *parent, char *cname, struct nfsd_net *nn)
 {
-	struct xdr_netobj name;
+	struct xdr_netobj name = { .len = HEXDIR_LEN, .data = cname };
 	struct xdr_netobj princhash = { .len = 0, .data = NULL };
 
 	if (strlen(cname) != HEXDIR_LEN - 1) {
@@ -470,16 +458,7 @@ load_recdir(struct dentry *parent, char *cname, struct nfsd_net *nn)
 		/* Keep trying; maybe the others are OK: */
 		return 0;
 	}
-	name.data = kstrdup(cname, GFP_KERNEL);
-	if (!name.data) {
-		dprintk("%s: failed to allocate memory for name.data!\n",
-			__func__);
-		goto out;
-	}
-	name.len = HEXDIR_LEN;
-	if (!nfs4_client_to_reclaim(name, princhash, nn))
-		kfree(name.data);
-out:
+	nfs4_client_to_reclaim(name, princhash, nn);
 	return 0;
 }
 
@@ -777,6 +756,8 @@ __cld_pipe_inprogress_downcall(const struct cld_msg_v2 __user *cmsg,
 {
 	uint8_t cmd, princhashlen;
 	struct xdr_netobj name, princhash = { .len = 0, .data = NULL };
+	char *namecopy __free(kfree) = NULL;
+	char *princhashcopy __free(kfree) = NULL;
 	uint16_t namelen;
 
 	if (get_user(cmd, &cmsg->cm_cmd)) {
@@ -794,20 +775,20 @@ __cld_pipe_inprogress_downcall(const struct cld_msg_v2 __user *cmsg,
 				dprintk("%s: invalid namelen (%u)", __func__, namelen);
 				return -EINVAL;
 			}
-			name.data = memdup_user(&ci->cc_name.cn_id, namelen);
-			if (IS_ERR(name.data))
-				return PTR_ERR(name.data);
+			namecopy = memdup_user(&ci->cc_name.cn_id, namelen);
+			if (IS_ERR(namecopy))
+				return PTR_ERR(namecopy);
+			name.data = namecopy;
 			name.len = namelen;
 			if (get_user(princhashlen, &ci->cc_princhash.cp_len))
 				return -EFAULT;
 			if (princhashlen > 0) {
-				princhash.data = memdup_user(
-						&ci->cc_princhash.cp_data,
-						princhashlen);
-				if (IS_ERR(princhash.data)) {
-					kfree(name.data);
-					return PTR_ERR(princhash.data);
-				}
+				princhashcopy = memdup_user(
+					&ci->cc_princhash.cp_data,
+					princhashlen);
+				if (IS_ERR(princhashcopy))
+					return PTR_ERR(princhashcopy);
+				princhash.data = princhashcopy;
 				princhash.len = princhashlen;
 			} else
 				princhash.len = 0;
@@ -821,9 +802,10 @@ __cld_pipe_inprogress_downcall(const struct cld_msg_v2 __user *cmsg,
 				dprintk("%s: invalid namelen (%u)", __func__, namelen);
 				return -EINVAL;
 			}
-			name.data = memdup_user(&cnm->cn_id, namelen);
-			if (IS_ERR(name.data))
-				return PTR_ERR(name.data);
+			namecopy = memdup_user(&cnm->cn_id, namelen);
+			if (IS_ERR(namecopy))
+				return PTR_ERR(namecopy);
+			name.data = namecopy;
 			name.len = namelen;
 		}
 #ifdef CONFIG_NFSD_LEGACY_CLIENT_TRACKING
@@ -831,15 +813,12 @@ __cld_pipe_inprogress_downcall(const struct cld_msg_v2 __user *cmsg,
 			struct cld_net *cn = nn->cld_net;
 
 			name.len = name.len - 5;
-			memmove(name.data, name.data + 5, name.len);
+			name.data = name.data + 5;
 			cn->cn_has_legacy = true;
 		}
 #endif
-		if (!nfs4_client_to_reclaim(name, princhash, nn)) {
-			kfree(name.data);
-			kfree(princhash.data);
+		if (!nfs4_client_to_reclaim(name, princhash, nn))
 			return -EFAULT;
-		}
 		return nn->client_tracking_ops->msglen;
 	}
 	return -EFAULT;
fs/nfsd/nfs4state.c +19 -3
index a063a4a83ec22d..a3e6076a3e645e 100644
@@ -8831,9 +8831,6 @@ nfs4_has_reclaimed_state(struct xdr_netobj name, struct nfsd_net *nn)
 
 /*
  * failure => all reset bets are off, nfserr_no_grace...
- *
- * The caller is responsible for freeing name.data if NULL is returned (it
- * will be freed in nfs4_remove_reclaim_record in the normal case).
  */
 struct nfs4_client_reclaim *
 nfs4_client_to_reclaim(struct xdr_netobj name, struct xdr_netobj princhash,
@@ -8842,6 +8839,22 @@ nfs4_client_to_reclaim(struct xdr_netobj name, struct xdr_netobj princhash,
 	unsigned int strhashval;
 	struct nfs4_client_reclaim *crp;
 
+	name.data = kmemdup(name.data, name.len, GFP_KERNEL);
+	if (!name.data) {
+		dprintk("%s: failed to allocate memory for name.data!\n",
+			__func__);
+		return NULL;
+	}
+	if (princhash.len) {
+		princhash.data = kmemdup(princhash.data, princhash.len, GFP_KERNEL);
+		if (!princhash.data) {
+			dprintk("%s: failed to allocate memory for princhash.data!\n",
+				__func__);
+			kfree(name.data);
+			return NULL;
+		}
+	} else
+		princhash.data = NULL;
 	crp = alloc_reclaim();
 	if (crp) {
 		strhashval = clientstr_hashval(name);
@@ -8853,6 +8866,9 @@ nfs4_client_to_reclaim(struct xdr_netobj name, struct xdr_netobj princhash,
 		crp->cr_princhash.len = princhash.len;
 		crp->cr_clp = NULL;
 		nn->reclaim_str_hashtbl_size++;
+	} else {
+		kfree(name.data);
+		kfree(princhash.data);
 	}
 	return crp;
 }
Signature · 1 line
2.53.0
author maintainer
#24 lore raw

PATCH 24/480 mm/khugepaged: write all dirty file folios when collapsing

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Pedro Falcato <[email protected]>

[There is no upstream commit, as this code was removed by upstream
commit 044925f9b565 ("mm: fs: remove filemap_nr_thps*() functions and their users")]

As-is, khugepaged and writable-file opening exclude each other. A file cannot be open writeable and have THPs (because the filesystem is not aware of them). khugepaged will never collapse file pages for files that are opened writeable. On an open(O_RDWR/O_WRONLY), the page cache for that particular file is dropped. This is fine because nothing could've been dirtied.

However, there is an edge-case: collapse_file() might not be able to coexist with concurrent writers, but it can coexist with dirty folios (from previous writers). Therefore, the following can happen:

open(file, O_RDWR)
write(file)
close(file)
madvise(file_mapping, MADV_COLLAPSE, some non-dirty range) open(file, O_RDWR)
nr_thps > 0
truncate_inode_pages()

    /* THPs are cleared out, but so are the dirty folios */

When this edge-case happens, there is data loss, as the dirty folios are fully discarded.

Fix it by fully writing back the page cache (and waiting) when collapsing file THPs. Doing so provides the guarantee that no dirty folio will be observed while there are active THPs. To fully ensure this is safe, the invalidate_lock needs to be held while doing the writeout, so that do_dentry_open()'s page cache truncation excludes this write-and-wait.

As a side effect, move the nr_thps counter bumping outside the i_pages lock. This is correct since the counter itself is an atomic_t and the producer <-> consumer correctness is provided by a full memory barrier:
smp_mb() in collapse_file()/memory barrier implied by full ordering in get_write_access() -> atomic_inc_unless_negative().

---
 mm/khugepaged.c | 39 +++++++++++++++++++++++++--------------
 1 file changed, 25 insertions(+), 14 deletions(-)
mm/khugepaged.c +25 -14
index 3dcd884c844e8f..01a5d443ffc586 100644
@@ -2077,32 +2077,43 @@ static int collapse_file(struct mm_struct *mm, unsigned long addr,
 		goto xa_unlocked;
 	}
 
-	if (!is_shmem) {
+xa_locked:
+	xas_unlock_irq(&xas);
+xa_unlocked:
+
+	/*
+	 * If collapse is successful, flush must be done now before copying.
+	 * If collapse is unsuccessful, does flush actually need to be done?
+	 * Do it anyway, to clear the state.
+	 */
+	try_to_unmap_flush();
+
+	if (result == SCAN_SUCCEED && !is_shmem && !mapping_large_folio_support(mapping)) {
+		/*
+		 * invalidate_lock as shared excludes against concurrent opens
+		 * in do_dentry_open() truncating the page cache. This is
+		 * particularly important if there are dirty folios in transit.
+		 */
+		filemap_invalidate_lock_shared(mapping);
 		filemap_nr_thps_inc(mapping);
 		/*
 		 * Paired with the fence in do_dentry_open() -> get_write_access()
 		 * to ensure i_writecount is up to date and the update to nr_thps
 		 * is visible. Ensures the page cache will be truncated if the
-		 * file is opened writable.
+		 * file is opened writable. If collapse looks to be successful,
+		 * flush any dirty pages out the page cache. With the nr_thps
+		 * incremented, there won't be any new writers (nor new dirties).
 		 */
 		smp_mb();
-		if (inode_is_open_for_write(mapping->host)) {
+		if (inode_is_open_for_write(mapping->host) || filemap_write_and_wait(mapping)) {
 			result = SCAN_FAIL;
 			filemap_nr_thps_dec(mapping);
+			filemap_invalidate_unlock_shared(mapping);
+			goto rollback;
 		}
+		filemap_invalidate_unlock_shared(mapping);
 	}
 
-xa_locked:
-	xas_unlock_irq(&xas);
-xa_unlocked:
-
-	/*
-	 * If collapse is successful, flush must be done now before copying.
-	 * If collapse is unsuccessful, does flush actually need to be done?
-	 * Do it anyway, to clear the state.
-	 */
-	try_to_unmap_flush();
-
 	if (result == SCAN_SUCCEED && nr_none &&
 	    !shmem_charge(mapping->host, nr_none))
 		result = SCAN_FAIL;
Signature · 1 line
2.53.0
author maintainer
#25 lore raw

PATCH 25/480 slab: Introduce kmalloc_flex() and family

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Kees Cook <[email protected]>

commit e4c8b46b924eb8de66c6f0accc9cdd0c2e8fa23b upstream.

As done for kmalloc_obj*(), introduce a type-aware allocator for flexible arrays, which may also have "counted_by" annotations:

	ptr = kmalloc(struct_size(ptr, flex_member, count), gfp);

becomes:

	ptr = kmalloc_flex(*ptr, flex_member, count, gfp);

The internal use of __flex_counter() allows for automatically setting the counter member of a struct's flexible array member when it has been annotated with __counted_by(), avoiding any missed early size initializations while __counted_by() annotations are added to the kernel. Additionally, this also checks for "too large" allocations based on the type size of the counter variable. For example:

	if (count > type_max(ptr->flex_counter))
		fail...;
	size = struct_size(ptr, flex_member, count);
	ptr = kmalloc(size, gfp);
	if (!ptr)
		fail...;
	ptr->flex_counter = count;

becomes (n.b. unchanged from earlier example):

	ptr = kmalloc_flex(*ptr, flex_member, count, gfp);
	if (!ptr)
		fail...;
	ptr->flex_counter = count;

Note that manual initialization of the flexible array counter is still required (at some point) after allocation as not all compiler versions support the __counted_by annotation yet. But doing it internally makes sure they cannot be missed when __counted_by _is_ available, meaning that the bounds checker will not trip due to the lack of "early enough" initializations that used to work before enabling the stricter bounds checking. For example:

	ptr = kmalloc_flex(*ptr, flex_member, count, gfp);
	fill(ptr->flex, count);
	ptr->flex_count = count;

This works correctly before adding a __counted_by annotation (since nothing is checking ptr->flex accesses against ptr->flex_count). After adding the annotation, the bounds sanitizer would trip during fill() because ptr->flex_count wasn't set yet. But with kmalloc_flex() setting ptr->flex_count internally at allocation time, the existing code works without needing to move the ptr->flex_count assignment before the call to fill(). (This has been a stumbling block for __counted_by adoption.)

[Backport-notes: Removed the actual flex counter handling. That's a new
feature, which isn't necessary for just adding the new allocation APIs to get backports to apply cleanly. Also, the allocation-time overflow check in the upstream commit was reverted upstream.]

---
 Documentation/process/deprecated.rst |    7 +++++
 include/linux/slab.h                 |   42 +++++++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+)
Documentation/process/deprecated.rst +7 -0
@@ -387,6 +387,7 @@ allocations. For example, these open cod
 	ptr = kzalloc(sizeof(*ptr), gfp);
 	ptr = kmalloc_array(count, sizeof(*ptr), gfp);
 	ptr = kcalloc(count, sizeof(*ptr), gfp);
+	ptr = kmalloc(struct_size(ptr, flex_member, count), gfp);
 	ptr = kmalloc(sizeof(struct foo, gfp);
 
 become, respectively::
@@ -395,4 +396,10 @@ become, respectively::
 	ptr = kzalloc_obj(*ptr, gfp);
 	ptr = kmalloc_objs(*ptr, count, gfp);
 	ptr = kzalloc_objs(*ptr, count, gfp);
+	ptr = kmalloc_flex(*ptr, flex_member, count, gfp);
 	__auto_type ptr = kmalloc_obj(struct foo, gfp);
+
+If `ptr->flex_member` is annotated with __counted_by(), the allocation
+will automatically fail if `count` is larger than the maximum
+representable value that can be stored in the counter member associated
+with `flex_member`.
include/linux/slab.h +42 -0

71 lines not on this page · raw message

author maintainer
#26 lore raw

PATCH 26/480 add default_gfp() helper macro and use it in the new *alloc_obj() helpers

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Linus Torvalds <[email protected]>

commit e19e1b480ac73c3e62ffebbca1174f0f511f43e7 upstream.

Most simple allocations use GFP_KERNEL, and with the new allocation helpers being introduced, let's just take advantage of that to simplify that default case.

It's a numbers game:

git grep 'alloc_obj(' |
sed 's/.*\(GFP_[_A-Z]*\).*/\1/' |
sort | uniq -c | sort -n | tail

shows that about 90% of all those new allocator instances just use that standard GFP_KERNEL.

Those helpers are already macros, and we can easily just make it be the default case when the gfp argument is missing.

And yes, we could do that for all the legacy interfaces too, but let's keep it to just the new ones at least for now, since those all got converted recently anyway, so this is not any "extra" noise outside of that limited conversion.

And, in fact, I want to do this before doing the -rc1 release, exactly so that we don't get extra merge conflicts.

---
 include/linux/gfp.h  |    4 ++++
 include/linux/slab.h |   48 ++++++++++++++++++++++++------------------------
 2 files changed, 28 insertions(+), 24 deletions(-)
include/linux/gfp.h +4 -0
@@ -13,6 +13,10 @@
 struct vm_area_struct;
 struct mempolicy;
 
+/* Helper macro to avoid gfp flags if they are the default one */
+#define __default_gfp(a,...) a
+#define default_gfp(...) __default_gfp(__VA_ARGS__ __VA_OPT__(,) GFP_KERNEL)
+
 /* Convert GFP flags to their corresponding migrate type */
 #define GFP_MOVABLE_MASK (__GFP_RECLAIMABLE|__GFP_MOVABLE)
 #define GFP_MOVABLE_SHIFT 3
include/linux/slab.h +24 -24

72 lines not on this page · raw message

author maintainer
#27 lore raw

PATCH 27/480 default_gfp(): avoid using the "newfangled" __VA_OPT__ trick

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Linus Torvalds <[email protected]>

commit 551d44200152cb26f75d2ef990aeb6185b7e37fd upstream.

The default_gfp() helper that I added is not wrong, but it turns out that it causes unnecessary headaches for 'sparse' which doesn't support the use of __VA_OPT__ (introduced in C++20 and C23, and supported by gcc and clang for a long time).

We do already use __VA_OPT__ in some other cases in the kernel (drm/xe and btrfs), but it has been fairly limited. Now it triggers for pretty much everything, and sparse ends up not working at all.

We can use the traditional gcc ',##__VA_ARGS__' syntax instead: it may not be the "C standard" way and is slightly less natural in this context, but it is the traditional model for this and avoids the sparse problem.

Fixes e19e1b480ac7 ("add default_gfp() helper macro and use it in the new *alloc_obj() helpers")
---
 include/linux/gfp.h |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
include/linux/gfp.h +2 -2
@@ -14,8 +14,8 @@ struct vm_area_struct;
 struct mempolicy;
 
 /* Helper macro to avoid gfp flags if they are the default one */
-#define __default_gfp(a,...) a
-#define default_gfp(...) __default_gfp(__VA_ARGS__ __VA_OPT__(,) GFP_KERNEL)
+#define __default_gfp(a,b,...) b
+#define default_gfp(...) __default_gfp(,##__VA_ARGS__,GFP_KERNEL)
 
 /* Convert GFP flags to their corresponding migrate type */
 #define GFP_MOVABLE_MASK (__GFP_RECLAIMABLE|__GFP_MOVABLE)
author maintainer
#28 lore raw

PATCH 28/480 slab: recognize @GFP parameter as optional in kernel-doc

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Randy Dunlap <[email protected]>

commit 7b5f5865fb11e60edd03c5e063e2d228b7062317 upstream.

Since the @GFP parameter in kmalloc_obj() etc. is now optional, change the kernel-doc to indicate that it is optional. This avoids kernel-doc warnings:

WARNING: include/linux/slab.h:1101 Excess function parameter 'GFP' description in 'kmalloc_obj'
WARNING: include/linux/slab.h:1113 Excess function parameter 'GFP' description in 'kmalloc_objs'
WARNING: include/linux/slab.h:1128 Excess function parameter 'GFP' description in 'kmalloc_flex'
Fixes e19e1b480ac7 ("add default_gfp() helper macro and use it in the new *alloc_obj() helpers")
---
 include/linux/slab.h |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
include/linux/slab.h +3 -3
@@ -1006,7 +1006,7 @@ void *kmalloc_nolock_noprof(size_t size,
 /**
  * kmalloc_obj - Allocate a single instance of the given type
  * @VAR_OR_TYPE: Variable or type to allocate.
- * @GFP: GFP flags for the allocation.
+ * @...: optional GFP flags for the allocation (GFP_KERNEL when not specified).
  *
  * Returns: newly allocated pointer to a @VAR_OR_TYPE on success, or NULL
  * on failure.
@@ -1018,7 +1018,7 @@ void *kmalloc_nolock_noprof(size_t size,
  * kmalloc_objs - Allocate an array of the given type
  * @VAR_OR_TYPE: Variable or type to allocate an array of.
  * @COUNT: How many elements in the array.
- * @GFP: GFP flags for the allocation.
+ * @...: optional GFP flags for the allocation (GFP_KERNEL when not specified).
  *
  * Returns: newly allocated pointer to array of @VAR_OR_TYPE on success,
  * or NULL on failure.
@@ -1031,7 +1031,7 @@ void *kmalloc_nolock_noprof(size_t size,
  * @VAR_OR_TYPE: Variable or type to allocate (with its flex array).
  * @FAM: The name of the flexible array member of the structure.
  * @COUNT: How many flexible array member elements are desired.
- * @GFP: GFP flags for the allocation.
+ * @...: optional GFP flags for the allocation (GFP_KERNEL when not specified).
  *
  * Returns: newly allocated pointer to @VAR_OR_TYPE on success, NULL on
  * failure. If @FAM has been annotated with __counted_by(), the allocation
author maintainer
#29 lore raw

PATCH 29/480 perf trace beauty fcntl: Fix build with older kernel headers

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Florian Fainelli <[email protected]>

commit 7ee7f48413c42b90230de4a8e40898b757bc8e82 upstream.

Toolchains with older kernel headers that do not include upstream commit c75b1d9421f80f41 ("fs: add fcntl() interface for setting/getting write life time hints") will now fail to build perf due to missing definitions for F_GET_RW_HINT/F_SET_RW_HINT/F_GET_FILE_RW_HINT/F_SET_FILE_RW_HINT.

Provide a fallback definition for these when they are not already defined.

Fixes 9c47f66748381ecb ("perf trace beauty fcntl: Basic 'arg' beautifier")
Cc Adrian Hunter <[email protected]>
Cc Alexander Shishkin <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc James Clark <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Mark Rutland <[email protected]>
Cc Markus Mayer <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Peter Zijlstra <[email protected]>
---
 tools/perf/trace/beauty/fcntl.c |   16 ++++++++++++++++
 1 file changed, 16 insertions(+)
tools/perf/trace/beauty/fcntl.c +16 -0
@@ -9,6 +9,22 @@
 #include <linux/kernel.h>
 #include <linux/fcntl.h>
 
+#ifndef F_GET_RW_HINT
+#define F_GET_RW_HINT		(F_LINUX_SPECIFIC_BASE + 11)
+#endif
+
+#ifndef F_SET_RW_HINT
+#define F_SET_RW_HINT		(F_LINUX_SPECIFIC_BASE + 12)
+#endif
+
+#ifndef F_GET_FILE_RW_HINT
+#define F_GET_FILE_RW_HINT	(F_LINUX_SPECIFIC_BASE + 13)
+#endif
+
+#ifndef F_SET_FILE_RW_HINT
+#define F_SET_FILE_RW_HINT	(F_LINUX_SPECIFIC_BASE + 14)
+#endif
+
 static size_t fcntl__scnprintf_getfd(unsigned long val, char *bf, size_t size, bool show_prefix)
 {
 	return val ? scnprintf(bf, size, "%s", "0") :
author maintainer
#30 lore raw

PATCH 30/480 KVM: x86: Move update_cr8_intercept() to lapic.c

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Sean Christopherson <[email protected]>

[ Upstream Commit c7722e5e1daeeabbd9f969554d52bb7158120b27 ]

Move update_cr8_intercept() to lapic.c so that it's globally visible in anticipation of extracting most of the register-specific code out of x86.c and into a new compilation unit. Opportunistically prefix the helper kvm_lapic_ to make its role/scope more obvious.

No functional change intended.

---
 arch/x86/kvm/lapic.c |   26 ++++++++++++++++++++++++++
 arch/x86/kvm/lapic.h |    1 +
 arch/x86/kvm/x86.c   |   34 +++-------------------------------
 3 files changed, 30 insertions(+), 31 deletions(-)
arch/x86/kvm/lapic.c +26 -0
@@ -2754,6 +2754,32 @@ u64 kvm_lapic_get_cr8(struct kvm_vcpu *v
 	return (tpr & 0xf0) >> 4;
 }
 
+void kvm_lapic_update_cr8_intercept(struct kvm_vcpu *vcpu)
+{
+	int max_irr, tpr;
+
+	if (!kvm_x86_ops.update_cr8_intercept)
+		return;
+
+	if (!lapic_in_kernel(vcpu))
+		return;
+
+	if (vcpu->arch.apic->apicv_active)
+		return;
+
+	if (!vcpu->arch.apic->vapic_addr)
+		max_irr = kvm_lapic_find_highest_irr(vcpu);
+	else
+		max_irr = -1;
+
+	if (max_irr != -1)
+		max_irr >>= 4;
+
+	tpr = kvm_lapic_get_cr8(vcpu);
+
+	kvm_x86_call(update_cr8_intercept)(vcpu, tpr, max_irr);
+}
+
 static void __kvm_apic_set_base(struct kvm_vcpu *vcpu, u64 value)
 {
 	u64 old_value = vcpu->arch.apic_base;
arch/x86/kvm/lapic.h +1 -0
@@ -100,6 +100,7 @@ int kvm_apic_accept_events(struct kvm_vc
 void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event);
 u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu);
 void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8);
+void kvm_lapic_update_cr8_intercept(struct kvm_vcpu *vcpu);
 void kvm_lapic_set_eoi(struct kvm_vcpu *vcpu);
 void kvm_apic_set_version(struct kvm_vcpu *vcpu);
 void kvm_apic_after_set_mcg_cap(struct kvm_vcpu *vcpu);
arch/x86/kvm/x86.c +3 -31
@@ -126,7 +126,6 @@ static u64 __read_mostly efer_reserved_b
 				    KVM_X2APIC_ENABLE_SUPPRESS_EOI_BROADCAST	| \
 				    KVM_X2APIC_DISABLE_SUPPRESS_EOI_BROADCAST)
 
-static void update_cr8_intercept(struct kvm_vcpu *vcpu);
 static void process_nmi(struct kvm_vcpu *vcpu);
 static void __kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags);
 static void store_regs(struct kvm_vcpu *vcpu);
@@ -5357,7 +5356,7 @@ static int kvm_vcpu_ioctl_set_lapic(stru
 	r = kvm_apic_set_state(vcpu, s);
 	if (r)
 		return r;
-	update_cr8_intercept(vcpu);
+	kvm_lapic_update_cr8_intercept(vcpu);
 
 	return 0;
 }
@@ -10565,33 +10564,6 @@ static void post_kvm_run_save(struct kvm
 		kvm_run->flags |= KVM_RUN_X86_GUEST_MODE;
 }
 
-static void update_cr8_intercept(struct kvm_vcpu *vcpu)
-{
-	int max_irr, tpr;
-
-	if (!kvm_x86_ops.update_cr8_intercept)
-		return;
-
-	if (!lapic_in_kernel(vcpu))
-		return;
-
-	if (vcpu->arch.apic->apicv_active)
-		return;
-
-	if (!vcpu->arch.apic->vapic_addr)
-		max_irr = kvm_lapic_find_highest_irr(vcpu);
-	else
-		max_irr = -1;
-
-	if (max_irr != -1)
-		max_irr >>= 4;
-
-	tpr = kvm_lapic_get_cr8(vcpu);
-
-	kvm_x86_call(update_cr8_intercept)(vcpu, tpr, max_irr);
-}
-
-
 int kvm_check_nested_events(struct kvm_vcpu *vcpu)
 {
 	if (kvm_test_request(KVM_REQ_TRIPLE_FAULT, vcpu)) {
@@ -11298,7 +11270,7 @@ static int vcpu_enter_guest(struct kvm_v
 			kvm_x86_call(enable_irq_window)(vcpu);
 
 		if (kvm_lapic_enabled(vcpu)) {
-			update_cr8_intercept(vcpu);
+			kvm_lapic_update_cr8_intercept(vcpu);
 			kvm_lapic_sync_to_vapic(vcpu);
 		}
 	}
@@ -12424,7 +12396,7 @@ static int __set_sregs_common(struct kvm
 	kvm_set_segment(vcpu, &sregs->tr, VCPU_SREG_TR);
 	kvm_set_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR);
 
-	update_cr8_intercept(vcpu);
+	kvm_lapic_update_cr8_intercept(vcpu);
 
 	/* Older userspace won't unhalt the vcpu on reset. */
 	if (kvm_vcpu_is_bsp(vcpu) && kvm_rip_read(vcpu) == 0xfff0 &&
author maintainer
#31 lore raw

PATCH 31/480 KVM: VMX: Grab vmcs12 on CR8 interception update iff vCPU is in guest mode

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Sean Christopherson <[email protected]>

[ Upstream commit 7ef78d71ca713d8c00f7c34ddcf276c808143f77 ]

When updating CR8 intercepts, get vmcs12 if and only if the vCPU is in guest mode so that a future change can have update CR8 intercepts during vCPU creation, without running afoul of get_vmcs12()'s lockdep assertion.

  ------------[ cut here ]------------
  debug_locks && !(lock_is_held(&(&vcpu->mutex)->dep_map) || !refcount_read(&vcpu->kvm->users_count))
  WARNING: arch/x86/kvm/vmx/nested.h:61 at get_vmcs12 arch/x86/kvm/vmx/nested.h:60 [inline], CPU#0: syz.2.19/5879
  WARNING: arch/x86/kvm/vmx/nested.h:61 at vmx_update_cr8_intercept+0x3de/0x4e0 arch/x86/kvm/vmx/vmx.c:6879, CPU#0: syz.2.19/5879
  Modules linked in:
  CPU: 0 UID: 0 PID: 5879 Comm: syz.2.19 Not tainted syzkaller #0 PREEMPT(full)
  Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
  RIP: 0010:get_vmcs12 arch/x86/kvm/vmx/nested.h:60 [inline]
  RIP: 0010:vmx_update_cr8_intercept+0x3de/0x4e0 arch/x86/kvm/vmx/vmx.c:6879
  Call Trace:
   <TASK>
   apic_update_ppr arch/x86/kvm/lapic.c:984 [inline]
   kvm_lapic_reset+0x1c24/0x2980 arch/x86/kvm/lapic.c:3023
   kvm_vcpu_reset+0x44c/0x1bf0 arch/x86/kvm/x86.c:12986
   kvm_arch_vcpu_create+0x746/0x8b0 arch/x86/kvm/x86.c:12847
   kvm_vm_ioctl_create_vcpu+0x428/0x930 virt/kvm/kvm_main.c:4201
   kvm_vm_ioctl+0x893/0xd50 virt/kvm/kvm_main.c:5159
   vfs_ioctl fs/ioctl.c:51 [inline]
   __do_sys_ioctl fs/ioctl.c:597 [inline]
   __se_sys_ioctl+0xfc/0x170 fs/ioctl.c:583
   do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
   do_syscall_64+0x174/0x580 arch/x86/entry/syscall_64.c:94
   entry_SYSCALL_64_after_hwframe+0x77/0x7f
   </TASK>

No functional change intended.

Message-ID: <[email protected]>

---
 arch/x86/kvm/vmx/vmx.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
arch/x86/kvm/vmx/vmx.c +1 -2
@@ -6734,11 +6734,10 @@ static noinstr void vmx_l1d_flush(struct
 
 void vmx_update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr)
 {
-	struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
 	int tpr_threshold;
 
 	if (is_guest_mode(vcpu) &&
-		nested_cpu_has(vmcs12, CPU_BASED_TPR_SHADOW))
+	    nested_cpu_has(get_vmcs12(vcpu), CPU_BASED_TPR_SHADOW))
 		return;
 
 	tpr_threshold = (irr == -1 || tpr < irr) ? 0 : irr;
author maintainer
#32 lore raw

PATCH 32/480 KVM: x86: Unconditionally recompute CR8 intercept on PPR update

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: "Carlos L�pez" <[email protected]>

[ Upstream commit bb365a506b1e6fb050c0fceaad354fe395385ef0 ]

The TPR_THRESHOLD field in the VMCS is used by VMX to induce VM exits when the guest's virtual TPR falls under the specified threshold, allowing KVM to inject previously masked interrupts.

KVM handles these VM exits in handle_tpr_below_threshold(). Commit eb90f3417a0c ("KVM: vmx: speed up TPR below threshold vmexits") optimized this function by calling apic_update_ppr() instead of raising KVM_REQ_EVENT. apic_update_ppr() then raises KVM_REQ_EVENT if there is a pending, deliverable interrupt.

However, if there are no new interrupts pending, apic_update_ppr() does not issue the request. Thus, kvm_lapic_update_cr8_intercept() and vmx_update_cr8_intercept() are not called before VM entry, which results in a high, stale TPR_THRESHOLD. This is problematic due to the following sentence in 28.2.1.1 "VM-Execution Control Fields" in the SDM:

The following check is performed if the “use TPR shadow” VM-execution control is 1 and the “virtualize APIC accesses” and “virtual-interrupt delivery” VM-execution controls are both 0: the value of bits 3:0 of the TPR threshold VM-execution control field should not be greater than the value of bits 7:4 of VTPR.

This error condition is typically not observed when KVM runs on a bare metal system because modern processors support APICv, which enables virtual-interrupt delivery, and which KVM uses when possible. This causes the processor to no longer generate TPR-below-threshold exits and to no longer check TPR_THRESHOLD on entry. However, when running on older platforms, or under nested virtualization on a hypervisor that does not support virtual-interrupt delivery and enforces this check (like Hyper-V) this can cause a VM entry failure with hardware error 0x7, as seen in [1].

Call kvm_lapic_update_cr8_intercept() if apic_update_ppr() does not find a deliverable interrupt (and thus does not raise KVM_REQ_EVENT). Remove calls to kvm_lapic_update_cr8_intercept() on paths that end up in apic_update_ppr(), as they now become redundant. This ensures that any path that updates the guest's PPR also figures out if KVM needs to wait for a TPR change (using TPR_THRESHOLD on VMX or CR8 intercepts on SVM).

Message-ID: <[email protected]>

---
 arch/x86/kvm/lapic.c |    2 ++
 arch/x86/kvm/x86.c   |    5 +----
 2 files changed, 3 insertions(+), 4 deletions(-)
arch/x86/kvm/lapic.c +2 -0
@@ -1001,6 +1001,8 @@ static void apic_update_ppr(struct kvm_l
 	if (__apic_update_ppr(apic, &ppr) &&
 	    apic_has_interrupt_for_ppr(apic, ppr) != -1)
 		kvm_make_request(KVM_REQ_EVENT, apic->vcpu);
+	else
+		kvm_lapic_update_cr8_intercept(apic->vcpu);
 }
 
 void kvm_apic_update_ppr(struct kvm_vcpu *vcpu)
arch/x86/kvm/x86.c +1 -4
@@ -5356,7 +5356,6 @@ static int kvm_vcpu_ioctl_set_lapic(stru
 	r = kvm_apic_set_state(vcpu, s);
 	if (r)
 		return r;
-	kvm_lapic_update_cr8_intercept(vcpu);
 
 	return 0;
 }
@@ -12366,8 +12365,6 @@ static int __set_sregs_common(struct kvm
 	kvm_register_mark_dirty(vcpu, VCPU_EXREG_CR3);
 	kvm_x86_call(post_set_cr3)(vcpu, sregs->cr3);
 
-	kvm_set_cr8(vcpu, sregs->cr8);
-
 	*mmu_reset_needed |= vcpu->arch.efer != sregs->efer;
 	kvm_x86_call(set_efer)(vcpu, sregs->efer);
 
@@ -12396,7 +12393,7 @@ static int __set_sregs_common(struct kvm
 	kvm_set_segment(vcpu, &sregs->tr, VCPU_SREG_TR);
 	kvm_set_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR);
 
-	kvm_lapic_update_cr8_intercept(vcpu);
+	kvm_set_cr8(vcpu, sregs->cr8);
 
 	/* Older userspace won't unhalt the vcpu on reset. */
 	if (kvm_vcpu_is_bsp(vcpu) && kvm_rip_read(vcpu) == 0xfff0 &&
author maintainer
#33 lore raw

PATCH 33/480 ACPI: CPPC: Suppress UBSAN warning caused by field misuse

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jeremy Linton <[email protected]>

commit 1b1acf2dada0cc3931bb2cb9ff8832edfbee46a1 upstream.

The definition of reg->access_width changes depending on the reg->space_id type. Type ACPI_ADR_SPACE_PLATFORM_COMM uses access_width to indicate the PCC region, which can result in a UBSAN if the value is greater than 4.

For example:

 UBSAN: shift-out-of-bounds in drivers/acpi/cppc_acpi.c:1090:9
 shift exponent 32 is too large for 32-bit type 'int'
 CPU: 61 UID: 0 PID: 1220 Comm: (udev-worker) Not tainted 7.0.10-201.fc44.aarch64 #1 PREEMPT(lazy)
 Hardware name: To be filled by O.E.M.
 Call trace:
  ...(trimming)
  ubsan_epilogue+0x10/0x48
  __ubsan_handle_shift_out_of_bounds+0xdc/0x1e0
  cpc_write+0x4d0/0x670
  cppc_set_perf+0x18c/0x490
  cppc_cpufreq_cpu_init+0x1c8/0x380 [cppc_cpufreq]
  ... (trimming)

Lets fix this by validating the region type, as well as whether access_width has a value. Then since we are returning bit_width directly for ACPI_ADR_SPACE_PLATFORM_COMM, drop the code correcting the size.

Fixes 2f4a4d63a193 ("ACPI: CPPC: Use access_width over bit_width for system memory accesses")
Cc All applicable <[email protected]>
---
 drivers/acpi/cppc_acpi.c |   11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/acpi/cppc_acpi.c +7 -4
@@ -185,8 +185,13 @@ show_cppc_data(cppc_get_perf_caps, cppc_
 show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, reference_perf);
 show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, wraparound_time);
 
-/* Check for valid access_width, otherwise, fallback to using bit_width */
-#define GET_BIT_WIDTH(reg) ((reg)->access_width ? (8 << ((reg)->access_width - 1)) : (reg)->bit_width)
+/*
+ * PCC reuses the access_width field as the subspace id, so only decode access
+ * size for non-PCC registers. Otherwise, use the bit_width.
+ */
+#define GET_BIT_WIDTH(reg) (((reg)->access_width &&				\
+			     (reg)->space_id != ACPI_ADR_SPACE_PLATFORM_COMM) ? \
+			    (8 << ((reg)->access_width - 1)) : (reg)->bit_width)
 
 /* Shift and apply the mask for CPC reads/writes */
 #define MASK_VAL_READ(reg, val) (((val) >> (reg)->bit_offset) &				\
@@ -1036,7 +1041,6 @@ static int cpc_read(int cpu, struct cpc_
 		 * by the bit width field; the access size is used to indicate
 		 * the PCC subspace id.
 		 */
-		size = reg->bit_width;
 		vaddr = GET_PCC_VADDR(reg->address, pcc_ss_id);
 	}
 	else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
@@ -1109,7 +1113,6 @@ static int cpc_write(int cpu, struct cpc
 		 * by the bit width field; the access size is used to indicate
 		 * the PCC subspace id.
 		 */
-		size = reg->bit_width;
 		vaddr = GET_PCC_VADDR(reg->address, pcc_ss_id);
 	}
 	else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
author maintainer
#34 lore raw

PATCH 34/480 ACPI: NFIT: core: Fix possible NULL pointer dereference

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Rafael J. Wysocki <[email protected]>

commit 027e128abb82788189d6d45b68e3e8e7329b67be upstream.

After commit 9b311b7313d6 ("ACPI: NFIT: Install Notify() handler before getting NFIT table"), acpi_nfit_probe() installs an ACPI notify handler for the NFIT device before checking the presence of the NFIT table. If that table is not there, 0 is returned without allocating the acpi_desc object and setting the driver data pointer of the NFIT device. If the platform firmware triggers an NFIT_NOTIFY_UC_MEMORY_ERROR notification on the NFIT device at that point, acpi_nfit_uc_error_notify() will dereference a NULL pointer.

Prevent that from occurring by adding an acpi_desc check against NULL to acpi_nfit_uc_error_notify().

Fixes 9b311b7313d6 ("ACPI: NFIT: Install Notify() handler before getting NFIT table")
Cc All applicable <[email protected]>
---
 drivers/acpi/nfit/core.c |    3 +++
 1 file changed, 3 insertions(+)
drivers/acpi/nfit/core.c +3 -0
@@ -3447,6 +3447,9 @@ static void acpi_nfit_uc_error_notify(st
 {
 	struct acpi_nfit_desc *acpi_desc = dev_get_drvdata(dev);
 
+	if (!acpi_desc)
+		return;
+
 	if (acpi_desc->scrub_mode == HW_ERROR_SCRUB_ON)
 		acpi_nfit_ars_rescan(acpi_desc, ARS_REQ_LONG);
 	else
author maintainer
#35 lore raw

PATCH 35/480 platform/x86: intel-hid: Protect ACPI notify handler against recursion

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: HyeongJun An <[email protected]>

commit c085d82613d5618814b84406c8b2d64f1bc305e7 upstream.

Since commit e2ffcda16290 ("ACPI: OSL: Allow Notify () handlers to run on all CPUs") ACPI notify handlers like the intel-hid notify_handler() may run on multiple CPU cores racing with themselves.

On convertibles and detachables (matched by DMI chassis-type 31 and 32 in dmi_auto_add_switch[]) the SW_TABLET_MODE input device is registered lazily from notify_handler() on the first tablet-mode event, via intel_hid_switches_setup(). When two such events race on different CPUs both can pass the !priv->switches check and register the priv->switches input device twice, resulting in a duplicate sysfs entry and a subsequent NULL pointer dereference.

This is the same class of bug fixed by commit e075c3b13a0a ("platform/x86:
intel-vbtn: Protect ACPI notify handler against recursion") for the sibling intel-vbtn driver.

Protect intel-hid notify_handler() from racing with itself with a mutex to fix this.

---
 drivers/platform/x86/intel/hid.c |    9 +++++++++
 1 file changed, 9 insertions(+)
drivers/platform/x86/intel/hid.c +9 -0
@@ -7,11 +7,13 @@
  */
 
 #include <linux/acpi.h>
+#include <linux/cleanup.h>
 #include <linux/dmi.h>
 #include <linux/input.h>
 #include <linux/input/sparse-keymap.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/mutex.h>
 #include <linux/platform_device.h>
 #include <linux/string_choices.h>
 #include <linux/suspend.h>
@@ -224,6 +226,7 @@ static const struct dmi_system_id dmi_au
 };
 
 struct intel_hid_priv {
+	struct mutex mutex; /* Avoid notify_handler() racing with itself */
 	struct input_dev *input_dev;
 	struct input_dev *array;
 	struct input_dev *switches;
@@ -559,6 +562,8 @@ static void notify_handler(acpi_handle h
 	struct key_entry *ke;
 	int err;
 
+	guard(mutex)(&priv->mutex);
+
 	/*
 	 * Some convertible have unreliable VGBS return which could cause incorrect
 	 * SW_TABLET_MODE report, in these cases we enable support when receiving
@@ -714,6 +719,10 @@ static int intel_hid_probe(struct platfo
 		return -ENOMEM;
 	dev_set_drvdata(&device->dev, priv);
 
+	err = devm_mutex_init(&device->dev, &priv->mutex);
+	if (err)
+		return err;
+
 	/* See dual_accel_detect.h for more info on the dual_accel check. */
 	if (enable_sw_tablet_mode == TABLET_SW_AUTO) {
 		if (dmi_check_system(dmi_vgbs_allow_list))
author maintainer
#36 lore raw

PATCH 36/480 LoongArch: Add PIO for early access before ACPI PCI root register

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Huacai Chen <[email protected]>

commit 6061e65f95713b01f4313cda6637dfe3aa5412b4 upstream.

For ACPI system we suppose the ISA/LPC PIO range is registered together with PCI root bridge. But the fact is there may be some early access to the ISA/LPC PIO range before ACPI PCI root register (most of them are due to abnormal BIOS). Unconditionally register the ISA/LPC PIO range usually causes ACPI PCI root register fail because of the address range confliction. So we add a pair of helpers: acpi_add_early_pio() to add PIO for early access, and acpi_remove_early_pio() to remove PIO before PCI root register. Since acpi_remove_early_pio() may be called multiple times, we add an acpi_pio flag to ensure PIO be removed only once.

---
 arch/loongarch/include/asm/acpi.h |    2 ++
 arch/loongarch/kernel/acpi.c      |   28 ++++++++++++++++++++++++++++
 arch/loongarch/kernel/setup.c     |    2 ++
 arch/loongarch/pci/acpi.c         |    2 ++
 4 files changed, 34 insertions(+)
arch/loongarch/include/asm/acpi.h +2 -0
@@ -38,6 +38,8 @@ static inline bool acpi_has_cpu_in_madt(
 extern struct list_head acpi_wakeup_device_list;
 extern struct acpi_madt_core_pic acpi_core_pic[MAX_CORE_PIC];
 
+extern void acpi_add_early_pio(void);
+extern void acpi_remove_early_pio(void);
 extern int __init parse_acpi_topology(void);
 
 static inline u32 get_acpi_id_for_cpu(unsigned int cpu)
arch/loongarch/kernel/acpi.c +28 -0
@@ -16,6 +16,7 @@
 #include <linux/memblock.h>
 #include <linux/of_fdt.h>
 #include <linux/serial_core.h>
+#include <linux/vmalloc.h>
 #include <asm/io.h>
 #include <asm/numa.h>
 #include <asm/loongson.h>
@@ -59,6 +60,33 @@ void __iomem *acpi_os_ioremap(acpi_physi
 		return ioremap_cache(phys, size);
 }
 
+#define PIO_BASE (unsigned long)PCI_IOBASE
+#define PIO_SIZE ALIGN(ISA_IOSIZE, PAGE_SIZE)
+
+static bool acpi_pio;
+
+/* Add PIO for early access */
+void acpi_add_early_pio(void)
+{
+	if (!acpi_disabled) {
+		acpi_pio = true;
+		vmap_page_range(PIO_BASE, PIO_BASE + PIO_SIZE,
+				LOONGSON_LIO_BASE, pgprot_device(PAGE_KERNEL));
+	}
+}
+
+/* Remove PIO for PCI register */
+void acpi_remove_early_pio(void)
+{
+	if (!acpi_pio)
+		return;
+
+	if (!acpi_disabled) {
+		acpi_pio = false;
+		vunmap_range(PIO_BASE, PIO_BASE + PIO_SIZE);
+	}
+}
+
 #ifdef CONFIG_SMP
 static int set_processor_mask(u32 id, u32 pass)
 {
arch/loongarch/kernel/setup.c +2 -0
@@ -510,6 +510,8 @@ static __init int arch_reserve_pio_range
 {
 	struct device_node *np;
 
+	acpi_add_early_pio();
+
 	for_each_node_by_name(np, "isa") {
 		struct of_range range;
 		struct of_range_parser parser;
arch/loongarch/pci/acpi.c +2 -0
@@ -65,6 +65,8 @@ static int acpi_prepare_root_resources(s
 	struct resource_entry *entry, *tmp;
 	struct acpi_device *device = ci->bridge;
 
+	acpi_remove_early_pio();
+
 	status = acpi_pci_probe_root_resources(ci);
 	if (status > 0) {
 		acpi_evaluate_integer(device->handle, "PCIH", NULL, &pci_h);
author maintainer
#37 lore raw

PATCH 37/480 rust: cpufreq: clean new `clippy::map_or_identity` lint for Rust 1.98.0

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Miguel Ojeda <[email protected]>

commit 3473e0a219fdb2cb013da0a5d917e66fef052325 upstream.

Starting with Rust 1.98.0 (expected 2026-08-20), Clippy is likely introducing a new lint clippy::map_or_identity [1][2], which currently triggers in a single case:

    warning: expression can be simplified using `Result::unwrap_or()`
        --> rust/kernel/cpufreq.rs:1326:60
         |
    1326 |         PolicyCpu::from_cpu(cpu_id).map_or(0, |mut policy| T::get(&mut policy).map_or(0, |f| f))
         |                                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#map_or_identity
         = note: `-W clippy::map-or-identity` implied by `-W clippy::all`
         = help: to override `-W clippy::all` add `#[allow(clippy::map_or_identity)]`
    help: consider using `unwrap_or`
         |
    1326 -         PolicyCpu::from_cpu(cpu_id).map_or(0, |mut policy| T::get(&mut policy).map_or(0, |f| f))
    1326 +         PolicyCpu::from_cpu(cpu_id).map_or(0, |mut policy| T::get(&mut policy).unwrap_or(0))
         |

The suggestion is valid, thus clean it up.

---
 rust/kernel/cpufreq.rs |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
rust/kernel/cpufreq.rs +1 -1
@@ -1323,7 +1323,7 @@ impl<T: Driver> Registration<T> {
         // SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.
         let cpu_id = unsafe { CpuId::from_u32_unchecked(cpu) };
 
-        PolicyCpu::from_cpu(cpu_id).map_or(0, |mut policy| T::get(&mut policy).map_or(0, |f| f))
+        PolicyCpu::from_cpu(cpu_id).map_or(0, |mut policy| T::get(&mut policy).unwrap_or(0))
     }
 
     /// Driver's `update_limit` callback.
author maintainer
#38 lore raw

PATCH 38/480 rust: block: fix GenDisk cleanup paths

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Haoze Xie <[email protected]>

commit 2957771379fa335103a4b539db57bb2271e12142 upstream.

GenDiskBuilder::build() still has fallible work after __blk_mq_alloc_disk(), but its error path only recovers the foreign queue data. That leaks the temporary gendisk and request_queue until later teardown. If the caller moved the last Arc<TagSet<T>> into build(), the leaked queue can retain blk-mq state after the tag set is dropped.

Fix the pre-registration failure path by dropping the temporary gendisk reference with put_disk() before recovering queue_data, so disk_release() can tear down the owned queue.

Also pair GenDisk::drop() with put_disk() after del_gendisk(). Once a Rust GenDisk has been added with device_add_disk(), del_gendisk() only unregisters it; the final gendisk reference still has to be dropped to complete the release path.

---
 rust/kernel/block/mq/gen_disk.rs |   20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)
rust/kernel/block/mq/gen_disk.rs +19 -1
@@ -153,6 +153,19 @@ impl GenDiskBuilder {
         // SAFETY: `gendisk` is a valid pointer as we initialized it above
         unsafe { (*gendisk).fops = &TABLE };
 
+        let cleanup_failure = ScopeGuard::new_with_data((gendisk, data), |(gendisk, data)| {
+            // SAFETY: `gendisk` came from `__blk_mq_alloc_disk()` above and
+            // has not been added to the VFS on this cleanup path.
+            unsafe { bindings::put_disk(gendisk) };
+            // SAFETY: `data` came from `into_foreign()` above and has not been
+            // converted back on this cleanup path.
+            drop(unsafe { T::QueueData::from_foreign(data) });
+        });
+
+        // The failure guard now owns both pieces of cleanup; the early guard
+        // must not run on this path anymore.
+        recover_data.dismiss();
+
         let mut writer = NullTerminatedFormatter::new(
             // SAFETY: `gendisk` points to a valid and initialized instance. We
             // have exclusive access, since the disk is not added to the VFS
@@ -175,7 +188,7 @@ impl GenDiskBuilder {
             },
         )?;
 
-        recover_data.dismiss();
+        cleanup_failure.dismiss();
 
         // INVARIANT: `gendisk` was initialized above.
         // INVARIANT: `gendisk` was added to the VFS via `device_add_disk` above.
@@ -218,6 +231,11 @@ impl<T: Operations> Drop for GenDisk<T>
         // to the VFS.
         unsafe { bindings::del_gendisk(self.gendisk) };
 
+        // SAFETY: By type invariant, `self.gendisk` was added to the VFS, so
+        // `put_disk()` must follow `del_gendisk()` to drop the final gendisk
+        // reference and trigger the remaining release path.
+        unsafe { bindings::put_disk(self.gendisk) };
+
         // SAFETY: `queue.queuedata` was created by `GenDiskBuilder::build` with
         // a call to `ForeignOwnable::into_foreign` to create `queuedata`.
         // `ForeignOwnable::from_foreign` is only called here.
author maintainer
#39 lore raw

PATCH 39/480 rust: doctest: fix incorrect pattern in replacement

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Gary Guo <[email protected]>

commit ac4d1caa82d487e7ed46d0597da1adc9c1a51c70 upstream.

The -> Result<(), impl core::fmt::Debug> string is generated by rustdoc and by adding "::" into the string it no longer finds anything, making the line useless.

Remove the "::" in the pattern. Omit it in the replacement too, for consistency with upstream rustdoc.

Fixes de7cd3e4d638 ("rust: use absolute paths in macros referencing core and kernel")

[ Added link in code comment to rustdoc's 1.87 PR that fully qualified
it for context. Improved comments for consistency. Reworded to drop changelog and to fix typo. - Miguel ]

---
 scripts/rustdoc_test_builder.rs |   16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)
scripts/rustdoc_test_builder.rs +10 -6
@@ -28,7 +28,7 @@ fn main() {
     //
     // ```
     // fn main() { #[allow(non_snake_case)] fn _doctest_main_rust_kernel_file_rs_28_0() {
-    // fn main() { #[allow(non_snake_case)] fn _doctest_main_rust_kernel_file_rs_37_0() -> Result<(), impl ::core::fmt::Debug> {
+    // fn main() { #[allow(non_snake_case)] fn _doctest_main_rust_kernel_file_rs_37_0() -> Result<(), impl core::fmt::Debug> {
     // ```
     //
     // It should be unlikely that doctest code matches such lines (when code is formatted properly).
@@ -47,12 +47,16 @@ fn main() {
         })
         .expect("No test function found in `rustdoc`'s output.");
 
-    // Qualify `Result` to avoid the collision with our own `Result` coming from the prelude.
+    // Replicate `rustdoc` 1.87+ behaviour [1] by fully qualifying `Result` to avoid the collision
+    // with our own `Result` coming from the prelude.
+    //
+    // [1]: https://github.com/rust-lang/rust/pull/137807
+    //
+    // TODO: Remove this when MSRV is bumped above 1.87.
     let body = body.replace(
-        &format!("{rustdoc_function_name}() -> Result<(), impl ::core::fmt::Debug> {{"),
-        &format!(
-            "{rustdoc_function_name}() -> ::core::result::Result<(), impl ::core::fmt::Debug> {{"
-        ),
+        &format!("{rustdoc_function_name}() -> Result<(), impl core::fmt::Debug> {{"),
+        // This intentionally does not use absolute paths to match `rustdoc` 1.87 behaviour.
+        &format!("{rustdoc_function_name}() -> core::result::Result<(), impl core::fmt::Debug> {{"),
     );
 
     // For tests that get generated with `Result`, like above, `rustdoc` generates an `unwrap()` on
author maintainer
#40 lore raw

PATCH 40/480 rust: Kbuild: set frame-pointer llvm module flag for CONFIG_FRAME_POINTER

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Alice Ryhl <[email protected]>

commit 191f49f1e38b1c10eb44b0f967c6175c884ef7db upstream.

Due to a rustc bug, the -Cforce-frame-pointers=y flag only emits the frame-pointer annotation for functions, but not for the module. This means that functions generated by the LLVM backend such as 'asan.module_ctor' do not receive the frame-pointer annotation.

This is likely to lead to broken backtraces and may also cause issues with ftrace if these features are used with functions generated by the LLVM backend.

Thus, use -Zllvm_module_flag to work around this rustc bug if using a rustc without the fix.

[ The fix [1] has landed for Rust 1.98.0 (expected release on
2026-08-20). - Miguel ]

Cc [email protected] # 6.12.y and later (flag not available in pinned Rust in older LTSs).
Fixes 2f7ab1267dc9 ("Kbuild: add Rust support")

[ - Adjusted Cc: stable@ as discussed.

- Added comment with link to the PR, similar to what we did in commit ac35b5580ace ("rust: arm64: set uwtable llvm module flag for CONFIG_UNWIND_TABLES").

- Miguel ]

---
 Makefile |    3 +++
 1 file changed, 3 insertions(+)
Makefile +3 -0
@@ -905,6 +905,9 @@ KBUILD_CFLAGS += $(stackp-flags-y)
 ifdef CONFIG_FRAME_POINTER
 KBUILD_CFLAGS	+= -fno-omit-frame-pointer -fno-optimize-sibling-calls
 KBUILD_RUSTFLAGS += -Cforce-frame-pointers=y
+# Work around rustc bug on compilers without
+# https://github.com/rust-lang/rust/pull/156980.
+KBUILD_RUSTFLAGS += $(if $(call rustc-min-version,109800),,-Zllvm_module_flag=frame-pointer:u32:2:max)
 else
 # Some targets (ARM with Thumb2, for example), can't be built with frame
 # pointers.  For those, we don't have FUNCTION_TRACER automatically
#41 lore raw

Re: [PATCH 6.18 040/480] rust: Kbuild: set frame-pointer llvm module flag for CONFIG_FRAME_POINTER

Quoted 10 lines · Greg Kroah-Hartman

[ - Adjusted Cc: stable@ as discussed.

- Added comment with link to the PR, similar to what we did in commit ac35b5580ace ("rust: arm64: set uwtable llvm module flag for CONFIG_UNWIND_TABLES").

- Miguel ]

Ditto.

Cheers,
Miguel

author maintainer
#42 lore raw

PATCH 41/480 futex/requeue: Revert "Prevent NULL pointer dereference in remove_waiter() on self-deadlock""

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Sebastian Andrzej Siewior <[email protected]>

commit 39def6d250d370298f86c116f4ac60093cefadaa upstream.

The commit cited below should not have been merged. It attemted to fix an existing problem ansd thereby introduced new problems by keeping the pi_state in state Q_REQUEUE_PI_IN_PROGRESS and leaking it.

Based on the commit description the intention was to handle the case when task_blocks_on_rt_mutex() returns -EDEADLK and the following remove_waiter() dereferences the NULL pointer in waiter->task.

That is already handled by Davidlohr in commit 40a25d59e85b3 ("locking/rtmutex: Skip remove_waiter() when waiter is not enqueued") and requires no further acting.

Revert the commit breaking the "waiter == owner" case again.

---
 kernel/futex/requeue.c |    6 ------
 1 file changed, 6 deletions(-)
kernel/futex/requeue.c +0 -6
@@ -643,12 +643,6 @@ retry_private:
 				continue;
 			}
 
-			/* Self-deadlock: non-top waiter already owns the PI futex. */
-			if (rt_mutex_owner(&pi_state->pi_mutex) == this->task) {
-				ret = -EDEADLK;
-				break;
-			}
-
 			ret = rt_mutex_start_proxy_lock(&pi_state->pi_mutex,
 							this->rt_waiter,
 							this->task);
author maintainer
#43 lore raw

PATCH 42/480 perf/core: Detach event groups during remove_on_exec

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Taeyang Lee <[email protected]>

[ Upstream commit 037a3c43edfb597665dd34457cd22b14692f2ba3 ]

perf_event_remove_on_exec() removes events by calling perf_event_exit_event(). For top-level events, this removes the event from the context with DETACH_EXIT only.

This can leave inconsistent group state when a removed event is a group leader and the group contains siblings without remove_on_exec. If the group was active, the surviving siblings can remain active and attached to the removed leader's sibling list, but are no longer represented by a valid group leader on the PMU context active lists.

A later close of the removed leader uses DETACH_GROUP and can promote the still-active siblings from this stale group state. The next schedule-in can then add an already-linked active_list entry again, corrupting the PMU context active list.

With DEBUG_LIST enabled, this is caught as a list_add double-add in merge_sched_in().

Fix this by detaching group relationships when remove_on_exec removes an event. This preserves the existing task-exit and revoke behavior, while ensuring surviving siblings are ungrouped before the removed event leaves the context.

Fixes 2e498d0a74e5 ("perf: Add support for event removal on exec")
---
 kernel/events/core.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)
kernel/events/core.c +9 -8
index 6b6fea8d33e044..449550b3bb286a 100644
@@ -4586,7 +4586,7 @@ static void perf_remove_from_owner(struct perf_event *event);
 static void perf_event_exit_event(struct perf_event *event,
 				  struct perf_event_context *ctx,
 				  struct task_struct *task,
-				  bool revoke);
+				  unsigned long detach_flags);
 
 /*
  * Removes all events from the current task that have been marked
@@ -4613,7 +4613,7 @@ static void perf_event_remove_on_exec(struct perf_event_context *ctx)
 
 		modified = true;
 
-		perf_event_exit_event(event, ctx, ctx->task, false);
+		perf_event_exit_event(event, ctx, ctx->task, DETACH_GROUP);
 	}
 
 	raw_spin_lock_irqsave(&ctx->lock, flags);
@@ -12511,7 +12511,7 @@ static void __pmu_detach_event(struct pmu *pmu, struct perf_event *event,
 	/*
 	 * De-schedule the event and mark it REVOKED.
 	 */
-	perf_event_exit_event(event, ctx, ctx->task, true);
+	perf_event_exit_event(event, ctx, ctx->task, DETACH_REVOKE);
 
 	/*
 	 * All _free_event() bits that rely on event->pmu:
@@ -14095,12 +14095,13 @@ static void
 perf_event_exit_event(struct perf_event *event,
 		      struct perf_event_context *ctx,
 		      struct task_struct *task,
-		      bool revoke)
+		      unsigned long detach_flags)
 {
 	struct perf_event *parent_event = event->parent;
-	unsigned long detach_flags = DETACH_EXIT;
 	unsigned int attach_state;
 
+	detach_flags |= DETACH_EXIT;
+
 	if (parent_event) {
 		/*
 		 * Do not destroy the 'original' grouping; because of the
@@ -14123,8 +14124,8 @@ perf_event_exit_event(struct perf_event *event,
 			sync_child_event(event, task);
 	}
 
-	if (revoke)
-		detach_flags |= DETACH_GROUP | DETACH_REVOKE;
+	if (detach_flags & DETACH_REVOKE)
+		detach_flags |= DETACH_GROUP;
 
 	perf_remove_from_context(event, detach_flags);
 	/*
@@ -14212,7 +14213,7 @@ static void perf_event_exit_task_context(struct task_struct *task, bool exit)
 		perf_event_task(task, ctx, 0);
 
 	list_for_each_entry_safe(child_event, next, &ctx->event_list, event_entry)
-		perf_event_exit_event(child_event, ctx, exit ? task : NULL, false);
+		perf_event_exit_event(child_event, ctx, exit ? task : NULL, 0);
 
 	mutex_unlock(&ctx->mutex);
 
Signature · 1 line
2.53.0
author maintainer
#44 lore raw

PATCH 43/480 rust: kasan: KASAN+RUST requires clang

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Alice Ryhl <[email protected]>

[ Upstream commit 5b271543d0f08e9733d4732721e960e285f6448f ]

Kernel KASAN involves passing various llvm/gcc specific arguments to the C and Rust compiler. Since these arguments differ between llvm and gcc, it's not safe to mix an llvm-based rustc with a gcc build when kasan is enabled.

---
 init/Kconfig | 1 +
 1 file changed, 1 insertion(+)
init/Kconfig +1 -0
index cab3ad28ca49e7..0c25e78e10f47e 100644
@@ -2096,6 +2096,7 @@ config RUST
 	depends on !CFI || HAVE_CFI_ICALL_NORMALIZE_INTEGERS_RUSTC
 	select CFI_ICALL_NORMALIZE_INTEGERS if CFI
 	depends on !CALL_PADDING || RUSTC_VERSION >= 108100
+	depends on !KASAN || CC_IS_CLANG
 	depends on !KASAN_SW_TAGS
 	depends on !(MITIGATION_RETHUNK && KASAN) || RUSTC_VERSION >= 108300
 	help
Signature · 1 line
2.53.0
author maintainer
#45 lore raw

PATCH 44/480 fscrypt: Fix key setup in edge case with multiple data unit sizes

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric Biggers <[email protected]>

[ Upstream commit dd015b566d505d698386103e9c80b739c7336eb8 ]

The addition of support for customizable data unit sizes introduced an edge case where a file's contents can be en/decrypted with the wrong data unit size. It occurs when there are multiple v2 policies that:

- Have *different* data unit sizes, via the log2_data_unit_size field

- Share the same master_key_identifier, contents_encryption_mode, and either FSCRYPT_POLICY_FLAG_DIRECT_KEY, FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32, or FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64

- Are being used on the same filesystem, which also must be mounted with the "inlinecrypt" mount option.

Fortunately this edge case doesn't actually occur in practice. I just found it via code review. But it needs to be fixed regardless.

The bug is caused by the data unit size not being fully considered when blk_crypto_keys are cached in mk_direct_keys, mk_iv_ino_lblk_32_keys, and mk_iv_ino_lblk_64_keys. They're differentiated only by master key, encryption mode, and flag. However, each one actually has a data unit size too. Only the first data unit size that is cached is used.

To fix this, start using the data unit size to differentiate the cached keys. For several reasons, including avoiding increasing the size of struct fscrypt_master_key, just replace all three arrays with a single linked list instead of changing them into two-dimensional arrays. This works well when considering that in practice at most 2 entries are used across all three arrays, so it was already mostly wasted space.

For simplicity, make the list also take over the publish/subscribe of the prepared key itself. That is, create separate list nodes for blk_crypto_keys vs crypto_skciphers, and add nodes to the list only when their key is actually prepared. (Note that the legacy fscrypt_direct_keys table in fs/crypto/keysetup_v1.c already works this way.) This eliminates the need for the additional memory barriers when reading and writing the fields of struct fscrypt_prepared_key.

Note that I technically should have included the data unit size in the HKDF info string as well. But it's too late to change that.

Fixes 5b1188847180 ("fscrypt: support crypto data unit size less than filesystem block size")
---
 fs/crypto/fscrypt_private.h |  52 +++++++++-------
 fs/crypto/inline_crypt.c    |   8 +--
 fs/crypto/keyring.c         |  23 ++++---
 fs/crypto/keysetup.c        | 118 ++++++++++++++++++++++--------------
 4 files changed, 120 insertions(+), 81 deletions(-)
fs/crypto/fscrypt_private.h +31 -21
index 4e8e82a9ccf9a3..3bcde4b59efb0e 100644
@@ -236,7 +236,7 @@ struct fscrypt_symlink_data {
  * @tfm: crypto API transform object
  * @blk_key: key for blk-crypto
  *
- * Normally only one of the fields will be non-NULL.
+ * Only one of the fields is non-NULL.
  */
 struct fscrypt_prepared_key {
 	struct crypto_sync_skcipher *tfm;
@@ -245,6 +245,15 @@ struct fscrypt_prepared_key {
 #endif
 };
 
+/* An entry in the linked list ->mk_mode_keys */
+struct fscrypt_mode_key {
+	struct fscrypt_prepared_key key;
+	struct list_head link;
+	u8 hkdf_context;
+	u8 mode_num;
+	u8 data_unit_bits;
+};
+
 /*
  * fscrypt_inode_info - the "encryption key" for an inode
  *
@@ -433,20 +442,12 @@ int fscrypt_derive_sw_secret(struct super_block *sb,
  * @prep_key, depending on which encryption implementation the file will use.
  */
 static inline bool
-fscrypt_is_key_prepared(struct fscrypt_prepared_key *prep_key,
+fscrypt_is_key_prepared(const struct fscrypt_prepared_key *prep_key,
 			const struct fscrypt_inode_info *ci)
 {
-	/*
-	 * The two smp_load_acquire()'s here pair with the smp_store_release()'s
-	 * in fscrypt_prepare_inline_crypt_key() and fscrypt_prepare_key().
-	 * I.e., in some cases (namely, if this prep_key is a per-mode
-	 * encryption key) another task can publish blk_key or tfm concurrently,
-	 * executing a RELEASE barrier.  We need to use smp_load_acquire() here
-	 * to safely ACQUIRE the memory the other task published.
-	 */
 	if (fscrypt_using_inline_encryption(ci))
-		return smp_load_acquire(&prep_key->blk_key) != NULL;
-	return smp_load_acquire(&prep_key->tfm) != NULL;
+		return prep_key->blk_key != NULL;
+	return prep_key->tfm != NULL;
 }
 
 #else /* CONFIG_FS_ENCRYPTION_INLINE_CRYPT */
@@ -489,10 +490,10 @@ fscrypt_derive_sw_secret(struct super_block *sb,
 }
 
 static inline bool
-fscrypt_is_key_prepared(struct fscrypt_prepared_key *prep_key,
+fscrypt_is_key_prepared(const struct fscrypt_prepared_key *prep_key,
 			const struct fscrypt_inode_info *ci)
 {
-	return smp_load_acquire(&prep_key->tfm) != NULL;
+	return prep_key->tfm != NULL;
 }
 #endif /* !CONFIG_FS_ENCRYPTION_INLINE_CRYPT */
 
@@ -580,8 +581,8 @@ struct fscrypt_master_key {
 	/*
 	 * Active and structural reference counts.  An active ref guarantees
 	 * that the struct continues to exist, continues to be in the keyring
-	 * ->s_master_keys, and that any embedded subkeys (e.g.
-	 * ->mk_direct_keys) that have been prepared continue to exist.
+	 * ->s_master_keys, and that any non-file-scoped subkeys (e.g.
+	 * ->mk_mode_keys) that have been prepared continue to exist.
 	 * A structural ref only guarantees that the struct continues to exist.
 	 *
 	 * There is one active ref associated with ->mk_present being true, and
@@ -635,12 +636,21 @@ struct fscrypt_master_key {
 	spinlock_t		mk_decrypted_inodes_lock;
 
 	/*
-	 * Per-mode encryption keys for the various types of encryption policies
-	 * that use them.  Allocated and derived on-demand.
+	 * A list of 'struct fscrypt_mode_key' for the (hkdf_context, mode_num,
+	 * data_unit_bits, inlinecrypt) combinations that are in use for this
+	 * master key, for hkdf_context in [HKDF_CONTEXT_DIRECT_KEY,
+	 * HKDF_CONTEXT_IV_INO_LBLK_32_KEY, HKDF_CONTEXT_IV_INO_LBLK_64_KEY].
+	 *
+	 * This is a linked list and not a hash table because in practice
+	 * there's just a single encryption policy per master key, using
+	 * _at most_ 2 nodes in this list.  Per-file keys don't use this at all.
+	 *
+	 * This list is append-only until the master key is fully removed, at
+	 * which time the list is cleared.  Before then,
+	 * fscrypt_mode_key_setup_mutex synchronizes appends, and searches use
+	 * the RCU read lock together with ->mk_sem held for read.
 	 */
-	struct fscrypt_prepared_key mk_direct_keys[FSCRYPT_MODE_MAX + 1];
-	struct fscrypt_prepared_key mk_iv_ino_lblk_64_keys[FSCRYPT_MODE_MAX + 1];
-	struct fscrypt_prepared_key mk_iv_ino_lblk_32_keys[FSCRYPT_MODE_MAX + 1];
+	struct list_head	mk_mode_keys;
 
 	/* Hash key for inode numbers.  Initialized only when needed. */
 	siphash_key_t		mk_ino_hash_key;
fs/crypto/inline_crypt.c +1 -7
index ed6e926226b51d..645cc493607294 100644
@@ -198,13 +198,7 @@ int fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key,
 		goto fail;
 	}
 
-	/*
-	 * Pairs with the smp_load_acquire() in fscrypt_is_key_prepared().
-	 * I.e., here we publish ->blk_key with a RELEASE barrier so that
-	 * concurrent tasks can ACQUIRE it.  Note that this concurrency is only
-	 * possible for per-mode keys, not for per-file keys.
-	 */
-	smp_store_release(&prep_key->blk_key, blk_key);
+	prep_key->blk_key = blk_key;
 	return 0;
 
 fail:
fs/crypto/keyring.c +14 -9
index 3adbd7167055a9..29bea5f3c98234 100644
@@ -87,14 +87,14 @@ void fscrypt_put_master_key(struct fscrypt_master_key *mk)
 void fscrypt_put_master_key_activeref(struct super_block *sb,
 				      struct fscrypt_master_key *mk)
 {
-	size_t i;
+	struct fscrypt_mode_key *node, *tmp;
 
 	if (!refcount_dec_and_test(&mk->mk_active_refs))
 		return;
 	/*
 	 * No active references left, so complete the full removal of this
 	 * fscrypt_master_key struct by removing it from the keyring and
-	 * destroying any subkeys embedded in it.
+	 * destroying any non-file-scoped subkeys.
 	 */
 
 	if (WARN_ON_ONCE(!sb->s_master_keys))
@@ -110,13 +110,16 @@ void fscrypt_put_master_key_activeref(struct super_block *sb,
 	WARN_ON_ONCE(mk->mk_present);
 	WARN_ON_ONCE(!list_empty(&mk->mk_decrypted_inodes));
 
-	for (i = 0; i <= FSCRYPT_MODE_MAX; i++) {
-		fscrypt_destroy_prepared_key(
-				sb, &mk->mk_direct_keys[i]);
-		fscrypt_destroy_prepared_key(
-				sb, &mk->mk_iv_ino_lblk_64_keys[i]);
-		fscrypt_destroy_prepared_key(
-				sb, &mk->mk_iv_ino_lblk_32_keys[i]);
+	/*
+	 * Destroy any non-file-scoped subkeys.  Since ->mk_active_refs == 0,
+	 * they're no longer referenced by any inodes.  Nor can key setup run
+	 * and use them again.  So they're no longer needed.  (This implies no
+	 * concurrent readers, so we don't need list_del_rcu() for example.)
+	 */
+	list_for_each_entry_safe(node, tmp, &mk->mk_mode_keys, link) {
+		fscrypt_destroy_prepared_key(sb, &node->key);
+		list_del(&node->link);
+		kfree(node);
 	}
 	memzero_explicit(&mk->mk_ino_hash_key,
 			 sizeof(mk->mk_ino_hash_key));
@@ -445,6 +448,8 @@ static int add_new_master_key(struct super_block *sb,
 	INIT_LIST_HEAD(&mk->mk_decrypted_inodes);
 	spin_lock_init(&mk->mk_decrypted_inodes_lock);
 
+	INIT_LIST_HEAD(&mk->mk_mode_keys);
+
 	if (mk_spec->type == FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER) {
 		err = allocate_master_key_users_keyring(mk);
 		if (err)
fs/crypto/keysetup.c +74 -44

176 lines not on this page · raw message

Signature · 1 line
2.53.0
author maintainer
#46 lore raw

PATCH 45/480 fscrypt: Replace mk_users keyring with simple list

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric Biggers <[email protected]>

[ Upstream commit 696c030e1e3438955aba443b308ee8b6faa3983e ]

Change mk_users (the set of user claims to an fscrypt master key) from a 'struct key' keyring to a simple linked list.

It's still a collection of 'struct key' for quota tracking. It was originally thought to be natural that a collection of 'struct key' should be held in a 'struct key' keyring. In reality, it's just been causing problems, similar to how using 'struct key' for the filesystem keyring caused problems and was removed in commit d7e7b9af104c ("fscrypt: stop using keyrings subsystem for fscrypt_master_key").

Commit d3a7bd420076 ("fscrypt: clear keyring before calling key_put()") fixed mk_users cleanup to be synchronous. But that apparently wasn't
enough: the keyring subsystem's redundant locking is still generating lockdep false positives due to the interaction with filesystem reclaim.

With the simple list, the redundant locking and lockdep issue goes away.

Of course, searching a linked list is linear-time whereas the 'struct key' keyring used a fancy constant-time associative array. But that's fine here, since in practice there's just one entry in the list. In fact the new code is much faster in practice, since it's much smaller and doesn't have to convert the kuid_t into a string to search for it.

---
 fs/crypto/fscrypt_private.h |  32 ++++--
 fs/crypto/keyring.c         | 216 +++++++++++++++---------------------
 2 files changed, 113 insertions(+), 135 deletions(-)
fs/crypto/fscrypt_private.h +22 -10
index 3bcde4b59efb0e..886ea39e924df0 100644
@@ -499,6 +499,19 @@ fscrypt_is_key_prepared(const struct fscrypt_prepared_key *prep_key,
 
 /* keyring.c */
 
+/*
+ * fscrypt_master_key_user - a user's claim to a master key
+ */
+struct fscrypt_master_key_user {
+	struct list_head link;
+	kuid_t uid;
+	/*
+	 * This 'struct key' contains no secret.  It exists solely to charge the
+	 * appropriate user's key quota.
+	 */
+	struct key *quota_key;
+};
+
 /*
  * fscrypt_master_key_secret - secret key material of an in-use master key
  */
@@ -614,19 +627,18 @@ struct fscrypt_master_key {
 	struct fscrypt_key_specifier		mk_spec;
 
 	/*
-	 * Keyring which contains a key of type 'key_type_fscrypt_user' for each
-	 * user who has added this key.  Normally each key will be added by just
-	 * one user, but it's possible that multiple users share a key, and in
-	 * that case we need to keep track of those users so that one user can't
-	 * remove the key before the others want it removed too.
+	 * List of user claims to this key (struct fscrypt_master_key_user).
+	 * Normally each key will be added by just one user, but it's possible
+	 * that multiple users share a key, and in that case we need to keep
+	 * track of those users so that one user can't remove the key before the
+	 * others want it removed too.
 	 *
-	 * This is NULL for v1 policy keys; those can only be added by root.
+	 * Used only for v2 policy keys.  v1 policy keys can be added only by
+	 * root, so user tracking doesn't apply to them.
 	 *
-	 * Locking: protected by ->mk_sem.  (We don't just rely on the keyrings
-	 * subsystem semaphore ->mk_users->sem, as we need support for atomic
-	 * search+insert along with proper synchronization with other fields.)
+	 * Locking: protected by ->mk_sem.
 	 */
-	struct key		*mk_users;
+	struct list_head	mk_users;
 
 	/*
 	 * List of inodes that were unlocked using this key.  This allows the
fs/crypto/keyring.c +91 -125

337 lines not on this page · raw message

Signature · 1 line
2.53.0
author maintainer
#47 lore raw

PATCH 46/480 usb: gadget: function: rndis: add length check to response query

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Griffin Kroah-Hartman <[email protected]>

commit 95f90eea070837f7c72207d5520f805bdefc3bc5 upstream.

Add variable representations for BufLength and BufOffset in rndis_query_response(), and perform a length check on them.

This is identical to how rndis_set_response() handles these parameters.

---
 drivers/usb/gadget/function/rndis.c |   14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)
drivers/usb/gadget/function/rndis.c +10 -4
@@ -591,6 +591,7 @@ static int rndis_init_response(struct rn
 static int rndis_query_response(struct rndis_params *params,
 				rndis_query_msg_type *buf)
 {
+	u32 BufLength, BufOffset;
 	rndis_query_cmplt_type *resp;
 	rndis_resp_t *r;
 
@@ -598,6 +599,13 @@ static int rndis_query_response(struct r
 	if (!params->dev)
 		return -ENOTSUPP;
 
+	BufLength = le32_to_cpu(buf->InformationBufferLength);
+	BufOffset = le32_to_cpu(buf->InformationBufferOffset);
+	if ((BufLength > RNDIS_MAX_TOTAL_SIZE) ||
+	    (BufOffset > RNDIS_MAX_TOTAL_SIZE) ||
+	    (BufOffset + 8 >= RNDIS_MAX_TOTAL_SIZE))
+		return -EINVAL;
+
 	/*
 	 * we need more memory:
 	 * gen_ndis_query_resp expects enough space for
@@ -614,10 +622,8 @@ static int rndis_query_response(struct r
 	resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
 
 	if (gen_ndis_query_resp(params, le32_to_cpu(buf->OID),
-			le32_to_cpu(buf->InformationBufferOffset)
-					+ 8 + (u8 *)buf,
-			le32_to_cpu(buf->InformationBufferLength),
-			r)) {
+				BufOffset + 8 + (u8 *)buf,
+				BufLength, r)) {
 		/* OID not supported */
 		resp->Status = cpu_to_le32(RNDIS_STATUS_NOT_SUPPORTED);
 		resp->MessageLength = cpu_to_le32(sizeof *resp);
author maintainer
#48 lore raw

PATCH 47/480 usb: gadget: function: rndis: add length check for header

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Griffin Kroah-Hartman <[email protected]>

commit 21b5bf155435008e0fb0736795289788e63d426f upstream.

Add a length check for the rndis header in rndis_rm_hdr, to ensure that MessageType, MessageLength, DataOffset, and DataLength fields are present before they are accessed.

---
 drivers/usb/gadget/function/rndis.c |    6 ++++++
 1 file changed, 6 insertions(+)
drivers/usb/gadget/function/rndis.c +6 -0
@@ -1080,6 +1080,12 @@ int rndis_rm_hdr(struct gether *port,
 	/* tmp points to a struct rndis_packet_msg_type */
 	__le32 *tmp = (void *)skb->data;
 
+	/* Need at least MessageType, MessageLength, DataOffset, DataLength */
+	if (skb->len < 16) {
+		dev_kfree_skb_any(skb);
+		return -EINVAL;
+	}
+
 	/* MessageType, MessageLength */
 	if (cpu_to_le32(RNDIS_MSG_PACKET)
 			!= get_unaligned(tmp++)) {
author maintainer
#49 lore raw

PATCH 48/480 iio: accel: bmc150: clamp the device-reported FIFO frame count

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Bryam Vargas <[email protected]>

commit ce0e1cae26096fe959a0da5563a6d6d5a801d5fb upstream.

__bmc150_accel_fifo_flush() copies the number of samples the device reports in its hardware FIFO into an on-stack buffer

	u16 buffer[BMC150_ACCEL_FIFO_LENGTH * 3];

which is sized for at most BMC150_ACCEL_FIFO_LENGTH (32) samples. The frame count is read from the FIFO_STATUS register and only masked to its 7 valid bits:

	count = val & 0x7F;

so it can be 0..127. The only other limit applied to it is the optional caller-supplied sample budget:

	if (samples && count > samples)
		count = samples;

which does not constrain count on the flush-all path (samples == 0), and leaves it well above 32 whenever samples is larger. count samples are then transferred into buffer[]:

	bmc150_accel_fifo_transfer(data, (u8 *)buffer, count);

bmc150_accel_fifo_transfer() reads count * 6 bytes through regmap, so a malfunctioning, malicious or counterfeit accelerometer (or an attacker tampering with the I2C/SPI bus) that reports up to 127 frames writes up to 762 bytes into the 192-byte buffer: a stack out-of-bounds write of up to 570 bytes that clobbers the stack canary, saved registers and the return address.

Clamp count to BMC150_ACCEL_FIFO_LENGTH, the number of samples buffer[] is sized for, before the transfer, mirroring the watermark clamp already done in bmc150_accel_set_watermark(). A well-formed flush reports at most BMC150_ACCEL_FIFO_LENGTH frames, so legitimate devices are unaffected.

Fixes 3bbec9773389 ("iio: bmc150_accel: add support for hardware fifo")
---
 drivers/iio/accel/bmc150-accel-core.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/iio/accel/bmc150-accel-core.c +2 -0
@@ -991,6 +991,8 @@ static int __bmc150_accel_fifo_flush(str
 	if (samples && count > samples)
 		count = samples;
 
+	count = min_t(u8, count, BMC150_ACCEL_FIFO_LENGTH);
+
 	ret = bmc150_accel_fifo_transfer(data, (u8 *)buffer, count);
 	if (ret)
 		return ret;
author maintainer
#50 lore raw

PATCH 49/480 iio: accel: kxsd9: fix runtime PM imbalance on write_raw() error

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Biren Pandya <[email protected]>

commit 44a5fd874bb6873bdaec59f722c1d57832fbc9df upstream.

kxsd9_write_raw() takes a runtime PM reference with pm_runtime_get_sync() but returns -EINVAL directly when a scale with a non-zero integer part is requested, skipping the matching pm_runtime_put_autosuspend(). This leaks a runtime PM usage-counter reference on every such write, after which the device can no longer autosuspend.

Set the error code and fall through to the existing put instead of returning early.

Fixes 9a9a369d6178 ("iio: accel: kxsd9: Deploy system and runtime PM")
Assisted-by Claude:claude-opus-4-8 coccinelle
---
 drivers/iio/accel/kxsd9.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/iio/accel/kxsd9.c +3 -2
@@ -147,8 +147,9 @@ static int kxsd9_write_raw(struct iio_de
 	if (mask == IIO_CHAN_INFO_SCALE) {
 		/* Check no integer component */
 		if (val)
-			return -EINVAL;
-		ret = kxsd9_write_scale(indio_dev, val2);
+			ret = -EINVAL;
+		else
+			ret = kxsd9_write_scale(indio_dev, val2);
 	}
 
 	pm_runtime_put_autosuspend(st->dev);
author maintainer
#51 lore raw

PATCH 50/480 iio: adc: ad7380: select REGMAP

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Samuel Moelius <[email protected]>

commit 6697091b386a4e2830bdd38512c87a4befff2b32 upstream.

The AD7380 driver uses generic regmap types and APIs. However, its Kconfig entry does not select REGMAP.

As a result, AD7380 can be enabled from an allnoconfig-derived config with SPI_MASTER=y while REGMAP remains unset, causing ad7380.o to fail to build.

Fixes b095217c104b ("iio: adc: ad7380: new driver for AD7380 ADCs")
---
 drivers/iio/adc/Kconfig |    1 +
 1 file changed, 1 insertion(+)
drivers/iio/adc/Kconfig +1 -0
@@ -282,6 +282,7 @@ config AD7298
 config AD7380
 	tristate "Analog Devices AD7380 ADC driver"
 	depends on SPI_MASTER
+	select REGMAP
 	select SPI_OFFLOAD
 	select IIO_BUFFER
 	select IIO_BUFFER_DMAENGINE
author maintainer
#52 lore raw

PATCH 51/480 iio: adc: ad7768-1: Select GPIOLIB

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jonathan Cameron <[email protected]>

commit 5a9c90350be4f6f175bdd193e8bd60a7aedfb4d2 upstream.

This driver provides a gpio chip a some related functions are not stubbed if GPIOLIB is not built.

ad7768-1.c:420: undefined reference to gpiochip_get_data' ad7768-1.c:498: undefined reference to devm_gpiochip_add_data_with_key'

Dual sign off reflects change of affiliation whilst this was under review.

---
 drivers/iio/adc/Kconfig |    1 +
 1 file changed, 1 insertion(+)
drivers/iio/adc/Kconfig +1 -0
@@ -386,6 +386,7 @@ config AD7766
 config AD7768_1
 	tristate "Analog Devices AD7768-1 ADC driver"
 	depends on SPI
+	select GPIOLIB
 	select REGULATOR
 	select REGMAP_SPI
 	select IIO_BUFFER
author maintainer
#53 lore raw

PATCH 52/480 iio: adc: ad7779: add missing select IIO_TRIGGERED_BUFFER to Kconfig

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Joshua Crofts <[email protected]>

commit fd354554af1d2b33232ca6c8a3d79ed82413d715 upstream.

The Kconfig entry for the AD7779 is missing a
'select IIO_TRIGGERED_BUFFER' parameter, causing build failures.

Fixes c9a3f8c7bfcb ("drivers: iio: adc: add support for ad777x family")
---
 drivers/iio/adc/Kconfig |    1 +
 1 file changed, 1 insertion(+)
drivers/iio/adc/Kconfig +1 -0
@@ -404,6 +404,7 @@ config AD7779
 	depends on SPI
 	select CRC8
 	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
 	select IIO_BACKEND
 	help
 	  Say yes here to build support for Analog Devices AD777X family
author maintainer
#54 lore raw

PATCH 53/480 iio: adc: ad_sigma_delta: fix clear_pending_event for registerless devices

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Radu Sabau <[email protected]>

commit 91bc6767a4f55dc470d8a56b55b9f2ea09094efe upstream.

ad_sigma_delta_clear_pending_event() falls through to the status register read path for devices with has_registers = false and no rdy_gpiod. For such devices, ad_sd_read_reg() skips the address byte entirely and clocks raw MISO bytes with no address phase — making it byte-for-byte identical to reading conversion data. If a pending conversion result is present, this partially consumes it and corrupts the data stream for the subsequent ad_sd_read_reg() call in ad_sigma_delta_single_conversion().

Furthermore, with num_resetclks = 0 on these devices, data_read_len evaluates to 0. If the clocked byte has bit 7 clear, pending_event is set and the code attempts memset(data + 2, 0xff, 0 - 1), overflowing to SIZE_MAX and corrupting the heap.

Fix by returning 0 immediately when neither rdy_gpiod nor has_registers is set. This is safe for all current registerless devices: ad7191 and ad7780 (with powerdown GPIO) are reset between conversions by CS deassertion, so there is no stale result to drain; ad7780 (without powerdown GPIO) and max11205 are continuously-converting and cycle ~DRDY at the output data rate regardless of whether the previous result was read, so the next falling edge fires naturally.

A future registerless device that holds ~DRDY asserted until data is read would be broken by this early return and would require either num_resetclks set or a rdy-gpio.

The same heap corruption is reachable on any device with rdy_gpiod set but num_resetclks = 0: if the GPIO indicates a pending event, the drain path executes memset(data + 2, 0xff, 0 - 1) regardless of has_registers. Add an explicit data_read_len == 0 guard after the pending event check; the stale result is then consumed by the first ad_sd_read_reg() call in ad_sigma_delta_single_conversion().

Fixes 132d44dc6966 ("iio: adc: ad_sigma_delta: Check for previous ready signals")
---
 drivers/iio/adc/ad_sigma_delta.c |   31 +++++++++++++++++++++++++++++--
 1 file changed, 29 insertions(+), 2 deletions(-)
drivers/iio/adc/ad_sigma_delta.c +29 -2
@@ -260,11 +260,25 @@ static int ad_sigma_delta_clear_pending_
 
 	/*
 	 * Read R̅D̅Y̅ pin (if possible) or status register to check if there is an
-	 * old event.
+	 * old event. For devices with neither an RDY GPIO nor registers,
+	 * ad_sd_read_reg() transmits no address byte and clocks raw MISO bytes,
+	 * which is indistinguishable from reading conversion data and would
+	 * partially consume a pending result. Skip the check for such devices.
+	 *
+	 * This is safe for all current registerless devices: ad7191 and ad7780
+	 * (with powerdown GPIO) are reset between conversions by CS deassertion,
+	 * so there is no stale result to drain; ad7780 (without powerdown GPIO)
+	 * and max11205 are continuously-converting and cycle ~DRDY at the output
+	 * data rate regardless of whether the previous result was read, so the
+	 * next falling edge fires naturally.
+	 *
+	 * A future registerless device that holds ~DRDY asserted until data is
+	 * read would be broken by this early return and would need either
+	 * num_resetclks set or a rdy-gpio.
 	 */
 	if (sigma_delta->rdy_gpiod) {
 		pending_event = gpiod_get_value(sigma_delta->rdy_gpiod);
-	} else {
+	} else if (sigma_delta->info->has_registers) {
 		unsigned int status_reg;
 
 		ret = ad_sd_read_reg(sigma_delta, AD_SD_REG_STATUS, 1, &status_reg);
@@ -272,12 +286,25 @@ static int ad_sigma_delta_clear_pending_
 			return ret;
 
 		pending_event = !(status_reg & AD_SD_REG_STATUS_RDY);
+	} else {
+		return 0;
 	}
 
 	if (!pending_event)
 		return 0;
 
 	/*
+	 * With num_resetclks = 0, data_read_len is 0 and the drain sequence
+	 * below would compute memset(data + 2, 0xff, 0 - 1), underflowing to
+	 * SIZE_MAX and corrupting the heap. There is no safe way to drain the
+	 * stale result without knowing the data register size; it will be
+	 * consumed by the first ad_sd_read_reg() call in
+	 * ad_sigma_delta_single_conversion().
+	 */
+	if (!data_read_len)
+		return 0;
+
+	/*
 	 * In general the size of the data register is unknown. It varies from
 	 * device to device, might be one byte longer if CONTROL.DATA_STATUS is
 	 * set and even varies on some devices depending on which input is
author maintainer
#55 lore raw

PATCH 54/480 iio: adc: ad_sigma_delta: fix CS held asserted and state leaks

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Radu Sabau <[email protected]>

commit c72da0688575e5ef39c36bb44fed53aa18f8ae65 upstream.

In ad_sigma_delta_single_conversion(), set_mode(AD_SD_MODE_IDLE) and disable_one() were called from the out: block while keep_cs_asserted was still true. This caused any SPI transfer issued by those callbacks to carry cs_change=1, leaving CS permanently asserted after the conversion. Fix by moving both calls into the out_unlock: block, after keep_cs_asserted is cleared, matching the pattern already used in ad_sd_calibrate().

In the error path of ad_sd_buffer_postenable(), if an operation fails after set_mode(AD_SD_MODE_CONTINUOUS) has already succeeded (e.g. spi_offload_trigger_enable()), the device is left in continuous conversion mode with CS physically asserted. Additionally, bus_locked remaining true after spi_bus_unlock() causes subsequent SPI operations to call spi_sync_locked() without the bus lock actually held, allowing concurrent SPI access.

Fix the error path by clearing keep_cs_asserted first, then calling set_mode(AD_SD_MODE_IDLE) to revert the device mode and deassert CS, then clearing bus_locked before releasing the bus.

For devices that implement neither set_mode nor disable_one (such as MAX11205, which has no physical CS pin), no SPI transfer is issued during cleanup and the cs_change flag has no effect on any physical line.

Fixes 132d44dc6966 ("iio: adc: ad_sigma_delta: Check for previous ready signals")
---
 drivers/iio/adc/ad_sigma_delta.c |    8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/iio/adc/ad_sigma_delta.c +5 -3
@@ -466,11 +466,10 @@ int ad_sigma_delta_single_conversion(str
 out:
 	ad_sd_disable_irq(sigma_delta);
 
-	ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
-	ad_sigma_delta_disable_one(sigma_delta, chan->address);
-
 out_unlock:
 	sigma_delta->keep_cs_asserted = false;
+	ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
+	ad_sigma_delta_disable_one(sigma_delta, chan->address);
 	sigma_delta->bus_locked = false;
 	spi_bus_unlock(sigma_delta->spi->controller);
 out_release:
@@ -603,6 +602,9 @@ static int ad_sd_buffer_postenable(struc
 	return 0;
 
 err_unlock:
+	sigma_delta->keep_cs_asserted = false;
+	ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
+	sigma_delta->bus_locked = false;
 	spi_bus_unlock(sigma_delta->spi->controller);
 	spi_unoptimize_message(&sigma_delta->sample_msg);
 
author maintainer
#56 lore raw

PATCH 55/480 iio: adc: lpc32xx: Initialize completion before requesting IRQ

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Maxwell Doose <[email protected]>

commit e561b35633f450ee607e87a6401d97f156a0cd54 upstream.

In the report from Jaeyoung Chung:

"lpc32xx_adc_probe() in drivers/iio/adc/lpc32xx_adc.c registers its interrupt handler with devm_request_irq() before it initializes st->completion with init_completion(). If an interrupt arrives after devm_request_irq() and before init_completion(), the handler calls complete() on an uninitialized completion, causing a kernel panic.

The probe path, in lpc32xx_adc_probe():

    iodev = devm_iio_device_alloc(&pdev->dev, sizeof(*st)); /* st kzalloc-zeroed */
    ...
    retval = devm_request_irq(&pdev->dev, irq, lpc32xx_adc_isr, 0,
                              LPC32XXAD_NAME, st);           /* register handler */
    ...
    init_completion(&st->completion);                       /* initialize completion */

lpc32xx_adc_isr() calls complete():

    complete(&st->completion);

If the device raises an interrupt before init_completion() runs, complete() acquires the uninitialized wait.lock and walks the zeroed task_list in swake_up_locked(). The zeroed task_list makes list_empty() return false, so swake_up_locked() dereferences a NULL list entry, triggering a KASAN wild-memory-access."

Fix the chance of a spurious IRQ causing an uninitialized pointer dereference by moving init_completion() above devm_request_irq().

---
 drivers/iio/adc/lpc32xx_adc.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/iio/adc/lpc32xx_adc.c +2 -2
@@ -179,6 +179,8 @@ static int lpc32xx_adc_probe(struct plat
 	if (irq < 0)
 		return irq;
 
+	init_completion(&st->completion);
+
 	retval = devm_request_irq(&pdev->dev, irq, lpc32xx_adc_isr, 0,
 				  LPC32XXAD_NAME, st);
 	if (retval < 0) {
@@ -197,8 +199,6 @@ static int lpc32xx_adc_probe(struct plat
 
 	platform_set_drvdata(pdev, iodev);
 
-	init_completion(&st->completion);
-
 	iodev->name = LPC32XXAD_NAME;
 	iodev->info = &lpc32xx_adc_iio_info;
 	iodev->modes = INDIO_DIRECT_MODE;
author maintainer
#57 lore raw

PATCH 56/480 iio: adc: spear: Initialize completion before requesting IRQ

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Maxwell Doose <[email protected]>

commit 3ee2128b6f0eb0be7b6cb8f6e0f1f113a65201a0 upstream.

In the report from Jaeyoung Chung:

"spear_adc_probe() in drivers/iio/adc/spear_adc.c registers its interrupt handler with devm_request_irq() before it initializes st->completion with init_completion(). If an interrupt arrives after devm_request_irq() and before init_completion(), the handler calls complete() on an uninitialized completion, causing a kernel panic.

The probe path, in spear_adc_probe():

    iodev = devm_iio_device_alloc(&pdev->dev, sizeof(*st)); /* st kzalloc-zeroed */
    ...
    retval = devm_request_irq(&pdev->dev, irq, spear_adc_isr, 0,
                              LPC32XXAD_NAME, st);           /* register handler */
    ...
    init_completion(&st->completion);                       /* initialize completion */

spear_adc_isr() calls complete():

    complete(&st->completion);

If the device raises an interrupt before init_completion() runs, complete() acquires the uninitialized wait.lock and walks the zeroed task_list in swake_up_locked(). The zeroed task_list makes list_empty() return false, so swake_up_locked() dereferences a NULL list entry, triggering a KASAN wild-memory-access."

Fix the chance of a spurious IRQ causing an uninitialized pointer dereference by moving init_completion() above devm_request_irq().

---
 drivers/iio/adc/spear_adc.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/iio/adc/spear_adc.c +1 -2
@@ -280,6 +280,7 @@ static int spear_adc_probe(struct platfo
 	st = iio_priv(indio_dev);
 	st->dev = dev;
 
+	init_completion(&st->completion);
 	mutex_init(&st->lock);
 
 	/*
@@ -326,8 +327,6 @@ static int spear_adc_probe(struct platfo
 
 	spear_adc_configure(st);
 
-	init_completion(&st->completion);
-
 	indio_dev->name = SPEAR_ADC_MOD_NAME;
 	indio_dev->info = &spear_adc_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
author maintainer
#58 lore raw

PATCH 57/480 iio: adc: ti-ads1119: fix PM reference leak in buffer preenable

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Guangshuo Li <[email protected]>

commit adf4bc07f814da8329278d32600147f5a150938c upstream.

ads1119_triggered_buffer_preenable() resumes the device with pm_runtime_resume_and_get() before starting a conversion.

If i2c_smbus_write_byte() fails, the function returns the error directly and leaves the runtime PM usage counter elevated. The matching postdisable callback is not called when preenable fails, so the reference is leaked and the device may remain runtime-active indefinitely.

Store the I2C transfer result in ret and drop the runtime PM reference on failure before returning the error.

Fixes a9306887eba41 ("iio: adc: ti-ads1119: Add driver")
---
 drivers/iio/adc/ti-ads1119.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/iio/adc/ti-ads1119.c +5 -1
@@ -459,7 +459,11 @@ static int ads1119_triggered_buffer_pree
 	if (ret)
 		return ret;
 
-	return i2c_smbus_write_byte(st->client, ADS1119_CMD_START_SYNC);
+	ret = i2c_smbus_write_byte(st->client, ADS1119_CMD_START_SYNC);
+	if (ret)
+		pm_runtime_put_autosuspend(dev);
+
+	return ret;
 }
 
 static int ads1119_triggered_buffer_postdisable(struct iio_dev *indio_dev)
author maintainer
#59 lore raw

PATCH 58/480 iio: adc: ti-ads124s08: Return reset GPIO lookup errors

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Pengpeng Hou <[email protected]>

commit 7dc4de2aa6316f1d044cde21f5acfec5f3ec6b47 upstream.

devm_gpiod_get_optional() returns NULL when the optional GPIO is absent, but returns an ERR_PTR when the GPIO provider lookup fails, including probe deferral.

Probe currently logs the ERR_PTR case as if the reset GPIO were simply absent and keeps the error pointer in reset_gpio. Later ads124s_reset() treats any non-NULL reset_gpio as a valid descriptor and passes it to gpiod_set_value_cansleep().

Return the lookup error instead of retaining the ERR_PTR.

---
 drivers/iio/adc/ti-ads124s08.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/iio/adc/ti-ads124s08.c +2 -1
@@ -321,7 +321,8 @@ static int ads124s_probe(struct spi_devi
 	ads124s_priv->reset_gpio = devm_gpiod_get_optional(&spi->dev,
 						   "reset", GPIOD_OUT_LOW);
 	if (IS_ERR(ads124s_priv->reset_gpio))
-		dev_info(&spi->dev, "Reset GPIO not defined\n");
+		return dev_err_probe(&spi->dev, PTR_ERR(ads124s_priv->reset_gpio),
+				     "Failed to get reset GPIO\n");
 
 	ads124s_priv->chip_info = &ads124s_chip_info_tbl[spi_id->driver_data];
 
author maintainer
#60 lore raw

PATCH 59/480 iio: backend: fix uninitialized data in debugfs

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Dan Carpenter <[email protected]>

commit a6e8b14a4897d0b6df9744f33d0a30e6b92368eb upstream.

If the *ppos value is non-zero then simple_write_to_buffer() will not initialize the start of the buf[] buffer. Non-zero ppos values aren't going to work at all. Check for that at the start of the function and return -ENOSPC.

Fixes cdf01e0809a4 ("iio: backend: add debugFs interface")
---
 drivers/iio/industrialio-backend.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/industrialio-backend.c +1 -1
@@ -155,7 +155,7 @@ static ssize_t iio_backend_debugfs_write
 	ssize_t rc;
 	int ret;
 
-	if (count >= sizeof(buf))
+	if (*ppos != 0 || count >= sizeof(buf))
 		return -ENOSPC;
 
 	rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, userbuf, count);
author maintainer
#61 lore raw

PATCH 60/480 iio: chemical: scd30: Cleanup initializations and fix sign-extension bug

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Maxwell Doose <[email protected]>

commit 60d877910a43c305b5165131b258a17b1d772d57 upstream.

Include linux/bitfield.h for FIELD_GET().

Create new macros for bit manipulation in combination with manual bit manipulation being replaced with FIELD_GET().

The current variable declaration and initializations are barely readable and use comma separations across multiple lines. Refactor the initializations so that mantissa and exp have separate declarations and sign gets initialized later.

In addition (and due to the nature of the cleanup), fix a sign-extension bug where, float32 would get bitwise anded with ~BIT(31) (which is 0xFFFFFFFF7FFFFFFF) which corrupted the exponent.

---
 drivers/iio/chemical/scd30_core.c |   19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)
drivers/iio/chemical/scd30_core.c +15 -4
@@ -4,6 +4,8 @@
  *
  * Copyright (c) 2020 Tomasz Duszynski <[email protected]>
  */
+
+#include <linux/bitfield.h>
 #include <linux/bits.h>
 #include <linux/cleanup.h>
 #include <linux/completion.h>
@@ -43,6 +45,11 @@
 #define SCD30_TEMP_OFFSET_MAX 655360
 #define SCD30_EXTRA_TIMEOUT_PER_S 250
 
+/* Floating point arithmetic macros */
+#define SCD30_FLOAT_MANTISSA_MSK GENMASK(22, 0)
+#define SCD30_FLOAT_EXP_MSK GENMASK(30, 23)
+#define SCD30_FLOAT_SIGN_MSK BIT(31)
+
 enum {
 	SCD30_CONC,
 	SCD30_TEMP,
@@ -89,10 +96,14 @@ static int scd30_reset(struct scd30_stat
 /* simplified float to fixed point conversion with a scaling factor of 0.01 */
 static int scd30_float_to_fp(int float32)
 {
-	int fraction, shift,
-	    mantissa = float32 & GENMASK(22, 0),
-	    sign = (float32 & BIT(31)) ? -1 : 1,
-	    exp = (float32 & ~BIT(31)) >> 23;
+	int fraction, shift, sign;
+	int mantissa = FIELD_GET(SCD30_FLOAT_MANTISSA_MSK, float32);
+	int exp = FIELD_GET(SCD30_FLOAT_EXP_MSK, float32);
+
+	if (float32 & SCD30_FLOAT_SIGN_MSK)
+		sign = -1;
+	else
+		sign = 1;
 
 	/* special case 0 */
 	if (!exp && !mantissa)
author maintainer
#62 lore raw

PATCH 61/480 iio: common: st_sensors: honour channel endianness in read_axis_data

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Herman van Hazendonk <[email protected]>

commit 55052184ac9011db2ea983e54d6c21f0b1079a12 upstream.

st_sensors_read_axis_data() unconditionally decoded multi-byte results with get_unaligned_le16() / get_unaligned_le24() regardless of the channel's declared scan_type.endianness.

For every ST sensor that has used this helper since it was introduced this happened to be fine because the ST IMU/accel/gyro/pressure families publish their data registers as little-endian and the channel specs in those drivers declare IIO_LE accordingly.

The LSM303DLH magnetometer however publishes its X/Y/Z output as a pair of big-endian bytes (the H register sits at the lower address, 0x03/0x05/0x07, and the L register immediately after), and its channel specs in st_magn_core.c correctly declare IIO_BE -- but read_axis_data() ignored that and decoded as little-endian, swapping the high and low bytes of every magnetometer sample. The LSM303DLHC and LSM303DLM share the same st_magn_16bit_channels (IIO_BE) and were therefore byte-swapped by the same bug; users of those parts will see different in_magn_*_raw values after this fix lands.

The bug is most visible on a stationary chip: in earth's field the true X reading is small and the high byte sits at 0x00, so swapping the bytes pins sysfs X at exactly the low byte's pattern (e.g. 0x00F0 = 240). Y and Z still appear "to vary" because their magnitudes are larger and the noise in the low byte produces big swings in the swapped high byte:

before (LSM303DLH flat, sysfs in_magn_*_raw):

      X=240 (stuck), Y= 12032..23296, Z=-16128..-9728

after (direct i2c-dev big-endian decode, same chip same orientation):
X≈-4096, Y≈210, Z≈80 (sensible values reflecting earth's
ambient field at low gauss range)

Fix read_axis_data() to dispatch on ch->scan_type.endianness and call get_unaligned_be16() / get_unaligned_be24() when the channel declares IIO_BE. Existing IIO_LE consumers (st_accel, st_gyro, st_pressure, st_lsm6dsx and others) are unaffected because their channel specs already declare IIO_LE and the LE path is unchanged.

While restructuring the branches, replace the previously implicit silent-success-with-uninitialised-*data fall-through for byte_for_channel outside 1..3 with an explicit return -EINVAL. No in-tree ST sensor publishes such a channel, but the new behaviour is strictly safer than handing userspace garbage.

Fixes 23491b513bcd ("iio:common: Add STMicroelectronics common library")
Assisted-by Claude:claude-opus-4-7 sparse smatch clang-analyzer coccinelle checkpatch
Assisted-by Sashiko:claude-opus-4-7
---
 drivers/iio/common/st_sensors/st_sensors_core.c |   23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)
drivers/iio/common/st_sensors/st_sensors_core.c +17 -6
@@ -498,6 +498,7 @@ static int st_sensors_read_axis_data(str
 	u8 *outdata;
 	struct st_sensor_data *sdata = iio_priv(indio_dev);
 	unsigned int byte_for_channel;
+	u32 tmp;
 
 	byte_for_channel = DIV_ROUND_UP(ch->scan_type.realbits +
 					ch->scan_type.shift, 8);
@@ -510,12 +511,22 @@ static int st_sensors_read_axis_data(str
 	if (err < 0)
 		goto st_sensors_free_memory;
 
-	if (byte_for_channel == 1)
-		*data = (s8)*outdata;
-	else if (byte_for_channel == 2)
-		*data = (s16)get_unaligned_le16(outdata);
-	else if (byte_for_channel == 3)
-		*data = (s32)sign_extend32(get_unaligned_le24(outdata), 23);
+	if (byte_for_channel == 1) {
+		tmp = *outdata;
+	} else if (byte_for_channel == 2) {
+		if (ch->scan_type.endianness == IIO_BE)
+			tmp = get_unaligned_be16(outdata);
+		else
+			tmp = get_unaligned_le16(outdata);
+	} else if (byte_for_channel == 3) {
+		if (ch->scan_type.endianness == IIO_BE)
+			tmp = get_unaligned_be24(outdata);
+		else
+			tmp = get_unaligned_le24(outdata);
+	} else {
+		return -EINVAL;
+	}
+	*data = sign_extend32(tmp, BYTES_TO_BITS(byte_for_channel) - 1);
 
 st_sensors_free_memory:
 	kfree(outdata);
author maintainer
#63 lore raw

PATCH 62/480 iio: core: fix uninitialized data in debugfs

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Dan Carpenter <[email protected]>

commit ab92ed206d41fd171ebd37bc46360d9f2140d043 upstream.

If *ppos is non-zero then simple_write_to_buffer() will not initialize the start of buf[]. Non zero values for *ppos aren't going to work anyway. Test for them at the start of the function and return -EINVAL.

Fixes 6d5dd486c715 ("iio: core: make use of simple_write_to_buffer()")
---
 drivers/iio/industrialio-core.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/industrialio-core.c +1 -1
@@ -418,7 +418,7 @@ static ssize_t iio_debugfs_write_reg(str
 	char buf[80];
 	int ret;
 
-	if (count >= sizeof(buf))
+	if (*ppos != 0 || count >= sizeof(buf))
 		return -EINVAL;
 
 	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, userbuf,
author maintainer
#64 lore raw

PATCH 63/480 iio: dac: ad3552r-hs: fix uninitialized data ni ad3552r_hs_write_data_source()

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Dan Carpenter <[email protected]>

commit eaaa7eef181892ef7ba56c6295b81f0ae4492c13 upstream.

If the *ppos value is non-zero then the simple_write_to_buffer() function won't initialized the start of the buf[] buffer. Non-zero values for *ppos won't work here generally, so just test for them and return -ENOSPC at the start of the function.

Fixes b1c5d68ea66e ("iio: dac: ad3552r-hs: add support for internal ramp")
---
 drivers/iio/dac/ad3552r-hs.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/dac/ad3552r-hs.c +1 -1
@@ -549,7 +549,7 @@ static ssize_t ad3552r_hs_write_data_sou
 
 	guard(mutex)(&st->lock);
 
-	if (count >= sizeof(buf))
+	if (*ppos != 0 || count >= sizeof(buf))
 		return -ENOSPC;
 
 	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, userbuf,
author maintainer
#65 lore raw

PATCH 64/480 iio: event: Fix event FIFO reset race

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Lars-Peter Clausen <[email protected]>

commit af791d295737ea6b6ff2c8d8488462a49c14af01 upstream.

iio_event_getfd() creates the event file descriptor with anon_inode_getfd(), which allocates a new fd, creates the anonymous file and installs it in the process fd table before returning to the caller.

The IIO code resets the event FIFO after anon_inode_getfd() has returned, but before IIO_GET_EVENT_FD_IOCTL has copied the fd number to userspace. But since fd tables are shared between threads, another thread can guess the newly allocated fd number and issue a read() on it as soon as the fd has been installed.

This means the kfifo_to_user() in iio_event_chrdev_read() can run in parallel with the kfifo_reset_out() in iio_event_getfd().

The kfifo documentation says that kfifo_reset_out() is only safe when it is called from the reader thread and there is only one concurrent reader. Otherwise it is dangerous and must be handled in the same way as kfifo_reset().

If that happens, kfifo_to_user() can advance the FIFO out index based on state from before the reset, after the reset has already moved the out index to the current in index. That can leave the FIFO with an out index past the in index. A later read() can then see an underflowed FIFO length and copy more data than the event FIFO buffer contains. This can result in an out-of-bounds read and leak adjacent kernel memory to userspace.

Move the FIFO reset before anon_inode_getfd(). At that point the event fd is marked busy, but the new fd has not been installed yet, so userspace cannot access it while the FIFO is reset.

Fixes b91accafbb10 ("iio:event: Fix and cleanup locking")
Reported-by Codex:gpt-5.5
---
 drivers/iio/industrialio-event.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/iio/industrialio-event.c +2 -3
@@ -207,6 +207,8 @@ static int iio_event_getfd(struct iio_de
 		goto unlock;
 	}
 
+	kfifo_reset_out(&ev_int->det_events);
+
 	iio_device_get(indio_dev);
 
 	fd = anon_inode_getfd("iio:event", &iio_event_chrdev_fileops,
@@ -214,10 +216,7 @@ static int iio_event_getfd(struct iio_de
 	if (fd < 0) {
 		clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags);
 		iio_device_put(indio_dev);
-	} else {
-		kfifo_reset_out(&ev_int->det_events);
 	}
-
 unlock:
 	mutex_unlock(&iio_dev_opaque->mlock);
 	return fd;
author maintainer
#66 lore raw

PATCH 65/480 iio: gyro: bmg160: bail out when bandwidth/filter is not in table

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Stepan Ionichev <[email protected]>

commit 8320c77e67382d5d55d77043a5f60a867d408a2b upstream.

bmg160_get_filter() walks bmg160_samp_freq_table[] looking for the entry matching the bw_bits value read from the chip:

	for (i = 0; i < ARRAY_SIZE(bmg160_samp_freq_table); ++i) {
		if (bmg160_samp_freq_table[i].bw_bits == bw_bits)
			break;
	}
	*val = bmg160_samp_freq_table[i].filter;

If no entry matches, i ends up equal to the array size and the next line reads one slot past the end. bmg160_set_filter() has the same shape, driven by 'val' instead of bw_bits.

smatch flags both:

drivers/iio/gyro/bmg160_core.c:204 bmg160_get_filter() error:
buffer overflow 'bmg160_samp_freq_table' 7 <= 7 drivers/iio/gyro/bmg160_core.c:222 bmg160_set_filter() error:
buffer overflow 'bmg160_samp_freq_table' 7 <= 7

Return -EINVAL when no entry matches.

The set_filter() path is reachable from userspace via the sysfs in_anglvel_filter_low_pass_3db_frequency interface, so userspace can trivially trigger the out-of-bounds read with a value that is not in bmg160_samp_freq_table[].filter.

Fixes 22b46c45fb9b ("iio:gyro:bmg160 Gyro Sensor driver")
---
 drivers/iio/gyro/bmg160_core.c |    6 ++++++
 1 file changed, 6 insertions(+)
drivers/iio/gyro/bmg160_core.c +6 -0
@@ -201,6 +201,9 @@ static int bmg160_get_filter(struct bmg1
 			break;
 	}
 
+	if (i == ARRAY_SIZE(bmg160_samp_freq_table))
+		return -EINVAL;
+
 	*val = bmg160_samp_freq_table[i].filter;
 
 	return ret ? ret : IIO_VAL_INT;
@@ -218,6 +221,9 @@ static int bmg160_set_filter(struct bmg1
 			break;
 	}
 
+	if (i == ARRAY_SIZE(bmg160_samp_freq_table))
+		return -EINVAL;
+
 	ret = regmap_write(data->regmap, BMG160_REG_PMU_BW,
 			   bmg160_samp_freq_table[i].bw_bits);
 	if (ret < 0) {
author maintainer
#67 lore raw

PATCH 66/480 iio: gyro: bmg160: wait full startup time after mode change at probe

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Stepan Ionichev <[email protected]>

commit 088fcb9b567f8723074ad9eb1bf5cb46f8a0096b upstream.

bmg160_chip_init() calls bmg160_set_mode(BMG160_MODE_NORMAL) and then waits only 500-1000 us. Per the BMG160 datasheet (BST-BMG160-DS000-07 Rev. 1.0, May 2013), the start-up and wake-up times (tsu, twusm) are 30 ms.

The same file already waits BMG160_MAX_STARTUP_TIME_MS (80 ms) in bmg160_runtime_resume() after the same set_mode(NORMAL) operation. The 500 us value at probe was likely a unit mix-up; the old comment said "500 ms" while the code used microseconds.

Reuse the same constant via msleep() and add a code comment explaining the datasheet basis for the wait. Without this, register writes that follow the mode change can hit the chip before it is ready.

Fixes 22b46c45fb9b ("iio:gyro:bmg160 Gyro Sensor driver")
---
 drivers/iio/gyro/bmg160_core.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/iio/gyro/bmg160_core.c +8 -2
@@ -264,8 +264,14 @@ static int bmg160_chip_init(struct bmg16
 	if (ret < 0)
 		return ret;
 
-	/* Wait upto 500 ms to be ready after changing mode */
-	usleep_range(500, 1000);
+	/*
+	 * Wait for the chip to be ready after switching to normal mode.
+	 * The BMG160 datasheet (BST-BMG160-DS000-07 Rev. 1.0, May 2013)
+	 * specifies a start-up / wake-up time (tsu, twusm) of 30 ms; use
+	 * BMG160_MAX_STARTUP_TIME_MS (80 ms) as a safety margin, matching
+	 * what bmg160_runtime_resume() already does.
+	 */
+	msleep(BMG160_MAX_STARTUP_TIME_MS);
 
 	/* Set Bandwidth */
 	ret = bmg160_set_bw(data, BMG160_DEF_BW);
author maintainer
#68 lore raw

PATCH 67/480 iio: imu: adis: add IRQF_NO_THREAD to non-FIFO trigger IRQ

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Runyu Xiao <[email protected]>

commit 6e1b9bff1202da55c464e36bd34a2b6863d7fe30 upstream.

devm_adis_probe_trigger() registers iio_trigger_generic_data_rdy_poll() through devm_request_irq() on the non-FIFO path, but it does not add IRQF_NO_THREAD to the IRQ flags.

When the kernel is booted with forced IRQ threading, the parent IRQ can otherwise be threaded by the IRQ core and the subsequent IIO trigger child IRQ is then dispatched from irq/... thread context instead of hardirq context. Because iio_trigger_generic_data_rdy_poll() immediately drives iio_trigger_poll(), this violates the hardirq-only IIO trigger helper contract and can push downstream trigger consumers through the wrong execution context.

Add IRQF_NO_THREAD on top of the existing adis->irq_flag value for the non-FIFO request_irq() path, while preserving the current trigger polarity and IRQF_NO_AUTOEN behavior.

Fixes fec86c6b8369 ("iio: imu: adis: Add Managed device functions")
---
 drivers/iio/imu/adis_trigger.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/imu/adis_trigger.c +1 -1
@@ -94,7 +94,7 @@ int devm_adis_probe_trigger(struct adis
 	else
 		ret = devm_request_irq(&adis->spi->dev, adis->spi->irq,
 				       &iio_trigger_generic_data_rdy_poll,
-				       adis->irq_flag,
+				       adis->irq_flag | IRQF_NO_THREAD,
 				       indio_dev->name,
 				       adis->trig);
 	if (ret)
author maintainer
#69 lore raw

PATCH 68/480 iio: imu: bmi160: add IRQF_NO_THREAD to data-ready trigger IRQ

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Runyu Xiao <[email protected]>

commit cd5a6a5096b246e10600da3ac47a1274ce9573c8 upstream.

bmi160_probe_trigger() registers iio_trigger_generic_data_rdy_poll() through devm_request_irq(), but it passes only irq_type and does not add IRQF_NO_THREAD.

When the kernel is booted with forced IRQ threading, the parent IRQ can otherwise be threaded by the IRQ core and the subsequent IIO trigger child IRQ is dispatched from irq/... thread context instead of hardirq context. Because the handler immediately pushes the event into iio_trigger_poll(), this violates the hardirq-only IIO trigger helper contract and can drive downstream trigger consumers through the wrong execution context.

Add IRQF_NO_THREAD on top of irq_type when registering the BMI160 data- ready trigger handler.

Fixes 895bf81e6bbf ("iio:bmi160: add drdy interrupt support")
---
 drivers/iio/imu/bmi160/bmi160_core.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/iio/imu/bmi160/bmi160_core.c +2 -1
@@ -788,7 +788,8 @@ int bmi160_probe_trigger(struct iio_dev
 
 	ret = devm_request_irq(&indio_dev->dev, irq,
 			       &iio_trigger_generic_data_rdy_poll,
-			       irq_type, "bmi160", data->trig);
+			       irq_type | IRQF_NO_THREAD,
+			       "bmi160", data->trig);
 	if (ret)
 		return ret;
 
author maintainer
#70 lore raw

PATCH 69/480 iio: imu: inv_icm42600: fix timestamp clock period by using lower value

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jean-Baptiste Maneyrol <[email protected]>

commit 8b0b864c11a2e2ada470f9d5010e1c2bf1eceef2 upstream.

Clock period value is used for computing periods of sampling. There is no need for it to be higher than the maximum odr, otherwise we are losing precision in the computation for nothing.

Switch clock period value to maximum odr period (8kHz).

Fixes 0ecc363ccea7 ("iio: make invensense timestamp module generic")
---
 drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c |    4 ++--
 drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c  |    4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)
drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c +2 -2
@@ -1170,10 +1170,10 @@ struct iio_dev *inv_icm42600_accel_init(
 	accel_st->filter = INV_ICM42600_FILTER_AVG_16X;
 
 	/*
-	 * clock period is 32kHz (31250ns)
+	 * clock period is 8kHz (125000ns)
 	 * jitter is +/- 2% (20 per mille)
 	 */
-	ts_chip.clock_period = 31250;
+	ts_chip.clock_period = 125000;
 	ts_chip.jitter = 20;
 	ts_chip.init_period = inv_icm42600_odr_to_period(st->conf.accel.odr);
 	inv_sensors_timestamp_init(&accel_st->ts, &ts_chip);
drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +2 -2
@@ -755,10 +755,10 @@ struct iio_dev *inv_icm42600_gyro_init(s
 	}
 
 	/*
-	 * clock period is 32kHz (31250ns)
+	 * clock period is 8kHz (125000ns)
 	 * jitter is +/- 2% (20 per mille)
 	 */
-	ts_chip.clock_period = 31250;
+	ts_chip.clock_period = 125000;
 	ts_chip.jitter = 20;
 	ts_chip.init_period = inv_icm42600_odr_to_period(st->conf.accel.odr);
 	inv_sensors_timestamp_init(&gyro_st->ts, &ts_chip);
author maintainer
#71 lore raw

PATCH 70/480 iio: imu: inv_icm42600: fix timestamping by limiting FIFO reading

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jean-Baptiste Maneyrol <[email protected]>

commit affe3f077d7a4eeb25937f5323ff059a54b4712c upstream.

Timestamps are made by measuring the chip clock using the watermark interrupts. If we read more than watermark samples as done today, we are reducing the period between interrupts and distort the time measurement. Fix that by reading only watermark samples in the interrupt case.

Fixes 7f85e42a6c54 ("iio: imu: inv_icm42600: add buffer support in iio devices")
---
 drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c |    9 +++++----
 drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h |    1 +
 2 files changed, 6 insertions(+), 4 deletions(-)
drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c +5 -4
@@ -248,6 +248,7 @@ int inv_icm42600_buffer_update_watermark
 
 	/* compute watermark value in bytes */
 	wm_size = watermark * packet_size;
+	st->fifo.watermark.value = watermark;
 
 	/* changing FIFO watermark requires to turn off watermark interrupt */
 	ret = regmap_update_bits_check(st->map, INV_ICM42600_REG_INT_SOURCE0,
@@ -454,11 +455,10 @@ int inv_icm42600_buffer_fifo_read(struct
 	st->fifo.nb.accel = 0;
 	st->fifo.nb.total = 0;
 
-	/* compute maximum FIFO read size */
+	/* compute maximum FIFO read size (watermark for max = 0 interrupt case) */
 	if (max == 0)
-		max_count = sizeof(st->fifo.data);
-	else
-		max_count = max * inv_icm42600_get_packet_size(st->fifo.en);
+		max = st->fifo.watermark.value;
+	max_count = max * inv_icm42600_get_packet_size(st->fifo.en);
 
 	/* read FIFO count value */
 	raw_fifo_count = (__be16 *)st->buffer;
@@ -574,6 +574,7 @@ int inv_icm42600_buffer_init(struct inv_
 
 	st->fifo.watermark.eff_gyro = 1;
 	st->fifo.watermark.eff_accel = 1;
+	st->fifo.watermark.value = 1;
 
 	/*
 	 * Default FIFO configuration (bits 7 to 5)
drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h +1 -0
@@ -34,6 +34,7 @@ struct inv_icm42600_fifo {
 		unsigned int accel;
 		unsigned int eff_gyro;
 		unsigned int eff_accel;
+		unsigned int value;
 	} watermark;
 	size_t count;
 	struct {
author maintainer
#72 lore raw

PATCH 71/480 iio: imu: st_lsm6dsx: deselect shub page before reading whoami

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Andreas Kempe <[email protected]>

commit aede83625ff5d9539508582036df30c809d51058 upstream.

As part of driver initialization, e.g. st_lsm6dsx_init_shub() selects the shub register page using st_lsm6dsx_set_page(). Selecting the shub register page shadows the regular register space so whoami, among other registers, is no longer accessible.

In applications where the IMU is permanently powered separately from the processor, there is a window where a reset of the CPU leaves the IMU in the shub register page. Once this occurs, any subsequent probe attempt fails because of the register shadowing.

Using the ism330dlc, the error typically looks like

    st_lsm6dsx_i2c 3-006a: unsupported whoami [10]

with the unknown whoami read from a reserved register in the shub page.

The reset register is also shadowed by the page select, preventing a reset from recovering the chip.

Unconditionally clear the shub page before the whoami readout to ensure normal register access and allow the initialization to proceed.

Place the fix in st_lsm6dsx_check_whoami() before the whoami check because hw->settings, which st_lsm6dsx_set_page() relies on, is first assigned in that function.

Placing the fix in a more logical place than the whoami check would require a bigger restructuring of the code.

Fixes c91c1c844ebd ("iio: imu: st_lsm6dsx: add i2c embedded controller support")
---
 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c |   21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +20 -1
@@ -1597,6 +1597,26 @@ static int st_lsm6dsx_check_whoami(struc
 		return -ENODEV;
 	}
 
+	hw->settings = &st_lsm6dsx_sensor_settings[i];
+
+	if (hw->settings->shub_settings.page_mux.addr) {
+		/*
+		 * If the IMU has the shub page selected on init, for example
+		 * after a CPU watchdog reset while the page is selected, the
+		 * regular register space is shadowed. While the regular
+		 * register space is shadowed, the registers needed for
+		 * initializing the IMU are not available.
+		 *
+		 * Unconditionally clear the shub page selection to ensure
+		 * normal register access.
+		 */
+		err = st_lsm6dsx_set_page(hw, false);
+		if (err < 0) {
+			dev_err(hw->dev, "failed to clear shub page\n");
+			return err;
+		}
+	}
+
 	err = regmap_read(hw->regmap, ST_LSM6DSX_REG_WHOAMI_ADDR, &data);
 	if (err < 0) {
 		dev_err(hw->dev, "failed to read whoami register\n");
@@ -1609,7 +1629,6 @@ static int st_lsm6dsx_check_whoami(struc
 	}
 
 	*name = st_lsm6dsx_sensor_settings[i].id[j].name;
-	hw->settings = &st_lsm6dsx_sensor_settings[i];
 
 	return 0;
 }
author maintainer
#73 lore raw

PATCH 72/480 iio: light: al3000a: add missing REGMAP_I2C to Kconfig

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Joshua Crofts <[email protected]>

commit a2d30022b7c316ad845d1b696e724058b88e5a4e upstream.

The KConfig entry for the al3000a is missing a select REGMAP_I2C, causing build failures.

Fixes d531b9f78949 ("iio: light: Add support for AL3000a illuminance sensor")
---
 drivers/iio/light/Kconfig |    1 +
 1 file changed, 1 insertion(+)
drivers/iio/light/Kconfig +1 -0
@@ -45,6 +45,7 @@ config ADUX1020
 
 config AL3000A
 	tristate "AL3000a ambient light sensor"
+	select REGMAP_I2C
 	depends on I2C
 	help
 	  Say Y here if you want to build a driver for the Dyna Image AL3000a
author maintainer
#74 lore raw

PATCH 73/480 iio: light: al3010: add missing REGMAP_I2C to Kconfig

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Joshua Crofts <[email protected]>

commit 84486e3bbda18a2df1ed74ca78e1e14bde9a941b upstream.

The KConfig entry for the AL3010 is missing a select REGMAP_I2C, causing build failures.

Fixes 0e5e21e23dd6 ("iio: light: al3010: Implement regmap support")
---
 drivers/iio/light/Kconfig |    1 +
 1 file changed, 1 insertion(+)
drivers/iio/light/Kconfig +1 -0
@@ -56,6 +56,7 @@ config AL3000A
 
 config AL3010
 	tristate "AL3010 ambient light sensor"
+	select REGMAP_I2C
 	depends on I2C
 	help
 	  Say Y here if you want to build a driver for the Dyna Image AL3010
author maintainer
#75 lore raw

PATCH 74/480 iio: light: al3010: fix incorrect scale for the highest gain range

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Vidhu Sarwal <[email protected]>

commit aa411adc6ce40ad1a55ebc965f255a4cfc0005f8 upstream.

al3010_scales[] encodes the highest gain range as {0, 1187200}. For IIO_VAL_INT_PLUS_MICRO, the fractional part must be less than 1000000, so the scale 1.1872 should instead be represented as { 1, 187200 }.

Since write_raw() compares the value from userspace against this table, writing the advertised 1.1872 scale never matches the malformed entry and returns -EINVAL. As a result, the highest gain range cannot be selected. Reading the scale in that state also reports the malformed value.

Fixes c36b5195ab70 ("iio: light: add Dyna-Image AL3010 driver")
---
 drivers/iio/light/al3010.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/light/al3010.c +1 -1
@@ -42,7 +42,7 @@ enum al3xxxx_range {
 };
 
 static const int al3010_scales[][2] = {
-	{0, 1187200}, {0, 296800}, {0, 74200}, {0, 18600}
+	{ 1, 187200 }, { 0, 296800 }, { 0, 74200 }, { 0, 18600 },
 };
 
 static const struct regmap_config al3010_regmap_config = {
author maintainer
#76 lore raw

PATCH 75/480 iio: light: al3010: read both ALS ADC registers again

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Alexander A. Klimov <[email protected]>

commit ee78fae068f52a5582aaf448d9414f826855c106 upstream.

al3010_read_raw() used to read two adjacent registers until the driver was modernized using the regmap framework. That cleanup accidentally replaced the 16-bit word read with a single byte read. I'm reverting latter.

Fixes 0e5e21e23dd6 ("iio: light: al3010: Implement regmap support")
---
 drivers/iio/light/al3010.c |    8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/iio/light/al3010.c +5 -3
@@ -111,7 +111,8 @@ static int al3010_read_raw(struct iio_de
 			   int *val2, long mask)
 {
 	struct al3010_data *data = iio_priv(indio_dev);
-	int ret, gain, raw;
+	int ret, gain;
+	__le16 raw;
 
 	switch (mask) {
 	case IIO_CHAN_INFO_RAW:
@@ -120,11 +121,12 @@ static int al3010_read_raw(struct iio_de
 		 * - low byte of output is stored at AL3010_REG_DATA_LOW
 		 * - high byte of output is stored at AL3010_REG_DATA_LOW + 1
 		 */
-		ret = regmap_read(data->regmap, AL3010_REG_DATA_LOW, &raw);
+		ret = regmap_bulk_read(data->regmap, AL3010_REG_DATA_LOW,
+				       &raw, sizeof(raw));
 		if (ret)
 			return ret;
 
-		*val = raw;
+		*val = le16_to_cpu(raw);
 
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_SCALE:
author maintainer
#77 lore raw

PATCH 76/480 iio: light: al3320a: add missing REGMAP_I2C to Kconfig

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Joshua Crofts <[email protected]>

commit 9efcc9ba9b2e940cc01e63d132ae741e4c5d09c7 upstream.

The Kconfig entry for the al3320a is missing a select REGMAP_I2C, causing build failures.

Fixes 1850e6ae7f91 ("iio: light: al3320a: Implement regmap support")
---
 drivers/iio/light/Kconfig |    1 +
 1 file changed, 1 insertion(+)
drivers/iio/light/Kconfig +1 -0
@@ -67,6 +67,7 @@ config AL3010
 
 config AL3320A
 	tristate "AL3320A ambient light sensor"
+	select REGMAP_I2C
 	depends on I2C
 	help
 	  Say Y here if you want to build a driver for the Dyna Image AL3320A
author maintainer
#78 lore raw

PATCH 77/480 iio: light: al3320a: read both ALS ADC registers again

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Alexander A. Klimov <[email protected]>

commit 744bccc2647c6b2206290e8e40890a23812116b3 upstream.

al3320a_read_raw() used to read two adjacent registers until the driver was modernized using the regmap framework. That cleanup accidentally replaced the 16-bit word read with a single byte read. I'm reverting latter.

Fixes 1850e6ae7f91 ("iio: light: al3320a: Implement regmap support")
---
 drivers/iio/light/al3320a.c |    8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/iio/light/al3320a.c +5 -3
@@ -135,7 +135,8 @@ static int al3320a_read_raw(struct iio_d
 			    int *val2, long mask)
 {
 	struct al3320a_data *data = iio_priv(indio_dev);
-	int ret, gain, raw;
+	int ret, gain;
+	__le16 raw;
 
 	switch (mask) {
 	case IIO_CHAN_INFO_RAW:
@@ -144,11 +145,12 @@ static int al3320a_read_raw(struct iio_d
 		 * - low byte of output is stored at AL3320A_REG_DATA_LOW
 		 * - high byte of output is stored at AL3320A_REG_DATA_LOW + 1
 		 */
-		ret = regmap_read(data->regmap, AL3320A_REG_DATA_LOW, &raw);
+		ret = regmap_bulk_read(data->regmap, AL3320A_REG_DATA_LOW,
+				       &raw, sizeof(raw));
 		if (ret)
 			return ret;
 
-		*val = raw;
+		*val = le16_to_cpu(raw);
 
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_SCALE:
author maintainer
#79 lore raw

PATCH 78/480 iio: light: gp2ap002: fix runtime PM leak on read error

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Biren Pandya <[email protected]>

commit 38b72267b7e22768a1f26d9935de4e1752a1dc85 upstream.

gp2ap002_read_raw() calls pm_runtime_get_sync() before reading the lux value, but if gp2ap002_get_lux() fails, it returns directly. This skips the pm_runtime_put_autosuspend() call at the "out" label, permanently leaking a runtime PM reference and preventing the device from autosuspending.

Replace the direct return with a "goto out" to ensure the reference is properly dropped on the error path.

Fixes f6dbf83c17cb ("iio: light: gp2ap002: Take runtime PM reference on light read")
---
 drivers/iio/light/gp2ap002.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/light/gp2ap002.c +1 -1
@@ -258,7 +258,7 @@ static int gp2ap002_read_raw(struct iio_
 		case IIO_LIGHT:
 			ret = gp2ap002_get_lux(gp2ap002);
 			if (ret < 0)
-				return ret;
+				goto out;
 			*val = ret;
 			ret = IIO_VAL_INT;
 			goto out;
author maintainer
#80 lore raw

PATCH 79/480 iio: light: opt3001: fix missing state reset on timeout

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Joshua Crofts <[email protected]>

commit c123ca6ee26ad98f70a866ff428b08145c5a24fe upstream.

Currently in the function opt3001_get_processed(), there is a check that directly returns -ETIMEDOUT if the conversion IRQ times out, completely bypassing the err label, leaving ok_to_ignore_lock permanently true, potentially breaking the device's falling threshold interrupt detection.

Assign -ETIMEDOUT to the return variable and jump to the error label to ensure ok_to_ignore_lock is properly reset.

---
 drivers/iio/light/opt3001.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/iio/light/opt3001.c +4 -2
@@ -366,8 +366,10 @@ static int opt3001_get_processed(struct
 		ret = wait_event_timeout(opt->result_ready_queue,
 				opt->result_ready,
 				msecs_to_jiffies(OPT3001_RESULT_READY_LONG));
-		if (ret == 0)
-			return -ETIMEDOUT;
+		if (ret == 0) {
+			ret = -ETIMEDOUT;
+			goto err;
+		}
 	} else {
 		/* Sleep for result ready time */
 		timeout = (opt->int_time == OPT3001_INT_TIME_SHORT) ?
author maintainer
#81 lore raw

PATCH 80/480 iio: light: tsl2591: return actual error from probe IRQ failure

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Stepan Ionichev <[email protected]>

commit a00ffd15674bfaf8b906503c1600e3d8709af56c upstream.

When devm_request_threaded_irq() fails, probe logs the error and then returns -EINVAL, dropping the real error code and breaking the deferred-probe flow for -EPROBE_DEFER.

Return ret directly; the IRQ subsystem already prints on failure.

Fixes 2335f0d7c790 ("iio: light: Added AMS tsl2591 driver implementation")
---
 drivers/iio/light/tsl2591.c |    6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/iio/light/tsl2591.c +2 -4
@@ -1137,10 +1137,8 @@ static int tsl2591_probe(struct i2c_clie
 						NULL, tsl2591_event_handler,
 						IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
 						"tsl2591_irq", indio_dev);
-		if (ret) {
-			dev_err_probe(&client->dev, ret, "IRQ request error\n");
-			return -EINVAL;
-		}
+		if (ret)
+			return ret;
 		indio_dev->info = &tsl2591_info;
 	} else {
 		indio_dev->info = &tsl2591_info_no_irq;
author maintainer
#82 lore raw

PATCH 81/480 iio: light: veml6030: fix channel type when pushing events

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Javier Carrasco <[email protected]>

commit c52bb33b641ebaae3e209f97714cb1758206f7d9 upstream.

The events are registered for IIO_LIGHT and not for IIO_INTENSITY. Use the correct channel type.

When at it, fix minor checkpatch code style warning (alignment).

Fixes 7b779f573c48 ("iio: light: add driver for veml6030 ambient light sensor")
---
 drivers/iio/light/veml6030.c |    8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/iio/light/veml6030.c +5 -3
@@ -875,9 +875,11 @@ static irqreturn_t veml6030_event_handle
 	else
 		evtdir = IIO_EV_DIR_FALLING;
 
-	iio_push_event(indio_dev, IIO_UNMOD_EVENT_CODE(IIO_INTENSITY,
-					0, IIO_EV_TYPE_THRESH, evtdir),
-					iio_get_time_ns(indio_dev));
+	iio_push_event(indio_dev, IIO_UNMOD_EVENT_CODE(IIO_LIGHT,
+						       0,
+						       IIO_EV_TYPE_THRESH,
+						       evtdir),
+		       iio_get_time_ns(indio_dev));
 
 	return IRQ_HANDLED;
 }
author maintainer
#83 lore raw

PATCH 82/480 iio: magnetometer: ak8975: Add missed pm_runtime_put_autosuspend() call

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Andy Shevchenko <[email protected]>

commit e94944d7364d3ddb273539492f9bd9c9a622549a upstream.

On the failure in the ak8975_read_axis() the PM runtime gets unbalanced. Balance it by calling pm_runtime_put_autosuspend() on error path as well.

---
 drivers/iio/magnetometer/ak8975.c |    1 +
 1 file changed, 1 insertion(+)
drivers/iio/magnetometer/ak8975.c +1 -0
@@ -784,6 +784,7 @@ static int ak8975_read_axis(struct iio_d
 
 exit:
 	mutex_unlock(&data->lock);
+	pm_runtime_put_autosuspend(&data->client->dev);
 	dev_err(&client->dev, "Error in reading axis\n");
 	return ret;
 }
author maintainer
#84 lore raw

PATCH 83/480 iio: pressure: bmp280: zero-init bmp580 trigger handler buffer

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: David Carlier <[email protected]>

commit 1172160f2a2de7bade3bec64b8c5ecf945cde5ed upstream.

bmp580_trigger_handler() builds an on-stack scan buffer containing two __le32 fields and an aligned_s64 timestamp, and pushes it to userspace via iio_push_to_buffers_with_ts(). However, only the low 3 bytes of each __le32 field are populated by the device data:

	memcpy(&buffer.comp_press, &data->buf[3], 3);
	memcpy(&buffer.comp_temp,  &data->buf[0], 3);

The high byte of each field is left uninitialised on the stack. The bmp580 channels declare storagebits = 32, so the IIO core transports all four bytes per sample to userspace as part of the scan element, leaking two bytes of kernel stack per scan.

Zero-initialise the buffer before populating it, mirroring the fix applied to bme280_trigger_handler() in commit 018f50909e66 ("iio:
bmp280: zero-init buffer").

Fixes 872c8014e05e ("iio: pressure: bmp280: drop sensor_data array")
---
 drivers/iio/pressure/bmp280-core.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/pressure/bmp280-core.c +1 -1
@@ -1910,7 +1910,7 @@ static irqreturn_t bmp380_trigger_handle
 		u32 comp_press;
 		s32 comp_temp;
 		aligned_s64 timestamp;
-	} buffer;
+	} buffer = { };
 	int ret;
 
 	guard(mutex)(&data->lock);
author maintainer
#85 lore raw

PATCH 84/480 iio: pressure: mpl115: fix runtime PM leak on read error

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Biren Pandya <[email protected]>

commit fbe67ff37a6fd855a6c097f84f3738bd13d0a898 upstream.

mpl115_read_raw() takes a runtime PM reference with pm_runtime_get_sync() before reading the processed pressure or raw temperature, but on the read error path it returns without calling pm_runtime_put_autosuspend(). Each failed read therefore leaks a runtime PM reference and prevents the device from autosuspending.

Drop the reference before checking the return value so both the success and error paths are balanced.

Fixes 0c3a333524a3 ("iio: pressure: mpl115: Implementing low power mode by shutdown gpio")
Assisted-by Claude:claude-opus-4-8 coccinelle
---
 drivers/iio/pressure/mpl115.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/iio/pressure/mpl115.c +2 -2
@@ -106,18 +106,18 @@ static int mpl115_read_raw(struct iio_de
 	case IIO_CHAN_INFO_PROCESSED:
 		pm_runtime_get_sync(data->dev);
 		ret = mpl115_comp_pressure(data, val, val2);
+		pm_runtime_put_autosuspend(data->dev);
 		if (ret < 0)
 			return ret;
-		pm_runtime_put_autosuspend(data->dev);
 
 		return IIO_VAL_INT_PLUS_MICRO;
 	case IIO_CHAN_INFO_RAW:
 		pm_runtime_get_sync(data->dev);
 		/* temperature -5.35 C / LSB, 472 LSB is 25 C */
 		ret = mpl115_read_temp(data);
+		pm_runtime_put_autosuspend(data->dev);
 		if (ret < 0)
 			return ret;
-		pm_runtime_put_autosuspend(data->dev);
 		*val = ret >> 6;
 
 		return IIO_VAL_INT;
author maintainer
#86 lore raw

PATCH 85/480 iio: proximity: vl53l0x: notify trigger and clear IRQ on error paths

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Stepan Ionichev <[email protected]>

commit be843b0579f872ec7590d825e2c9a656d4790c4b upstream.

vl53l0x_trigger_handler() returns directly on the I2C read failure paths without calling iio_trigger_notify_done() or vl53l0x_clear_irq().

A single transient i2c_smbus_read_i2c_block_data() failure (negative errno or a short read) therefore leaves two pieces of state behind:

- iio_trigger_notify_done() never decrements the trigger's use_count,

    so iio_trigger_poll_nested() silently drops further dispatches
    (see industrialio-trigger.c, the !atomic_read(&trig->use_count)
    guard);

- vl53l0x_clear_irq() never writes SYSTEM_INTERRUPT_CLEAR, so the chip keeps the DRDY interrupt asserted.

The sensor's buffer mode stays wedged from then on, recoverable only by re-binding the driver. The sibling driver vl53l1x-i2c.c handles exactly the same case correctly by jumping to a "notify_and_clear_irq" label that always calls both helpers; mirror that here.

The bogus negative-int return value cast to irqreturn_t also goes away as a side effect.

Fixes 762186c6e7b1 ("iio: proximity: vl53l0x-i2c: Added continuous mode support")
---
 drivers/iio/proximity/vl53l0x-i2c.c |    7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)
drivers/iio/proximity/vl53l0x-i2c.c +3 -4
@@ -87,15 +87,14 @@ static irqreturn_t vl53l0x_trigger_handl
 	ret = i2c_smbus_read_i2c_block_data(data->client,
 					VL_REG_RESULT_RANGE_STATUS,
 					sizeof(buffer), buffer);
-	if (ret < 0)
-		return ret;
-	else if (ret != 12)
-		return -EREMOTEIO;
+	if (ret != 12)
+		goto done;
 
 	scan.chan = get_unaligned_be16(&buffer[10]);
 	iio_push_to_buffers_with_ts(indio_dev, &scan, sizeof(scan),
 				    iio_get_time_ns(indio_dev));
 
+done:
 	iio_trigger_notify_done(indio_dev->trig);
 	vl53l0x_clear_irq(data);
 
author maintainer
#87 lore raw

PATCH 86/480 iio: resolver: ad2s1210: notify trigger and clear state on fault read error

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Stepan Ionichev <[email protected]>

commit 70247658d0e783c93b48fcbc3b81d99e992ff478 upstream.

ad2s1210_trigger_handler() walks several scan-mask branches and uses "goto error_ret" to land on the iio_trigger_notify_done() teardown at the bottom of the function for every I/O error -- except the MOD_CONFIG fault-register read, which uses a bare "return ret":

	if (st->fixed_mode == MOD_CONFIG) {
		unsigned int reg_val;

		ret = regmap_read(st->regmap, AD2S1210_REG_FAULT, &reg_val);
		if (ret < 0)
			return ret;
		...
	}

Two problems on that path:

- the handler returns a negative errno where the prototype expects an irqreturn_t (IRQ_HANDLED / IRQ_NONE), so the caller in the IIO core sees a value outside the enum;
- iio_trigger_notify_done() is skipped, leaving the trigger busy-flag set. A single transient SPI/regmap error on the fault read then wedges the trigger so subsequent samples are dropped until the consumer is detached.

Convert the error path to "goto error_ret" so the failure path goes through the same notify_done() teardown as every other error in the handler.

Fixes f9b9ff95be8c ("iio: resolver: ad2s1210: add support for adi,fixed-mode")
---
 drivers/iio/resolver/ad2s1210.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/resolver/ad2s1210.c +1 -1
@@ -1334,7 +1334,7 @@ static irqreturn_t ad2s1210_trigger_hand
 
 		ret = regmap_read(st->regmap, AD2S1210_REG_FAULT, &reg_val);
 		if (ret < 0)
-			return ret;
+			goto error_ret;
 
 		st->sample.fault = reg_val;
 	}
author maintainer
#88 lore raw

PATCH 87/480 iio: temperature: Build mlx90635 with CONFIG_MLX90635

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Pengpeng Hou <[email protected]>

commit 63a76e3a587c4143e8e24e8a6b0c232fa0676034 upstream.

drivers/iio/temperature/Kconfig has a dedicated MLX90635 option, but the Makefile currently builds mlx90635.o under CONFIG_MLX90632.

This means enabling CONFIG_MLX90635 alone does not carry its provider object into the build, while enabling CONFIG_MLX90632 unexpectedly also builds mlx90635.o.

Gate mlx90635.o on the matching generated Kconfig symbol.

Fixes a1d1ba5e1c28 ("iio: temperature: mlx90635 MLX90635 IR Temperature sensor")
---
 drivers/iio/temperature/Makefile |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/temperature/Makefile +1 -1
@@ -13,7 +13,7 @@ obj-$(CONFIG_MAX31865) += max31865.o
 obj-$(CONFIG_MCP9600) += mcp9600.o
 obj-$(CONFIG_MLX90614) += mlx90614.o
 obj-$(CONFIG_MLX90632) += mlx90632.o
-obj-$(CONFIG_MLX90632) += mlx90635.o
+obj-$(CONFIG_MLX90635) += mlx90635.o
 obj-$(CONFIG_TMP006) += tmp006.o
 obj-$(CONFIG_TMP007) += tmp007.o
 obj-$(CONFIG_TMP117) += tmp117.o
author maintainer
#89 lore raw

PATCH 88/480 iio: temperature: ltc2983: Fix n_wires default bypassing rotation check

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Liviu Stan <[email protected]>

commit 434c150752675f44dc52c384a7fa22e5176bc35a upstream.

When adi,number-of-wires is absent, n_wires is left at 0. The binding documents a default of 2 wires, matching the hardware default. However the current-rotate validation checks n_wires == 2 || n_wires == 3, so with n_wires = 0 the guard is bypassed and adi,current-rotate is accepted for a 2-wire RTD.

Initialize n_wires = 2 to match the binding default and ensure the rotation check fires correctly when the property is absent.

Fixes f110f3188e56 ("iio: temperature: Add support for LTC2983")
---
 drivers/iio/temperature/ltc2983.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/temperature/ltc2983.c +1 -1
@@ -741,7 +741,7 @@ ltc2983_rtd_new(const struct fwnode_hand
 	struct ltc2983_rtd *rtd;
 	int ret = 0;
 	struct device *dev = &st->spi->dev;
-	u32 excitation_current = 0, n_wires = 0;
+	u32 excitation_current = 0, n_wires = 2;
 
 	rtd = devm_kzalloc(dev, sizeof(*rtd), GFP_KERNEL);
 	if (!rtd)
author maintainer
#90 lore raw

PATCH 89/480 iio: temperature: ltc2983: Fix reinit_completion() called after conversion start

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Liviu Stan <[email protected]>

commit 5cb9fdb446bfc3ae0524496f53fb68e67051701b upstream.

reinit_completion() was called after regmap_write() initiated the hardware conversion, creating a race window where the interrupt could fire and call complete() before reinit_completion() reset the completion.

Move reinit_completion() before the regmap_write() to close the race. ltc2983_eeprom_cmd() already does it in the correct order.

Fixes f110f3188e56 ("iio: temperature: Add support for LTC2983")
---
 drivers/iio/temperature/ltc2983.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/iio/temperature/ltc2983.c +1 -2
@@ -1177,12 +1177,11 @@ static int ltc2983_chan_read(struct ltc2
 	start_conversion |= LTC2983_STATUS_CHAN_SEL(sensor->chan);
 	dev_dbg(&st->spi->dev, "Start conversion on chan:%d, status:%02X\n",
 		sensor->chan, start_conversion);
+	reinit_completion(&st->completion);
 	/* start conversion */
 	ret = regmap_write(st->regmap, LTC2983_STATUS_REG, start_conversion);
 	if (ret)
 		return ret;
-
-	reinit_completion(&st->completion);
 	/*
 	 * wait for conversion to complete.
 	 * 300 ms should be more than enough to complete the conversion.
author maintainer
#91 lore raw

PATCH 90/480 iio: temperature: tmp006: use devm_iio_trigger_register

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Stepan Ionichev <[email protected]>

commit 3c5eed894efd93d68d7f6a359a81ddef0e928774 upstream.

tmp006_probe() allocates the DRDY trigger with devm_iio_trigger_alloc() but registers it with plain iio_trigger_register(). The driver has no .remove() callback, so on module unload the trigger stays in the global trigger list while its memory is freed by devm, leaving a dangling entry.

Switch to devm_iio_trigger_register() so the registration is undone in the same devm scope as the allocation.

Fixes 91f75ccf9f03 ("iio: temperature: tmp006: add triggered buffer support")
---
 drivers/iio/temperature/tmp006.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/temperature/tmp006.c +1 -1
@@ -350,7 +350,7 @@ static int tmp006_probe(struct i2c_clien
 
 		data->drdy_trig->ops = &tmp006_trigger_ops;
 		iio_trigger_set_drvdata(data->drdy_trig, indio_dev);
-		ret = iio_trigger_register(data->drdy_trig);
+		ret = devm_iio_trigger_register(&client->dev, data->drdy_trig);
 		if (ret)
 			return ret;
 
author maintainer
#92 lore raw

PATCH 91/480 ALSA: usx2y: us144mkii: fix work UAF on disconnect

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: HyeongJun An <[email protected]>

commit 147996e7e7c9e8339c0e04f6fa7ccb3e4d448ff7 upstream.

tascam_disconnect() cancels capture_work and midi_in_work before usb_kill_anchored_urbs() kills the capture/MIDI-in URBs. Those URBs self-resubmit, and their completion handlers reschedule the work.

A URB that completes in the small window between cancel_work_sync() and usb_kill_anchored_urbs() therefore re-arms the work after its only cancel. Nothing cancels it again before snd_card_free() frees the card-private tascam structure, so the work handler then runs on freed memory.

Kill the anchored URBs before cancelling the work; once the work is cancelled no remaining URB can complete to re-arm it.

Fixes c1bb0c13e430 ("ALSA: usb-audio: us144mkii: Implement audio capture and decoding")
Assisted-by Claude:claude-opus-4-8
---
 sound/usb/usx2y/us144mkii.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)
sound/usb/usx2y/us144mkii.c +11 -6
index 94553b61013c..58ef23146f20 100644
@@ -585,19 +585,24 @@ static void tascam_disconnect(struct usb_interface *intf)
 		return;
 
 	if (intf->cur_altsetting->desc.bInterfaceNumber == 0) {
-		/* Ensure all deferred work is complete before freeing resources */
 		snd_card_disconnect(tascam->card);
-		cancel_work_sync(&tascam->stop_work);
-		cancel_work_sync(&tascam->capture_work);
-		cancel_work_sync(&tascam->midi_in_work);
-		cancel_work_sync(&tascam->midi_out_work);
-		cancel_work_sync(&tascam->stop_pcm_work);
 
+		/*
+		 * Kill the URBs before cancelling the work, so a late URB
+		 * completion cannot re-arm a work that then runs after
+		 * snd_card_free().
+		 */
 		usb_kill_anchored_urbs(&tascam->playback_anchor);
 		usb_kill_anchored_urbs(&tascam->capture_anchor);
 		usb_kill_anchored_urbs(&tascam->feedback_anchor);
 		usb_kill_anchored_urbs(&tascam->midi_in_anchor);
 		usb_kill_anchored_urbs(&tascam->midi_out_anchor);
+
+		cancel_work_sync(&tascam->stop_work);
+		cancel_work_sync(&tascam->capture_work);
+		cancel_work_sync(&tascam->midi_in_work);
+		cancel_work_sync(&tascam->midi_out_work);
+		cancel_work_sync(&tascam->stop_pcm_work);
 		timer_delete_sync(&tascam->error_timer);
 		tascam_free_urbs(tascam);
 		snd_card_free(tascam->card);
Signature · 1 line
2.55.0
author maintainer
#93 lore raw

PATCH 92/480 ALSA: virtio: Add missing 384 kHz PCM rate mapping

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Cássio Gabriel <[email protected]>

commit 83fbbcb7935ec6d2c8ba3bc133e8a0ead2ab0b2d upstream.

The VirtIO sound UAPI defines VIRTIO_SND_PCM_RATE_384000, and ALSA has SNDRV_PCM_RATE_384000. However, virtio-snd's rate conversion tables stop at 192 kHz.

A device advertising only 384 kHz is rejected as having no supported PCM frame rates. A device advertising 384 kHz together with lower rates does not expose 384 kHz through the ALSA hardware constraints. The selected ALSA rate also needs a reverse mapping for SET_PARAMS.

Add the missing 384 kHz entries to both conversion tables.

Fixes 29b96bf50ba9 ("ALSA: virtio: build PCM devices and substream hardware descriptors")
Fixes da76e9f3e43a ("ALSA: virtio: PCM substream operators")
---
 sound/virtio/virtio_pcm.c     |    3 ++-
 sound/virtio/virtio_pcm_ops.c |    3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)
sound/virtio/virtio_pcm.c +2 -1
@@ -77,7 +77,8 @@ static const struct virtsnd_v2a_rate g_v
 	[VIRTIO_SND_PCM_RATE_88200] = { SNDRV_PCM_RATE_88200, 88200 },
 	[VIRTIO_SND_PCM_RATE_96000] = { SNDRV_PCM_RATE_96000, 96000 },
 	[VIRTIO_SND_PCM_RATE_176400] = { SNDRV_PCM_RATE_176400, 176400 },
-	[VIRTIO_SND_PCM_RATE_192000] = { SNDRV_PCM_RATE_192000, 192000 }
+	[VIRTIO_SND_PCM_RATE_192000] = { SNDRV_PCM_RATE_192000, 192000 },
+	[VIRTIO_SND_PCM_RATE_384000] = { SNDRV_PCM_RATE_384000, 384000 }
 };
 
 /**
sound/virtio/virtio_pcm_ops.c +2 -1
@@ -90,7 +90,8 @@ static const struct virtsnd_a2v_rate g_a
 	{ 88200, VIRTIO_SND_PCM_RATE_88200 },
 	{ 96000, VIRTIO_SND_PCM_RATE_96000 },
 	{ 176400, VIRTIO_SND_PCM_RATE_176400 },
-	{ 192000, VIRTIO_SND_PCM_RATE_192000 }
+	{ 192000, VIRTIO_SND_PCM_RATE_192000 },
+	{ 384000, VIRTIO_SND_PCM_RATE_384000 }
 };
 
 static int virtsnd_pcm_sync_stop(struct snd_pcm_substream *substream);
author maintainer
#94 lore raw

PATCH 93/480 ALSA: virtio: Validate control metadata from the device

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Cássio Gabriel <[email protected]>

commit c77a6cbb36ff8cbc1f084d94f8dcda5250935271 upstream.

virtio-snd control handling trusts the device-provided control type and value count returned by the device.

That metadata is then used directly to index g_v2a_type_map[] in virtsnd_kctl_info(), and to size loops and memcpy() operations in virtsnd_kctl_get() and virtsnd_kctl_put() against fixed-size virtio_snd_ctl_value and snd_ctl_elem_value arrays.

A buggy or malicious device can therefore trigger out-of-bounds access by advertising an invalid control type or an oversized value count.

Validate control type and count once in virtsnd_kctl_parse_cfg(), before querying enumerated items or exposing the control to ALSA.

---
 sound/virtio/virtio_kctl.c |   50 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)
sound/virtio/virtio_kctl.c +50 -0
@@ -18,6 +18,21 @@ static const snd_ctl_elem_type_t g_v2a_t
 	[VIRTIO_SND_CTL_TYPE_IEC958] = SNDRV_CTL_ELEM_TYPE_IEC958
 };
 
+/* Map for converting VirtIO types to maximum value counts. */
+static const unsigned int g_v2a_count_map[] = {
+	[VIRTIO_SND_CTL_TYPE_BOOLEAN] =
+		ARRAY_SIZE(((struct virtio_snd_ctl_value *)0)->value.integer),
+	[VIRTIO_SND_CTL_TYPE_INTEGER] =
+		ARRAY_SIZE(((struct virtio_snd_ctl_value *)0)->value.integer),
+	[VIRTIO_SND_CTL_TYPE_INTEGER64] =
+		ARRAY_SIZE(((struct virtio_snd_ctl_value *)0)->value.integer64),
+	[VIRTIO_SND_CTL_TYPE_ENUMERATED] =
+		ARRAY_SIZE(((struct virtio_snd_ctl_value *)0)->value.enumerated),
+	[VIRTIO_SND_CTL_TYPE_BYTES] =
+		ARRAY_SIZE(((struct virtio_snd_ctl_value *)0)->value.bytes),
+	[VIRTIO_SND_CTL_TYPE_IEC958] = 1
+};
+
 /* Map for converting VirtIO access rights to ALSA access rights. */
 static const unsigned int g_v2a_access_map[] = {
 	[VIRTIO_SND_CTL_ACCESS_READ] = SNDRV_CTL_ELEM_ACCESS_READ,
@@ -36,6 +51,37 @@ static const unsigned int g_v2a_mask_map
 	[VIRTIO_SND_CTL_EVT_MASK_TLV] = SNDRV_CTL_EVENT_MASK_TLV
 };
 
+static int virtsnd_kctl_validate_info(struct virtio_snd *snd, u32 cid,
+				      struct virtio_snd_ctl_info *kinfo)
+{
+	struct virtio_device *vdev = snd->vdev;
+	unsigned int type = le32_to_cpu(kinfo->type);
+	unsigned int count = le32_to_cpu(kinfo->count);
+
+	if (type >= ARRAY_SIZE(g_v2a_type_map)) {
+		dev_err(&vdev->dev, "control #%u: unknown type %u\n",
+			cid, type);
+		return -EINVAL;
+	}
+
+	if (count > g_v2a_count_map[type] ||
+	    (type == VIRTIO_SND_CTL_TYPE_IEC958 && count != 1)) {
+		dev_err(&vdev->dev, "control #%u: invalid count %u for type %u\n",
+			cid, count, type);
+		return -EINVAL;
+	}
+
+	if (type == VIRTIO_SND_CTL_TYPE_ENUMERATED &&
+	    !le32_to_cpu(kinfo->value.enumerated.items)) {
+		dev_err(&vdev->dev,
+			"control #%u: no items for enumerated control\n",
+			cid);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 /**
  * virtsnd_kctl_info() - Returns information about the control.
  * @kcontrol: ALSA control element.
@@ -385,6 +431,10 @@ int virtsnd_kctl_parse_cfg(struct virtio
 		struct virtio_snd_ctl_info *kinfo = &snd->kctl_infos[i];
 		unsigned int type = le32_to_cpu(kinfo->type);
 
+		rc = virtsnd_kctl_validate_info(snd, i, kinfo);
+		if (rc)
+			return rc;
+
 		if (type == VIRTIO_SND_CTL_TYPE_ENUMERATED) {
 			rc = virtsnd_kctl_get_enum_items(snd, i);
 			if (rc)
author maintainer
#95 lore raw

PATCH 94/480 ALSA: ymfpci: check snd_ctl_new1() return value

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Zhao Dongdong <[email protected]>

commit e64d170346d00b580c0043de3e5ccb3e331c47d4 upstream.

snd_ctl_new1() can return NULL when memory allocation fails. snd_ymfpci_create_spdif_controls() does not check the return value before dereferencing kctl->id.device, which can lead to a NULL pointer dereference.

Add NULL checks after snd_ctl_new1() calls and return -ENOMEM if any fails.

Assisted-by Opencode:DeepSeek-V4-Flash
Fixes c9b83ae4a160 ("ALSA: ymfpci: Fix kctl->id initialization")
---
 sound/pci/ymfpci/ymfpci_main.c |    6 ++++++
 1 file changed, 6 insertions(+)
sound/pci/ymfpci/ymfpci_main.c +6 -0
@@ -1781,16 +1781,22 @@ int snd_ymfpci_mixer(struct snd_ymfpci *
 	if (snd_BUG_ON(!chip->pcm_spdif))
 		return -ENXIO;
 	kctl = snd_ctl_new1(&snd_ymfpci_spdif_default, chip);
+	if (!kctl)
+		return -ENOMEM;
 	kctl->id.device = chip->pcm_spdif->device;
 	err = snd_ctl_add(chip->card, kctl);
 	if (err < 0)
 		return err;
 	kctl = snd_ctl_new1(&snd_ymfpci_spdif_mask, chip);
+	if (!kctl)
+		return -ENOMEM;
 	kctl->id.device = chip->pcm_spdif->device;
 	err = snd_ctl_add(chip->card, kctl);
 	if (err < 0)
 		return err;
 	kctl = snd_ctl_new1(&snd_ymfpci_spdif_stream, chip);
+	if (!kctl)
+		return -ENOMEM;
 	kctl->id.device = chip->pcm_spdif->device;
 	err = snd_ctl_add(chip->card, kctl);
 	if (err < 0)
author maintainer
#96 lore raw

PATCH 95/480 ALSA: aoa: check snd_ctl_new1() return value

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Zhao Dongdong <[email protected]>

commit 8df560fefe6fed6a20b7e06720eeaeccec349ac0 upstream.

snd_ctl_new1() can return NULL when memory allocation fails. In layout.c, the function does not check the return value before dereferencing ctl->id.name or passing to aoa_snd_ctl_add(), which can lead to a NULL pointer dereference.

Add NULL checks after snd_ctl_new1() calls and return early if any fails.

Assisted-by Opencode:DeepSeek-V4-Flash
Fixes f3d9478b2ce4 ("[ALSA] snd-aoa: add snd-aoa")
---
 sound/aoa/fabrics/layout.c |    6 ++++++
 1 file changed, 6 insertions(+)
sound/aoa/fabrics/layout.c +6 -0
@@ -948,6 +948,8 @@ static void layout_attached_codec(struct
 			if (lineout == 1)
 				ldev->gpio.methods->set_lineout(codec->gpio, 1);
 			ctl = snd_ctl_new1(&lineout_ctl, codec->gpio);
+			if (!ctl)
+				return;
 			if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
 				strscpy(ctl->id.name, "Headphone Switch");
 			ldev->lineout_ctrl = ctl;
@@ -961,12 +963,16 @@ static void layout_attached_codec(struct
 			if (ldev->have_lineout_detect) {
 				ctl = snd_ctl_new1(&lineout_detect_choice,
 						   ldev);
+				if (!ctl)
+					return;
 				if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
 					strscpy(ctl->id.name,
 						"Headphone Detect Autoswitch");
 				aoa_snd_ctl_add(ctl);
 				ctl = snd_ctl_new1(&lineout_detected,
 						   ldev);
+				if (!ctl)
+					return;
 				if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
 					strscpy(ctl->id.name,
 						"Headphone Detected");
author maintainer
#97 lore raw

PATCH 96/480 ALSA: caiaq: fix out-of-bounds read in the Traktor Kontrol S4 input parser

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Maoyi Xie <[email protected]>

commit f7f3f9fd81e7adbaa12c2e62ee07f0e094a543fd upstream.

snd_usb_caiaq_tks4_dispatch() decodes the Traktor Kontrol S4 input stream in fixed 16-byte (TKS4_MSGBLOCK_SIZE) message blocks. On every iteration it advances buf and subtracts the block size while looping on "while (len)".

len is urb->actual_length. That value is supplied by the device and is not guaranteed to be a multiple of 16. When a final short block leaves len between 1 and 15, the loop runs once more, reads up to buf[15], and then does "len -= TKS4_MSGBLOCK_SIZE". As len is unsigned this underflows to a huge value. The loop then keeps iterating and walking buf far past the end of the 512-byte ep4_in_buf, reading out of bounds until a bogus block id happens to be hit.

Iterate only while a full message block is available. This stops the unsigned underflow and silently drops any trailing partial block, which carries no complete control value anyway.

The sibling endpoint-4 parsers are not affected. The Traktor Kontrol X1 and Maschine arms in snd_usb_caiaq_ep4_reply_dispatch() floor urb->actual_length before dispatching.

Fixes 15c5ab607045 ("ALSA: snd-usb-caiaq: Add support for Traktor Kontrol S4")
---
 sound/usb/caiaq/input.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
sound/usb/caiaq/input.c +1 -1
@@ -330,7 +330,7 @@ static void snd_usb_caiaq_tks4_dispatch(
 {
 	struct device *dev = caiaqdev_to_dev(cdev);
 
-	while (len) {
+	while (len >= TKS4_MSGBLOCK_SIZE) {
 		unsigned int i, block_id = (buf[0] << 8) | buf[1];
 
 		switch (block_id) {
author maintainer
#98 lore raw

PATCH 97/480 ALSA: cmipci: check snd_ctl_new1() return value

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Zhao Dongdong <[email protected]>

commit c205bd1b28fb7e5f1061a4e78813fad7d315cb3e upstream.

snd_ctl_new1() can return NULL when memory allocation fails. snd_cmipci_spdif_controls() does not check the return value before dereferencing kctl->id.device, which can lead to a NULL pointer dereference.

Add NULL checks after snd_ctl_new1() calls and return -ENOMEM if any fails.

Assisted-by Opencode:DeepSeek-V4-Flash
Fixes f2f312ad88c6 ("ALSA: cmipci: Fix kctl->id initialization")
---
 sound/pci/cmipci.c |    6 ++++++
 1 file changed, 6 insertions(+)
sound/pci/cmipci.c +6 -0
@@ -2637,16 +2637,22 @@ static int snd_cmipci_mixer_new(struct c
 		}
 		if (cm->can_ac3_hw) {
 			kctl = snd_ctl_new1(&snd_cmipci_spdif_default, cm);
+			if (!kctl)
+				return -ENOMEM;
 			kctl->id.device = pcm_spdif_device;
 			err = snd_ctl_add(card, kctl);
 			if (err < 0)
 				return err;
 			kctl = snd_ctl_new1(&snd_cmipci_spdif_mask, cm);
+			if (!kctl)
+				return -ENOMEM;
 			kctl->id.device = pcm_spdif_device;
 			err = snd_ctl_add(card, kctl);
 			if (err < 0)
 				return err;
 			kctl = snd_ctl_new1(&snd_cmipci_spdif_stream, cm);
+			if (!kctl)
+				return -ENOMEM;
 			kctl->id.device = pcm_spdif_device;
 			err = snd_ctl_add(card, kctl);
 			if (err < 0)
author maintainer
#99 lore raw

PATCH 98/480 ALSA: compress: Fix task creation error unwind

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Cássio Gabriel <[email protected]>

commit 4a60127debb9e370d6c0e22a307326b624a141f3 upstream.

snd_compr_task_new() allocates the driver task before validating the returned DMA buffers and reserving file descriptors. When either of those later steps fails, the core frees its task wrapper and DMA-buffer references without calling the driver's task_free() callback. Any driver resources allocated by task_create() are therefore leaked.

The dual-fd allocation path also jumps to cleanup without storing the negative get_unused_fd_flags() result in retval. Since retval still contains the successful task_create() return value, TASK_CREATE can incorrectly report success although the task was discarded.

Preserve the fd allocation errors and call task_free() when failure occurs after a successful task_create() callback.

Fixes 04177158cf98 ("ALSA: compress_offload: introduce accel operation mode")
Fixes 3d3f43fab4cf ("ALSA: compress_offload: improve file descriptors installation for dma-buf")
---
 sound/core/compress_offload.c |   13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)
sound/core/compress_offload.c +9 -4
@@ -1070,15 +1070,18 @@ static int snd_compr_task_new(struct snd
 	   file descriptors are allocated before fd_install() */
 	if (!task->input || !task->input->file || !task->output || !task->output->file) {
 		retval = -EINVAL;
-		goto cleanup;
+		goto free_driver_task;
 	}
 	fd_i = get_unused_fd_flags(O_WRONLY|O_CLOEXEC);
-	if (fd_i < 0)
-		goto cleanup;
+	if (fd_i < 0) {
+		retval = fd_i;
+		goto free_driver_task;
+	}
 	fd_o = get_unused_fd_flags(O_RDONLY|O_CLOEXEC);
 	if (fd_o < 0) {
+		retval = fd_o;
 		put_unused_fd(fd_i);
-		goto cleanup;
+		goto free_driver_task;
 	}
 	/* keep dmabuf reference until freed with task free ioctl */
 	get_dma_buf(task->input);
@@ -1090,6 +1093,8 @@ static int snd_compr_task_new(struct snd
 	list_add_tail(&task->list, &stream->runtime->tasks);
 	stream->runtime->total_tasks++;
 	return 0;
+free_driver_task:
+	stream->ops->task_free(stream, task);
 cleanup:
 	snd_compr_task_free(task);
 	return retval;
author maintainer
#100 lore raw

PATCH 99/480 ALSA: es1938: check snd_ctl_new1() return value

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Zhao Dongdong <[email protected]>

commit 1edd1f02dddd20aeb6066ded41017615766ea42f upstream.

snd_ctl_new1() can return NULL when memory allocation fails. snd_es1938_mixer() does not check the return value before dereferencing the pointer, which can lead to a NULL pointer dereference.

Add a NULL check after snd_ctl_new1() and return -ENOMEM if it fails.

Assisted-by Opencode:DeepSeek-V4-Flash
Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")
---
 sound/pci/es1938.c |    2 ++
 1 file changed, 2 insertions(+)
sound/pci/es1938.c +2 -0
@@ -1655,6 +1655,8 @@ static int snd_es1938_mixer(struct es193
 	for (idx = 0; idx < ARRAY_SIZE(snd_es1938_controls); idx++) {
 		struct snd_kcontrol *kctl;
 		kctl = snd_ctl_new1(&snd_es1938_controls[idx], chip);
+		if (!kctl)
+			return -ENOMEM;
 		switch (idx) {
 			case 0:
 				chip->master_volume = kctl;
author maintainer
#101 lore raw

PATCH 100/480 ALSA: FCP: Add Focusrite ISA C8X support

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Geoffrey D. Bennett <[email protected]>

commit e0ecb324246be9cf3a0689346a658e48a38546b2 upstream.

Add USB PID 0x821e to the list of devices handled by the Focusrite Control Protocol (FCP) driver.

---
 sound/usb/mixer_quirks.c |    1 +
 1 file changed, 1 insertion(+)
sound/usb/mixer_quirks.c +1 -0
@@ -4346,6 +4346,7 @@ int snd_usb_mixer_apply_create_quirk(str
 	case USB_ID(0x1235, 0x821b): /* Focusrite Scarlett 16i16 4th Gen */
 	case USB_ID(0x1235, 0x821c): /* Focusrite Scarlett 18i16 4th Gen */
 	case USB_ID(0x1235, 0x821d): /* Focusrite Scarlett 18i20 4th Gen */
+	case USB_ID(0x1235, 0x821e): /* Focusrite ISA C8X */
 		err = snd_fcp_init(mixer);
 		break;
 
author maintainer
#102 lore raw

PATCH 101/480 ALSA: firewire: isight: bound the sample count to the packet payload

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Maoyi Xie <[email protected]>

commit 29b9667982e4df2ed7744f86b1144f8bb58eb698 upstream.

isight_packet() takes the frame count from the device iso packet and checks it only against the device claimed iso length.

	count = be32_to_cpu(payload->sample_count);
	if (likely(count <= (length - 16) / 4))
		isight_samples(isight, payload->samples, count);

length is the iso header data_length. It can be up to 0xffff. So the gate allows a count up to about 16379. isight_samples() then copies count frames out of payload->samples into the PCM DMA buffer.

payload->samples holds only 2 * MAX_FRAMES_PER_PACKET values. The device multiplexes two samples per frame. A count past MAX_FRAMES_PER_PACKET reads past the payload. A count past the buffer size writes past runtime->dma_area. The smallest PCM buffer is larger than MAX_FRAMES_PER_PACKET. Bounding the count to MAX_FRAMES_PER_PACKET keeps both the read and the write in range.

A malicious or faulty Apple iSight on the FireWire bus reaches this during a normal capture.

Add the MAX_FRAMES_PER_PACKET bound to the gate.

---
 sound/firewire/isight.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
sound/firewire/isight.c +2 -1
@@ -179,7 +179,8 @@ static void isight_packet(struct fw_iso_
 	if (likely(length >= 16 &&
 		   payload->signature == cpu_to_be32(0x73676874/*"sght"*/))) {
 		count = be32_to_cpu(payload->sample_count);
-		if (likely(count <= (length - 16) / 4)) {
+		if (likely(count <= (length - 16) / 4 &&
+			   count <= MAX_FRAMES_PER_PACKET)) {
 			total = be32_to_cpu(payload->sample_total);
 			if (unlikely(total != isight->total_samples)) {
 				if (!isight->first_packet)
author maintainer
#103 lore raw

PATCH 102/480 ALSA: gus: check snd_ctl_new1() return value

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Zhao Dongdong <[email protected]>

commit c7fa99d30c7a166a5e5db5a585ce7501ff68326b upstream.

snd_ctl_new1() can return NULL when memory allocation fails. snd_gf1_pcm_volume_control() does not check the return value before dereferencing kctl->id.index, which can lead to a NULL pointer dereference.

Add a NULL check after snd_ctl_new1() and return -ENOMEM if it fails.

Assisted-by Opencode:DeepSeek-V4-Flash
Fixes c5ae57b1bb99 ("ALSA: gus: Fix kctl->id initialization")
---
 sound/isa/gus/gus_pcm.c |    2 ++
 1 file changed, 2 insertions(+)
sound/isa/gus/gus_pcm.c +2 -0
@@ -849,6 +849,8 @@ int snd_gf1_pcm_new(struct snd_gus_card
 		kctl = snd_ctl_new1(&snd_gf1_pcm_volume_control1, gus);
 	else
 		kctl = snd_ctl_new1(&snd_gf1_pcm_volume_control, gus);
+	if (!kctl)
+		return -ENOMEM;
 	kctl->id.index = control_index;
 	err = snd_ctl_add(card, kctl);
 	if (err < 0)
author maintainer
#104 lore raw

PATCH 103/480 ALSA: hda/cs35l41: Fix firmware load work teardown

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Cássio Gabriel <[email protected]>

commit b65020d5398f499c09498c9786dba6d67ae57664 upstream.

cs35l41_hda creates ALSA controls whose private data points at the cs35l41_hda object. The firmware load control can also queue fw_load_work.

Those controls are not removed on component unbind, and device remove only cancels fw_load_work through cs35l41_remove_dsp(). That helper is skipped when halo_initialized is false. With firmware_autostart disabled, a firmware load can be requested before the DSP has been initialized. If the component or device is removed before the queued work runs, the worker can run after teardown and dereference driver state that is no longer valid.

Track the created controls and remove them on unbind so no new control callback can reach the driver data or queue more work. Then cancel fw_load_work to drain any request that was already queued. Also cancel the work unconditionally during device remove before runtime PM teardown.

Fixes 47ceabd99a28 ("ALSA: hda: cs35l41: Support Firmware switching and reloading")
Fixes 4c870513fbb0 ("ALSA: hda: cs35l41: Add read-only ALSA control for forced mute")
---
 sound/hda/codecs/side-codecs/cs35l41_hda.c |   77 ++++++++++++++++++++---------
 sound/hda/codecs/side-codecs/cs35l41_hda.h |    5 +
 2 files changed, 60 insertions(+), 22 deletions(-)
sound/hda/codecs/side-codecs/cs35l41_hda.c +55 -22
@@ -1328,6 +1328,43 @@ static int cs35l41_fw_type_ctl_info(stru
 	return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(cs35l41_hda_fw_ids), cs35l41_hda_fw_ids);
 }
 
+static void cs35l41_remove_controls(struct cs35l41_hda *cs35l41)
+{
+	if (!cs35l41->codec)
+		return;
+
+	snd_ctl_remove(cs35l41->codec->card, cs35l41->mute_override_ctl);
+	cs35l41->mute_override_ctl = NULL;
+
+	snd_ctl_remove(cs35l41->codec->card, cs35l41->fw_load_ctl);
+	cs35l41->fw_load_ctl = NULL;
+
+	snd_ctl_remove(cs35l41->codec->card, cs35l41->fw_type_ctl);
+	cs35l41->fw_type_ctl = NULL;
+}
+
+static int cs35l41_add_control(struct cs35l41_hda *cs35l41,
+			       struct snd_kcontrol_new *ctl,
+			       struct snd_kcontrol **kctl)
+{
+	int ret;
+
+	*kctl = snd_ctl_new1(ctl, cs35l41);
+	if (!*kctl)
+		return -ENOMEM;
+
+	ret = snd_ctl_add(cs35l41->codec->card, *kctl);
+	if (ret) {
+		dev_err(cs35l41->dev, "Failed to add KControl %s = %d\n", ctl->name, ret);
+		*kctl = NULL;
+		return ret;
+	}
+
+	dev_dbg(cs35l41->dev, "Added Control %s\n", ctl->name);
+
+	return 0;
+}
+
 static int cs35l41_create_controls(struct cs35l41_hda *cs35l41)
 {
 	char fw_type_ctl_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
@@ -1363,32 +1400,23 @@ static int cs35l41_create_controls(struc
 	scnprintf(mute_override_ctl_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s Forced Mute Status",
 		  cs35l41->amp_name);
 
-	ret = snd_ctl_add(cs35l41->codec->card, snd_ctl_new1(&fw_type_ctl, cs35l41));
-	if (ret) {
-		dev_err(cs35l41->dev, "Failed to add KControl %s = %d\n", fw_type_ctl.name, ret);
-		return ret;
-	}
-
-	dev_dbg(cs35l41->dev, "Added Control %s\n", fw_type_ctl.name);
-
-	ret = snd_ctl_add(cs35l41->codec->card, snd_ctl_new1(&fw_load_ctl, cs35l41));
-	if (ret) {
-		dev_err(cs35l41->dev, "Failed to add KControl %s = %d\n", fw_load_ctl.name, ret);
-		return ret;
-	}
-
-	dev_dbg(cs35l41->dev, "Added Control %s\n", fw_load_ctl.name);
+	ret = cs35l41_add_control(cs35l41, &fw_type_ctl, &cs35l41->fw_type_ctl);
+	if (ret)
+		goto err;
 
-	ret = snd_ctl_add(cs35l41->codec->card, snd_ctl_new1(&mute_override_ctl, cs35l41));
-	if (ret) {
-		dev_err(cs35l41->dev, "Failed to add KControl %s = %d\n", mute_override_ctl.name,
-			ret);
-		return ret;
-	}
+	ret = cs35l41_add_control(cs35l41, &fw_load_ctl, &cs35l41->fw_load_ctl);
+	if (ret)
+		goto err;
 
-	dev_dbg(cs35l41->dev, "Added Control %s\n", mute_override_ctl.name);
+	ret = cs35l41_add_control(cs35l41, &mute_override_ctl, &cs35l41->mute_override_ctl);
+	if (ret)
+		goto err;
 
 	return 0;
+
+err:
+	cs35l41_remove_controls(cs35l41);
+	return ret;
 }
 
 static bool cs35l41_dsm_supported(acpi_handle handle, unsigned int commands)
@@ -1527,6 +1555,10 @@ static void cs35l41_hda_unbind(struct de
 		device_link_remove(&cs35l41->codec->core.dev, cs35l41->dev);
 		unlock_system_sleep(sleep_flags);
 		memset(comp, 0, sizeof(*comp));
+
+		cs35l41_remove_controls(cs35l41);
+		cancel_work_sync(&cs35l41->fw_load_work);
+		cs35l41->codec = NULL;
 	}
 }
 
@@ -2065,6 +2097,7 @@ void cs35l41_hda_remove(struct device *d
 	struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev);
 
 	component_del(cs35l41->dev, &cs35l41_hda_comp_ops);
+	cancel_work_sync(&cs35l41->fw_load_work);
 
 	pm_runtime_get_sync(cs35l41->dev);
 	pm_runtime_dont_use_autosuspend(cs35l41->dev);
sound/hda/codecs/side-codecs/cs35l41_hda.h +5 -0
@@ -57,6 +57,8 @@ enum control_bus {
 	SPI
 };
 
+struct snd_kcontrol;
+
 struct cs35l41_hda {
 	struct device *dev;
 	struct regmap *regmap;
@@ -75,6 +77,9 @@ struct cs35l41_hda {
 	int speaker_id;
 	struct mutex fw_mutex;
 	struct work_struct fw_load_work;
+	struct snd_kcontrol *fw_type_ctl;
+	struct snd_kcontrol *fw_load_ctl;
+	struct snd_kcontrol *mute_override_ctl;
 
 	struct regmap_irq_chip_data *irq_data;
 	bool firmware_running;
author maintainer
#105 lore raw

PATCH 104/480 ALSA: hda/hdmi: Add force-connect quirk for HP EliteDesk 800 G5 Mini

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Cameron Graham <[email protected]>

commit 0ec17ee704615125c0b6e100c38129393a346bcc upstream.

The HP EliteDesk 800 G5 Mini (PCI subsystem 103c:8595) uses Cannon Lake PCH cAVS HDA with DisplayPort audio pins 0x05 and 0x06 set to AC_JACK_PORT_NONE (N/A) in BIOS defaults, causing hdmi_add_pin() to skip them and the DP audio device to not appear in ALSA.

Add the board to the existing force_connect_list alongside the similar HP EliteDesk 800 G4 entries.

---
 sound/hda/codecs/hdmi/hdmi.c |    1 +
 1 file changed, 1 insertion(+)
sound/hda/codecs/hdmi/hdmi.c +1 -0
@@ -1549,6 +1549,7 @@ static const struct snd_pci_quirk force_
 	SND_PCI_QUIRK(0x103c, 0x83e2, "HP EliteDesk 800 G4", 1),
 	SND_PCI_QUIRK(0x103c, 0x83ef, "HP MP9 G4 Retail System AMS", 1),
 	SND_PCI_QUIRK(0x103c, 0x845a, "HP EliteDesk 800 G4 DM 65W", 1),
+	SND_PCI_QUIRK(0x103c, 0x8595, "HP EliteDesk 800 G5 Mini", 1),
 	SND_PCI_QUIRK(0x103c, 0x83f3, "HP ProDesk 400", 1),
 	SND_PCI_QUIRK(0x103c, 0x870f, "HP", 1),
 	SND_PCI_QUIRK(0x103c, 0x871a, "HP", 1),
author maintainer
#106 lore raw

PATCH 105/480 ALSA: hda/hdmi: Use AC_PINSENSE_ELDV to detect pinsense for Loongson

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Huacai Chen <[email protected]>

commit 958e4450e961d75bd9d8f5bfe245fb15bc78e02a upstream.

Due to a hardware defect, for Loongson PCI HDMI devices with a reversion ID of 2, the pin sense status must be determined via the ELD.

Add a codec flag, eld_jack_detect, to indicate this case, and do special handlings in read_pin_sense().

---
 include/sound/hda_codec.h    |    1 +
 sound/hda/codecs/hdmi/hdmi.c |    8 +++++++-
 sound/hda/common/jack.c      |    6 ++++++
 3 files changed, 14 insertions(+), 1 deletion(-)
include/sound/hda_codec.h +1 -0
@@ -259,6 +259,7 @@ struct hda_codec {
 	unsigned int forced_resume:1; /* forced resume for jack */
 	unsigned int no_stream_clean_at_suspend:1; /* do not clean streams at suspend */
 	unsigned int ctl_dev_id:1; /* old control element id build behaviour */
+	unsigned int eld_jack_detect:1;	/* Machine jack-detection by ELD */
 
 	unsigned long power_on_acct;
 	unsigned long power_off_acct;
sound/hda/codecs/hdmi/hdmi.c +7 -1
@@ -2286,6 +2286,7 @@ EXPORT_SYMBOL_NS_GPL(snd_hda_hdmi_acomp_
 enum {
 	MODEL_GENERIC,
 	MODEL_GF,
+	MODEL_LOONGSON,
 };
 
 static int generichdmi_probe(struct hda_codec *codec,
@@ -2303,6 +2304,11 @@ static int generichdmi_probe(struct hda_
 	if (id->driver_data == MODEL_GF)
 		codec->no_sticky_stream = 1;
 
+	if (id->driver_data == MODEL_LOONGSON) {
+		if (codec->bus && codec->bus->pci->revision == 0x2)
+			codec->eld_jack_detect = 1; /* Jack-detection by ELD */
+	}
+
 	return 0;
 }
 
@@ -2320,7 +2326,7 @@ static const struct hda_codec_ops generi
 /*
  */
 static const struct hda_device_id snd_hda_id_generichdmi[] = {
-	HDA_CODEC_ID_MODEL(0x00147a47, "Loongson HDMI",		MODEL_GENERIC),
+	HDA_CODEC_ID_MODEL(0x00147a47, "Loongson HDMI",		MODEL_LOONGSON),
 	HDA_CODEC_ID_MODEL(0x10951390, "SiI1390 HDMI",		MODEL_GENERIC),
 	HDA_CODEC_ID_MODEL(0x10951392, "SiI1392 HDMI",		MODEL_GENERIC),
 	HDA_CODEC_ID_MODEL(0x11069f84, "VX11 HDMI/DP",		MODEL_GENERIC),
sound/hda/common/jack.c +6 -0
@@ -58,6 +58,12 @@ static u32 read_pin_sense(struct hda_cod
 				  AC_VERB_GET_PIN_SENSE, dev_id);
 	if (codec->inv_jack_detect)
 		val ^= AC_PINSENSE_PRESENCE;
+	if (codec->eld_jack_detect) {
+		if (val & AC_PINSENSE_ELDV)
+			val |= AC_PINSENSE_PRESENCE;
+		else
+			val &= ~AC_PINSENSE_PRESENCE;
+	}
 	return val;
 }
 
author maintainer
#107 lore raw

PATCH 106/480 ALSA: hda/realtek: Fix noisy mic for Clevo V6xxAW

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Aaron Erhardt <[email protected]>

commit 493765b8e922a506e09e22e80b6cc9ff05e8295b upstream.

Add a PCI quirk to reduce the volume of the internal microphone to prevent extremely noisy signal.

---
 sound/hda/codecs/realtek/alc269.c |    1 +
 1 file changed, 1 insertion(+)
sound/hda/codecs/realtek/alc269.c +1 -0
@@ -7290,6 +7290,7 @@ static const struct hda_quirk alc269_fix
 	SND_PCI_QUIRK(0x1558, 0x51b3, "Clevo NS70AU", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1558, 0x5630, "Clevo NP50RNJS", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1558, 0x5700, "Clevo X560WN[RST]", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
+	SND_PCI_QUIRK(0x1558, 0x6480, "Clevo V6xxAW", ALC245_FIXUP_CLEVO_NOISY_MIC),
 	SND_PCI_QUIRK(0x1558, 0x70a1, "Clevo NB70T[HJK]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1558, 0x70b3, "Clevo NK70SB", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1558, 0x70f2, "Clevo NH79EPY", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
author maintainer
#108 lore raw

PATCH 107/480 ALSA: ice1712: check snd_ctl_new1() return value

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Zhao Dongdong <[email protected]>

commit 2b929b91b0f3bc6de8a844370049cd99ee8e31ff upstream.

snd_ctl_new1() can return NULL when memory allocation fails. The ice1712 driver calls snd_ctl_new1() without checking the return value before dereferencing the pointer in multiple places (ice1712.c, ice1724.c, aureon.c), which can lead to NULL pointer dereferences.

Add NULL checks after snd_ctl_new1() calls and return -ENOMEM if any fails.

Assisted-by Opencode:DeepSeek-V4-Flash
Fixes b9a4efd61b6b ("ALSA: ice1712,ice1724: fix the kcontrol->id initialization")
---
 sound/pci/ice1712/aureon.c  |    2 ++
 sound/pci/ice1712/ice1712.c |    8 ++++++++
 sound/pci/ice1712/ice1724.c |    6 ++++++
 3 files changed, 16 insertions(+)
sound/pci/ice1712/aureon.c +2 -0
@@ -1891,6 +1891,8 @@ static int aureon_add_controls(struct sn
 			for (i = 0; i < ARRAY_SIZE(cs8415_controls); i++) {
 				struct snd_kcontrol *kctl;
 				kctl = snd_ctl_new1(&cs8415_controls[i], ice);
+				if (!kctl)
+					return -ENOMEM;
 				if (i > 1)
 					kctl->id.device = ice->pcm->device;
 				err = snd_ctl_add(ice->card, kctl);
sound/pci/ice1712/ice1712.c +8 -0
@@ -2346,21 +2346,29 @@ int snd_ice1712_spdif_build_controls(str
 	if (snd_BUG_ON(!ice->pcm_pro))
 		return -EIO;
 	kctl = snd_ctl_new1(&snd_ice1712_spdif_default, ice);
+	if (!kctl)
+		return -ENOMEM;
 	kctl->id.device = ice->pcm_pro->device;
 	err = snd_ctl_add(ice->card, kctl);
 	if (err < 0)
 		return err;
 	kctl = snd_ctl_new1(&snd_ice1712_spdif_maskc, ice);
+	if (!kctl)
+		return -ENOMEM;
 	kctl->id.device = ice->pcm_pro->device;
 	err = snd_ctl_add(ice->card, kctl);
 	if (err < 0)
 		return err;
 	kctl = snd_ctl_new1(&snd_ice1712_spdif_maskp, ice);
+	if (!kctl)
+		return -ENOMEM;
 	kctl->id.device = ice->pcm_pro->device;
 	err = snd_ctl_add(ice->card, kctl);
 	if (err < 0)
 		return err;
 	kctl = snd_ctl_new1(&snd_ice1712_spdif_stream, ice);
+	if (!kctl)
+		return -ENOMEM;
 	kctl->id.device = ice->pcm_pro->device;
 	err = snd_ctl_add(ice->card, kctl);
 	if (err < 0)
sound/pci/ice1712/ice1724.c +6 -0
@@ -2379,16 +2379,22 @@ static int snd_vt1724_spdif_build_contro
 		return err;
 
 	kctl = snd_ctl_new1(&snd_vt1724_spdif_default, ice);
+	if (!kctl)
+		return -ENOMEM;
 	kctl->id.device = ice->pcm->device;
 	err = snd_ctl_add(ice->card, kctl);
 	if (err < 0)
 		return err;
 	kctl = snd_ctl_new1(&snd_vt1724_spdif_maskc, ice);
+	if (!kctl)
+		return -ENOMEM;
 	kctl->id.device = ice->pcm->device;
 	err = snd_ctl_add(ice->card, kctl);
 	if (err < 0)
 		return err;
 	kctl = snd_ctl_new1(&snd_vt1724_spdif_maskp, ice);
+	if (!kctl)
+		return -ENOMEM;
 	kctl->id.device = ice->pcm->device;
 	err = snd_ctl_add(ice->card, kctl);
 	if (err < 0)
author maintainer
#109 lore raw

PATCH 108/480 ALSA: seq: Fix uninitialised heap leak in snd_seq_event_dup()

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: HyeongJun An <[email protected]>

commit 435990e25bf1f4af3e6df12a6fbfd1f7ba4a97d4 upstream.

snd_seq_event_dup() copies an incoming event into a pool cell and, in the UMP-enabled build, clears the trailing cell->ump.raw.extra word that the memcpy() did not cover. The guard deciding whether to clear it compares the copied size against sizeof(cell->event):

	memcpy(&cell->ump, event, size);
	if (size < sizeof(cell->event))
		cell->ump.raw.extra = 0;

For a legacy (non-UMP) event, size == sizeof(struct snd_seq_event) == sizeof(cell->event), so the condition is false and the extra word keeps stale data. The cell pool is allocated with kvmalloc() (not zeroed) and cells are reused via a free list, so that word holds uninitialised heap or leftover event data.

When such a cell is delivered to a UMP client (client->midi_version > 0) that set SNDRV_SEQ_FILTER_NO_CONVERT -- so the legacy event reaches it unconverted -- snd_seq_read() reads it out as the larger struct snd_seq_ump_event and copies the stale word to user space, a 4-byte kernel heap infoleak to an unprivileged /dev/snd/seq client.

Compare against sizeof(cell->ump) instead, so the trailing word is zeroed for every event shorter than the UMP cell.

Fixes 46397622a3fa ("ALSA: seq: Add UMP support")
Assisted-by Claude:claude-opus-4-8
---
 sound/core/seq/seq_memory.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
sound/core/seq/seq_memory.c +1 -1
@@ -364,7 +364,7 @@ int snd_seq_event_dup(struct snd_seq_poo
 	size = snd_seq_event_packet_size(event);
 	memcpy(&cell->ump, event, size);
 #if IS_ENABLED(CONFIG_SND_SEQ_UMP)
-	if (size < sizeof(cell->event))
+	if (size < sizeof(cell->ump))
 		cell->ump.raw.extra = 0;
 #endif
 
author maintainer
#110 lore raw

PATCH 109/480 ALSA: us144mkii: capture_urb_complete: redundant usb_anchor_urb corrupts anchor list on each resubmission

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: WenTao Liang <[email protected]>

commit 5cff1529a2f9b3461a7f5a6e36a86682fc290534 upstream.

In capture_urb_complete(), usb_anchor_urb() is called on every completion callback, but the URB is already anchored from the initial submission in tascam_trigger_start(). Each redundant call corrupts the anchor's doubly-linked list and inflates the URB refcount. When usb_kill_anchored_urbs() traverses the list during stream stop / suspend / disconnect, the corrupted list leads to use-after-free.

Remove the redundant usb_anchor_urb() from the resubmit path.

Fixes c1bb0c13e430 ("ALSA: usb-audio: us144mkii: Implement audio capture and decoding")
---
 sound/usb/usx2y/us144mkii_capture.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
sound/usb/usx2y/us144mkii_capture.c +1 -1
@@ -302,7 +302,6 @@ void capture_urb_complete(struct urb *ur
 	}
 
 	usb_get_urb(urb);
-	usb_anchor_urb(urb, &tascam->capture_anchor);
 	ret = usb_submit_urb(urb, GFP_ATOMIC);
 	if (ret < 0) {
 		dev_err_ratelimited(tascam->card->dev,
@@ -312,6 +311,7 @@ void capture_urb_complete(struct urb *ur
 		usb_put_urb(urb);
 		atomic_dec(
 			&tascam->active_urbs); /* Decrement on failed resubmission */
+		return;
 	}
 out:
 	usb_put_urb(urb);
author maintainer
#111 lore raw

PATCH 110/480 ALSA: usb-audio: avoid kobject path lookup in DualSense match

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Darvell Long <[email protected]>

commit 7693c0cc415f3a16a7a3355f245474a5e661be4e upstream.

The DualSense jack-detection input handler verifies that a matching input device belongs to the same physical controller by building kobject path strings for both the input device and the USB audio device, then comparing the path prefix.

This was observed when a weak physical connection caused the controller to rapidly disconnect and reconnect. During that repeated hotplug, snd_dualsense_ih_match() can run while the controller's USB device is being disconnected. kobject_get_path() walks ancestor kobjects and dereferences their names; if the USB device kobject name is no longer valid, this can fault in strlen():

  RIP: 0010:strlen+0x10/0x30
  Call Trace:
   kobject_get_path+0x34/0x150
   snd_dualsense_ih_match+0x49/0xd0 [snd_usb_audio]
   input_register_device+0x566/0x6a0
   ps_probe+0xb89/0x1590 [hid_playstation]

The same ownership check can be done without building kobject path strings. The input device is parented below the HID device, USB interface and USB device, so walking the input device parent chain and comparing against the mixer USB device preserves the check without dereferencing kobject names during disconnect.

Fixes 79d561c4ec04 ("ALSA: usb-audio: Add mixer quirk for Sony DualSense PS5")
Assisted-by Cute:gpt-5.5
---
 sound/usb/mixer_quirks.c |   40 ++++++++++++----------------------------
 1 file changed, 12 insertions(+), 28 deletions(-)
sound/usb/mixer_quirks.c +12 -28
@@ -567,46 +567,30 @@ static bool snd_dualsense_ih_match(struc
 {
 	struct dualsense_mixer_elem_info *mei;
 	struct usb_device *snd_dev;
-	char *input_dev_path, *usb_dev_path;
-	size_t usb_dev_path_len;
-	bool match = false;
+	struct device *parent;
 
 	mei = container_of(handler, struct dualsense_mixer_elem_info, ih);
 	snd_dev = mei->info.head.mixer->chip->dev;
 
-	input_dev_path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
-	if (!input_dev_path) {
-		dev_warn(&snd_dev->dev, "Failed to get input dev path\n");
-		return false;
-	}
-
-	usb_dev_path = kobject_get_path(&snd_dev->dev.kobj, GFP_KERNEL);
-	if (!usb_dev_path) {
-		dev_warn(&snd_dev->dev, "Failed to get USB dev path\n");
-		goto free_paths;
-	}
-
 	/*
 	 * Ensure the VID:PID matched input device supposedly owned by the
 	 * hid-playstation driver belongs to the actual hardware handled by
-	 * the current USB audio device, which implies input_dev_path being
-	 * a subpath of usb_dev_path.
+	 * the current USB audio device.
 	 *
 	 * This verification is necessary when there is more than one identical
 	 * controller attached to the host system.
+	 *
+	 * The input device is registered below the HID device, USB interface and
+	 * USB device, so compare the parent chain directly instead of building
+	 * kobject path strings. This avoids dereferencing kobject names while the
+	 * USB device hierarchy is being torn down during disconnect.
 	 */
-	usb_dev_path_len = strlen(usb_dev_path);
-	if (usb_dev_path_len >= strlen(input_dev_path))
-		goto free_paths;
-
-	usb_dev_path[usb_dev_path_len] = '/';
-	match = !memcmp(input_dev_path, usb_dev_path, usb_dev_path_len + 1);
-
-free_paths:
-	kfree(input_dev_path);
-	kfree(usb_dev_path);
+	for (parent = dev->dev.parent; parent; parent = parent->parent) {
+		if (parent == &snd_dev->dev)
+			return true;
+	}
 
-	return match;
+	return false;
 }
 
 static int snd_dualsense_ih_connect(struct input_handler *handler,
author maintainer
#112 lore raw

PATCH 111/480 ALSA: usb-audio: Propagate errors in scarlett_ctl_enum_put()

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Cássio Gabriel <[email protected]>

commit 0f25cf1f02e3dba626791d949c759a48c0a44996 upstream.

scarlett_ctl_enum_put() ignores the return value from snd_usb_set_cur_mix_value() and reports success whenever the requested enum value differs from the current one.

If the SET_CUR request fails, the callback still returns success even though neither the hardware state nor the cached mixer value changed.

Fixes 76b188c4b370 ("ALSA: usb-audio: Scarlett mixer interface for 6i6, 18i6, 18i8 and 18i20")
---
 sound/usb/mixer_scarlett.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
sound/usb/mixer_scarlett.c +3 -1
@@ -439,7 +439,9 @@ static int scarlett_ctl_enum_put(struct
 	val = ucontrol->value.integer.value[0];
 	val = val + opt->start;
 	if (val != oval) {
-		snd_usb_set_cur_mix_value(elem, 0, 0, val);
+		err = snd_usb_set_cur_mix_value(elem, 0, 0, val);
+		if (err < 0)
+			return err;
 		return 1;
 	}
 	return 0;
author maintainer
#113 lore raw

PATCH 112/480 ALSA: usb-audio: Propagate US-16x08 write errors in route/mix EQ-switch put callbacks

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Cássio Gabriel <[email protected]>

commit 3c06aec8abda6ba068b58a8b7119cdb2a48456b1 upstream.

Several US-16x08 mixer put callbacks log failed control URBs but still return success to userspace. That hides device write failures even though the requested value was not applied.

Return the negative write error instead in the route, master, bus, channel, and EQ switch put callbacks.

Fixes d2bb390a2081 ("ALSA: usb-audio: Tascam US-16x08 DSP mixer quirk")
---
 sound/usb/mixer_us16x08.c |   49 ++++++++++++++++++++++------------------------
 1 file changed, 24 insertions(+), 25 deletions(-)
sound/usb/mixer_us16x08.c +24 -25
@@ -224,14 +224,14 @@ static int snd_us16x08_route_put(struct
 
 	err = snd_us16x08_send_urb(chip, buf, sizeof(route_msg));
 
-	if (err > 0) {
-		elem->cached |= 1 << index;
-		elem->cache_val[index] = val;
-	} else {
+	if (err < 0) {
 		usb_audio_dbg(chip, "Failed to set routing, err:%d\n", err);
+		return err;
 	}
 
-	return err > 0 ? 1 : 0;
+	elem->cached |= 1 << index;
+	elem->cache_val[index] = val;
+	return 1;
 }
 
 static int snd_us16x08_master_info(struct snd_kcontrol *kcontrol,
@@ -283,14 +283,14 @@ static int snd_us16x08_master_put(struct
 	buf[5] = index + 1;
 	err = snd_us16x08_send_urb(chip, buf, sizeof(mix_msg_out));
 
-	if (err > 0) {
-		elem->cached |= 1 << index;
-		elem->cache_val[index] = val;
-	} else {
+	if (err < 0) {
 		usb_audio_dbg(chip, "Failed to set master, err:%d\n", err);
+		return err;
 	}
 
-	return err > 0 ? 1 : 0;
+	elem->cached |= 1 << index;
+	elem->cache_val[index] = val;
+	return 1;
 }
 
 static int snd_us16x08_bus_put(struct snd_kcontrol *kcontrol,
@@ -324,14 +324,14 @@ static int snd_us16x08_bus_put(struct sn
 		break;
 	}
 
-	if (err > 0) {
-		elem->cached |= 1;
-		elem->cache_val[0] = val;
-	} else {
+	if (err < 0) {
 		usb_audio_dbg(chip, "Failed to set bus parameter, err:%d\n", err);
+		return err;
 	}
 
-	return err > 0 ? 1 : 0;
+	elem->cached |= 1;
+	elem->cache_val[0] = val;
+	return 1;
 }
 
 static int snd_us16x08_bus_get(struct snd_kcontrol *kcontrol,
@@ -392,14 +392,14 @@ static int snd_us16x08_channel_put(struc
 
 	err = snd_us16x08_send_urb(chip, buf, sizeof(mix_msg_in));
 
-	if (err > 0) {
-		elem->cached |= 1 << index;
-		elem->cache_val[index] = val;
-	} else {
+	if (err < 0) {
 		usb_audio_dbg(chip, "Failed to set channel, err:%d\n", err);
+		return err;
 	}
 
-	return err > 0 ? 1 : 0;
+	elem->cached |= 1 << index;
+	elem->cache_val[index] = val;
+	return 1;
 }
 
 static int snd_us16x08_mix_info(struct snd_kcontrol *kcontrol,
@@ -529,13 +529,13 @@ static int snd_us16x08_eqswitch_put(stru
 		msleep(15);
 	}
 
-	if (err > 0) {
-		elem->cached |= 1 << index;
-		elem->cache_val[index] = val;
-	} else {
+	if (err < 0) {
 		usb_audio_dbg(chip, "Failed to set eq switch, err:%d\n", err);
+		return err;
 	}
 
+	elem->cached |= 1 << index;
+	elem->cache_val[index] = val;
 	return 1;
 }
 
@@ -1418,4 +1418,3 @@ int snd_us16x08_controls_create(struct u
 
 	return 0;
 }
-
author maintainer
#114 lore raw

PATCH 113/480 ALSA: usb-audio: Roll back quirk control caches on write errors

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Cássio Gabriel <[email protected]>

commit 6380957fa24251856a532e48a46a4dc3d1ae26b6 upstream.

Several mixer quirk callbacks cache the requested
control value in kcontrol->private_value before
issuing a single vendor or class write.

Their paired get and resume paths consume that cache directly, so a failed write currently leaves software state changed even though the update did not succeed. That can make later reads report a value the device never accepted and can replay the stale cache on resume.

Restore the previous cached value on failure in
the Audigy2NX LED, Emu0204 channel switch,
Xonar U1 output switch, Native Instruments controls,
FTU effect program switch, and Sound Blaster E1 input source switch.

Fixes 9cf3689bfe07 ("ALSA: usb-audio: Add audigy2nx resume support")
Fixes 5f503ee9e270 ("ALSA: usb-audio: Add Emu0204 channel switch resume support")
Fixes 2bfb14c3b8fb ("ALSA: usb-audio: Add Xonar U1 resume support")
Fixes da6d276957ea ("ALSA: usb-audio: Add resume support for Native Instruments controls")
Fixes 0b4e9cfcef05 ("ALSA: usb-audio: Add resume support for FTU controls")
Fixes 388fdb8f882a ("ALSA: usb-audio: Support changing input on Sound Blaster E1")
---
 sound/usb/mixer_quirks.c |   45 +++++++++++++++++++++++++++++++++++++--------
 1 file changed, 37 insertions(+), 8 deletions(-)
sound/usb/mixer_quirks.c +37 -8
@@ -333,6 +333,7 @@ static int snd_audigy2nx_led_put(struct
 	int index = kcontrol->private_value & 0xff;
 	unsigned int value = ucontrol->value.integer.value[0];
 	int old_value = kcontrol->private_value >> 8;
+	unsigned long old_pval = kcontrol->private_value;
 	int err;
 
 	if (value > 1)
@@ -341,7 +342,11 @@ static int snd_audigy2nx_led_put(struct
 		return 0;
 	kcontrol->private_value = (value << 8) | index;
 	err = snd_audigy2nx_led_update(mixer, value, index);
-	return err < 0 ? err : 1;
+	if (err < 0) {
+		kcontrol->private_value = old_pval;
+		return err;
+	}
+	return 1;
 }
 
 static int snd_audigy2nx_led_resume(struct usb_mixer_elem_list *list)
@@ -487,6 +492,7 @@ static int snd_emu0204_ch_switch_put(str
 	struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
 	struct usb_mixer_interface *mixer = list->mixer;
 	unsigned int value = ucontrol->value.enumerated.item[0];
+	unsigned long old_pval = kcontrol->private_value;
 	int err;
 
 	if (value > 1)
@@ -497,7 +503,11 @@ static int snd_emu0204_ch_switch_put(str
 
 	kcontrol->private_value = value;
 	err = snd_emu0204_ch_switch_update(mixer, value);
-	return err < 0 ? err : 1;
+	if (err < 0) {
+		kcontrol->private_value = old_pval;
+		return err;
+	}
+	return 1;
 }
 
 static int snd_emu0204_ch_switch_resume(struct usb_mixer_elem_list *list)
@@ -805,7 +815,11 @@ static int snd_xonar_u1_switch_put(struc
 
 	kcontrol->private_value = new_status;
 	err = snd_xonar_u1_switch_update(list->mixer, new_status);
-	return err < 0 ? err : 1;
+	if (err < 0) {
+		kcontrol->private_value = old_status;
+		return err;
+	}
+	return 1;
 }
 
 static int snd_xonar_u1_switch_resume(struct usb_mixer_elem_list *list)
@@ -1143,7 +1157,8 @@ static int snd_nativeinstruments_control
 					     struct snd_ctl_elem_value *ucontrol)
 {
 	struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
-	u8 oldval = (kcontrol->private_value >> 24) & 0xff;
+	unsigned long old_pval = kcontrol->private_value;
+	u8 oldval = (old_pval >> 24) & 0xff;
 	u8 newval = ucontrol->value.integer.value[0];
 	int err;
 
@@ -1153,7 +1168,11 @@ static int snd_nativeinstruments_control
 	kcontrol->private_value &= ~(0xff << 24);
 	kcontrol->private_value |= (unsigned int)newval << 24;
 	err = snd_ni_update_cur_val(list);
-	return err < 0 ? err : 1;
+	if (err < 0) {
+		kcontrol->private_value = old_pval;
+		return err;
+	}
+	return 1;
 }
 
 static const struct snd_kcontrol_new snd_nativeinstruments_ta6_mixers[] = {
@@ -1308,7 +1327,8 @@ static int snd_ftu_eff_switch_put(struct
 				  struct snd_ctl_elem_value *ucontrol)
 {
 	struct usb_mixer_elem_list *list = snd_kcontrol_chip(kctl);
-	unsigned int pval = list->kctl->private_value;
+	unsigned long old_pval = list->kctl->private_value;
+	unsigned int pval = old_pval;
 	int cur_val, err, new_val;
 
 	cur_val = pval >> 24;
@@ -1319,7 +1339,11 @@ static int snd_ftu_eff_switch_put(struct
 	kctl->private_value &= ~(0xff << 24);
 	kctl->private_value |= new_val << 24;
 	err = snd_ftu_eff_switch_update(list);
-	return err < 0 ? err : 1;
+	if (err < 0) {
+		kctl->private_value = old_pval;
+		return err;
+	}
+	return 1;
 }
 
 static int snd_ftu_create_effect_switch(struct usb_mixer_interface *mixer,
@@ -2098,13 +2122,18 @@ static int snd_soundblaster_e1_switch_pu
 {
 	struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
 	unsigned char value = !!ucontrol->value.integer.value[0];
+	unsigned long old_pval = kcontrol->private_value;
 	int err;
 
 	if (kcontrol->private_value == value)
 		return 0;
 	kcontrol->private_value = value;
 	err = snd_soundblaster_e1_switch_update(list->mixer, value);
-	return err < 0 ? err : 1;
+	if (err < 0) {
+		kcontrol->private_value = old_pval;
+		return err;
+	}
+	return 1;
 }
 
 static int snd_soundblaster_e1_switch_resume(struct usb_mixer_elem_list *list)
author maintainer
#115 lore raw

PATCH 114/480 ALSA: usb-audio: Update Babyface Pro control caches only after successful writes

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Cássio Gabriel <[email protected]>

commit d8f802ccf1fdbeb89d62748d6a0d0fbd442c8127 upstream.

snd_bbfpro_ctl_put() and snd_bbfpro_vol_put() cache the requested packed control state in kcontrol->private_value before issuing the USB write.

Their get and resume paths use that cached value directly, so a failed write can leave the driver reporting and later replaying a setting the hardware never accepted.

Update the cached state only after a successful USB write.

---
 sound/usb/mixer_quirks.c |   16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)
sound/usb/mixer_quirks.c +10 -6
@@ -2905,12 +2905,14 @@ static int snd_bbfpro_ctl_put(struct snd
 	if (val == old_value)
 		return 0;
 
+	err = snd_bbfpro_ctl_update(mixer, reg, idx, val);
+	if (err < 0)
+		return err;
+
 	kcontrol->private_value = reg
 		| ((idx & SND_BBFPRO_CTL_IDX_MASK) << SND_BBFPRO_CTL_IDX_SHIFT)
 		| ((val & SND_BBFPRO_CTL_VAL_MASK) << SND_BBFPRO_CTL_VAL_SHIFT);
-
-	err = snd_bbfpro_ctl_update(mixer, reg, idx, val);
-	return err < 0 ? err : 1;
+	return 1;
 }
 
 static int snd_bbfpro_ctl_resume(struct usb_mixer_elem_list *list)
@@ -3095,11 +3097,13 @@ static int snd_bbfpro_vol_put(struct snd
 
 	new_val = uvalue & SND_BBFPRO_MIXER_VAL_MASK;
 
+	err = snd_bbfpro_vol_update(mixer, idx, new_val);
+	if (err < 0)
+		return err;
+
 	kcontrol->private_value = idx
 		| (new_val << SND_BBFPRO_MIXER_VAL_SHIFT);
-
-	err = snd_bbfpro_vol_update(mixer, idx, new_val);
-	return err < 0 ? err : 1;
+	return 1;
 }
 
 static int snd_bbfpro_vol_resume(struct usb_mixer_elem_list *list)
author maintainer
#116 lore raw

PATCH 115/480 ALSA: usb-audio: Update US-16x08 EQ/comp shadow state after successful writes

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Cássio Gabriel <[email protected]>

commit a440c17869ecd71da0f295b62868fc742d09a8ba upstream.

snd_us16x08_comp_put() and snd_us16x08_eq_put() update their software stores before sending the USB write. If the transfer fails, later get callbacks report a value the hardware never accepted.

Build the outgoing message from the current store plus the pending value, then commit the store only after a successful write.

Fixes d2bb390a2081 ("ALSA: usb-audio: Tascam US-16x08 DSP mixer quirk")
---
 sound/usb/mixer_us16x08.c |   78 ++++++++++++++++++++++++++++++----------------
 1 file changed, 52 insertions(+), 26 deletions(-)
sound/usb/mixer_us16x08.c +52 -26
@@ -435,6 +435,7 @@ static int snd_us16x08_comp_put(struct s
 	int index = ucontrol->id.index;
 	char buf[sizeof(comp_msg)];
 	int val_idx, val;
+	int threshold, ratio, attack, release, gain, switch_on;
 	int err;
 
 	val = ucontrol->value.integer.value[0];
@@ -447,36 +448,61 @@ static int snd_us16x08_comp_put(struct s
 	/* new control value incl. bias*/
 	val_idx = elem->head.id - SND_US16X08_ID_COMP_BASE;
 
-	store->val[val_idx][index] = ucontrol->value.integer.value[0];
+	threshold = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_THRESHOLD)]
+		[index];
+	ratio = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RATIO)][index];
+	attack = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_ATTACK)][index];
+	release = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RELEASE)]
+		[index];
+	gain = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_GAIN)][index];
+	switch_on = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH)]
+		[index];
+
+	switch (val_idx) {
+	case COMP_STORE_IDX(SND_US16X08_ID_COMP_THRESHOLD):
+		threshold = val;
+		break;
+	case COMP_STORE_IDX(SND_US16X08_ID_COMP_RATIO):
+		ratio = val;
+		break;
+	case COMP_STORE_IDX(SND_US16X08_ID_COMP_ATTACK):
+		attack = val;
+		break;
+	case COMP_STORE_IDX(SND_US16X08_ID_COMP_RELEASE):
+		release = val;
+		break;
+	case COMP_STORE_IDX(SND_US16X08_ID_COMP_GAIN):
+		gain = val;
+		break;
+	case COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH):
+		switch_on = val;
+		break;
+	}
 
 	/* prepare compressor URB message from template  */
 	memcpy(buf, comp_msg, sizeof(comp_msg));
 
 	/* place comp values in message buffer watch bias! */
-	buf[8] = store->val[
-		COMP_STORE_IDX(SND_US16X08_ID_COMP_THRESHOLD)][index]
-		- SND_US16X08_COMP_THRESHOLD_BIAS;
-	buf[11] = ratio_map[store->val[
-		COMP_STORE_IDX(SND_US16X08_ID_COMP_RATIO)][index]];
-	buf[14] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_ATTACK)][index]
-		+ SND_US16X08_COMP_ATTACK_BIAS;
-	buf[17] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RELEASE)][index]
-		+ SND_US16X08_COMP_RELEASE_BIAS;
-	buf[20] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_GAIN)][index];
-	buf[26] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH)][index];
+	buf[8] = threshold - SND_US16X08_COMP_THRESHOLD_BIAS;
+	buf[11] = ratio_map[ratio];
+	buf[14] = attack + SND_US16X08_COMP_ATTACK_BIAS;
+	buf[17] = release + SND_US16X08_COMP_RELEASE_BIAS;
+	buf[20] = gain;
+	buf[26] = switch_on;
 
 	/* place channel selector in message buffer */
 	buf[5] = index + 1;
 
 	err = snd_us16x08_send_urb(chip, buf, sizeof(comp_msg));
 
-	if (err > 0) {
-		elem->cached |= 1 << index;
-		elem->cache_val[index] = val;
-	} else {
+	if (err < 0) {
 		usb_audio_dbg(chip, "Failed to set compressor, err:%d\n", err);
+		return err;
 	}
 
+	store->val[val_idx][index] = val;
+	elem->cached |= 1 << index;
+	elem->cache_val[index] = val;
 	return 1;
 }
 
@@ -578,11 +604,10 @@ static int snd_us16x08_eq_put(struct snd
 	/* copy URB buffer from EQ template */
 	memcpy(buf, eqs_msq, sizeof(eqs_msq));
 
-	store->val[b_idx][p_idx][index] = val;
-	buf[20] = store->val[b_idx][3][index];
-	buf[17] = store->val[b_idx][2][index];
-	buf[14] = store->val[b_idx][1][index];
-	buf[11] = store->val[b_idx][0][index];
+	buf[20] = p_idx == 3 ? val : store->val[b_idx][3][index];
+	buf[17] = p_idx == 2 ? val : store->val[b_idx][2][index];
+	buf[14] = p_idx == 1 ? val : store->val[b_idx][1][index];
+	buf[11] = p_idx == 0 ? val : store->val[b_idx][0][index];
 
 	/* place channel index in URB buffer */
 	buf[5] = index + 1;
@@ -592,14 +617,15 @@ static int snd_us16x08_eq_put(struct snd
 
 	err = snd_us16x08_send_urb(chip, buf, sizeof(eqs_msq));
 
-	if (err > 0) {
-		/* store new value in EQ band cache */
-		elem->cached |= 1 << index;
-		elem->cache_val[index] = val;
-	} else {
+	if (err < 0) {
 		usb_audio_dbg(chip, "Failed to set eq param, err:%d\n", err);
+		return err;
 	}
 
+	store->val[b_idx][p_idx][index] = val;
+	/* store new value in EQ band cache */
+	elem->cached |= 1 << index;
+	elem->cache_val[index] = val;
 	return 1;
 }
 
author maintainer
#117 lore raw

PATCH 116/480 vfio/pci: Use a private flag to prevent power state change with VFs

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Raghavendra Rao Ananta <[email protected]>

commit 40ef3edf151e184d021917a5c4c771cc0870844a upstream.

The current implementation uses pci_num_vf() while holding the memory_lock to prevent changing the power state of a PF when VFs are enabled. This creates a lockdep circular dependency warning because memory_lock is held during device probing.

[  286.997167] ======================================================
[  287.003363] WARNING: possible circular locking dependency detected
[  287.009562] 7.0.0-dbg-DEV #3 Tainted: G S
[  287.015074] ------------------------------------------------------
[  287.021270] vfio_pci_sriov_/18636 is trying to acquire lock:
[  287.026942] ff45bea2294d4968 (&vdev->memory_lock){+.+.}-{4:4}, at:
vfio_pci_core_runtime_resume+0x1f/0xa0
[  287.036530]
[  287.036530] but task is already holding lock:
[  287.042383] ff45bea3a96b8230 (&new_dev_set->lock){+.+.}-{4:4}, at:
vfio_group_fops_unl_ioctl+0x44d/0x7b0
[  287.051879]
[  287.051879] which lock already depends on the new lock.
[  287.051879]
[  287.060070]
[  287.060070] the existing dependency chain (in reverse order) is:
[  287.067568]
[  287.067568] -> #2 (&new_dev_set->lock){+.+.}-{4:4}:
[  287.073941]        __mutex_lock+0x92/0xb80
[  287.078058]        vfio_assign_device_set+0x66/0x1b0
[  287.083042]        vfio_pci_core_register_device+0xd1/0x2a0
[  287.088638]        vfio_pci_probe+0xd2/0x100
[  287.092933]        local_pci_probe_callback+0x4d/0xa0
[  287.098001]        process_scheduled_works+0x2ca/0x680
[  287.103158]        worker_thread+0x1e8/0x2f0
[  287.107452]        kthread+0x10c/0x140
[  287.111230]        ret_from_fork+0x18e/0x360
[  287.115519]        ret_from_fork_asm+0x1a/0x30
[  287.119983]
[  287.119983] -> #1 ((work_completion)(&arg.work)){+.+.}-{0:0}:
[  287.127219]        __flush_work+0x345/0x490
[  287.131429]        pci_device_probe+0x2e3/0x490
[  287.135979]        really_probe+0x1f9/0x4e0
[  287.140180]        __driver_probe_device+0x77/0x100
[  287.145079]        driver_probe_device+0x1e/0x110
[  287.149803]        __device_attach_driver+0xe3/0x170
[  287.154789]        bus_for_each_drv+0x125/0x150
[  287.159346]        __device_attach+0xca/0x1a0
[  287.163720]        device_initial_probe+0x34/0x50
[  287.168445]        pci_bus_add_device+0x6e/0x90
[  287.172995]        pci_iov_add_virtfn+0x3c9/0x3e0
[  287.177719]        sriov_add_vfs+0x2c/0x60
[  287.181838]        sriov_enable+0x306/0x4a0
[  287.186038]        vfio_pci_core_sriov_configure+0x184/0x220
[  287.191715]        sriov_numvfs_store+0xd9/0x1c0
[  287.196351]        kernfs_fop_write_iter+0x13f/0x1d0
[  287.201338]        vfs_write+0x2be/0x3b0
[  287.205286]        ksys_write+0x73/0x100
[  287.209233]        do_syscall_64+0x14d/0x750
[  287.213529]        entry_SYSCALL_64_after_hwframe+0x77/0x7f
[  287.219120]
[  287.219120] -> #0 (&vdev->memory_lock){+.+.}-{4:4}:
[  287.225491]        __lock_acquire+0x14c6/0x2800
[  287.230048]        lock_acquire+0xd3/0x2f0
[  287.234168]        down_write+0x3a/0xc0
[  287.238019]        vfio_pci_core_runtime_resume+0x1f/0xa0
[  287.243436]        __rpm_callback+0x8c/0x310
[  287.247730]        rpm_resume+0x529/0x6f0
[  287.251765]        __pm_runtime_resume+0x68/0x90
[  287.256402]        vfio_pci_core_enable+0x44/0x310
[  287.261216]        vfio_pci_open_device+0x1c/0x80
[  287.265947]        vfio_df_open+0x10f/0x150
[  287.270148]        vfio_group_fops_unl_ioctl+0x4a4/0x7b0
[  287.275476]        __se_sys_ioctl+0x71/0xc0
[  287.279679]        do_syscall_64+0x14d/0x750
[  287.283975]        entry_SYSCALL_64_after_hwframe+0x77/0x7f
[  287.289559]
[  287.289559] other info that might help us debug this:
[  287.289559]
[  287.297582] Chain exists of:
[  287.297582]   &vdev->memory_lock --> (work_completion)(&arg.work)
--> &new_dev_set->lock
[  287.297582]
[  287.310023]  Possible unsafe locking scenario:
[  287.310023]
[  287.315961]        CPU0                    CPU1
[  287.320510]        ----                    ----
[  287.325059]   lock(&new_dev_set->lock);
[  287.328917]
lock((work_completion)(&arg.work));
[  287.336153]                                lock(&new_dev_set->lock);
[  287.342523]   lock(&vdev->memory_lock);
[  287.346382]
[  287.346382]  *** DEADLOCK ***
[  287.346382]
[  287.352315] 2 locks held by vfio_pci_sriov_/18636:
[  287.357125]  #0: ff45bea208ed3e18 (&group->group_lock){+.+.}-{4:4},
at: vfio_group_fops_unl_ioctl+0x3e3/0x7b0
[  287.367048]  #1: ff45bea3a96b8230 (&new_dev_set->lock){+.+.}-{4:4},
at: vfio_group_fops_unl_ioctl+0x44d/0x7b0
[  287.376976]
[  287.376976] stack backtrace:
[  287.381353] CPU: 191 UID: 0 PID: 18636 Comm: vfio_pci_sriov_
Tainted: G S                  7.0.0-dbg-DEV #3 PREEMPTLAZY
[  287.381355] Tainted: [S]=CPU_OUT_OF_SPEC
[  287.381356] Call Trace:
[  287.381357]  <TASK>
[  287.381358]  dump_stack_lvl+0x54/0x70
[  287.381361]  print_circular_bug+0x2e1/0x300
[  287.381363]  check_noncircular+0xf9/0x120
[  287.381364]  ? __lock_acquire+0x5b4/0x2800
[  287.381366]  __lock_acquire+0x14c6/0x2800
[  287.381368]  ? pci_mmcfg_read+0x4f/0x220
[  287.381370]  ? pci_mmcfg_write+0x57/0x220
[  287.381371]  ? lock_acquire+0xd3/0x2f0
[  287.381373]  ? pci_mmcfg_write+0x57/0x220
[  287.381374]  ? lock_release+0xef/0x360
[  287.381376]  ? vfio_pci_core_runtime_resume+0x1f/0xa0
[  287.381377]  lock_acquire+0xd3/0x2f0
[  287.381378]  ? vfio_pci_core_runtime_resume+0x1f/0xa0
[  287.381379]  ? lock_is_held_type+0x76/0x100
[  287.381382]  down_write+0x3a/0xc0
[  287.381382]  ? vfio_pci_core_runtime_resume+0x1f/0xa0
[  287.381383]  vfio_pci_core_runtime_resume+0x1f/0xa0
[  287.381384]  ? __pfx_pci_pm_runtime_resume+0x10/0x10
[  287.381385]  __rpm_callback+0x8c/0x310
[  287.381386]  ? ktime_get_mono_fast_ns+0x3d/0xb0
[  287.381389]  ? __pfx_pci_pm_runtime_resume+0x10/0x10
[  287.381390]  rpm_resume+0x529/0x6f0
[  287.381392]  ? lock_is_held_type+0x76/0x100
[  287.381394]  __pm_runtime_resume+0x68/0x90
[  287.381396]  vfio_pci_core_enable+0x44/0x310
[  287.381398]  vfio_pci_open_device+0x1c/0x80
[  287.381399]  vfio_df_open+0x10f/0x150
[  287.381401]  vfio_group_fops_unl_ioctl+0x4a4/0x7b0
[  287.381402]  __se_sys_ioctl+0x71/0xc0
[  287.381404]  do_syscall_64+0x14d/0x750
[  287.381405]  ? entry_SYSCALL_64_after_hwframe+0x77/0x7f
[  287.381406]  ? trace_irq_disable+0x25/0xd0
[  287.381409]  entry_SYSCALL_64_after_hwframe+0x77/0x7f

Introduce a private flag 'sriov_active' in the vfio_pci_core_device struct. This allows the driver to track the SR-IOV power state requirement without relying on pci_num_vf() while holding the memory_lock. The lock is now only held to set the flag and ensure the device is in D0, after which pci_enable_sriov() can be called without the lock.

Fixes f4162eb1e2fc ("vfio/pci: Change the PF power state to D0 before enabling VFs")
[promote bitfield to plain bool to avoid storage-unit races]
---
 drivers/vfio/pci/vfio_pci_core.c |   17 ++++++++++++++---
 include/linux/vfio_pci_core.h    |    1 +
 2 files changed, 15 insertions(+), 3 deletions(-)
drivers/vfio/pci/vfio_pci_core.c +14 -3
@@ -271,8 +271,11 @@ int vfio_pci_set_power_state(struct vfio
 	int ret;
 
 	/* Prevent changing power state for PFs with VFs enabled */
-	if (pci_num_vf(pdev) && state > PCI_D0)
-		return -EBUSY;
+	if (state > PCI_D0) {
+		lockdep_assert_held_write(&vdev->memory_lock);
+		if (vdev->sriov_active)
+			return -EBUSY;
+	}
 
 	if (vdev->needs_pm_restore) {
 		if (pdev->current_state < PCI_D3hot && state >= PCI_D3hot) {
@@ -2309,8 +2312,9 @@ int vfio_pci_core_sriov_configure(struct
 
 		down_write(&vdev->memory_lock);
 		vfio_pci_set_power_state(vdev, PCI_D0);
-		ret = pci_enable_sriov(pdev, nr_virtfn);
+		vdev->sriov_active = true;
 		up_write(&vdev->memory_lock);
+		ret = pci_enable_sriov(pdev, nr_virtfn);
 		if (ret) {
 			pm_runtime_put(&pdev->dev);
 			goto out_del;
@@ -2324,6 +2328,13 @@ int vfio_pci_core_sriov_configure(struct
 	}
 
 out_del:
+	/*
+	 * Avoid taking the memory_lock intentionally. A race with a power
+	 * state transition would at most result in an -EBUSY, leaving the
+	 * device in PCI_D0.
+	 */
+	vdev->sriov_active = false;
+
 	mutex_lock(&vfio_pci_sriov_pfs_mutex);
 	list_del_init(&vdev->sriov_pfs_item);
 out_unlock:
include/linux/vfio_pci_core.h +1 -0
@@ -86,6 +86,7 @@ struct vfio_pci_core_device {
 	bool			needs_pm_restore:1;
 	bool			pm_intx_masked:1;
 	bool			pm_runtime_engaged:1;
+	bool			sriov_active;
 	struct pci_saved_state	*pci_saved_state;
 	struct pci_saved_state	*pm_save;
 	int			ioeventfds_nr;
author maintainer
#118 lore raw

PATCH 117/480 vfio/pci: Latch disable_idle_d3 per device

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Alex Williamson <[email protected]>

commit 4575e9aac5336d1365138c0284773bf8da4b1fa3 upstream.

When disable_idle_d3 was introduced in vfio-pci, it directly manipulated the device power state with pci_set_power_state(). There were no refcounts to maintain or balanced operations, we could unconditionally bring the device to D0 and conditionally move it to D3hot. Therefore the module parameter was made writable.

Later, in commit c61302aa48f7 ("vfio/pci: Move module parameters to vfio_pci.c"), as part of the vfio-pci-core split, the writable aspect of the module parameter was nullified. The parameter value could still be changed through sysfs, but the vfio-pci driver latched the values into vfio-pci-core globals at module init. Loading the vfio-pci module, or unloading and reloading, with non-default or different values could change the globals relative to existing devices bound to vfio-pci variant drivers.

Runtime PM was introduced in commit 7ab5e10eda02 ("vfio/pci: Move the unused device into low power state with runtime PM"), which marks the point where power states became refcounted. PM get and put operations need to be balanced, but the same module operations noted above can change the global variables relative to those devices already bound to vfio-pci variant drivers. This introduces a window where PM operations can now become unbalanced.

To resolve this with a narrow footprint for stable backports, the disable_idle_d3 flag is latched into the vfio_pci_core_device at the time of initialization, such that the device always operates with a consistent value.

NB. vfio_pci_dev_set_try_reset() now unconditionally raises the runtime PM usage count around bus reset to account for disable_idle_d3 becoming a per-device rather than global flag. When this flag is set, the additional get/put pair is harmless and allows continued use of the shared vfio_pci_dev_set_pm_runtime_get() helper.

Fixes 7ab5e10eda02 ("vfio/pci: Move the unused device into low power state with runtime PM")
Assisted-by Claude:claude-opus-4-8
---
 drivers/vfio/pci/vfio_pci_core.c |   19 ++++++++++---------
 include/linux/vfio_pci_core.h    |    1 +
 2 files changed, 11 insertions(+), 9 deletions(-)
drivers/vfio/pci/vfio_pci_core.c +10 -9
@@ -506,7 +506,7 @@ int vfio_pci_core_enable(struct vfio_pci
 	u16 cmd;
 	u8 msix_pos;
 
-	if (!disable_idle_d3) {
+	if (!vdev->disable_idle_d3) {
 		ret = pm_runtime_resume_and_get(&pdev->dev);
 		if (ret < 0)
 			return ret;
@@ -584,7 +584,7 @@ out_free_state:
 out_disable_device:
 	pci_disable_device(pdev);
 out_power:
-	if (!disable_idle_d3)
+	if (!vdev->disable_idle_d3)
 		pm_runtime_put(&pdev->dev);
 	return ret;
 }
@@ -720,7 +720,7 @@ out:
 	vfio_pci_dev_set_try_reset(vdev->vdev.dev_set);
 
 	/* Put the pm-runtime usage counter acquired during enable */
-	if (!disable_idle_d3)
+	if (!vdev->disable_idle_d3)
 		pm_runtime_put(&pdev->dev);
 }
 EXPORT_SYMBOL_GPL(vfio_pci_core_disable);
@@ -2131,6 +2131,8 @@ int vfio_pci_core_init_dev(struct vfio_d
 	init_rwsem(&vdev->memory_lock);
 	xa_init(&vdev->ctx);
 
+	vdev->disable_idle_d3 = disable_idle_d3;
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(vfio_pci_core_init_dev);
@@ -2222,7 +2224,7 @@ int vfio_pci_core_register_device(struct
 
 	dev->driver->pm = &vfio_pci_core_pm_ops;
 	pm_runtime_allow(dev);
-	if (!disable_idle_d3)
+	if (!vdev->disable_idle_d3)
 		pm_runtime_put(dev);
 
 	ret = vfio_register_group_dev(&vdev->vdev);
@@ -2231,7 +2233,7 @@ int vfio_pci_core_register_device(struct
 	return 0;
 
 out_power:
-	if (!disable_idle_d3)
+	if (!vdev->disable_idle_d3)
 		pm_runtime_get_noresume(dev);
 
 	pm_runtime_forbid(dev);
@@ -2250,7 +2252,7 @@ void vfio_pci_core_unregister_device(str
 	vfio_pci_vf_uninit(vdev);
 	vfio_pci_vga_uninit(vdev);
 
-	if (!disable_idle_d3)
+	if (!vdev->disable_idle_d3)
 		pm_runtime_get_noresume(&vdev->pdev->dev);
 
 	pm_runtime_forbid(&vdev->pdev->dev);
@@ -2578,7 +2580,7 @@ static void vfio_pci_dev_set_try_reset(s
 	 * state. Increment the usage count for all the devices in the dev_set
 	 * before reset and decrement the same after reset.
 	 */
-	if (!disable_idle_d3 && vfio_pci_dev_set_pm_runtime_get(dev_set))
+	if (vfio_pci_dev_set_pm_runtime_get(dev_set))
 		return;
 
 	if (!pci_reset_bus(pdev))
@@ -2588,8 +2590,7 @@ static void vfio_pci_dev_set_try_reset(s
 		if (reset_done)
 			cur->needs_reset = false;
 
-		if (!disable_idle_d3)
-			pm_runtime_put(&cur->pdev->dev);
+		pm_runtime_put(&cur->pdev->dev);
 	}
 }
 
include/linux/vfio_pci_core.h +1 -0
@@ -86,6 +86,7 @@ struct vfio_pci_core_device {
 	bool			needs_pm_restore:1;
 	bool			pm_intx_masked:1;
 	bool			pm_runtime_engaged:1;
+	bool			disable_idle_d3:1;
 	bool			sriov_active;
 	struct pci_saved_state	*pci_saved_state;
 	struct pci_saved_state	*pm_save;
author maintainer
#119 lore raw

PATCH 118/480 vfio/pci: Release the VGA arbiter client on register_device() failure

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Alex Williamson <[email protected]>

commit daedde7f024ecf88bc8e832ed40cf2c795f0796a upstream.

The re-order in the Fixes commit below displaced vfio_pci_vga_init() as the last failure point of what is now vfio_pci_core_register_device() without introducing an unwind for the VGA arbiter registration.

In current kernels this is mostly benign because vfio_pci_set_decode() only uses pci_dev state, but the original failure path could leave a callback with a freed vdev cookie. The stale registration also becomes unsafe again once the callback follows drvdata to the vfio device.

Add the required VGA unwind callout.

Fixes 4aeec3984ddc ("vfio/pci: Re-order vfio_pci_probe()")
Assisted-by Claude:claude-opus-4-8
---
 drivers/vfio/pci/vfio_pci_core.c |    1 +
 1 file changed, 1 insertion(+)
drivers/vfio/pci/vfio_pci_core.c +1 -0
@@ -2237,6 +2237,7 @@ out_power:
 		pm_runtime_get_noresume(dev);
 
 	pm_runtime_forbid(dev);
+	vfio_pci_vga_uninit(vdev);
 out_vf:
 	vfio_pci_vf_uninit(vdev);
 	return ret;
author maintainer
#120 lore raw

PATCH 119/480 vfio/pci: Fix racy bitfields and tighten struct layout

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Alex Williamson <[email protected]>

commit e73638e55f861758d49f14d7bb5dba3035981cd7 upstream.

Bitfield operations are not atomic, they use a read-modify-write pattern, therefore we should be careful not to pack bitfields that can be concurrently updated into the same storage unit.

This split takes a binary approach: flags that are only modified pre/post open/close remain bitfields, flags modified from user action, including actions that reach across to another device (ex. reset) use dedicated storage units.

Note that the virq_disabled and bardirty flags are relocated to fill an existing hole in the structure.

Bitfield justifications:

has_dyn_msix: written only in vfio_pci_core_enable()
pci_2_3: written only in vfio_pci_core_enable()
reset_works: written only in vfio_pci_core_enable()
extended_caps: written only in vfio_cap_len() under vfio_config_init()
has_vga: written only in vfio_pci_core_enable()
nointx: written only in vfio_pci_core_enable()
needs_pm_restore: written only in vfio_pci_probe_power_state()
disable_idle_d3: written only at .init in vfio_pci_core_init_dev()

Dedicated storage units:

virq_disabled: written by guest INTx command writes in
vfio_basic_config_write() while the device is open
bardirty: written by guest BAR writes in vfio_basic_config_write()
while the device is open
pm_intx_masked: written in the runtime-PM suspend path.
pm_runtime_engaged: written by low-power feature entry/exit paths
needs_reset: set in vfio_pci_core_disable() and cleared for devices in
the set by vfio_pci_dev_set_try_reset()
sriov_active: written by vfio_pci_core_sriov_configure() via sysfs
sriov_numvfs while bound.

Fixes 9cd0f6d5cbb6 ("vfio/pci: Use bitfield for struct vfio_pci_core_device flags")
Assisted-by Claude:claude-opus-4-8
---
 include/linux/vfio_pci_core.h |   13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)
include/linux/vfio_pci_core.h +8 -5
@@ -60,6 +60,9 @@ struct vfio_pci_core_device {
 	struct pci_dev		*pdev;
 	void __iomem		*barmap[PCI_STD_NUM_BARS];
 	bool			bar_mmap_supported[PCI_STD_NUM_BARS];
+	/* Flags modified at runtime - dedicated storage unit */
+	bool			virq_disabled;
+	bool			bardirty;
 	u8			*pci_config_map;
 	u8			*vconfig;
 	struct perm_bits	*msi_perm;
@@ -74,19 +77,19 @@ struct vfio_pci_core_device {
 	u16			msix_size;
 	u32			msix_offset;
 	u32			rbar[7];
+	/* Flags only modified on setup/release - bitfield ok */
 	bool			has_dyn_msix:1;
 	bool			pci_2_3:1;
-	bool			virq_disabled:1;
 	bool			reset_works:1;
 	bool			extended_caps:1;
-	bool			bardirty:1;
 	bool			has_vga:1;
-	bool			needs_reset:1;
 	bool			nointx:1;
 	bool			needs_pm_restore:1;
-	bool			pm_intx_masked:1;
-	bool			pm_runtime_engaged:1;
 	bool			disable_idle_d3:1;
+	/* Flags modified at runtime - dedicated storage unit */
+	bool			needs_reset;
+	bool			pm_intx_masked;
+	bool			pm_runtime_engaged;
 	bool			sriov_active;
 	struct pci_saved_state	*pci_saved_state;
 	struct pci_saved_state	*pm_save;
author maintainer
#121 lore raw

PATCH 120/480 vfio: prevent infinite loop in vfio_mig_get_next_state() on blocked arc

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Junrui Luo <[email protected]>

commit a26b499b757cfc8bbff1088bb1b844639e250893 upstream.

vfio_mig_get_next_state() walks vfio_from_fsm_table[] one step at a time, looping to skip optional states the device does not support until *next_fsm is supported. A blocked transition is encoded as VFIO_DEVICE_STATE_ERROR, which the trailing return reports as -EINVAL.

The skip loop does not account for the ERROR sentinel. state_flags_table[ERROR] is ~0U and vfio_from_fsm_table[ERROR][*] is ERROR, so once *next_fsm becomes ERROR the loop condition stays true and *next_fsm never changes. The blocked arcs STOP_COPY -> PRE_COPY and STOP_COPY -> PRE_COPY_P2P map to ERROR yet pass the support check on a precopy-capable device, causing the loop to spin forever while holding the driver state mutex. This can result in a soft lockup, and a panic with softlockup_panic set.

Terminate the skip loop on the ERROR sentinel so a blocked transition falls through to the existing return and reports -EINVAL.

---
 drivers/vfio/vfio_main.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/vfio/vfio_main.c +2 -1
@@ -846,7 +846,8 @@ int vfio_mig_get_next_state(struct vfio_
 	 * logical state, as per the above comment.
 	 */
 	*next_fsm = vfio_from_fsm_table[cur_fsm][new_fsm];
-	while ((state_flags_table[*next_fsm] & device->migration_flags) !=
+	while (*next_fsm != VFIO_DEVICE_STATE_ERROR &&
+	       (state_flags_table[*next_fsm] & device->migration_flags) !=
 			state_flags_table[*next_fsm])
 		*next_fsm = vfio_from_fsm_table[*next_fsm][new_fsm];
 
author maintainer
#122 lore raw

PATCH 121/480 vfio: Remove device debugfs before releasing devres

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Alex Williamson <[email protected]>

commit dc7fe87de492ea7f33a72b78d26650b75bf37f4f upstream.

VFIO device debugfs files created with debugfs_create_devm_seqfile() store a devres allocated debugfs_devm_entry as inode private data. vfio_unregister_group_dev() currently calls vfio_device_del() before vfio_device_debugfs_exit(), but device_del() releases devres. This can leave debugfs entries visible with stale inode private data while unregister waits for userspace references to drain.

Remove the per-device debugfs tree before vfio_device_del(). The debugfs view is diagnostic only, so losing it at the start of unregister is preferable to preserving entries whose backing storage may already have been released.

Complete the teardown by clearing the per-device debugfs root after removal. This matches the global debugfs root cleanup and prevents future users from mistaking a removed dentry for a live debugfs tree during the remainder of unregister.

---
 drivers/vfio/debugfs.c   |    1 +
 drivers/vfio/vfio_main.c |    8 +++++++-
 2 files changed, 8 insertions(+), 1 deletion(-)
drivers/vfio/debugfs.c +1 -0
@@ -97,6 +97,7 @@ void vfio_device_debugfs_init(struct vfi
 void vfio_device_debugfs_exit(struct vfio_device *vdev)
 {
 	debugfs_remove_recursive(vdev->debug_root);
+	vdev->debug_root = NULL;
 }
 
 void vfio_debugfs_create_root(void)
drivers/vfio/vfio_main.c +7 -1
@@ -396,6 +396,13 @@ void vfio_unregister_group_dev(struct vf
 	vfio_device_group_unregister(device);
 
 	/*
+	 * Remove debugfs before device_del(), which releases devres.  Some
+	 * debugfs entries are created with debugfs_create_devm_seqfile() and
+	 * therefore rely on devres-managed inode private data.
+	 */
+	vfio_device_debugfs_exit(device);
+
+	/*
 	 * Balances vfio_device_add() in register path, also prevents
 	 * new device opened by userspace in the cdev path.
 	 */
@@ -424,7 +431,6 @@ void vfio_unregister_group_dev(struct vf
 		}
 	}
 
-	vfio_device_debugfs_exit(device);
 	/* Balances vfio_device_set_group in register path */
 	vfio_device_remove_group(device);
 }
author maintainer
#123 lore raw

PATCH 122/480 Bluetooth: btusb: Add USB ID 2c4e:0128 for Mercusys MA60XNB

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Zenm Chen <[email protected]>

commit 88b4d528eda4ac71c2952b3458f2abbc80a91cd2 upstream.

Add USB ID 2c4e:0128 for Mercusys MA60XNB, an RTL8851BU-based Wi-Fi + Bluetooth adapter.

The information in /sys/kernel/debug/usb/devices about the Bluetooth device is listed as the below:

T:  Bus=03 Lev=01 Prnt=01 Port=04 Cnt=01 Dev#=  3 Spd=480  MxCh= 0
D:  Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=2c4e ProdID=0128 Rev= 0.00
S:  Manufacturer=Realtek
S:  Product=802.11ax WLAN Adapter
S:  SerialNumber=00e04c000001
C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=500mA
A:  FirstIf#= 0 IfCount= 2 Cls=e0(wlcon) Sub=01 Prot=01
I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=81(I) Atr=03(Int.) MxPS=  16 Ivl=1ms
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=03(O) Atr=01(Isoc) MxPS=   0 Ivl=1ms
E:  Ad=83(I) Atr=01(Isoc) MxPS=   0 Ivl=1ms
I:  If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=03(O) Atr=01(Isoc) MxPS=   9 Ivl=1ms
E:  Ad=83(I) Atr=01(Isoc) MxPS=   9 Ivl=1ms
I:  If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=03(O) Atr=01(Isoc) MxPS=  17 Ivl=1ms
E:  Ad=83(I) Atr=01(Isoc) MxPS=  17 Ivl=1ms
I:  If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=03(O) Atr=01(Isoc) MxPS=  25 Ivl=1ms
E:  Ad=83(I) Atr=01(Isoc) MxPS=  25 Ivl=1ms
I:  If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=03(O) Atr=01(Isoc) MxPS=  33 Ivl=1ms
E:  Ad=83(I) Atr=01(Isoc) MxPS=  33 Ivl=1ms
I:  If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=03(O) Atr=01(Isoc) MxPS=  49 Ivl=1ms
E:  Ad=83(I) Atr=01(Isoc) MxPS=  49 Ivl=1ms
I:  If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=03(O) Atr=01(Isoc) MxPS=  63 Ivl=1ms
E:  Ad=83(I) Atr=01(Isoc) MxPS=  63 Ivl=1ms
I:* If#= 2 Alt= 0 #EPs= 8 Cls=ff(vend.) Sub=ff Prot=ff Driver=rtw89_8851bu
E:  Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=09(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=0a(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=0b(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=0c(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
---
 drivers/bluetooth/btusb.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/bluetooth/btusb.c +2 -0
@@ -531,6 +531,8 @@ static const struct usb_device_id quirks
 						     BTUSB_WIDEBAND_SPEECH },
 	{ USB_DEVICE(0x7392, 0xe611), .driver_info = BTUSB_REALTEK |
 						     BTUSB_WIDEBAND_SPEECH },
+	{ USB_DEVICE(0x2c4e, 0x0128), .driver_info = BTUSB_REALTEK |
+						     BTUSB_WIDEBAND_SPEECH },
 
 	/* Realtek 8852AE Bluetooth devices */
 	{ USB_DEVICE(0x0bda, 0x2852), .driver_info = BTUSB_REALTEK |
author maintainer
#124 lore raw

PATCH 123/480 Bluetooth: btusb: fix use-after-free on registration failure

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit eedc6867ebad73edbfaf9a0a65fbef7115cc4753 upstream.

Make sure to release the sibling interfaces in case controller registration fails to avoid use-after-free and double-free when they are eventually disconnected.

This issue was reported by Sashiko while reviewing a fix for a wakeup source leak in the btusb probe errors paths.

Fixes 9bfa35fe422c ("[Bluetooth] Add SCO support to btusb driver")
Fixes 9d08f50401ac ("Bluetooth: btusb: Add support for Broadcom LM_DIAG interface")
Cc [email protected] # 2.6.27
---
 drivers/bluetooth/btusb.c |   11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)
drivers/bluetooth/btusb.c +10 -1
@@ -4381,7 +4381,7 @@ static int btusb_probe(struct usb_interf
 
 	err = hci_register_dev(hdev);
 	if (err < 0)
-		goto out_free_dev;
+		goto err_release_siblings;
 
 	usb_set_intfdata(intf, data);
 
@@ -4390,6 +4390,15 @@ static int btusb_probe(struct usb_interf
 
 	return 0;
 
+err_release_siblings:
+	if (data->diag) {
+		usb_set_intfdata(data->diag, NULL);
+		usb_driver_release_interface(&btusb_driver, data->diag);
+	}
+	if (data->isoc) {
+		usb_set_intfdata(data->isoc, NULL);
+		usb_driver_release_interface(&btusb_driver, data->isoc);
+	}
 out_free_dev:
 	if (data->reset_gpio)
 		gpiod_put(data->reset_gpio);
author maintainer
#125 lore raw

PATCH 124/480 Bluetooth: btusb: fix use-after-free on marvell probe failure

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit c5b600a3c05b1a7a110d558df935a8fc8a471c79 upstream.

Make sure to stop any TX URBs submitted during Marvell OOB wakeup configuration on later probe failures to avoid use-after-free in the completion callback.

This issue was reported by Sashiko while reviewing a fix for a wakeup source leak in the btusb probe errors paths.

Fixes a4ccc9e33d2f ("Bluetooth: btusb: Configure Marvell to use one of the pins for oob wakeup")
Cc Rajat Jain <[email protected]>
---
 drivers/bluetooth/btusb.c |    8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/bluetooth/btusb.c +5 -3
@@ -4193,7 +4193,7 @@ static int btusb_probe(struct usb_interf
 	if (id->driver_info & BTUSB_INTEL_COMBINED) {
 		err = btintel_configure_setup(hdev, btusb_driver.name);
 		if (err)
-			goto out_free_dev;
+			goto err_kill_tx_urbs;
 
 		/* Transport specific configuration */
 		hdev->send = btusb_send_frame_intel;
@@ -4355,7 +4355,7 @@ static int btusb_probe(struct usb_interf
 		err = usb_set_interface(data->udev, 0, 0);
 		if (err < 0) {
 			BT_ERR("failed to set interface 0, alt 0 %d", err);
-			goto out_free_dev;
+			goto err_kill_tx_urbs;
 		}
 	}
 
@@ -4363,7 +4363,7 @@ static int btusb_probe(struct usb_interf
 		err = usb_driver_claim_interface(&btusb_driver,
 						 data->isoc, data);
 		if (err < 0)
-			goto out_free_dev;
+			goto err_kill_tx_urbs;
 	}
 
 	if (IS_ENABLED(CONFIG_BT_HCIBTUSB_BCM) && data->diag) {
@@ -4399,6 +4399,8 @@ err_release_siblings:
 		usb_set_intfdata(data->isoc, NULL);
 		usb_driver_release_interface(&btusb_driver, data->isoc);
 	}
+err_kill_tx_urbs:
+	usb_kill_anchored_urbs(&data->tx_anchor);
 out_free_dev:
 	if (data->reset_gpio)
 		gpiod_put(data->reset_gpio);
author maintainer
#126 lore raw

PATCH 125/480 Bluetooth: btusb: fix wakeup source leak on probe failure

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 3d93e1bb0fb881fe3ef961d1120556658e9cac4d upstream.

Make sure to disable wakeup on probe failure to avoid leaking the wakeup source.

Fixes fd913ef7ce61 ("Bluetooth: btusb: Add out-of-band wakeup support")
Cc Rajat Jain <[email protected]>
---
 drivers/bluetooth/btusb.c |   18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)
drivers/bluetooth/btusb.c +15 -3
@@ -2934,6 +2934,11 @@ static int marvell_config_oob_wake(struc
 
 	return 0;
 }
+#else
+static inline int marvell_config_oob_wake(struct hci_dev *hdev)
+{
+	return 0;
+}
 #endif
 
 static int btusb_set_bdaddr_marvell(struct hci_dev *hdev,
@@ -3793,6 +3798,11 @@ static int btusb_config_oob_wake(struct
 	bt_dev_info(hdev, "OOB Wake-on-BT configured at IRQ %u", irq);
 	return 0;
 }
+#else
+static inline int btusb_config_oob_wake(struct hci_dev *hdev)
+{
+	return 0;
+}
 #endif
 
 static void btusb_check_needs_reset_resume(struct usb_interface *intf)
@@ -4147,7 +4157,6 @@ static int btusb_probe(struct usb_interf
 	hdev->wakeup  = btusb_wakeup;
 	hdev->hci_drv = &btusb_hci_drv;
 
-#ifdef CONFIG_PM
 	err = btusb_config_oob_wake(hdev);
 	if (err)
 		goto out_free_dev;
@@ -4156,9 +4165,9 @@ static int btusb_probe(struct usb_interf
 	if (id->driver_info & BTUSB_MARVELL && data->oob_wake_irq) {
 		err = marvell_config_oob_wake(hdev);
 		if (err)
-			goto out_free_dev;
+			goto err_disable_wakeup;
 	}
-#endif
+
 	if (id->driver_info & BTUSB_CW6622)
 		hci_set_quirk(hdev, HCI_QUIRK_BROKEN_STORED_LINK_KEY);
 
@@ -4401,6 +4410,9 @@ err_release_siblings:
 	}
 err_kill_tx_urbs:
 	usb_kill_anchored_urbs(&data->tx_anchor);
+err_disable_wakeup:
+	if (data->oob_wake_irq)
+		device_init_wakeup(&data->udev->dev, false);
 out_free_dev:
 	if (data->reset_gpio)
 		gpiod_put(data->reset_gpio);
author maintainer
#127 lore raw

PATCH 126/480 binder: fix UAF in binder_thread_release()

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Carlos Llamas <[email protected]>

commit 114a116aaa5f0295376cdf12da743c5bce3b20ce upstream.

When a thread exits, binder_thread_release() walks its transaction stack to clear the t->from and t->to_proc that correspond with the exiting thread. However, a process dying in parallel might attempt to kfree some of these transactions. And if one of them has no associated t->to_proc, the t->to_proc->inner_lock will not be acquired.

This means that transaction accesses in binder_thread_release() after t->to_proc has been cleared might race with binder_free_transaction() and cause a use-after-free error as reported by KASAN:

==================================================================

  BUG: KASAN: slab-use-after-free in binder_thread_release+0x5d0/0x798
  Write of size 8 at addr ffff000016627500 by task X/715

  CPU: 17 UID: 0 PID: 715 Comm: X Not tainted 7.1.0-rc5-00149-g8fde5d1d47f6 #30 PREEMPT
  Hardware name: linux,dummy-virt (DT)
  Call trace:
   binder_thread_release+0x5d0/0x798
   binder_ioctl+0x12c0/0x299c
   [...]

  Allocated by task 717 on cpu 18 at 67.267803s:
   __kasan_kmalloc+0xa0/0xbc
   __kmalloc_cache_noprof+0x174/0x444
   binder_transaction+0x554/0x8150
   binder_thread_write+0xa30/0x4354
   binder_ioctl+0x20f0/0x299c
   [...]

  Freed by task 202 on cpu 18 at 90.416221s:
   __kasan_slab_free+0x58/0x80
   kfree+0x1a0/0x4a4
   binder_free_transaction+0x150/0x294
   binder_send_failed_reply+0x398/0x6d8
   binder_release_work+0x3e4/0x4ec
   binder_deferred_func+0xbd8/0x104c
   [...]
  ==================================================================

In order to avoid this, make sure that binder_free_transaction() reads the t->to_proc under the transaction lock. This will serialize the transaction release with the accesses in binder_thread_release(). Plus, it matches the documented locking rules for @to_proc.

Cc stable <[email protected]>
Fixes 7a4408c6bd3e ("binder: make sure accesses to proc/thread are safe")
---
 drivers/android/binder.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/android/binder.c +5 -1
@@ -1658,7 +1658,11 @@ static void binder_txn_latency_free(stru
 
 static void binder_free_transaction(struct binder_transaction *t)
 {
-	struct binder_proc *target_proc = t->to_proc;
+	struct binder_proc *target_proc;
+
+	spin_lock(&t->lock);
+	target_proc = t->to_proc;
+	spin_unlock(&t->lock);
 
 	if (target_proc) {
 		binder_inner_proc_lock(target_proc);
author maintainer
#128 lore raw

PATCH 127/480 binder: fix UAF in binder_free_transaction()

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Carlos Llamas <[email protected]>

commit f223d27a546c1e1f48d38fd67760e78f068fe8c4 upstream.

In binder_free_transaction(), the t->to_proc is read under the t->lock. However, once the t->lock is dropped, the to_proc can die in parallel. This leads to a use-after-free error when we attempt to acquire its inner lock right afterwards:

==================================================================

  BUG: KASAN: slab-use-after-free in _raw_spin_lock+0xe4/0x1a0
  Write of size 4 at addr ffff00001125da70 by task B/672

  CPU: 20 UID: 0 PID: 672 Comm: B Not tainted 7.1.0-rc6-00284-g8e65320d91cd #4 PREEMPT
  Hardware name: linux,dummy-virt (DT)
  Call trace:
   _raw_spin_lock+0xe4/0x1a0
   binder_free_transaction+0x8c/0x320
   binder_send_failed_reply+0x21c/0x2f8
   binder_thread_release+0x488/0x7e0
   binder_ioctl+0x12c0/0x29a0
  [...]

  Allocated by task 675:
   __kmalloc_cache_noprof+0x174/0x444
   binder_open+0x118/0xb70
   do_dentry_open+0x374/0x1040
   vfs_open+0x58/0x3bc
  [...]

  Freed by task 212:
   __kasan_slab_free+0x58/0x80
   kfree+0x1a0/0x4a4
   binder_proc_dec_tmpref+0x32c/0x5e0
   binder_deferred_func+0xc48/0x104c
   process_one_work+0x53c/0xbc0
  [...]
  ==================================================================

To prevent this, pin the target thread (t->to_thread) to guarantee the target process remains alive. Undelivered transactions without a target thread are already safe, as the target process can only be the current context in those paths.

---
 drivers/android/binder.c |   13 +++++++++++++
 1 file changed, 13 insertions(+)
drivers/android/binder.c +13 -0
@@ -1658,10 +1658,19 @@ static void binder_txn_latency_free(stru
 
 static void binder_free_transaction(struct binder_transaction *t)
 {
+	struct binder_thread *target_thread;
 	struct binder_proc *target_proc;
 
 	spin_lock(&t->lock);
 	target_proc = t->to_proc;
+	target_thread = t->to_thread;
+	/*
+	 * Pin target_thread to keep target_proc alive. Undelivered
+	 * transactions with !target_thread are safe, as target_proc
+	 * can only be the current context there.
+	 */
+	if (target_thread)
+		atomic_inc(&target_thread->tmp_ref);
 	spin_unlock(&t->lock);
 
 	if (target_proc) {
@@ -1676,6 +1685,10 @@ static void binder_free_transaction(stru
 			t->buffer->transaction = NULL;
 		binder_inner_proc_unlock(target_proc);
 	}
+
+	if (target_thread)
+		binder_thread_dec_tmpref(target_thread);
+
 	if (trace_binder_txn_latency_free_enabled())
 		binder_txn_latency_free(t);
 	/*
author maintainer
#129 lore raw

PATCH 128/480 rust_binder: use a u64 stride when cleaning up the offsets array

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Hyunwoo Kim <[email protected]>

commit 803c8a9502e9b97cd6ae937618ef4a8fd6274343 upstream.

Allocation's Drop walks the offsets array (binder_size_t = u64 entries), cleaning up the objects, but it used usize instead of u64 for both the stride and the per-entry read.

On 64-bit kernels (usize == u64) this is harmless, but on 32-bit kernels it walks the 8-byte entries in 4-byte steps, iterating an N-entry array 2N times, and reads the always-zero high word as offset 0, cleaning up the object at offset 0 N extra times. As a result the referenced node or handle ends up with a lower reference count than it actually has (a refcount over-decrement), and binder's reference accounting is corrupted; for example, the owner can be notified of a strong reference release (BR_RELEASE) even though references still remain.

Change the stride to u64, and read each entry as a u64, narrowing it to usize with try_into().

On 32-bit ARM, when this over-decrement would drive a count below zero, the driver's existing refcount guard refuses it and fires:

rust_binder: Failure: refcount underflow!

---
 drivers/android/binder/allocation.rs |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/android/binder/allocation.rs +3 -2
@@ -261,7 +261,7 @@ impl Drop for Allocation {
 
             if let Some(offsets) = info.offsets.clone() {
                 let view = AllocationView::new(self, offsets.start);
-                for i in offsets.step_by(size_of::<usize>()) {
+                for i in offsets.step_by(size_of::<u64>()) {
                     if view.cleanup_object(i).is_err() {
                         pr_warn!("Error cleaning up object at offset {}\n", i)
                     }
@@ -419,7 +419,8 @@ impl<'a> AllocationView<'a> {
     }
 
     fn cleanup_object(&self, index_offset: usize) -> Result {
-        let offset = self.alloc.read(index_offset)?;
+        let offset = self.alloc.read::<u64>(index_offset)?;
+        let offset: usize = offset.try_into().map_err(|_| EINVAL)?;
         let header = self.read::<BinderObjectHeader>(offset)?;
         match header.type_ {
             BINDER_TYPE_WEAK_BINDER | BINDER_TYPE_BINDER => {
author maintainer
#130 lore raw

PATCH 129/480 rust_binder: reject context manager self-transaction

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Keshav Verma <[email protected]>

commit 6849cabfd30fb5727cfd31e8241e15801e17ebf9 upstream.

Rust binder resolved handle 0 to the context manager node, but it does not reject the case where the caller owns the same node.

The C binder driver rejects transactions from the context-manager process to handle 0 after resolving the target node. Match that behavior in Rust Binder by rejecting handle 0 transactions when the resolved context-manager node is owned by the calling process.

This applies to both synchronous and oneway transactions because both paths resolve the target through Process::get_transaction_node().

---
 drivers/android/binder/process.rs |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/android/binder/process.rs +5 -1
@@ -873,7 +873,11 @@ impl Process {
     pub(crate) fn get_transaction_node(&self, handle: u32) -> BinderResult<NodeRef> {
         // When handle is zero, try to get the context manager.
         if handle == 0 {
-            Ok(self.ctx.get_manager_node(true)?)
+            let node_ref = self.ctx.get_manager_node(true)?;
+            if core::ptr::eq(self, &*node_ref.node.owner) {
+                return Err(EINVAL.into());
+            }
+            Ok(node_ref)
         } else {
             Ok(self.get_node_from_handle(handle, true)?)
         }
author maintainer
#131 lore raw

PATCH 130/480 rust_binder: synchronize Rust Binder stats with freeze commands

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Keshav Verma <[email protected]>

commit eb1645bf10190e71f6f0316e37ff70755d719b53 upstream.

Rust Binder stats use BC_COUNT and BR_COUNT to size the command and return counters, and use event string tables when printing debug statistics.

The Binder protocol includes freeze-related commands and return codes, but the Rust Binder statistics code was not updated to cover them. As a result, those commands and return codes are not accounted for or printed by the stats debug output.

Update the counts and event string tables so these commands and return codes are included in the debug statistics output.

---
 drivers/android/binder/rust_binder_events.c |    7 ++++++-
 drivers/android/binder/stats.rs             |    4 ++--
 2 files changed, 8 insertions(+), 3 deletions(-)
drivers/android/binder/rust_binder_events.c +6 -1
@@ -28,6 +28,9 @@ const char * const binder_command_string
 	"BC_DEAD_BINDER_DONE",
 	"BC_TRANSACTION_SG",
 	"BC_REPLY_SG",
+	"BC_REQUEST_FREEZE_NOTIFICATION",
+	"BC_CLEAR_FREEZE_NOTIFICATION",
+	"BC_FREEZE_NOTIFICATION_DONE",
 };
 
 const char * const binder_return_strings[] = {
@@ -51,7 +54,9 @@ const char * const binder_return_strings
 	"BR_FAILED_REPLY",
 	"BR_FROZEN_REPLY",
 	"BR_ONEWAY_SPAM_SUSPECT",
-	"BR_TRANSACTION_PENDING_FROZEN"
+	"BR_TRANSACTION_PENDING_FROZEN",
+	"BR_FROZEN_BINDER",
+	"BR_CLEAR_FREEZE_NOTIFICATION_DONE",
 };
 
 #define CREATE_TRACE_POINTS
drivers/android/binder/stats.rs +2 -2
@@ -8,8 +8,8 @@ use crate::defs::*;
 use core::sync::atomic::{AtomicU32, Ordering::Relaxed};
 use kernel::{ioctl::_IOC_NR, seq_file::SeqFile, seq_print};
 
-const BC_COUNT: usize = _IOC_NR(BC_REPLY_SG) as usize + 1;
-const BR_COUNT: usize = _IOC_NR(BR_TRANSACTION_PENDING_FROZEN) as usize + 1;
+const BC_COUNT: usize = _IOC_NR(BC_FREEZE_NOTIFICATION_DONE) as usize + 1;
+const BR_COUNT: usize = _IOC_NR(BR_CLEAR_FREEZE_NOTIFICATION_DONE) as usize + 1;
 
 pub(crate) static GLOBAL_STATS: BinderStats = BinderStats::new();
 
author maintainer
#132 lore raw

PATCH 131/480 rust_binder: clear freeze listener on node removal

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Alice Ryhl <[email protected]>

commit bc4a9828897871ff3e5a1f8a1d346decbf4ee95e upstream.

Generally userspace is supposed to explicitly clear freeze listeners before they drop the refcount on the node ref to zero, but there's nothing forcing that. Currently, in this scenario the freeze listener remains in the freeze_listeners rbtree and in the remote node's freeze listener list, even though the ref for which the listener is registered is gone. This could potentially lead to a memory leak due to a refcount cycle. Thus, remove the freeze listener in this scenario.

---
 drivers/android/binder/freeze.rs  |   11 +++++++++--
 drivers/android/binder/node.rs    |   10 ++++++----
 drivers/android/binder/process.rs |   12 +++++++++++-
 3 files changed, 26 insertions(+), 7 deletions(-)
drivers/android/binder/freeze.rs +9 -2
@@ -154,10 +154,17 @@ impl DeliverToRead for FreezeMessage {
 }
 
 impl FreezeListener {
-    pub(crate) fn on_process_exit(&self, proc: &Arc<Process>) {
+    /// Called when this freeze listener is cleared abnormally.
+    ///
+    /// This occurs either because the process exited or because the process dropped its last
+    /// refcount on the node ref without explicitly removing the freeze listener first.
+    ///
+    /// The returned `KVVec` is just a value that should be dropped outside of the lock.
+    pub(crate) fn on_process_cleanup(&self, proc: &Process) -> KVVec<Arc<Process>> {
         if !self.is_clearing {
-            self.node.remove_freeze_listener(proc);
+            return self.node.remove_freeze_listener(proc);
         }
+        KVVec::new()
     }
 }
 
drivers/android/binder/node.rs +6 -4
@@ -674,12 +674,13 @@ impl Node {
         }
     }
 
-    pub(crate) fn remove_freeze_listener(&self, p: &Arc<Process>) {
-        let _unused_capacity;
+    pub(crate) fn remove_freeze_listener(&self, p: &Process) -> KVVec<Arc<Process>> {
         let mut guard = self.owner.inner.lock();
         let inner = self.inner.access_mut(&mut guard);
         let len = inner.freeze_list.len();
-        inner.freeze_list.retain(|proc| !Arc::ptr_eq(proc, p));
+        inner
+            .freeze_list
+            .retain(|proc| !core::ptr::eq::<Process>(&**proc, p));
         if len == inner.freeze_list.len() {
             pr_warn!(
                 "Could not remove freeze listener for {}\n",
@@ -687,8 +688,9 @@ impl Node {
             );
         }
         if inner.freeze_list.is_empty() {
-            _unused_capacity = mem::take(&mut inner.freeze_list);
+            return mem::take(&mut inner.freeze_list);
         }
+        KVVec::new()
     }
 
     pub(crate) fn freeze_list<'a>(&'a self, guard: &'a ProcessInner) -> &'a [Arc<Process>] {
drivers/android/binder/process.rs +11 -1
@@ -919,6 +919,8 @@ impl Process {
 
         // To preserve original binder behaviour, we only fail requests where the manager tries to
         // increment references on itself.
+        let _to_free_freeze_listener;
+        let _to_free_freeze_listener_cleanup;
         let mut refs = self.node_refs.lock();
         if let Some(info) = refs.by_handle.get_mut(&handle) {
             if info.node_ref().update(inc, strong) {
@@ -934,6 +936,14 @@ impl Process {
                 unsafe { info.node_ref2().node.remove_node_info(info) };
 
                 let id = info.node_ref().node.global_id();
+
+                if let Some(freeze) = *info.freeze() {
+                    if let Some(fl) = refs.freeze_listeners.remove(&freeze) {
+                        _to_free_freeze_listener_cleanup = fl.on_process_cleanup(&self);
+                        _to_free_freeze_listener = fl;
+                    }
+                }
+
                 refs.by_handle.remove(&handle);
                 refs.by_node.remove(&id);
             }
@@ -1348,7 +1358,7 @@ impl Process {
         // Clean up freeze listeners.
         let freeze_listeners = take(&mut self.node_refs.lock().freeze_listeners);
         for listener in freeze_listeners.values() {
-            listener.on_process_exit(&self);
+            listener.on_process_cleanup(&self);
         }
         drop(freeze_listeners);
 
author maintainer
#133 lore raw

PATCH 132/480 usb: xhci: Fix sleep in atomic context in xhci_free_streams()

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: 胡连勤 <[email protected]>

commit 42c37c4b75d38b51d84f31a8e29427f5e06a7c2a upstream.

When a USB device with active stream endpoints is disconnected, xhci_free_streams() is called from the hub_event workqueue to free the stream resources. It calls xhci_free_stream_info() while holding xhci->lock with irqs disabled.

xhci_free_stream_info() invokes xhci_free_stream_ctx(), which calls dma_free_coherent() for large stream context arrays.

dma_free_coherent() can sleep (e.g. via vunmap), triggering a BUG when called from atomic context.

Call trace:
 dma_free_attrs+0x174/0x220
 xhci_free_stream_info+0xd0/0x11c
 xhci_free_streams+0x278/0x37c
 usb_free_streams+0x98/0xc0
 usb_unbind_interface+0x1b8/0x2f8
 device_release_driver_internal+0x1d4/0x2cc
 device_release_driver+0x18/0x28
 bus_remove_device+0x160/0x1a4
 device_del+0x1ec/0x350
 usb_disable_device+0x98/0x214
 usb_disconnect+0xf0/0x35c
 hub_event+0xab4/0x19ec
 process_one_work+0x278/0x63c

Fix this by saving the stream_info pointers and clearing the ep references under the lock, then calling xhci_free_stream_info() outside the lock where sleeping is allowed.

Fixes 8df75f42f8e6 ("USB: xhci: Add memory allocation for USB3 bulk streams.")
Cc stable <[email protected]>
---
 drivers/usb/host/xhci.c |   11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)
drivers/usb/host/xhci.c +10 -1
@@ -3774,6 +3774,7 @@ static int xhci_free_streams(struct usb_
 	struct xhci_virt_device *vdev;
 	struct xhci_command *command;
 	struct xhci_input_control_ctx *ctrl_ctx;
+	struct xhci_stream_info *stream_info[EP_CTX_PER_DEV];
 	unsigned int ep_index;
 	unsigned long flags;
 	u32 changed_ep_bitmask;
@@ -3834,10 +3835,15 @@ static int xhci_free_streams(struct usb_
 	if (ret < 0)
 		return ret;
 
+	/*
+	 * dma_free_coherent() called by xhci_free_stream_info() may sleep,
+	 * so save stream_info pointers and clear references under lock,
+	 * then free the memory outside lock.
+	 */
 	spin_lock_irqsave(&xhci->lock, flags);
 	for (i = 0; i < num_eps; i++) {
 		ep_index = xhci_get_endpoint_index(&eps[i]->desc);
-		xhci_free_stream_info(xhci, vdev->eps[ep_index].stream_info);
+		stream_info[i] = vdev->eps[ep_index].stream_info;
 		vdev->eps[ep_index].stream_info = NULL;
 		/* FIXME Unset maxPstreams in endpoint context and
 		 * update deq ptr to point to normal string ring.
@@ -3847,6 +3853,9 @@ static int xhci_free_streams(struct usb_
 	}
 	spin_unlock_irqrestore(&xhci->lock, flags);
 
+	for (i = 0; i < num_eps; i++)
+		xhci_free_stream_info(xhci, stream_info[i]);
+
 	return 0;
 }
 
author maintainer
#134 lore raw

PATCH 133/480 xhci: sideband: fix ring sg table pages leak

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Xu Rao <[email protected]>

commit 49f6e3c3ef19f04f6657ed8dce550e36c763abb8 upstream.

xhci_ring_to_sgtable() allocates a temporary pages array and uses it to build the returned sg_table with sg_alloc_table_from_pages().

The error paths free the pages array, but the success path returns the sg_table without freeing it. This leaks the temporary array every time a sideband client gets an endpoint or event ring buffer.

Free the pages array after sg_alloc_table_from_pages() succeeds. The returned sg_table has its own scatterlist entries and does not depend on the temporary array after construction.

Fixes de66754e9f80 ("xhci: sideband: add initial api to register a secondary interrupter entity")
Cc stable <[email protected]>
---
 drivers/usb/host/xhci-sideband.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/usb/host/xhci-sideband.c +2 -0
@@ -58,6 +58,8 @@ xhci_ring_to_sgtable(struct xhci_sideban
 	if (sg_alloc_table_from_pages(sgt, pages, n_pages, 0, sz, GFP_KERNEL))
 		goto err;
 
+	kvfree(pages);
+
 	/*
 	 * Save first segment dma address to sg dma_address field for the sideband
 	 * client to have access to the IOVA of the ring.
author maintainer
#135 lore raw

PATCH 134/480 usb: typec: tcpci_rt1711h: unregister TCPCI port with devres

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Myeonghun Pak <[email protected]>

commit e8da46d99d3710106e7c44db14566bf9b57386b5 upstream.

rt1711h_probe() registers the TCPCI port before requesting the interrupt and enabling alert interrupts. If either of those later steps fails, the probe function returns without unregistering the TCPCI port. The explicit unregister currently only happens from the remove callback.

Register a devres action immediately after tcpci_register_port() succeeds, so tcpci_unregister_port() runs on later probe failures and on driver detach. Drop the remove callback to avoid unregistering the same port twice.

This issue was identified during our ongoing static-analysis research while reviewing kernel code.

Fixes 302c570bf36e ("usb: typec: tcpci_rt1711h: avoid screaming irq causing boot hangs")
Cc stable <[email protected]>
---
 drivers/usb/typec/tcpm/tcpci_rt1711h.c |   13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)
drivers/usb/typec/tcpm/tcpci_rt1711h.c +8 -5
@@ -330,6 +330,8 @@ static int rt1711h_check_revision(struct
 	return ret;
 }
 
+static void rt1711h_unregister_tcpci_port(void *tcpci);
+
 static int rt1711h_probe(struct i2c_client *client)
 {
 	int ret;
@@ -381,6 +383,10 @@ static int rt1711h_probe(struct i2c_clie
 	if (IS_ERR_OR_NULL(chip->tcpci))
 		return PTR_ERR(chip->tcpci);
 
+	ret = devm_add_action_or_reset(chip->dev, rt1711h_unregister_tcpci_port, chip->tcpci);
+	if (ret)
+		return ret;
+
 	ret = devm_request_threaded_irq(chip->dev, client->irq, NULL,
 					rt1711h_irq,
 					IRQF_ONESHOT | IRQF_TRIGGER_LOW,
@@ -398,11 +404,9 @@ static int rt1711h_probe(struct i2c_clie
 	return 0;
 }
 
-static void rt1711h_remove(struct i2c_client *client)
+static void rt1711h_unregister_tcpci_port(void *tcpci)
 {
-	struct rt1711h_chip *chip = i2c_get_clientdata(client);
-
-	tcpci_unregister_port(chip->tcpci);
+	tcpci_unregister_port(tcpci);
 }
 
 static const struct rt1711h_chip_info rt1711h = {
@@ -435,7 +439,6 @@ static struct i2c_driver rt1711h_i2c_dri
 		.of_match_table = rt1711h_of_match,
 	},
 	.probe = rt1711h_probe,
-	.remove = rt1711h_remove,
 	.id_table = rt1711h_id,
 };
 module_i2c_driver(rt1711h_i2c_driver);
author maintainer
#136 lore raw

PATCH 135/480 PCI: loongson: Override PCIe bridge supported speeds for Loongson-3C6000 series

In reply to Greg Kroah-Hartman

6.18-stable review patch. If anyone has any objections, please let me know.

------------------

From: Ziyao Li <[email protected]>

commit e373c789bac0ad73b472d8b44714df3bd18a4edf upstream.

Older steppings of the Loongson-3C6000 series incorrectly report the supported link speeds on their PCIe bridges (device IDs 0x3c19, 0x3c29) as only 2.5 GT/s, despite the upstream bus supporting speeds from 2.5 GT/s up to 16 GT/s.

As a result, since commit 774c71c52aa4 ("PCI/bwctrl: Enable only if more than one speed is supported"), bwctrl will be disabled if there's only one 2.5 GT/s value in vector 'supported_speeds'.

Manually override the 'supported_speeds' field for affected PCIe bridges with those found on the upstream bus to correctly reflect the supported link speeds. Updating the speeds to reflect what the hardware actually supports avoids quirks in drivers consuming the speed information.

This commit was originally found from AOSC OS[1].

Fixes cd89edda4002 ("PCI: loongson: Add ACPI init support")
[Ziyao Li: move from drivers/pci/quirks.c to drivers/pci/controller/pci-loongson.c]
[Xi Ruoyao: Fixed falling through logic, added debug log, Fixes tag and rebased to 7.0-rc7]
[bhelgaas: commit log, https://lore.kernel.org/all/[email protected]]
---
 drivers/pci/controller/pci-loongson.c |   36 ++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)
drivers/pci/controller/pci-loongson.c +36 -0
@@ -176,6 +176,42 @@ static void loongson_pci_msi_quirk(struc
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, DEV_LS7A_PCIE_PORT5, loongson_pci_msi_quirk);
 
+/*
+ * Older steppings of the Loongson-3C6000 series incorrectly report the
+ * supported link speeds on their PCIe bridges (device IDs 0x3c19,
+ * 0x3c29) as only 2.5 GT/s, despite the upstream bus supporting speeds
+ * from 2.5 GT/s up to 16 GT/s.
+ */
+static void loongson_pci_bridge_speed_quirk(struct pci_dev *pdev)
+{
+	u8 old_supported_speeds = pdev->supported_speeds;
+
+	switch (pdev->bus->max_bus_speed) {
+	case PCIE_SPEED_16_0GT:
+		pdev->supported_speeds |= PCI_EXP_LNKCAP2_SLS_16_0GB;
+		fallthrough;
+	case PCIE_SPEED_8_0GT:
+		pdev->supported_speeds |= PCI_EXP_LNKCAP2_SLS_8_0GB;
+		fallthrough;
+	case PCIE_SPEED_5_0GT:
+		pdev->supported_speeds |= PCI_EXP_LNKCAP2_SLS_5_0GB;
+		fallthrough;
+	case PCIE_SPEED_2_5GT:
+		pdev->supported_speeds |= PCI_EXP_LNKCAP2_SLS_2_5GB;
+		break;
+	default:
+		pci_warn(pdev, "unexpected max bus speed");
+
+		return;
+	}
+
+	if (pdev->supported_speeds != old_supported_speeds)
+		pci_info(pdev, "fixed up supported link speeds: 0x%x => 0x%x",
+			 old_supported_speeds, pdev->supported_speeds);
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_LOONGSON, 0x3c19, loongson_pci_bridge_speed_quirk);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_LOONGSON, 0x3c29, loongson_pci_bridge_speed_quirk);
+
 static struct loongson_pci *pci_bus_to_loongson_pci(struct pci_bus *bus)
 {
 	struct pci_config_window *cfg;