6.18.39-rc1 review
Greg Kroah-Hartman
maintainercover 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(-)
Greg Kroah-Hartman
maintainerPATCH 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.
--- arch/arm64/lib/insn.c | 2 ++ 1 file changed, 2 insertions(+)
arch/arm64/lib/insn.c +2 -0
@@ -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
Greg Kroah-Hartman
maintainerPATCH 2/480 nfsd: update mtime/ctime on CLONE in presense of delegated attributes
In reply to Greg Kroah-Hartman6.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.
--- 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
@@ -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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 3/480 nfsd: update mtime/ctime on COPY in presence of delegated attributes
In reply to Greg Kroah-Hartman6.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.
--- fs/nfsd/nfs4proc.c | 11 ++++++++++- fs/nfsd/xdr4.h | 1 + 2 files changed, 11 insertions(+), 1 deletion(-)
fs/nfsd/nfs4proc.c +10 -1
@@ -1956,8 +1956,10 @@ static int nfsd4_do_async_copy(void *data)set_bit (NFSD4_COPY_F_COMPLETED , ©->cp_flags);trace_nfsd_copy_async_done (copy); -nfsd4_send_cb_offload (copy);atomic_dec (©->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, ©->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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 4/480 nfsd: release layout stid on setlease failure
In reply to Greg Kroah-Hartman6.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).
--- fs/nfsd/nfs4layouts.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
fs/nfsd/nfs4layouts.c +1 -3
@@ -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
Greg Kroah-Hartman
maintainerPATCH 5/480 rust: str: use the "kernel vertical" imports style
In reply to Greg Kroah-Hartman6.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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 6/480 rust: str: clean unused import for Rust >= 1.98
In reply to Greg Kroah-Hartman6.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
@@ -4,7 +4,6 @@use crate ::{ alloc::{ - flags::*,AllocError ,KVec ,// },
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 7/480 userfaultfd: gate must_wait writability check on pte_present()
In reply to Greg Kroah-Hartman6.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.
[ 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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 8/480 device property: initialize the remaining fields of fwnode_handle in fwnode_init()
In reply to Greg Kroah-Hartman6.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,
Greg Kroah-Hartman
maintainerPATCH 9/480 f2fs: remove non-uptodate folio from the page cache in move_data_block
In reply to Greg Kroah-Hartman6.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; }
Greg Kroah-Hartman
maintainerPATCH 10/480 f2fs: atomic: fix UAF issue on f2fs_inode_info.atomic_inode
In reply to Greg Kroah-Hartman6.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.
--- 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_infostatic 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 *inodf2fs_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);
Greg Kroah-Hartman
maintainerPATCH 11/480 f2fs: bound i_inline_xattr_size for non-inline-xattr inodes
In reply to Greg Kroah-Hartman6.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.
--- 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 );
Greg Kroah-Hartman
maintainerPATCH 12/480 f2fs: fix potential deadlock in f2fs_balance_fs()
In reply to Greg Kroah-Hartman6.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/0x198The 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);
Greg Kroah-Hartman
maintainerPATCH 13/480 f2fs: fix potential deadlock in gc_merge path of f2fs_balance_fs()
In reply to Greg Kroah-Hartman6.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);
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_infoif (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);
Greg Kroah-Hartman
maintainerPATCH 14/480 f2fs: fix listxattr handling of corrupted xattr entries
In reply to Greg Kroah-Hartman6.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.
--- 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 *desize_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 *deset_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 ;
Greg Kroah-Hartman
maintainerPATCH 15/480 f2fs: use memalloc_retry_wait() as much as possible
In reply to Greg Kroah-Hartman6.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 );
Greg Kroah-Hartman
maintainerPATCH 16/480 f2fs: introduce f2fs_schedule_timeout()
In reply to Greg Kroah-Hartman6.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(strf2fs_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_discareturn 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 ;
Greg Kroah-Hartman
maintainerPATCH 17/480 f2fs: optimize trace_f2fs_write_checkpoint with enums
In reply to Greg Kroah-Hartman6.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_sbstat_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,
Greg Kroah-Hartman
maintainerPATCH 18/480 f2fs: detect more inconsistent cases in sanity_check_node_footer()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <[email protected]>
[ 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 = trueNODE_TYPE_INODE inode = false or xnode = trueNODE_TYPE_XATTR inode = true or xnode = falseNODE_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 :
Greg Kroah-Hartman
maintainerPATCH 19/480 f2fs: fix to do sanity check on f2fs_get_node_folio_ra()
In reply to Greg Kroah-Hartman6.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(structif (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_foliostruct 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)
Greg Kroah-Hartman
maintainerPATCH 20/480 fbdev: fbcon: fix out-of-bounds read in err_out of fbcon_do_set_font()
In reply to Greg Kroah-Hartman6.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.
--- 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_dstruct 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; }
Greg Kroah-Hartman
maintainerPATCH 21/480 net/sched: dualpi2: fix GSO backlog accounting
In reply to Greg Kroah-Hartman6.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(structif (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); }
Greg Kroah-Hartman
maintainerPATCH 22/480 nfsd: move name lookup out of nfsd4_list_rec_dir()
In reply to Greg Kroah-Hartman6.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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 23/480 nfsd: change nfs4_client_to_reclaim() to allocate data
In reply to Greg Kroah-Hartman6.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
@@ -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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 24/480 mm/khugepaged: write all dirty file folios when collapsing
In reply to Greg Kroah-Hartman6.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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 25/480 slab: Introduce kmalloc_flex() and family
In reply to Greg Kroah-Hartman6.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
Greg Kroah-Hartman
maintainerPATCH 26/480 add default_gfp() helper macro and use it in the new *alloc_obj() helpers
In reply to Greg Kroah-Hartman6.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
Greg Kroah-Hartman
maintainerPATCH 27/480 default_gfp(): avoid using the "newfangled" __VA_OPT__ trick
In reply to Greg Kroah-Hartman6.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.
--- 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)
Greg Kroah-Hartman
maintainerPATCH 28/480 slab: recognize @GFP parameter as optional in kernel-doc
In reply to Greg Kroah-Hartman6.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'
--- 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
Greg Kroah-Hartman
maintainerPATCH 29/480 perf trace beauty fcntl: Fix build with older kernel headers
In reply to Greg Kroah-Hartman6.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.
--- 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") :
Greg Kroah-Hartman
maintainerPATCH 30/480 KVM: x86: Move update_cr8_intercept() to lapic.c
In reply to Greg Kroah-Hartman6.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 *vreturn (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_vcvoid 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_vkvm_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 kvmkvm_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 &&
Greg Kroah-Hartman
maintainerPATCH 31/480 KVM: VMX: Grab vmcs12 on CR8 interception update iff vCPU is in guest mode
In reply to Greg Kroah-Hartman6.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(structvoid 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;
Greg Kroah-Hartman
maintainerPATCH 32/480 KVM: x86: Unconditionally recompute CR8 intercept on PPR update
In reply to Greg Kroah-Hartman6.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_lif (__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 kvmkvm_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 kvmkvm_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 &&
Greg Kroah-Hartman
maintainerPATCH 33/480 ACPI: CPPC: Suppress UBSAN warning caused by field misuse
In reply to Greg Kroah-Hartman6.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.
--- 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 )
Greg Kroah-Hartman
maintainerPATCH 34/480 ACPI: NFIT: core: Fix possible NULL pointer dereference
In reply to Greg Kroah-Hartman6.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().
--- 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
Greg Kroah-Hartman
maintainerPATCH 35/480 platform/x86: intel-hid: Protect ACPI notify handler against recursion
In reply to Greg Kroah-Hartman6.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 hstruct 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 platforeturn -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))
Greg Kroah-Hartman
maintainerPATCH 36/480 LoongArch: Add PIO for early access before ACPI PCI root register
In reply to Greg Kroah-Hartman6.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_physireturn 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(sstruct 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);
Greg Kroah-Hartman
maintainerPATCH 37/480 rust: cpufreq: clean new `clippy::map_or_identity` lint for Rust 1.98.0
In reply to Greg Kroah-Hartman6.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.
Greg Kroah-Hartman
maintainerPATCH 38/480 rust: block: fix GenDisk cleanup paths
In reply to Greg Kroah-Hartman6.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.
Greg Kroah-Hartman
maintainerPATCH 39/480 rust: doctest: fix incorrect pattern in replacement
In reply to Greg Kroah-Hartman6.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.
[ 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
Greg Kroah-Hartman
maintainerPATCH 40/480 rust: Kbuild: set frame-pointer llvm module flag for CONFIG_FRAME_POINTER
In reply to Greg Kroah-Hartman6.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 ]
[ - 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
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.
Signed-off-by Greg Kroah-Hartman <[email protected]>- Added comment with link to the PR, similar to what we did in commit
ac35b5580ace("rust: arm64: set uwtable llvm module flag forCONFIG_UNWIND_TABLES").- Miguel ]
Signed-off-by Miguel Ojeda <[email protected]>
Ditto.
Cheers,
Miguel
Greg Kroah-Hartman
maintainerPATCH 41/480 futex/requeue: Revert "Prevent NULL pointer dereference in remove_waiter() on self-deadlock""
In reply to Greg Kroah-Hartman6.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);
Greg Kroah-Hartman
maintainerPATCH 42/480 perf/core: Detach event groups during remove_on_exec
In reply to Greg Kroah-Hartman6.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.
--- kernel/events/core.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-)
kernel/events/core.c +9 -8
@@ -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
Greg Kroah-Hartman
maintainerPATCH 43/480 rust: kasan: KASAN+RUST requires clang
In reply to Greg Kroah-Hartman6.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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 44/480 fscrypt: Fix key setup in edge case with multiple data unit sizes
In reply to Greg Kroah-Hartman6.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.
--- 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
@@ -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
@@ -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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 45/480 fscrypt: Replace mk_users keyring with simple list
In reply to Greg Kroah-Hartman6.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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 46/480 usb: gadget: function: rndis: add length check to response query
In reply to Greg Kroah-Hartman6.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 rnstatic 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 rif (!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);
Greg Kroah-Hartman
maintainerPATCH 47/480 usb: gadget: function: rndis: add length check for header
In reply to Greg Kroah-Hartman6.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++)) {
Greg Kroah-Hartman
maintainerPATCH 48/480 iio: accel: bmc150: clamp the device-reported FIFO frame count
In reply to Greg Kroah-Hartman6.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.
--- 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(strif (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;
Greg Kroah-Hartman
maintainerPATCH 49/480 iio: accel: kxsd9: fix runtime PM imbalance on write_raw() error
In reply to Greg Kroah-Hartman6.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.
--- 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_deif (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);
Greg Kroah-Hartman
maintainerPATCH 50/480 iio: adc: ad7380: select REGMAP
In reply to Greg Kroah-Hartman6.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.
--- 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
Greg Kroah-Hartman
maintainerPATCH 51/480 iio: adc: ad7768-1: Select GPIOLIB
In reply to Greg Kroah-Hartman6.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
Greg Kroah-Hartman
maintainerPATCH 52/480 iio: adc: ad7779: add missing select IIO_TRIGGERED_BUFFER to Kconfig
In reply to Greg Kroah-Hartman6.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.
--- 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
Greg Kroah-Hartman
maintainerPATCH 53/480 iio: adc: ad_sigma_delta: fix clear_pending_event for registerless devices
In reply to Greg Kroah-Hartman6.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().
--- 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
Greg Kroah-Hartman
maintainerPATCH 54/480 iio: adc: ad_sigma_delta: fix CS held asserted and state leaks
In reply to Greg Kroah-Hartman6.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.
--- 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(strucreturn 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);
Greg Kroah-Hartman
maintainerPATCH 55/480 iio: adc: lpc32xx: Initialize completion before requesting IRQ
In reply to Greg Kroah-Hartman6.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 platif (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 platplatform_set_drvdata (pdev, iodev); -init_completion (&st->completion); - iodev->name =LPC32XXAD_NAME ; iodev->info = &lpc32xx_adc_iio_info; iodev->modes =INDIO_DIRECT_MODE ;
Greg Kroah-Hartman
maintainerPATCH 56/480 iio: adc: spear: Initialize completion before requesting IRQ
In reply to Greg Kroah-Hartman6.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 platfospear_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 ;
Greg Kroah-Hartman
maintainerPATCH 57/480 iio: adc: ti-ads1119: fix PM reference leak in buffer preenable
In reply to Greg Kroah-Hartman6.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.
--- 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_preeif (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)
Greg Kroah-Hartman
maintainerPATCH 58/480 iio: adc: ti-ads124s08: Return reset GPIO lookup errors
In reply to Greg Kroah-Hartman6.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];
Greg Kroah-Hartman
maintainerPATCH 59/480 iio: backend: fix uninitialized data in debugfs
In reply to Greg Kroah-Hartman6.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.
--- 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_writessize_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);
Greg Kroah-Hartman
maintainerPATCH 60/480 iio: chemical: scd30: Cleanup initializations and fix sign-extension bug
In reply to Greg Kroah-Hartman6.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)
Greg Kroah-Hartman
maintainerPATCH 61/480 iio: common: st_sensors: honour channel endianness in read_axis_data
In reply to Greg Kroah-Hartman6.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.
--- 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(stru8 *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(strif (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);
Greg Kroah-Hartman
maintainerPATCH 62/480 iio: core: fix uninitialized data in debugfs
In reply to Greg Kroah-Hartman6.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.
--- 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(strchar 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,
Greg Kroah-Hartman
maintainerPATCH 63/480 iio: dac: ad3552r-hs: fix uninitialized data ni ad3552r_hs_write_data_source()
In reply to Greg Kroah-Hartman6.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.
--- 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_souguard (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,
Greg Kroah-Hartman
maintainerPATCH 64/480 iio: event: Fix event FIFO reset race
In reply to Greg Kroah-Hartman6.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.
--- 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_deif (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;
Greg Kroah-Hartman
maintainerPATCH 65/480 iio: gyro: bmg160: bail out when bandwidth/filter is not in table
In reply to Greg Kroah-Hartman6.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.
--- 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 bmg1break ; } +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 bmg1break ; } +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 ) {
Greg Kroah-Hartman
maintainerPATCH 66/480 iio: gyro: bmg160: wait full startup time after mode change at probe
In reply to Greg Kroah-Hartman6.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.
--- 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 bmg16if (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 );
Greg Kroah-Hartman
maintainerPATCH 67/480 iio: imu: adis: add IRQF_NO_THREAD to non-FIFO trigger IRQ
In reply to Greg Kroah-Hartman6.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.
--- 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 adiselse 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)
Greg Kroah-Hartman
maintainerPATCH 68/480 iio: imu: bmi160: add IRQF_NO_THREAD to data-ready trigger IRQ
In reply to Greg Kroah-Hartman6.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.
--- 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;
Greg Kroah-Hartman
maintainerPATCH 69/480 iio: imu: inv_icm42600: fix timestamp clock period by using lower value
In reply to Greg Kroah-Hartman6.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).
--- 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);
Greg Kroah-Hartman
maintainerPATCH 70/480 iio: imu: inv_icm42600: fix timestamping by limiting FIFO reading
In reply to Greg Kroah-Hartman6.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.
--- 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 {
Greg Kroah-Hartman
maintainerPATCH 71/480 iio: imu: st_lsm6dsx: deselect shub page before reading whoami
In reply to Greg Kroah-Hartman6.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.
--- 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(strucreturn -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 ; }
Greg Kroah-Hartman
maintainerPATCH 72/480 iio: light: al3000a: add missing REGMAP_I2C to Kconfig
In reply to Greg Kroah-Hartman6.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.
--- 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
Greg Kroah-Hartman
maintainerPATCH 73/480 iio: light: al3010: add missing REGMAP_I2C to Kconfig
In reply to Greg Kroah-Hartman6.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.
--- 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
Greg Kroah-Hartman
maintainerPATCH 74/480 iio: light: al3010: fix incorrect scale for the highest gain range
In reply to Greg Kroah-Hartman6.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.
--- 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 = {
Greg Kroah-Hartman
maintainerPATCH 75/480 iio: light: al3010: read both ALS ADC registers again
In reply to Greg Kroah-Hartman6.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.
--- 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 :
Greg Kroah-Hartman
maintainerPATCH 76/480 iio: light: al3320a: add missing REGMAP_I2C to Kconfig
In reply to Greg Kroah-Hartman6.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.
--- 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
Greg Kroah-Hartman
maintainerPATCH 77/480 iio: light: al3320a: read both ALS ADC registers again
In reply to Greg Kroah-Hartman6.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.
--- 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 :
Greg Kroah-Hartman
maintainerPATCH 78/480 iio: light: gp2ap002: fix runtime PM leak on read error
In reply to Greg Kroah-Hartman6.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.
--- 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;
Greg Kroah-Hartman
maintainerPATCH 79/480 iio: light: opt3001: fix missing state reset on timeout
In reply to Greg Kroah-Hartman6.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) ?
Greg Kroah-Hartman
maintainerPATCH 80/480 iio: light: tsl2591: return actual error from probe IRQ failure
In reply to Greg Kroah-Hartman6.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.
--- 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_clieNULL , 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;
Greg Kroah-Hartman
maintainerPATCH 81/480 iio: light: veml6030: fix channel type when pushing events
In reply to Greg Kroah-Hartman6.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).
--- 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_handleelse 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 ; }
Greg Kroah-Hartman
maintainerPATCH 82/480 iio: magnetometer: ak8975: Add missed pm_runtime_put_autosuspend() call
In reply to Greg Kroah-Hartman6.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; }
Greg Kroah-Hartman
maintainerPATCH 83/480 iio: pressure: bmp280: zero-init bmp580 trigger handler buffer
In reply to Greg Kroah-Hartman6.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").
--- 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_handleu32 comp_press;s32 comp_temp;aligned_s64 timestamp; - } buffer; + } buffer = { };int ret;guard (mutex)(&data->lock);
Greg Kroah-Hartman
maintainerPATCH 84/480 iio: pressure: mpl115: fix runtime PM leak on read error
In reply to Greg Kroah-Hartman6.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.
--- 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_decase 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 ;
Greg Kroah-Hartman
maintainerPATCH 85/480 iio: proximity: vl53l0x: notify trigger and clear IRQ on error paths
In reply to Greg Kroah-Hartman6.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.
--- 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);
Greg Kroah-Hartman
maintainerPATCH 86/480 iio: resolver: ad2s1210: notify trigger and clear state on fault read error
In reply to Greg Kroah-Hartman6.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, ®_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.
--- 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 , ®_val);if (ret <0 ) -return ret; + goto error_ret; st->sample.fault = reg_val; }
Greg Kroah-Hartman
maintainerPATCH 87/480 iio: temperature: Build mlx90635 with CONFIG_MLX90635
In reply to Greg Kroah-Hartman6.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.
--- 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
Greg Kroah-Hartman
maintainerPATCH 88/480 iio: temperature: ltc2983: Fix n_wires default bypassing rotation check
In reply to Greg Kroah-Hartman6.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.
--- 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_handstruct 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)
Greg Kroah-Hartman
maintainerPATCH 89/480 iio: temperature: ltc2983: Fix reinit_completion() called after conversion start
In reply to Greg Kroah-Hartman6.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.
--- 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.
Greg Kroah-Hartman
maintainerPATCH 90/480 iio: temperature: tmp006: use devm_iio_trigger_register
In reply to Greg Kroah-Hartman6.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.
--- 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;
Greg Kroah-Hartman
maintainerPATCH 91/480 ALSA: usx2y: us144mkii: fix work UAF on disconnect
In reply to Greg Kroah-Hartman6.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.
--- sound/usb/usx2y/us144mkii.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
sound/usb/usx2y/us144mkii.c +11 -6
@@ -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
Greg Kroah-Hartman
maintainerPATCH 92/480 ALSA: virtio: Add missing 384 kHz PCM rate mapping
In reply to Greg Kroah-Hartman6.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.
--- 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);
Greg Kroah-Hartman
maintainerPATCH 93/480 ALSA: virtio: Validate control metadata from the device
In reply to Greg Kroah-Hartman6.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 virtiostruct 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)
Greg Kroah-Hartman
maintainerPATCH 94/480 ALSA: ymfpci: check snd_ctl_new1() return value
In reply to Greg Kroah-Hartman6.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.
--- 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 )
Greg Kroah-Hartman
maintainerPATCH 95/480 ALSA: aoa: check snd_ctl_new1() return value
In reply to Greg Kroah-Hartman6.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.
--- 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(structif (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(structif (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" );
Greg Kroah-Hartman
maintainerPATCH 96/480 ALSA: caiaq: fix out-of-bounds read in the Traktor Kontrol S4 input parser
In reply to Greg Kroah-Hartman6.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.
--- 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) {
Greg Kroah-Hartman
maintainerPATCH 97/480 ALSA: cmipci: check snd_ctl_new1() return value
In reply to Greg Kroah-Hartman6.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.
--- 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 )
Greg Kroah-Hartman
maintainerPATCH 98/480 ALSA: compress: Fix task creation error unwind
In reply to Greg Kroah-Hartman6.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.
--- 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 sndfile 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 sndlist_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;
Greg Kroah-Hartman
maintainerPATCH 99/480 ALSA: es1938: check snd_ctl_new1() return value
In reply to Greg Kroah-Hartman6.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.
--- 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 es193for (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;
Greg Kroah-Hartman
maintainerPATCH 100/480 ALSA: FCP: Add Focusrite ISA C8X support
In reply to Greg Kroah-Hartman6.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(strcase 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 ;
Greg Kroah-Hartman
maintainerPATCH 101/480 ALSA: firewire: isight: bound the sample count to the packet payload
In reply to Greg Kroah-Hartman6.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)
Greg Kroah-Hartman
maintainerPATCH 102/480 ALSA: gus: check snd_ctl_new1() return value
In reply to Greg Kroah-Hartman6.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.
--- 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 )
Greg Kroah-Hartman
maintainerPATCH 103/480 ALSA: hda/cs35l41: Fix firmware load work teardown
In reply to Greg Kroah-Hartman6.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.
--- 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(strureturn 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(strucscnprintf (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 dedevice_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 *dstruct 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;
Greg Kroah-Hartman
maintainerPATCH 104/480 ALSA: hda/hdmi: Add force-connect quirk for HP EliteDesk 800 G5 Mini
In reply to Greg Kroah-Hartman6.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),
Greg Kroah-Hartman
maintainerPATCH 105/480 ALSA: hda/hdmi: Use AC_PINSENSE_ELDV to detect pinsense for Loongson
In reply to Greg Kroah-Hartman6.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; }
Greg Kroah-Hartman
maintainerPATCH 106/480 ALSA: hda/realtek: Fix noisy mic for Clevo V6xxAW
In reply to Greg Kroah-Hartman6.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_fixSND_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),
Greg Kroah-Hartman
maintainerPATCH 107/480 ALSA: ice1712: check snd_ctl_new1() return value
In reply to Greg Kroah-Hartman6.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.
--- 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 snfor (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(strif (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_controreturn 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 )
Greg Kroah-Hartman
maintainerPATCH 108/480 ALSA: seq: Fix uninitialised heap leak in snd_seq_event_dup()
In reply to Greg Kroah-Hartman6.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.
--- 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
Greg Kroah-Hartman
maintainerPATCH 109/480 ALSA: us144mkii: capture_urb_complete: redundant usb_anchor_urb corrupts anchor list on each resubmission
In reply to Greg Kroah-Hartman6.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.
--- 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 *urusb_put_urb (urb);atomic_dec ( &tascam->active_urbs);/* Decrement on failed resubmission */ +return ; } out:usb_put_urb (urb);
Greg Kroah-Hartman
maintainerPATCH 110/480 ALSA: usb-audio: avoid kobject path lookup in DualSense match
In reply to Greg Kroah-Hartman6.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.
--- 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,
Greg Kroah-Hartman
maintainerPATCH 111/480 ALSA: usb-audio: Propagate errors in scarlett_ctl_enum_put()
In reply to Greg Kroah-Hartman6.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.
--- 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 ;
Greg Kroah-Hartman
maintainerPATCH 112/480 ALSA: usb-audio: Propagate US-16x08 write errors in route/mix EQ-switch put callbacks
In reply to Greg Kroah-Hartman6.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.
--- 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 snbreak ; } -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(strumsleep (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 ureturn 0 ; } -
Greg Kroah-Hartman
maintainerPATCH 113/480 ALSA: usb-audio: Roll back quirk control caches on write errors
In reply to Greg Kroah-Hartman6.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.
--- 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(structint 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(structreturn 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(strstruct 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)
Greg Kroah-Hartman
maintainerPATCH 114/480 ALSA: usb-audio: Update Babyface Pro control caches only after successful writes
In reply to Greg Kroah-Hartman6.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 sndif (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)
Greg Kroah-Hartman
maintainerPATCH 115/480 ALSA: usb-audio: Update US-16x08 EQ/comp shadow state after successful writes
In reply to Greg Kroah-Hartman6.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.
--- 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 sint 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 ; }
Greg Kroah-Hartman
maintainerPATCH 116/480 vfio/pci: Use a private flag to prevent power state change with VFs
In reply to Greg Kroah-Hartman6.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/0x7fIntroduce 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.
--- 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 vfioint 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(structdown_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;
Greg Kroah-Hartman
maintainerPATCH 117/480 vfio/pci: Latch disable_idle_d3 per device
In reply to Greg Kroah-Hartman6.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.
--- 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_pciu16 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_dinit_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(structreturn 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(strvfio_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(sif (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;
Greg Kroah-Hartman
maintainerPATCH 118/480 vfio/pci: Release the VGA arbiter client on register_device() failure
In reply to Greg Kroah-Hartman6.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.
--- 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;
Greg Kroah-Hartman
maintainerPATCH 119/480 vfio/pci: Fix racy bitfields and tighten struct layout
In reply to Greg Kroah-Hartman6.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.
--- 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;
Greg Kroah-Hartman
maintainerPATCH 120/480 vfio: prevent infinite loop in vfio_mig_get_next_state() on blocked arc
In reply to Greg Kroah-Hartman6.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];
Greg Kroah-Hartman
maintainerPATCH 121/480 vfio: Remove device debugfs before releasing devres
In reply to Greg Kroah-Hartman6.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 vfivoid 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 vfvfio_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); }
Greg Kroah-Hartman
maintainerPATCH 122/480 Bluetooth: btusb: Add USB ID 2c4e:0128 for Mercusys MA60XNB
In reply to Greg Kroah-Hartman6.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 |
Greg Kroah-Hartman
maintainerPATCH 123/480 Bluetooth: btusb: fix use-after-free on registration failure
In reply to Greg Kroah-Hartman6.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.
--- 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_interfreturn 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);
Greg Kroah-Hartman
maintainerPATCH 124/480 Bluetooth: btusb: fix use-after-free on marvell probe failure
In reply to Greg Kroah-Hartman6.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.
--- 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_interfif (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);
Greg Kroah-Hartman
maintainerPATCH 125/480 Bluetooth: btusb: fix wakeup source leak on probe failure
In reply to Greg Kroah-Hartman6.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.
--- 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(strucreturn 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(structbt_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_interfif (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);
Greg Kroah-Hartman
maintainerPATCH 126/480 binder: fix UAF in binder_thread_release()
In reply to Greg Kroah-Hartman6.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.
--- 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(strustatic 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);
Greg Kroah-Hartman
maintainerPATCH 127/480 binder: fix UAF in binder_free_transaction()
In reply to Greg Kroah-Hartman6.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(strustatic 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);/*
Greg Kroah-Hartman
maintainerPATCH 128/480 rust_binder: use a u64 stride when cleaning up the offsets array
In reply to Greg Kroah-Hartman6.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 iin offsets.step_by (size_of ::<usize >()) { +for iin 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 => {
Greg Kroah-Hartman
maintainerPATCH 129/480 rust_binder: reject context manager self-transaction
In reply to Greg Kroah-Hartman6.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 )?) }
Greg Kroah-Hartman
maintainerPATCH 130/480 rust_binder: synchronize Rust Binder stats with freeze commands
In reply to Greg Kroah-Hartman6.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 ();
Greg Kroah-Hartman
maintainerPATCH 131/480 rust_binder: clear freeze listener on node removal
In reply to Greg Kroah-Hartman6.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: &'aProcessInner ) -> &'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 listenerin freeze_listeners.values () { - listener.on_process_exit (&self); + listener.on_process_cleanup (&self); }drop (freeze_listeners);
Greg Kroah-Hartman
maintainerPATCH 132/480 usb: xhci: Fix sleep in atomic context in xhci_free_streams()
In reply to Greg Kroah-Hartman6.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.
--- 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 ; }
Greg Kroah-Hartman
maintainerPATCH 133/480 xhci: sideband: fix ring sg table pages leak
In reply to Greg Kroah-Hartman6.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.
--- 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_sidebanif (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.
Greg Kroah-Hartman
maintainerPATCH 134/480 usb: typec: tcpci_rt1711h: unregister TCPCI port with devres
In reply to Greg Kroah-Hartman6.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.
--- 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(structreturn 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_clieif (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_cliereturn 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);
Greg Kroah-Hartman
maintainerPATCH 135/480 PCI: loongson: Override PCIe bridge supported speeds for Loongson-3C6000 series
In reply to Greg Kroah-Hartman6.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].
--- 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;