6.18.42-rc1 review
Subsystems (2)
Greg Kroah-Hartman
maintainercover 6.18.42-rc1 review
This is the start of the stable review cycle for the 6.18.42 release. There are 675 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, 01 Aug 2026 14:13:45 +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.42-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.42-rc1
Nikunj A Dadhania <[email protected]>
KVM: SVM: Bump asid_generation on CPU online to avoid ASID collision after hotplug
Koen Koning <[email protected]>
gpu: Fix uninitialized buddy for built-in drivers
Russell King (Oracle) <[email protected]>
net: stmmac: fix dwmac4 transmit performance regression
Gal Pressman <[email protected]>
net/mlx5e: Fix NULL pointer dereference in ioctl module EEPROM query
Cen Zhang <[email protected]>
usb: gadget: f_tcm: synchronize delayed set_alt with teardown
Alice Ryhl <[email protected]>
rust: device: avoid trailing ; in printing macros
Miguel Ojeda <[email protected]>
rust: allow suspicious_runtime_symbol_definitions lint for Rust >= 1.98
SJ Park <[email protected]>
mm/damon/core: disallow overlapping input ranges for damon_set_regions()
SJ Park <[email protected]>
mm/damon/core: validate ranges in damon_set_regions()
Adrian Hunter <[email protected]>
i3c: mipi-i3c-hci: Fix handling of shared IRQs during early initialization
Adrian Hunter <[email protected]>
i3c: mipi-i3c-hci: Fix Hot-Join NACK
Guoniu Zhou <[email protected]>
pmdomain: imx93-blk-ctrl: Extract PHY as shared domain for DSI/CSI
Marco Felsch <[email protected]>
pmdomain: imx93-blk-ctrl: convert to devm_* only
Haoxiang Li <[email protected]>
net: ipa: fix SMEM state handle leaks in SMP2P init
Bryam Vargas <[email protected]>
ata: libata-core: Reject an invalid concurrent positioning ranges count
Breno Leitao <[email protected]>
bootconfig: fix NULL-pointer arithmetic in xbc_snprint_cmdline()
Breno Leitao <[email protected]>
bootconfig: move xbc_snprint_cmdline() to lib/bootconfig.c
Junrui Luo <[email protected]>
octeontx2-af: cn10k: restrict VF LMTLINE sharing to its own PF
Michael Bommarito <[email protected]>
octeontx2-af: validate body pcifunc in rvu_mbox_handler_rep_event_notify
Shradha Gupta <[email protected]>
net: mana: Optimize irq affinity for low vcpu configs
Dexuan Cui <[email protected]>
net: mana: Validate the packet length reported by the NIC
Tony Luck <[email protected]>
fs/resctrl: Fix use-after-free during unmount
Tony Luck <[email protected]>
fs/resctrl: Move RMID initialization to first mount
Tony Luck <[email protected]>
fs/resctrl: Move allocation/free of closid_num_dirty_rmid[]
Tony Luck <[email protected]>
x86,fs/resctrl: Rename some L3 specific functions
Tony Luck <[email protected]>
x86,fs/resctrl: Rename struct rdt_mon_domain and rdt_hw_mon_domain
Tony Luck <[email protected]>
fs/resctrl: Split L3 dependent parts out of __mon_event_count()
Guangshuo Li <[email protected]>
mmc: vub300: fix use-after-free on probe failure
Johan Hovold <[email protected]>
mmc: vub300: rename probe error labels
Ingo Blechschmidt <[email protected]>
dm: avoid leaking the caller's thread keyring via the table device file
Christian Brauner <[email protected]>
cred: add kernel_cred() helper
Doruk Tan Ozturk <[email protected]>
accel/amdxdna: reject command submission on devices without a submit op
Souvik Banerjee <[email protected]>
ovl: use linked upper dentry in copy-up tmpfile
Koichiro Den <[email protected]>
dmaengine: dw-edma-pcie: Reject devices without driver data
Krzysztof Kozlowski <[email protected]>
dmaengine: dw-edma: Fix confusing cleanup.h syntax
Michael Bommarito <[email protected]>
thunderbolt: Prevent XDomain delayed work use-after-free on disconnect
Mika Westerberg <[email protected]>
thunderbolt: Remove XDomain from the bus without holding tb->lock
Mika Westerberg <[email protected]>
thunderbolt: Remove service debugfs entries during unregister
Mika Westerberg <[email protected]>
thunderbolt: Keep XDomain reference during the lifetime of a service
Florian Fuchs <[email protected]>
mtd: maps: vmu-flash: fix fault in unaligned fixup
Pratyush Yadav (Google) <[email protected]>
kho: make sure scratch size is always aligned by CMA_MIN_ALIGNMENT_BYTES
Muchun Song <[email protected]>
mm/sparse-vmemmap: fix vmemmap accounting underflow
Tanmay Shah <[email protected]>
remoteproc: xlnx: Check remote core state
Terry Bowman <[email protected]>
cxl: Fix CXL_HEADERLOG_SIZE to match RAS Capability size
Dave Jiang <[email protected]>
cxl/pci: Remove CXL VH handling in CONFIG_PCIEAER_CXL conditional blocks from core/pci.c
Terry Bowman <[email protected]>
cxl/pci: Remove unnecessary CXL RCH handling helper functions
Terry Bowman <[email protected]>
cxl/pci: Remove unnecessary CXL Endpoint handling helper functions
Chuck Lever <[email protected]>
SUNRPC: Return an error from xdr_buf_to_bvec() on overflow
Chuck Lever <[email protected]>
SUNRPC: Add helpers to convert xdr_buf byte ranges to scatterlists
Jeff Layton <[email protected]>
sunrpc: allocate a separate bvec array for socket sends
Mike Snitzer <[email protected]>
NFSD: pass nfsd_file to nfsd_iter_read()
Claudiu Beznea <[email protected]>
pinctrl: renesas: rzg2l: Use -ENOTSUPP instead of -EOPNOTSUPP
Arunpravin Paneer Selvam <[email protected]>
gpu/buddy: bail out of try_harder when alignment cannot be honoured
Joel Fernandes <[email protected]>
gpu: Move DRM buddy allocator one level up (part two)
Pablo Neira Ayuso <[email protected]>
netfilter: nf_conntrack_sip: validate skb_dst() before accessing it
Florian Westphal <[email protected]>
netfilter: nf_conntrack_sip: remove net variable shadowing
Theodor Arsenij Larionov-Trichkine <[email protected]>
netfilter: nft_fib: reject fib expression on the netdev egress hook
Florian Westphal <[email protected]>
netfilter: nf_tables: remove register tracking infrastructure
Abel Vesa <[email protected]>
arm64: dts: qcom: hamoa: Fix OPP tables for all DisplayPort controllers
Dmitry Baryshkov <[email protected]>
arm64: dts: qcom: correct RBR opp entry
Jason Wang <[email protected]>
VDUSE: avoid leaking information to userspace
Eugenio Pérez <[email protected]>
vduse: take out allocations from vduse_dev_alloc_coherent
Eugenio Pérez <[email protected]>
vduse: remove unused vaddr parameter of vduse_domain_free_coherent
Eugenio Pérez <[email protected]>
vduse: return internal vq group struct as map token
Darrick J. Wong <[email protected]>
xfs: don't replace the wrong part of the cow fork
Joanne Koong <[email protected]>
fuse-uring: fix race between registration and connection abortion
Ricardo Robaina <[email protected]>
audit: fix recursive locking deadlock in audit_dupe_exe()
Ricardo Robaina <[email protected]>
audit: use 'unsigned int' instead of 'unsigned'
Jeff Layton <[email protected]>
audit: widen ino fields to u64
Mickaël Salaün <[email protected]>
landlock: Account all audit data allocations to user space
Mickaël Salaün <[email protected]>
landlock: Fix formatting
Harry Wentland <[email protected]>
drm/amd/display: Fix DTB DTO updates breaking live pixel rate sources
Eric Biggers <[email protected]>
fscrypt: Avoid dynamic allocation in fscrypt_get_devices()
Namjae Jeon <[email protected]>
ksmbd: validate ACE size against SID sub-authorities
Namjae Jeon <[email protected]>
ksmbd: bound DACL dedup walk to copied ACEs
Wentao Guan <[email protected]>
ksmbd: restore DACL size on check_add_overflow() to avoid malformed ACL
Haofeng Li <[email protected]>
ksmbd: validate num_subauth when copying ACE in set_ntacl_dacl
Youssef Samir <[email protected]>
net: qrtr: ns: Raise node count limit to 512
Ming Lei <[email protected]>
ublk: wait on ublk_dev_ready() instead of ub->completion
Jia Yao <[email protected]>
drm/xe/uapi: Reject coh_none PAT index for CPU_ADDR_MIRROR
Mikulas Patocka <[email protected]>
dm-verity: fix buffer overflow in FEC calculation
Eric Biggers <[email protected]>
dm-verity-fec: replace {MAX,MIN}_RSN with {MIN,MAX}_ROOTS
Eric Biggers <[email protected]>
dm-verity-fec: fix reading parity bytes split across blocks (take 3)
Eric Biggers <[email protected]>
dm-verity-fec: fix the size of dm_verity_fec_io::erasures
Jiayuan Chen <[email protected]>
bpf: Fix same-register dst/src OOB read and pointer leak in sock_ops
Christian König <[email protected]>
drm/amdgpu: fix check in amdgpu_hmm_invalidate_gfx
Yang Wang <[email protected]>
drm/amd/pm: fix smu13 power limit range calculation
Asad Kamal <[email protected]>
drm/amdgpu: fix aperture mapping leak
Ce Sun <[email protected]>
drm/amdgpu: invoke pm_genpd_remove() before freeing genpd
Ce Sun <[email protected]>
drm/amdgpu: fix resource leak on ACP reset timeout
Boyuan Zhang <[email protected]>
drm/amdgpu: fix division by zero with invalid uvd dimensions
Luca Coelho <[email protected]>
drm/dp_mst: Handle torn-down topology gracefully in drm_dp_mst_topology_queue_probe()
Boyuan Zhang <[email protected]>
drm/amdgpu/vcn4: avoid rereading IB param length
Boyuan Zhang <[email protected]>
drm/amdgpu/vce: fix integer overflow in image size
Jakob Linke <[email protected]>
drm/amdgpu/soc24: reset dGPU if suspend got aborted
Alex Deucher <[email protected]>
drm/amdgpu/sdma4.4.2: replace BUG_ON() with WARN_ON()
Boyuan Zhang <[email protected]>
drm/amdgpu/jpeg: fix jpeg_v5_0_1_is_idle detection
Boyuan Zhang <[email protected]>
drm/amdgpu/jpeg: fix jpeg_v4_0_3_is_idle detection
Alex Deucher <[email protected]>
drm/amdgpu/gfx9: replace BUG_ON() with WARN_ON()
Alex Deucher <[email protected]>
drm/amdgpu/gfx9.4.3: replace BUG_ON() with WARN_ON()
Alex Deucher <[email protected]>
drm/amdgpu/gfx8: drop unecessary BUG_ON()
Alex Deucher <[email protected]>
drm/amdgpu/gfx12: replace BUG_ON() with WARN_ON()
Alex Deucher <[email protected]>
drm/amdgpu/gfx11: replace BUG_ON() with WARN_ON()
Alex Deucher <[email protected]>
drm/amdgpu/gfx10: replace BUG_ON() with WARN_ON()
Yang Wang <[email protected]>
drm/amd/pm: make pp_features read-only when scpm is enabled
Yang Wang <[email protected]>
drm/amd/pm: fix amdgpu_pm_info power display units
Ethan Nelson-Moore <[email protected]>
watchdog: s32g_wdt: remove incorrect options in watchdog_info struct
James Raphael Tiovalen <[email protected]>
vxlan: mdb: Fix source list corruption on a failed replace
Stefano Garzarella <[email protected]>
vsock/virtio: collapse receive queue under memory pressure
Daehyeon Ko <[email protected]>
tipc: clear sock->sk on the failed-insert path in tipc_sk_create()
Yuxiang Yang <[email protected]>
tcp: challenge ACK for non-exact RST in SYN-RECEIVED
Yizhou Zhao <[email protected]>
tcp: initialize standalone TCP-AO response padding
Justin Lai <[email protected]>
rtase: Workaround for TX hang caused by hardware packet parsing
Asim Viladi Oglu Manizada <[email protected]>
pppoe: reload header pointer after dev_hard_header()
Shuvam Pandey <[email protected]>
ovpn: hold peer before scheduling keepalive work
Pavitra Jha <[email protected]>
ovpn: fix peer refcount leak in TCP error paths
Kyle Zeng <[email protected]>
openvswitch: fix GSO userspace truncation underflow
Doruk Tan Ozturk <[email protected]>
mctp: serial: handle zero-length frames to prevent rx buffer overflow
Doruk Tan Ozturk <[email protected]>
mac802154: llsec: reject frames shorter than the authentication tag
Ibrahim Hashimov <[email protected]>
mac802154: hold an interface reference across the scan worker
Michael Bommarito <[email protected]>
ila: reload IPv6 header after pskb_may_pull in checksum adjust
Sergey Temerkhanov <[email protected]>
ice: use READ_ONCE() to access cached PHC time
Aleksandr Loktionov <[email protected]>
ice: reject out-of-range ptype in ice_parser_profile_init
Eddie Phillips <[email protected]>
gve: fix Rx queue stall on alloc failure
James Montgomery <[email protected]>
ksmbd: defer destroy_previous_session() until after NTLM authentication
Carl Johnson <[email protected]>
smb: client: handle STATUS_STOPPED_ON_SYMLINK responses without a symlink target
Raphael Zimmer <[email protected]>
rbd: Reset positive result codes to zero in object map update path
Christian Brauner <[email protected]>
super: fix emergency thaw deadlock on frozen block devices
Masami Hiramatsu (Google) <[email protected]>
selftests/ftrace: Reset triggers at top level before instance loop
Paul Greenwalt <[email protected]>
ice: fix PTP Call Trace during PTP release
Sven Schnelle <[email protected]>
ptp: ptp_s390: Add missing facility check
Jann Horn <[email protected]>
proc: Fix broken error paths for namespace links
Coia Prant <[email protected]>
net: pcs: xpcs: fix SGMII state reading
Fan Wu <[email protected]>
net: hip04: fix RX buffer leak on build_skb failure
Shiming Cheng <[email protected]>
net: gro: fix double aggregation of flush-marked skbs
David Lee <[email protected]>
net/x25: fix use-after-free in x25_kill_by_neigh()
Manjunath Patil <[email protected]>
net/mlx5e: Use sender devcom for MPV master-up
Bryam Vargas <[email protected]>
net/iucv: fix use-after-free of a severed iucv_path
Hidayath Khan <[email protected]>
net/af_iucv: fix NULL deref in afiucv_hs_callback_syn()
Doruk Tan Ozturk <[email protected]>
geneve: require CAP_NET_ADMIN in the device netns for changelink
Sungmin Kang <[email protected]>
net: slip: serialize receive against buffer reallocation
Doruk Tan Ozturk <[email protected]>
vxlan: require CAP_NET_ADMIN in the device netns for changelink
Breno Leitao <[email protected]>
phonet: pep: fix use-after-free in pep_get_sb()
Markus Breitenberger <[email protected]>
net: stmmac: intel: skip SerDes reconfig when rate is unchanged
Lu Baolu <[email protected]>
iommu/vt-d: Disallow SVA if page walk is not coherent
Zhang Yi <[email protected]>
iomap: fix out-of-bounds bitmap_set() with zero-length range
Yitang Yang <[email protected]>
io_uring/rw: fix missing ERESTARTSYS conversion in read paths
Tengda Wu <[email protected]>
ftrace: Add global mutex to serialize trace_parser access
Eric Biggers <[email protected]>
fscrypt: Add missing superblock check in find_or_insert_direct_key()
Amir Goldstein <[email protected]>
fs: preserve ACL_DONT_CACHE state in forget_cached_acl()
Chen Changcheng <[email protected]>
fs/super: fix emergency thaw double-unlock of s_umount
Christian Brauner <[email protected]>
binfmt_elf_fdpic: only honour the first PT_INTERP
Chancel Liu <[email protected]>
ASoC: fsl_sai: Fix spurious BCLK on resume by clearing BYP
Chancel Liu <[email protected]>
ASoC: fsl: imx-card: Skip sysclk reset for active DAIs in shutdown
Shihuang Liu <[email protected]>
amt: fix use-after-free in AMT delayed works
Douya Le <[email protected]>
libceph: remove debugfs files before client teardown
Douya Le <[email protected]>
libceph: reject zero bucket types in crush_decode
Raphael Zimmer <[email protected]>
libceph: Reject monmaps advertising zero monitors
Shuangpeng Bai <[email protected]>
libceph: refresh auth->authorizer_buf{,_len} after authorizer updateZhao Zhang <[email protected]>
libceph: guard missing CRUSH type name lookup
Raphael Zimmer <[email protected]>
libceph: Fix multiplication overflow in decode_new_up_state_weight()
Douya Le <[email protected]>
libceph: bound get_version reply decode to front len
Wentao Liang <[email protected]>
ceph: fix writeback_count leak in write_folio_nounlock()
WenTao Liang <[email protected]>
ceph: fix refcount leak in ceph_readdir()
Bryam Vargas <[email protected]>
ceph: fix pre-auth out-of-bounds read on snaptrace in ceph_handle_caps()
Max Kellermann <[email protected]>
ceph: add owner/capability checks for CEPH_IOC_SET_LAYOUT*
Zhiling Zou <[email protected]>
sctp: close UDP tunnel sockets during netns teardown
Zhiling Zou <[email protected]>
sctp: avoid auth_enable sysctl UAF during netns teardown
Jun Yang <[email protected]>
sctp: don't free the ASCONF's own transport in DEL-IP processing
Rik van Riel <[email protected]>
mm/huge_memory: set PG_has_hwpoisoned only after new folio head is established
Breno Leitao <[email protected]>
mm/kmemleak: fix checksum computation for per-cpu objects
David Howells <[email protected]>
afs: Fix afs_edit_dir_remove() to get, not find, block 0
Geliang Tang <[email protected]>
mptcp: pm: userspace: fix use-after-free in get_local_id
Michael Bommarito <[email protected]>
mptcp: only set DATA_FIN when a mapping is present
Chenguang Zhao <[email protected]>
mptcp: decrement subflows counter on failed passive join
Will Deacon <[email protected]>
Revert "arm64: syscall: Ensure saved x0 is kept in-sync with tracer updates"
Will Deacon <[email protected]>
arm64: syscall: Ensure saved x0 is kept in-sync with tracer updates
Dev Jain <[email protected]>
arm64: make huge_ptep_get handled unaligned addresses
Masami Hiramatsu (Google) <[email protected]>
tracing/probes: Prevent out-of-bounds write in __trace_probe_log_err()
Masami Hiramatsu (Google) <[email protected]>
tracing/probes: Fix potential underflow in LEN_OR_ZERO macro
Masami Hiramatsu (Google) <[email protected]>
tracing/probes: Avoid temporary buffer truncation in trace_probe_match_command_args()
Masami Hiramatsu (Google) <[email protected]>
tracing/eprobe: Fix exact system name matching in eprobe_dyn_event_match()
Masami Hiramatsu (Google) <[email protected]>
tracing: Fix union collision of module and refcnt for dynamic events
deepakraog <[email protected]>
tracing: Fix resource leak on mmiotrace trace_pipe close
Steven Rostedt <[email protected]>
tracing: Fix mmiotrace possible NULL dereferencing of hiter->dev
Usama Arif <[email protected]>
tracing: Fix context switch counter truncation
Xu Rao <[email protected]>
misc: nsm: pin the module while the device is open
Runyu Xiao <[email protected]>
misc: nsm: only unlock nsm_dev on post-lock error paths
Guangshuo Li <[email protected]>
intel_th: fix MSC output device reference leak
Alexander Usyskin <[email protected]>
mei: bus: access mei_device under device_lock on cleanup
Ethan Nelson-Moore <[email protected]>
selftests: ntsync: correct CONFIG_NTSYNC name
Jiangshan Yi <[email protected]>
serial: 8250_mid: Fix NULL function pointer dereference on DNV/ICX-D/SNR platforms
Hugo Villeneuve <[email protected]>
serial: sc16is7xx: implement gpio get_direction() callback
Ben Hutchings <[email protected]>
uio_hv_generic: Bind to FCopy device by default
Ian Abbott <[email protected]>
comedi: comedi_parport: deal with premature interrupt
Nathan Chancellor <[email protected]>
x86/boot/compressed: Disable jump tables
Tze Yee Ng <[email protected]>
firmware: stratix10-svc: fix memory leaks and list corruption bugs
Cen Zhang (Microsoft) <[email protected]>
rhashtable: clear stale iter->p on table restart
Xu Rao <[email protected]>
cdrom: fix stack out-of-bounds read in CDROMVOLCTRL
Rong Bao <[email protected]>
LoongArch: Retrieve CPU package ID from PPTT when available
Kanglong Wang <[email protected]>
LoongArch: Move jump_label_init() before parse_early_param()
Haoran Jiang <[email protected]>
LoongArch: Fix oops during single-step debugging
George Guo <[email protected]>
LoongArch: Fix address space mismatch in kexec command line lookup
Miguel Ojeda <[email protected]>
objtool/rust: add one more noreturn Rust function for Rust 1.99.0
Alexandre Courbot <[email protected]>
rust: allow clippy::unwrap_or_default globally
FUJITA Tomonori <[email protected]>
rust: time: fix as_micros_ceil() to round correctly for negative Delta
Alice Ryhl <[email protected]>
rust_binder: only print failure if error has source
Zixing Liu <[email protected]>
platform/loongarch: laptop: Explicitly reset bl_powered state when suspend
Christian Brauner <[email protected]>
binfmt_misc: set have_execfd only once the interpreter is opened
Christian Brauner <[email protected]>
exec: fix unsigned loop counter wrap in transfer_args_to_stack()
Chengfeng Ye <[email protected]>
Bluetooth: RFCOMM: Fix session UAF in set_termios
Chengfeng Ye <[email protected]>
Bluetooth: hci_sync: Protect UUID list traversal
MinJea Kim <[email protected]>
staging: rtl8723bs: fix inverted HT40 secondary channel offset
Moksh Panicker <[email protected]>
staging: rtl8723bs: fix OOB reads in rtw_get_wps_ie()
Wentao Liang <[email protected]>
wifi: ath11k: fix refcount leak in ath11k_ahb_fw_resources_init()
LiangCheng Wang <[email protected]>
wifi: brcmfmac: set F2 blocksize to 256 for BCM43752
Fan Wu <[email protected]>
wifi: brcmfmac: make release_scratchbuffers idempotent
Devin Wittmayer <[email protected]>
wifi: mt76: mt7925: drop TXRX_NOTIFY on non-mmio buses
Devin Wittmayer <[email protected]>
wifi: mt76: mt7921: drop TXRX_NOTIFY on non-mmio buses
Devin Wittmayer <[email protected]>
wifi: mt76: mt7615: drop TXRX_NOTIFY on non-mmio buses
Huihui Huang <[email protected]>
wifi: wilc1000: validate assoc response length before subtracting header
Doruk Tan Ozturk <[email protected]>
wifi: mwifiex: fix NULL dereference when the AP has HT-cap but no HT-oper
Daniel Hodges <[email protected]>
wifi: ath6kl: fix use-after-free in aggr_reset_state()
Tristan Madani <[email protected]>
wifi: ath6kl: fix OOB access from firmware ADDBA window size
Norbert Szetei <[email protected]>
ALSA: timer: don't re-enter an instance callback that is still running
Norbert Szetei <[email protected]>
ALSA: timer: drain a slave's callback before its master detaches it
Kai Vehmanen <[email protected]>
ALSA: hda: codecs: hdmi: disable keep-alive before audio format change
Norbert Szetei <[email protected]>
ALSA: seq: close a re-opened queue timer in the destructor
Nikita Maksimov <[email protected]>
ALSA: hda/realtek: Fix speakers on Lunnen Ground 14
Johan Hovold <[email protected]>
media: vpif_capture: fix OF node reference imbalance
Guangshuo Li <[email protected]>
media: vivid: fix cleanup bugs in vivid_init()
Hans Verkuil <[email protected]>
media: vivid: check for vb2_is_busy() when toggling caps
Hans Verkuil <[email protected]>
media: vivid: add vivid_update_reduced_fps()
Guangshuo Li <[email protected]>
media: vimc: fix reference leak on failed device registration
Guangshuo Li <[email protected]>
media: vidtv: fix reference leak on failed device registration
Benjamin Gaignard <[email protected]>
media: verisilicon: Export only needed pixels formats
Zile Xiong <[email protected]>
media: vb2: use ssize_t for vb2_read/vb2_write
Sakari Ailus <[email protected]>
media: v4l2-subdev: Fail {enable,disable}_streams and s_streaming nicely
Mirela Rabulea <[email protected]>
media: v4l2-fwnode: Fix subdev owner overwritten in v4l2_async_register_subdev_sensor()
Pengpeng Hou <[email protected]>
media: v4l2-ctrls: validate HEVC active reference counts
Sergey Shtylyov <[email protected]>
media: v4l2-ctrls-request: add NULL check in v4l2_ctrl_request_complete()
Myeonghun Pak <[email protected]>
media: ti: vpe: unwind v4l2 device registration on probe error
Hungyu Lin <[email protected]>
media: tegra-video: vi: fix invalid u32 return value in format lookup
Dmitry Osipenko <[email protected]>
media: synopsys: hdmirx: Fix HPD lane hold time
Valery Borovsky <[email protected]>
media: sun4i-csi: Return queued buffers on start_streaming() failure
Myeonghun Pak <[email protected]>
media: stm32: dcmi: unregister notifier on probe failure
Valery Borovsky <[email protected]>
media: stm32-dcmipp: Return queued buffers on start_streaming() failure
Ma Ke <[email protected]>
media: saa7134: Fix a possible memory leak in saa7134_video_init1
Tommaso Merciai <[email protected]>
media: rzg2l-cru: Skip ICnMC configuration when ICnSVC is used
Valery Borovsky <[email protected]>
media: rtl2832_sdr: Return queued buffers on start_streaming() failure
Deepanshu Kartikey <[email protected]>
media: rtl2832: fix use-after-free in rtl2832_remove()
Myeonghun Pak <[email protected]>
media: radio-si476x: Unregister v4l2_device on probe failure
Bryan O'Donoghue <[email protected]>
media: qcom: camss: Fix RDI streaming for CSID GEN3
Bryan O'Donoghue <[email protected]>
media: qcom: camss: Fix RDI streaming for CSID GEN2
Bryan O'Donoghue <[email protected]>
media: qcom: camss: Fix RDI streaming for CSID 680
Valery Borovsky <[email protected]>
media: pwc: Return queued buffers on start_streaming() failure
Valery Borovsky <[email protected]>
media: pwc: Drain fill_buf on start_streaming() failure
Krzysztof Kozlowski <[email protected]>
media: pci: dm1105: Free allocated workqueue
Guoniu Zhou <[email protected]>
media: nxp: imx8-isi: Fix scale factor calculation for hardware rounding
Guoniu Zhou <[email protected]>
media: nxp: imx8-isi: Fix potential out-of-bounds issues
Xiaolei Wang <[email protected]>
media: nxp: imx8-isi: Fix missing v4l2_subdev_cleanup() in pipe init error path
Xiaolei Wang <[email protected]>
media: nxp: imx8-isi: Clean up already-initialized pipes on probe failure
Xiaolei Wang <[email protected]>
media: nxp: imx8-isi: Add missing v4l2_subdev_cleanup() in crossbar and pipe
David Carlier <[email protected]>
media: nuvoton: npcm-video: fix memory leaks in probe and remove
David Carlier <[email protected]>
media: nuvoton: npcm-video: fix error handling in npcm_video_init()
Valery Borovsky <[email protected]>
media: msi2500: Return queued buffers on start_streaming() failure
Anand Moon <[email protected]>
media: meson: vdec: Fix memory leak in error path of vdec_open
Guangshuo Li <[email protected]>
media: marvell-cam: fix missing pci_disable_device() on remove
Dmitry Baryshkov <[email protected]>
media: iris: Fix use IRQF_NO_AUTOEN when requesting the IRQ
Marco Nenciarini <[email protected]>
media: intel/ipu6: Improve DWC PHY HSFREQRANGE band selection for overlapping ranges
Sakari Ailus <[email protected]>
media: imx219: Fix maximum frame length in lines
Martin Hecht <[email protected]>
media: i2c: alvium: fix critical pointer access in alvium_ctrl_init
Wang Jun <[email protected]>
media: cx23885: add ioremap return check and cleanup
Johan Hovold <[email protected]>
media: cx231xx: fix devres lifetime
Brandon Brnich <[email protected]>
media: chips-media: wave5: Move src_buf Removal to finish_encode
Pengpeng Hou <[email protected]>
media: cedrus: skip invalid H.264 reference list entries
Samuel Holland <[email protected]>
media: cedrus: Fix missing cleanup in error path
Myeonghun Pak <[email protected]>
media: cedrus: clean up media device on probe failure
Myeonghun Pak <[email protected]>
media: cec: seco: unregister adapter on IR probe failure
David Carlier <[email protected]>
media: aspeed: fix missing of_reserved_mem_device_release() on probe failure
Ricardo Ribalda <[email protected]>
media: amlogic-c3: Add validations for ae and awb config
Valery Borovsky <[email protected]>
media: airspy: Return queued buffers on start_streaming() failure
Maíra Canal <[email protected]>
drm/v3d: Reach the GMP through the hub registers on V3D 7.x
Matthew Brost <[email protected]>
drm/gpusvm: Fix MM reference leak in drm_gpusvm_range_evict
Linmao Li <[email protected]>
drm/vc4: Prevent shader BO mappings from becoming writable
Ian Forbes <[email protected]>
drm/vmwgfx: Validate vmw_surface_metadata::array_size
Leo Li <[email protected]>
drm/amd/display: Fix missing DCE check in dm_gpureset_toggle_interrupts()
Linmao Li <[email protected]>
drm/vc4: Shut down BO cache timer before teardown
Leo Li <[email protected]>
drm/amd/display: Fix flip-done timeouts on mode1 reset
Zhu Lingshan <[email protected]>
drm/amdgpu: fix bo->pin leaking in amdgpu_bo_create_reserved
Mario Limonciello <[email protected]>
drm/amdgpu: Disable PCIe dynamic speed switching on Ryzen Pinnacle Ridge
Mario Limonciello <[email protected]>
drm/amd/display: Fix backlight max_brightness to match exported range
Alessandro Rinaldi <[email protected]>
drm/amd/display: Force PWM backlight on Lenovo Legion 5 15ARH05
Andriy Korud <[email protected]>
drm/amd/display: dce100: skip non-DP stream encoders for DP MST
Leo Li <[email protected]>
drm/amd/display: consolidate DCN vblank/flip handling onto vupdate_no_lock
WenTao Liang <[email protected]>
drm/amd/display: set new_stream to NULL after release
Timur Kristóf <[email protected]>
drm/amd/pm/ci: Don't disable MCLK DPM on Bonaire 0x6658 (R7 260X)
Mario Limonciello <[email protected]>
drm/amdgpu: Fix VFCT bus number matching with soft filter
Mario Limonciello <[email protected]>
drm/amdgpu: Release VFCT ACPI table reference
Osama Abdelkader <[email protected]>
drm/panthor: return error on truncated firmware
Matthew Brost <[email protected]>
drm/ttm: Account for NULL and handle pages in ttm_pool_backup
Jason Macnak <[email protected]>
drm/virtio: Don't detach GEM from a non-created context
Alex Deucher <[email protected]>
drm/gfx10: Program DB_RING_CONTROL
Yang Wang <[email protected]>
drm/amd/pm: fix smu14 power limit range calculation
Jani Nikula <[email protected]>
drm/i915/mst: limit DP MST ESI service loop
Joonas Lahtinen <[email protected]>
drm/i915/gem: Fix NULL deref in I915_CONTEXT_PARAM_SSEU
Joonas Lahtinen <[email protected]>
drm/i915/gem: Do not leak siblings[] on proto context error
Shahyan Soltani <[email protected]>
drm/amdgpu: fix lifetime issue of amdgpu_vm_get_task_info_pasid()
Kenneth Feng <[email protected]>
drm/amd/amdgpu: disable ASPM on VI if pcie dpm is disabled
Jani Nikula <[email protected]>
drm/i915/bios: range check LFP Data Block panel_type2
Joonas Lahtinen <[email protected]>
drm/i915: Return NULL on error in active_instance
Alex Deucher <[email protected]>
drm/amdgpu/sdma5.0: replace BUG_ON() with WARN_ON()
Alex Deucher <[email protected]>
drm/amdgpu/sdma5.2: replace BUG_ON() with WARN_ON()
Alex Deucher <[email protected]>
drm/amdgpu/sdma6.0: replace BUG_ON() with WARN_ON()
Alex Deucher <[email protected]>
drm/amdgpu/sdma7.0: replace BUG_ON() with WARN_ON()
Jani Nikula <[email protected]>
drm/i915/hdcp: check streams[] bounds before overflow
Jani Nikula <[email protected]>
drm/i915/hdcp: require monotonically increasing seq_num_v
Bryam Vargas <[email protected]>
drm/virtio: bound EDID block reads to the response buffer
WenTao Liang <[email protected]>
drm/amd/display: detect_link_and_local_sink: DP alt mode timeout path leaks prev_sink reference
Thomas Zimmermann <[email protected]>
drm/amd/display: Handle struct drm_plane_state.ignore_damage_clips
Yongqiang Sun <[email protected]>
drm/amdkfd: fix 32-bit overflow in CWSR total size calculation
David Francis <[email protected]>
drm/amdkfd: Check bounds on CRIU restore queue type and mqd size
David Francis <[email protected]>
drm/amdkfd: Check bounds in allocate_event_notification_slot
David Francis <[email protected]>
drm/amdkfd: Use kvcalloc to allocate arrays
Icenowy Zheng <[email protected]>
drm/imagination: acquire vm_ctx->lock before mapping memory to GPU VM
Luigi Santivetti <[email protected]>
drm/imagination: fix error checking of pvr_vm_context_lookup()
Shuvam Pandey <[email protected]>
drm/imagination: Fix user array stride in pvr_set_uobj_array()
Brajesh Gupta <[email protected]>
drm/imagination: Fix double call to drm_sched_entity_fini()
Nitin Gote <[email protected]>
drm/xe: Hold a dma-buf reference for imported BOs
Matthew Brost <[email protected]>
drm/xe: Fix PTE index in xe_vm_populate_pgtable() for chunked binds
Matthew Brost <[email protected]>
drm/xe: Return error on non-migratable faults requiring devmem
Pavel Ondračka <[email protected]>
drm/radeon: fix r100_copy_blit for large BOs
Wentao Liang <[email protected]>
drm/nouveau/acr: fix missing nvkm_done() in error path of nvkm_acr_oneinit()
Joonas Lahtinen <[email protected]>
drm/i915/gem: Add missing nospec on parallel submit slot
Jani Nikula <[email protected]>
drm/displayid: fix Tiled Display Topology ID size
Thomas Zimmermann <[email protected]>
drm/sysfb: Return errno code from drm_sysfb_get_visible_size()
Thomas Zimmermann <[email protected]>
drm/sysfb: Avoid possible truncation with calculating visible size
Junrui Luo <[email protected]>
drm/nouveau: fix reversed error cleanup order in ucopy functions
Mario Limonciello <[email protected]>
drm/amdgpu: validate CP_GFX_SHADOW chunk size in CS pass1
Timur Kristóf <[email protected]>
drm/amdgpu: Fix amdgpu_bo_move() when old_mem and new_mem are both GTT
Jiqian Chen <[email protected]>
drm/amdgpu/gfx9: Fix Ring and IB test fail after mode2
Thomas Zimmermann <[email protected]>
drm/sysfb: Avoid truncating maximum stride
Thomas Zimmermann <[email protected]>
drm/sysfb: Do not page-align visible size of the framebuffer
Mario Limonciello <[email protected]>
drm/amdgpu: check amdgpu_vm_bo_find() result in GET_MAPPING_INFO
Timur Kristóf <[email protected]>
drm/amdgpu/uvd: Place VCPU BO only in VRAM for UVD 4.x and older
Timur Kristóf <[email protected]>
drm/amdgpu/uvd: Fix forcing MSG, FB BOs into VCPU segment when it isn't at 0 (v2)
Asad Kamal <[email protected]>
drm/amdgpu/gfx: fix cleaner shader IB buffer overflow
Ashutosh Desai <[email protected]>
drm/dp/mst: fix OOB reads on 2-byte fields in sideband reply parsers
Alessio Belle <[email protected]>
drm/imagination: Fit paired fragment job in the correct CCCB
Ashutosh Desai <[email protected]>
drm/dp/mst: fix buffer overflows in sideband chunk accumulation
Ashutosh Desai <[email protected]>
drm/dp/mst: fix OOB reads in remote DPCD/I2C sideband reply parsers
Vitor Soares <[email protected]>
drm/bridge: cdns-dsi: Replace deprecated UNIVERSAL_DEV_PM_OPS()
Alessio Belle <[email protected]>
drm/imagination: Count paired job fence as dependency in prepare_job()
Chen Ni <[email protected]>
drm/rockchip: analogix_dp: Add missing error check for platform_get_resource()
Sergey Shtylyov <[email protected]>
drm/rockchip: cdn-dp: add missing check in cdn_dp_config_video()
Tomi Valkeinen <[email protected]>
drm/tidss: Fix missing drm_bridge_add() call
Biju Das <[email protected]>
drm: renesas: rzg2l_mipi_dsi: Move rzg2l_mipi_dsi_set_display_timing()
Biju Das <[email protected]>
drm: renesas: rzg2l_mipi_dsi: Increase reset deassertion delay
Chengfeng Ye <[email protected]>
bpf, sockmap: Fix cork use-after-free in tcp_bpf_sendmsg()
Lorenzo Bianconi <[email protected]>
net: airoha: fix ETS channel derivation in airoha_tc_setup_qdisc_ets()
Minhong He <[email protected]>
mctp: check register_netdevice_notifier() error in mctp_device_init()
Clark Wang <[email protected]>
ptp: netc: explicitly clear TMR_OFF during initialization
Cen Zhang (Microsoft) <[email protected]>
rds: tcp: unregister sysctl before tearing down listen socket
Nikola Z. Ivanov <[email protected]>
ipv6: Change allocation flags to match rcu_read_lock section requirements
Paul Greenwalt <[email protected]>
ice: prevent tstamp ring allocation for non-PF VSI types
Marcin Szycik <[email protected]>
ice: fix LAG recipe to profile association
Vincent Chen <[email protected]>
ice: allow creating VFs when !CONFIG_ICE_SWITCHDEV
Li RongQing <[email protected]>
net: ipv6: fix dif and sdif mismatch in raw6_icmp_error
Hariprasad Kelam <[email protected]>
octeontx2-pf: tc: fix egress ratelimiting
Alexei Lazar <[email protected]>
net/mlx5e: Reject unsupported CB Shaper TSA in ETS validation
Alexei Lazar <[email protected]>
net/mlx5e: Report zero bandwidth for non-ETS traffic classes
Yael Chemla <[email protected]>
net/mlx5: E-Switch, fix zero num_dest in prio_tag egress vlan rule
Gal Pressman <[email protected]>
net/mlx5: Fix MCIA register buffer overflow on 32 dword reads
Gal Pressman <[email protected]>
net/mlx5: Refactor EEPROM query error handling to return status separately
Runyu Xiao <[email protected]>
raw: annotate lockless match fields in raw_v4_match()
Aldo Ariel Panzardo <[email protected]>
net: qrtr: restrict socket creation to the initial network namespace
Chenguang Zhao <[email protected]>
hinic: remove unused ethtool RSS user configuration buffers
Eric Dumazet <[email protected]>
ppp: annotate data races in ppp_generic
Eric Dumazet <[email protected]>
ipv4: icmp: fill flow parameters in icmp_route_lookup decoy lookup
Suman Ghosh <[email protected]>
octeontx2-vf: set TC flower flag on MCAM entry allocation
Yun Zhou <[email protected]>
net: gre: fix lltx regression for GRE tunnels with SEQ/CSUM
vadik likholetov <[email protected]>
net: stmmac: enable the MAC on link up for all supported speeds
Nazim Amirul <[email protected]>
net: stmmac: reset residual action in L3L4 filters on delete
Nazim Amirul <[email protected]>
net: stmmac: fix l3l4 filter rejecting unsupported offload requests
Nazim Amirul <[email protected]>
net: stmmac: xgmac: fix l4 filter port overwrite on register update
Russell King (Oracle) <[email protected]>
net: stmmac: cores: remove many xxx_SHIFT definitions
Rohan G Thomas <[email protected]>
net: stmmac: socfpga: Add hardware supported cross-timestamp
Rohan G Thomas <[email protected]>
net: stmmac: socfpga: Enable TBS support for Agilex5
Rohan G Thomas <[email protected]>
net: stmmac: socfpga: Agilex5 EMAC platform configuration
Russell King (Oracle) <[email protected]>
net: stmmac: remove xstats.pcs_* members
Xiang Mei (Microsoft) <[email protected]>
bpf: tcp: fix double sock release on batch realloc
José Expósito <[email protected]>
drm/tests: shmem: Set DMA mask to 64-bit in drm_gem_shmem
Cen Zhang (Microsoft) <[email protected]>
tipc: fix u16 MTU truncation in media and bearer MTU validation
Zhang Yi <[email protected]>
iomap: correct the range of a partial dirty clear
Shuicheng Lin <[email protected]>
drm/xe/vm: Fix SVM leak on resv obj alloc failure in xe_vm_create()
Raag Jadav <[email protected]>
drm/xe/i2c: Allow per domain unique id
Harshaka Narayana <[email protected]>
vmxnet3: fix BUG_ON in vmxnet3_get_hdr_len() for Geneve packets
Qing Luo <[email protected]>
sctp: auth: verify auth requirement when auth_chunk is NULL
Michael Walle <[email protected]>
net: dpaa: fix mode setting
Eric Dumazet <[email protected]>
net: hsr: fix memory leak on slave unregistration by removing synced VLANs
Nikolay Aleksandrov <[email protected]>
net: bridge: vlan: fix vlan range dumps starting with pvid
Michael Bommarito <[email protected]>
amt: make the head writable before rewriting the L2 header
Michael Bommarito <[email protected]>
amt: re-read skb header pointers after every pull
Amir Goldstein <[email protected]>
ovl: check access to copy_file_range source with src mounter creds
Christian Brauner <[email protected]>
ovl: port ovl_copyfile() to cred guard
Christian Brauner <[email protected]>
ovl: add override_creds cleanup guard extension for overlayfs
Christian Brauner <[email protected]>
cred: add scoped_with_kernel_creds()
Julian Braha <[email protected]>
drm/panel: s6e3ha8: fix unmet dependency on DRM_DISPLAY_HELPER
Yichong Chen <[email protected]>
ovl: fix trusted xattr escape prefix matching
Shelley Yang <[email protected]>
wifi: brcmfmac: fix 802.1X-SHA256 call trace warning
Lorenzo Bianconi <[email protected]>
wifi: mt76: mt7996: fix possible NULL-pointer deref in mt7996_mcu_sta_bfer_eht()
Sean Wang <[email protected]>
wifi: mt76: mt7925: fix crash in reset link replay
Lorenzo Bianconi <[email protected]>
wifi: mt76: mt7996: check pointer returned by mt76_connac_get_he_phy_cap()
Lorenzo Bianconi <[email protected]>
wifi: mt76: mt7925: fix possible NULL-pointer deref in mt7925_mcu_bss_he_tlv()
Lorenzo Bianconi <[email protected]>
wifi: mt76: connac: fix possible NULL-pointer deref in mt76_connac_mcu_uni_bss_he_tlv()
Ruoyu Wang <[email protected]>
wifi: mt76: mt7915: guard HE capability lookups
Guangshuo Li <[email protected]>
wifi: mt76: mt7925: guard link STA in decap offload
Eric Dumazet <[email protected]>
ppp: annotate concurrent dev->stats accesses
Qingfang Deng <[email protected]>
ppp: don't store tx skb in the fastpath
Qingfang Deng <[email protected]>
ppp: enable TX scatter-gather
Helen Koike <[email protected]>
tipc: fix infinite loop in __tipc_nl_compat_dumpit
Xiang Mei (Microsoft) <[email protected]>
nexthop: initialize extack in nh_res_bucket_migrate()
Xiang Mei (Microsoft) <[email protected]>
gtp: check skb_pull_data() return in gtp1u_send_echo_resp()
Matthieu Baerts (NGI0) <[email protected]>
selftests: drv-net: increase timeout
Matthieu Baerts (NGI0) <[email protected]>
selftests: ovpn: increase timeout
Matthieu Baerts (NGI0) <[email protected]>
selftests: ovpn: add IPV6 and VETH configs
Matthieu Baerts (NGI0) <[email protected]>
selftests: openvswitch: add config file
Matthieu Baerts (NGI0) <[email protected]>
selftests: af_unix: add USER_NS config
Rishikesh Jethwani <[email protected]>
tls: device: push pending open record on splice EOF
Myeonghun Pak <[email protected]>
net: mctp i3c: clean up notifier and buses if driver register fails
Cen Zhang (Microsoft) <[email protected]>
sctp: validate stream count in sctp_process_strreset_inreq()
Nikhil P. Rao <[email protected]>
pds_core: check for workqueue allocation failure
Nikhil P. Rao <[email protected]>
pds_core: fix auxiliary device add/del races
Nikhil P. Rao <[email protected]>
pds_core: order completion reads after the ownership check
Nikhil P. Rao <[email protected]>
pds_core: yield the CPU while waiting for the adminq to drain
Nikhil P. Rao <[email protected]>
pds_core: fix use-after-free on workqueue during remove
Nikhil P. Rao <[email protected]>
pds_core: fix deadlock between reset thread and remove
HanQuan <[email protected]>
sctp: fix auth_chunk_list capacity check in sctp_auth_ep_add_chunkid
Chenguang Zhao <[email protected]>
net: txgbe: fix FDIR filter leak on remove
Kuniyuki Iwashima <[email protected]>
net: Call net_enable_timestamp() before failure in sk_clone().
Kuniyuki Iwashima <[email protected]>
soreuseport: Clear sk_reuseport_cb before failure in sk_clone().
Prashanth Kumar KR <[email protected]>
amd-xgbe: fix MAC_AUTO_SW handling in CL37 AN
Steven Price <[email protected]>
arm64: Correct value returned by ESR_ELx_FSC_ADDRSZ_nL()
Nikhil P. Rao <[email protected]>
pds_core: reject component parameter in legacy firmware update
Andrew Pope <[email protected]>
wifi: mac80211: recalculate TIM when a station enters power save
Li RongQing <[email protected]>
iommu/intel: Fix out-of-bounds memset in dmar_latency_disable()
Pengpeng Hou <[email protected]>
iommu/amd: Bound the early ACPI HID map
HE WEI (ギカク) <[email protected]>
wifi: mwifiex: bound uAP association event IEs to the event buffer
Enrico Zanda <[email protected]>
vhost-net: fix TX stall when vhost owns virtio-net header
Ruoyu Wang <[email protected]>
wan: wanxl: Only reset hardware after BAR mapping
Ruoyu Wang <[email protected]>
nfp: Check resource mutex allocation
Xiang Mei <[email protected]>
wifi: mac80211: tear down new links on vif update error path
Guanghui Feng <[email protected]>
iommu/amd: Wait for completion instead of returning early in iommu_completion_wait()
Wayen Yan <[email protected]>
net: airoha: Fix DMA direction for NPU mailbox buffer
Guangshuo Li <[email protected]>
dpaa2-eth: put MAC endpoint device on disconnect
Wayen Yan <[email protected]>
net: airoha: Fix potential use-after-free in airoha_ppe_deinit()
Guangshuo Li <[email protected]>
dpaa2-switch: put MAC endpoint device on disconnect
Xuanqiang Luo <[email protected]>
rxrpc: fix io_thread race in rxrpc_wake_up_io_thread()
Zhixing Chen <[email protected]>
gtp: parse extension headers before reading inner protocol
Aldo Ariel Panzardo <[email protected]>
rds: drop incoming messages that cross network namespace boundaries
Zhaolong Zhang <[email protected]>
bonding: fix devconf_all NULL dereference when IPv6 is disabled
David Lee <[email protected]>
net/packet: avoid fanout hook re-registration after unregister
Danielle Ratson <[email protected]>
netlink: specs: rt-link: convert bridge port flag attributes to u8
Michael Walle <[email protected]>
net: phy: marvell: fix return code
Pengpeng Hou <[email protected]>
Bluetooth: btusb: validate Realtek vendor event length
Daniel Golle <[email protected]>
regulator: mt6358: use regmap helper to read fixed LDO calibration
Pengpeng Hou <[email protected]>
hwmon: occ: validate poll response sensor blocks
Marco Baffo <[email protected]>
ovpn: use monotonic clock for peer keepalive timeouts
Marco Baffo <[email protected]>
ovpn: fix use after free in unlock_ovpn()
longlong yan <[email protected]>
selftests/net: ovpn: fix getaddrinfo memory leak in ovpn_parse_remote()
Qing Ming <[email protected]>
ovpn: avoid putting unrelated P2P peer on socket release
Yichong Chen <[email protected]>
smb: client: validate DFS referral PathConsumed
Eugene Shalygin <[email protected]>
hwmon: (asus-ec-sensors) add missed handle for ENOMEM
Eugene Shalygin <[email protected]>
hwmon: (asus-ec-sensors) fix EC read intervals
Eugene Shalygin <[email protected]>
hwmon: (asus-ec-sensors) fix looping over banks while reading from EC
Mostafa Saleh <[email protected]>
drivers/virt: pkvm: Fix end calculation in mmio_guard_ioremap_hook()
Diego Fernando Mancera Gomez <[email protected]>
usb: atm: ueagle-atm: reject descriptors that confuse probe and disconnect
Shahar Tzarfati <[email protected]>
wifi: iwlwifi: mvm: fix read in wake packet notification handler
Emmanuel Grumbach <[email protected]>
wifi: iwlwifi: validate payload length in iwl_pnvm_complete_fn
Emmanuel Grumbach <[email protected]>
wifi: iwlwifi: fix pointer arithmetic in iwl_add_mcc_to_tas_block_list
Pagadala Yesu Anjaneyulu <[email protected]>
wifi: iwlwifi: mvm: validate SAR GEO response payload size
Richard Fitzgerald <[email protected]>
ASoC: cs35l56: Use complete_all() to signal init_completion
Richard Fitzgerald <[email protected]>
ASoC: cs35l56: Fix potential probe() deadlock
Richard Fitzgerald <[email protected]>
ASoC: cs35l56: Don't use devres to unregister component
Shengjiu Wang <[email protected]>
ASoC: bt-sco: fix duplicate DAPM widget names for wideband DAI
Guangshuo Li <[email protected]>
ALSA: hda: cs35l41: validate and free ACPI mute object
Chen-Yu Tsai <[email protected]>
ASoC: sun4i-codec: Set quirks.playback_only for H616 codec
Pengpeng Hou <[email protected]>
ASoC: tas2781: bound firmware description string parsing
Guanghui Yang <[email protected]>
btrfs: free mapping node on duplicate reloc root insert
Leo Martins <[email protected]>
btrfs: don't propagate EXTENT_FLAG_LOGGING to split extent maps
Dave Chen <[email protected]>
btrfs: fix u32 to s64 type conversion in dirty_metadata_bytes accounting
You-Kai Zheng <[email protected]>
btrfs: declare btrfs_ioctl_search_args_v2::buf as __u8
Tristan Madani <[email protected]>
wifi: carl9170: fix buffer overflow in rx_stream failover path
Tristan Madani <[email protected]>
wifi: carl9170: fix OOB read from off-by-two in TX status handler
Tristan Madani <[email protected]>
wifi: carl9170: bound memcpy length in cmd callback to prevent OOB read
Tristan Madani <[email protected]>
wifi: ath6kl: fix OOB read from firmware IE lengths in connect event
Tristan Madani <[email protected]>
wifi: ath6kl: fix OOB read from firmware num_msg in TX complete handler
Ruoyu Wang <[email protected]>
firewire: net: Fix fragmented datagram reassembly
Manivannan Sadhasivam <[email protected]>
wifi: ath12k: Flush the posted write after writing to PCIE_SOC_GLOBAL_RESET
Manivannan Sadhasivam <[email protected]>
wifi: ath11k: Flush the posted write after writing to PCIE_SOC_GLOBAL_RESET
Dmitry Morgun <[email protected]>
wifi: ath11k: fix potential buffer underflow in ath11k_hal_rx_msdu_list_get()
Wayen Yan <[email protected]>
watchdog: airoha: Prevent division by zero when clock frequency is zero
Tzung-Bi Shih <[email protected]>
watchdog: pretimeout: Fix UAF in watchdog_unregister_governor()
Guenter Roeck <[email protected]>
hwmon: (nzxt-kraken3) Stop device IO before calling hid_hw_stop
Guenter Roeck <[email protected]>
hwmon: (nzxt-smart2) Stop device IO before calling hid_hw_stop
Guenter Roeck <[email protected]>
hwmon: (gigabyte_waterforce) Stop device IO before calling hid_hw_stop
Guenter Roeck <[email protected]>
hwmon: (corsair-cpro) Stop device IO before calling hid_hw_stop
Edward Adam Davis <[email protected]>
hwmon: (corsair-psu) Stop device IO before calling hid_hw_stop
Gaole Zhang <[email protected]>
wifi: ath11k: fix NULL pointer dereference in ath11k_hal_srng_access_begin
Cheng Yongkang <[email protected]>
wifi: ath9k: hif_usb: don't dereference hif_dev after re-arming firmware request
Daniel Borkmann <[email protected]>
selftests/bpf: Keep verifier_map_ptr exercising ops pointer access
KP Singh <[email protected]>
selftests/bpf: Adjust verifier_map_ptr for the map's excl field
Xincheng Zhang <[email protected]>
usb: xhci-pci: Limit VIA VL805 DMA addressing to 36 bits
Sasha Levin <[email protected]>
Revert "drm/amd/display: Add missing kdoc for ALLM parameters"
Xie Bo <[email protected]>
RISC-V: KVM: Serialize virtual interrupt pending state updates
Georgi Valkov <[email protected]>
wifi: mwifiex: fix freeze for 60 seconds caused by request_firmware
Chia-Lin Kao (AceLan) <[email protected]>
usb: typec: ucsi: Add duplicate detection to nvidia registration path
Chia-Lin Kao (AceLan) <[email protected]>
usb: typec: ucsi: Detect and skip duplicate altmodes from buggy firmware
Chukun Pan <[email protected]>
USB: serial: option: add TDTECH MT5710-CN
Johan Hovold <[email protected]>
USB: serial: keyspan_pda: fix data loss on receive throttling
Sunho Park <[email protected]>
USB: serial: io_edgeport: cap received transmit credits
Tim Pambor <[email protected]>
USB: serial: ftdi_sio: add support for E+H FXA291
Muhammad Bilal <[email protected]>
usb: gadget: uvc: clamp SEND_RESPONSE length to the response buffer
Fan Wu <[email protected]>
usb: gadget: udc: bdc: free IRQ and drain func_wake_notify before teardown
Sonali Pradhan <[email protected]>
usb: gadget: f_ncm: validate datagram bounds in ncm_unwrap_ntb()
Johan Hovold <[email protected]>
USB: gadget: fsl-udc: fix dev_printk() device
Johan Hovold <[email protected]>
USB: gadget: fsl-udc: fix device name leak on probe failure
Johan Hovold <[email protected]>
USB: gadget: snps-udc: fix device name leak on probe failure
Melbin K Mathew <[email protected]>
usb: gadget: printer: fix infinite loop in printer_read()
Fan Wu <[email protected]>
usb: gadget: f_midi: cancel pending IN work before freeing the midi object
Jinchao Wang <[email protected]>
usb: gadget: dummy_hcd: prevent fifo_req reuse during giveback
Xu Yang <[email protected]>
usb: chipidea: fix usage_count leak when autosuspend_delay is negative
Huang Wei <[email protected]>
USB: storage: add NO_ATA_1X quirk for Longmai USB Key
Guangshuo Li <[email protected]>
usb: musb: omap2430: Do not put borrowed of_node in probe
Chia-Lin Kao (AceLan) <[email protected]>
usb: core: port: Deattach Type-C connector on component unbind
Huihui Huang <[email protected]>
wifi: at76c50x-usb: avoid length underflow in at76_guess_freq()
Griffin Kroah-Hartman <[email protected]>
usb: core: sysfs: add lock to bos_descriptors_read()
Weiming Shi <[email protected]>
mpls: fix NULL deref in mpls_valid_fib_dump_req() on CONFIG_INET=n
Xin Long <[email protected]>
sctp: fix auth_hmacs array size in struct sctp_cookie
Jamal Hadi Salim <[email protected]>
net/sched: act_tunnel_key: Defer dst_release to RCU callback
Ivan Vecera <[email protected]>
dpll: fix NULL pointer dereference in dpll_msg_add_pin_ref_sync()
Eric Dumazet <[email protected]>
tcp: fix TIME_WAIT socket reference leak on PSP policy failure
Lizhi Hou <[email protected]>
accel/amdxdna: Fix use-after-free of mm_struct in job scheduler
Emre Cecanpunar <[email protected]>
drm/i915/selftests: Fix GT PM sort comparators
Vinod Govindapillai <[email protected]>
drm/i915/wm: clear the plane ddb_y entries on plane disable
Xiang Mei (Microsoft) <[email protected]>
ksmbd: validate compound request size before reading StructureSize2
Qihang <[email protected]>
ksmbd: pin conn during async oplock break notification
Daniele Ceraolo Spurio <[email protected]>
drm/xe/wopcm: fix WOPCM size for LNL+
Matthew Brost <[email protected]>
drm/xe/vf: Fix VF CCS attach/detach race with in-flight BO moves
Satyanarayana K V P <[email protected]>
drm/xe/vf: Shadow buffer management for CCS read/write operations
Satyanarayana K V P <[email protected]>
drm/xe/sa: Shadow buffer support in the sub-allocator pool
Michał Winiarski <[email protected]>
drm/xe: Allow the caller to pass guc_buf_cache size
Shuhao Fu <[email protected]>
can: j1939: fix lockless local-destination check
Mark Harris <[email protected]>
riscv: hwprobe: Avoid uninitialized read in hwprobe_get_cpus()
Vasily Gorbik <[email protected]>
s390/checksum: Fix csum_partial() without vector facility
Linmao Li <[email protected]>
drm/panthor: Check debugfs GEM lock initialization
Michal Luczaj <[email protected]>
bpf, sockmap: Reject unhashed UDP sockets on sockmap update
Shrikanth Hegde <[email protected]>
powerpc/vtime: Initialize starttime at boot for native accounting
Frederic Weisbecker <[email protected]>
powerpc/time: Prepare to stop elapsing in dynticks-idle
Rosen Penev <[email protected]>
powerpc/85xx: Add fsl,ifc to common device ids
Oliver Hartkopp <[email protected]>
can: raw: add locking for raw flags bitfield
Pengpeng Hou <[email protected]>
drm/i915/gt: use correct selftest config symbol
Huiwen He <[email protected]>
smb/client: handle overlapping allocated ranges in fallocate
Ruoyu Wang <[email protected]>
Bluetooth: hci_qca: Clear memdump state on invalid dump size
Pauli Virtanen <[email protected]>
Bluetooth: mgmt: hold reference for hci_conn in mgmt_pending_cmds
Pauli Virtanen <[email protected]>
Bluetooth: mgmt: fix locking in unpair_device/disconnect_sync
Pauli Virtanen <[email protected]>
Bluetooth: hci_sync: extend conn_hash lookup critical sections
Cen Zhang <[email protected]>
Bluetooth: MGMT: revalidate LOAD_CONN_PARAM queued update
Xiang Mei <[email protected]>
Bluetooth: qca: fix NVM tag length underflow in TLV parser
Takashi Iwai <[email protected]>
ALSA: usb-audio: Skip DSD quirk for Musical Fidelity M6s DAC
Karol Wachowski <[email protected]>
accel/ivpu: Fix wrong register read in LNL failure diagnostics
Rosen Penev <[email protected]>
ata: sata_dwc_460ex: fix infinite loop in NCQ tag completion bit-scanning
Rosen Penev <[email protected]>
ata: sata_dwc_460ex: fix clear_interrupt_bit() clearing all pending interrupts
Rosen Penev <[email protected]>
ata: sata_dwc_460ex: use platform_get_irq()
Rosen Penev <[email protected]>
ata: sata_dwc_460ex: enable SATA interrupts only after IRQ handler is registered
David Jeffery <[email protected]>
scsi: core: wake eh reliably when using scsi_schedule_eh
Robert Mader <[email protected]>
udmabuf: Ensure to perform cache synchronisation in begin_cpu_udmabuf()
Bryam Vargas <[email protected]>
net/iucv: take a reference on the socket found in afiucv_hs_rcv()
Weiming Shi <[email protected]>
ipv4: fib: free fib_alias with kfree_rcu() on insert error path
Norbert Szetei <[email protected]>
ppp: defer channel free to an RCU grace period to fix pppol2tp RX UAF
Rafael J. Wysocki <[email protected]>
cpufreq: Make cpufreq_update_pressure() fall back to cpuinfo.max_freq
Pushpendra Singh <[email protected]>
firmware: arm_scmi: Rate-limit queue-full warnings in IRQ context
Uday Khare <[email protected]>
ASoC: tas2562: fix deprecated 'shut-down' GPIO always cleared after lookup
Charles Keepax <[email protected]>
ASoC: cs42l43: Correct report for forced microphone jack
Vijendar Mukunda <[email protected]>
ASoC: amd: ps: replace bitwise OR with logical OR in IRQ return check
Vijendar Mukunda <[email protected]>
ASoC: amd: ps: fix wrong ACP version string in pci_request_regions()
Vijendar Mukunda <[email protected]>
ASoC: amd: ps: disable MSI on resume in ACP PCI driver
Christian Hewitt <[email protected]>
ASoC: meson: aiu: fifo-spdif: soft reset the S/PDIF datapath on start/stop
Sebastian Ene <[email protected]>
firmware: arm_ffa: Fix Endpoint Memory Access Descriptor offset calculation
Mostafa Saleh <[email protected]>
firmware: arm_ffa: Fix out-of-bound writes in ffa_setup_and_transmit()
HE WEI (ギカク) <[email protected]>
wifi: cfg80211: bound element ID read when checking non-inheritance
Runyu Xiao <[email protected]>
wifi: brcmfmac: initialize SDIO data work before cleanup
Cen Zhang <[email protected]>
wifi: mac80211: free AP_VLAN bc_buf SKBs outside IRQ lock
Zhao Li <[email protected]>
wifi: mac80211: avoid non-S1G AID fallback for S1G assoc
Zhao Li <[email protected]>
wifi: cfg80211: reject unsupported PMSR FTM location requests
Zhao Li <[email protected]>
wifi: cfg80211: validate PMSR FTM preamble range
Zhao Li <[email protected]>
wifi: cfg80211: validate PMSR measurement type data
Zhao Li <[email protected]>
wifi: nl80211: constrain MBSSID TX link ID range
Zhao Li <[email protected]>
wifi: nl80211: validate nested MBSSID IE blobs
Zhao Li <[email protected]>
wifi: cfg80211: derive S1G beacon TSF from S1G fields
Zhao Li <[email protected]>
wifi: nl80211: free RNR data on MBSSID mismatch
Peddolla Harshavardhan Reddy <[email protected]>
wifi: cfg80211: convert pmsr_free_wk to wiphy_work to fix deadlock
Xiang Mei <[email protected]>
wifi: p54: validate RX frame length in p54_rx_eeprom_readback()
Maoyi Xie <[email protected]>
wifi: mac80211: defer link RX stats percpu free to RCU
Dawei Feng <[email protected]>
wifi: libertas: fix memory leak in helper_firmware_cb()
Xiang Mei <[email protected]>
wifi: mac80211: fix fils_discovery double free on alloc failure
Xiang Mei <[email protected]>
wifi: mac80211: fix unsol_bcast_probe_resp double free on alloc failure
Bryam Vargas <[email protected]>
wifi: mac80211_hwsim: clamp virtio RX length before skb_put
Christophe JAILLET <[email protected]>
wifi: cfg80211: Fix an error handling path in cfg80211_wext_siwscan()
Abdun Nihaal <[email protected]>
wifi: ipw2100: fix potential memory leak in ipw2100_pci_init_one()
Cen Zhang <[email protected]>
wifi: cfg80211: cancel sched scan results work on unregister
Xiang Mei (Microsoft) <[email protected]>
xfrm: policy: preallocate inexact bins before xfrm_hash_rebuild reinsert
Xiang Mei (Microsoft) <[email protected]>
xfrm6: clear dst.dev on error to avoid double netdev_put in xfrm6_fill_dst()
Chen YanJun <[email protected]>
xfrm: iptfs: propagate SKBFL_SHARED_FRAG in iptfs_skb_add_frags()
Cen Zhang <[email protected]>
xfrm: clear mode callbacks after failed mode setup
Aleksandrova Alyona <[email protected]>
RDMA/irdma: Prevent overflows in memory contiguity checks
Malaya Kumar Rout <[email protected]>
selftests/alsa: Fix memory leak in find_controls error path
Xue Lei <[email protected]>
mtd: fix double free and WARN_ON in add_mtd_device() error paths
Ruoyu Wang <[email protected]>
RDMA/siw: publish QP after initialization
Danila Chernetsov <[email protected]>
RDMA/hns: Fix potential integer overflow in mhop hem cleanup
Ruoyu Wang <[email protected]>
RDMA/mana_ib: initialize err for empty send WR lists
Ruoyu Wang <[email protected]>
RDMA/erdma: initialize ret for empty receive WR lists
Jacob Moroni <[email protected]>
RDMA/irdma: Prevent user-triggered null deref on QP create
Jacob Moroni <[email protected]>
RDMA/irdma: Remove redundant legacy_mode checks
Jacob Moroni <[email protected]>
RDMA/irdma: Prevent rereg_mr for non-mem regions
Jacob Moroni <[email protected]>
RDMA/umem: Add pinned revocable dmabuf import interface
Or Gerlitz <[email protected]>
RDMA/cma: Fix hardware address comparison length in netevent callback
Antony Antony <[email protected]>
xfrm: reject optional IPTFS templates in outbound policies
Tejun Heo <[email protected]>
sched_ext: Don't warn on core-sched forced idle in put_prev_task_scx()
John Stultz <[email protected]>
sched/ext: Avoid null ptr traversal when ->put_prev_task() is called with NULL next
Unnathi Chalicheemala <[email protected]>
firmware: arm_ffa: Fix NULL dereference in ffa_partition_info_get()
Boris Burkov <[email protected]>
btrfs: fallback to transaction csum tree on a commit root csum miss
Filipe Manana <[email protected]>
btrfs: use bool type for btrfs_path members used as booleans
Filipe Manana <[email protected]>
btrfs: fix root leak if its reloc root is unexpected in merge_reloc_roots()
Xiang Mei <[email protected]>
btrfs: reject free space cache with more entries than pages
Pengpeng Hou <[email protected]>
mtd: nand: mtk-ecc: stop on ECC idle timeouts
Pengpeng Hou <[email protected]>
mtd: mtdswap: remove debugfs stats file on teardown
Michael Bommarito <[email protected]>
IB/mad: Drop unmatched RMPP responses before reassembly
Seth Forshee <[email protected]>
firmware: arm_ffa: Respect firmware advertised RX/TX buffer size limits
Petr Wozniak <[email protected]>
xfrm: fix stale skb->prev after async crypto steals a GSO segment
Petr Wozniak <[email protected]>
xfrm: propagate -EINPROGRESS from validate_xmit_xfrm()
Eric Dumazet <[email protected]>
net: plumb drop reasons to __dev_queue_xmit()
Eric Dumazet <[email protected]>
net: dropreason: add SKB_DROP_REASON_RECURSION_LIMIT
Sumit Gupta <[email protected]>
arm64: tegra: Fix CPU compatible string to cortex-a78ae on Tegra234
Akhil R <[email protected]>
arm64: tegra: Remove fallback compatible for GPCDMA
Junxi Qian <[email protected]>
fuse: fix writeback array overflow when max_pages is one
Dmitry Torokhov <[email protected]>
Input: ims-pcu - fix logic error in packet reset
Seungjin Bae <[email protected]>
Input: ims-pcu - fix heap-buffer-overflow in ims_pcu_process_data()
Chuck Lever <[email protected]>
xprtrdma: Clear receive-side ownership pointers on release
Mikko Perttunen <[email protected]>
crypto: tegra - Don't touch bo refcount in host1x bo pin/unpin
Mikko Perttunen <[email protected]>
gpu: host1x: Fix use-after-free in host1x_bo_clear_cached_mappings
Claudiu Beznea <[email protected]>
dmaengine: sh: rz-dmac: Move interrupt request after everything is set up
Oliver Hartkopp <[email protected]>
can: bcm: track a single source interface for ANYDEV timeout/throttle ops
Oliver Hartkopp <[email protected]>
can: bcm: fix data race on rx_stamp/rx_ifindex in bcm_rx_handler()
Oliver Hartkopp <[email protected]>
can: bcm: fix stale rx/tx ops after device removal
Oliver Hartkopp <[email protected]>
can: bcm: add missing device refcount for CAN filter removal
Oliver Hartkopp <[email protected]>
can: bcm: validate frame length in bcm_rx_setup() for RTR replies
Oliver Hartkopp <[email protected]>
can: bcm: extend bcm_tx_lock usage for data and timer updates
Oliver Hartkopp <[email protected]>
can: bcm: fix CAN frame rx/tx statistics
Oliver Hartkopp <[email protected]>
can: bcm: add locking when updating filter and timer values
Phil Rosenthal <[email protected]>
KVM: x86/mmu: Fix use-after-free on vendor module reload
Hyunwoo Kim <[email protected]>
KVM: nVMX: Hide shadow VMCS right after VMCLEAR
Venkatesh Srinivas <[email protected]>
KVM: x86: Only reset TSC Deadline Timer in apic_timer_expired on KVM_RUN
Sean Christopherson <[email protected]>
KVM: x86: Check for invalid/obsolete root *after* making MMU pages available
Heiko Carstens <[email protected]>
seqlock: Allow UBSAN_ALIGNMENT to fail optimizing
Peter Zijlstra <[email protected]>
seqlock: Allow KASAN to fail optimizing
Peter Zijlstra <[email protected]>
seqlock: Cure some more scoped_seqlock() optimization fails
Kiryl Shutsemau <[email protected]>
fs/proc/task_mmu: fix make_uffd_wp_huge_pte() prot-update race
Ryosuke Yasuoka <[email protected]>
drm/virtio: fix deadlock in display_info_cb by removing hotplug from dequeue worker
Brian Witte <[email protected]>
netfilter: nf_tables: revert commit_mutex usage in reset path
Brian Witte <[email protected]>
netfilter: nft_quota: use atomic64_xchg for reset
Brian Witte <[email protected]>
netfilter: nft_counter: serialize reset with spinlock
Daniel Borkmann <[email protected]>
selftests/bpf: Add tests for ld_{abs,ind} failure path in subprogs
Daniel Borkmann <[email protected]>
bpf: Fix ld_{abs,ind} failure path analysis in subprogs
Guixiong Wei <[email protected]>
platform/x86/intel-uncore-freq: Fix current_freq_khz after CPU hotplug
-------------
Diffstat:
Documentation/gpu/drm-mm.rst | 10 +-
Documentation/netlink/specs/rt-link.yaml | 40 +-
MAINTAINERS | 13 +
Makefile | 9 +-
arch/arm64/boot/dts/nvidia/tegra234.dtsi | 24 +-
arch/arm64/boot/dts/nvidia/tegra264.dtsi | 2 +-
arch/arm64/boot/dts/qcom/lemans.dtsi | 8 +-
arch/arm64/boot/dts/qcom/sc7180.dtsi | 4 +-
arch/arm64/boot/dts/qcom/sc7280.dtsi | 8 +-
arch/arm64/boot/dts/qcom/sc8180x.dtsi | 12 +-
arch/arm64/boot/dts/qcom/sc8280xp.dtsi | 32 +-
arch/arm64/boot/dts/qcom/sm6350.dtsi | 4 +-
arch/arm64/boot/dts/qcom/sm8150.dtsi | 4 +-
arch/arm64/boot/dts/qcom/sm8250.dtsi | 4 +-
arch/arm64/boot/dts/qcom/sm8350.dtsi | 4 +-
arch/arm64/boot/dts/qcom/sm8450.dtsi | 4 +-
arch/arm64/boot/dts/qcom/x1e80100.dtsi | 77 +-
arch/arm64/include/asm/esr.h | 2 +-
arch/arm64/mm/hugetlbpage.c | 2 +-
arch/loongarch/kernel/acpi.c | 27 +-
arch/loongarch/kernel/kgdb.c | 3 +-
arch/loongarch/kernel/machine_kexec.c | 5 +-
arch/loongarch/kernel/setup.c | 3 +-
arch/loongarch/kernel/smp.c | 4 +-
arch/powerpc/kernel/time.c | 43 +
arch/powerpc/platforms/85xx/common.c | 2 +
arch/riscv/include/asm/kvm_host.h | 10 +-
arch/riscv/kernel/sys_hwprobe.c | 1 +
arch/riscv/kvm/aia.c | 35 +-
arch/riscv/kvm/vcpu.c | 68 +-
arch/riscv/kvm/vcpu_onereg.c | 8 +-
arch/s390/lib/csum-partial.c | 2 +-
arch/x86/boot/compressed/Makefile | 1 +
arch/x86/kernel/cpu/resctrl/core.c | 32 +-
arch/x86/kernel/cpu/resctrl/internal.h | 18 +-
arch/x86/kernel/cpu/resctrl/monitor.c | 36 +-
arch/x86/kvm/lapic.c | 2 +-
arch/x86/kvm/mmu/mmu.c | 11 +-
arch/x86/kvm/mmu/paging_tmpl.h | 10 +-
arch/x86/kvm/svm/svm.c | 7 +-
arch/x86/kvm/vmx/nested.c | 11 +-
drivers/accel/amdxdna/amdxdna_ctx.c | 8 +
drivers/accel/ivpu/ivpu_hw_btrs.c | 2 +-
drivers/android/binder/thread.rs | 14 +-
drivers/ata/libata-core.c | 18 +
drivers/ata/libata-scsi.c | 2 -
drivers/ata/libata.h | 9 +
drivers/ata/sata_dwc_460ex.c | 38 +-
drivers/block/rbd.c | 7 +-
drivers/block/ublk_drv.c | 52 +-
drivers/bluetooth/btqca.c | 2 +-
drivers/bluetooth/btusb.c | 4 +-
drivers/bluetooth/hci_qca.c | 4 +
drivers/cdrom/cdrom.c | 1 +
drivers/comedi/drivers/comedi_parport.c | 13 +-
drivers/cpufreq/cpufreq.c | 3 +
drivers/crypto/tegra/tegra-se-main.c | 3 +-
drivers/cxl/Kconfig | 4 +
drivers/cxl/core/Makefile | 2 +-
drivers/cxl/core/core.h | 31 +
drivers/cxl/core/pci.c | 215 +---
drivers/cxl/core/ras.c | 197 ++-
drivers/cxl/core/trace.h | 24 +-
drivers/cxl/cxl.h | 22 +-
drivers/cxl/cxlpci.h | 16 +
drivers/dma-buf/udmabuf.c | 9 +-
drivers/dma/dw-edma/dw-edma-pcie.c | 7 +-
drivers/dma/sh/rz-dmac.c | 96 +-
drivers/dpll/dpll_netlink.c | 3 +
drivers/firewire/net.c | 37 +-
drivers/firmware/arm_ffa/driver.c | 54 +-
drivers/firmware/arm_scmi/notify.c | 6 +-
drivers/firmware/stratix10-svc.c | 10 +-
drivers/firmware/xilinx/zynqmp.c | 1 +
drivers/gpu/Kconfig | 13 +
drivers/gpu/Makefile | 4 +-
drivers/gpu/buddy.c | 1347 ++++++++++++++++++++
drivers/gpu/drm/Kconfig | 5 +-
drivers/gpu/drm/Kconfig.debug | 1 -
drivers/gpu/drm/Makefile | 1 -
drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | 13 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c | 62 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 6 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 14 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 6 +
drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 10 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c | 3 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 13 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 2 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h | 12 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 54 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 58 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | 17 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 25 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 79 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h | 20 +-
drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 22 +-
drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 13 +-
drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c | 13 +-
drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 3 -
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 49 +-
drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c | 11 +-
drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c | 2 +-
drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c | 2 +-
drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c | 4 +-
drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c | 4 +-
drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c | 4 +-
drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c | 4 +-
drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c | 4 +-
drivers/gpu/drm/amd/amdgpu/soc24.c | 28 +
drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c | 15 +-
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 12 +-
.../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 6 +
.../gpu/drm/amd/amdkfd/kfd_device_queue_manager.h | 2 +
drivers/gpu/drm/amd/amdkfd/kfd_events.c | 3 +
drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 3 +-
.../gpu/drm/amd/amdkfd/kfd_process_queue_manager.c | 24 +-
drivers/gpu/drm/amd/amdkfd/kfd_queue.c | 23 +-
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 374 +++---
.../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c | 81 +-
.../amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c | 9 +-
.../amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c | 9 +-
.../gpu/drm/amd/display/dc/link/link_detection.c | 5 +-
.../display/dc/resource/dce100/dce100_resource.c | 7 +-
.../amd/display/modules/info_packet/info_packet.c | 2 -
drivers/gpu/drm/amd/pm/amdgpu_pm.c | 26 +-
drivers/gpu/drm/amd/pm/powerplay/hwmgr/hwmgr.c | 7 +-
.../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 11 +-
.../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 15 +-
.../gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c | 28 +-
drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 11 +-
drivers/gpu/drm/display/drm_dp_mst_topology.c | 36 +-
drivers/gpu/drm/drm_buddy.c | 1278 +------------------
drivers/gpu/drm/drm_connector.c | 12 +-
drivers/gpu/drm/drm_displayid_internal.h | 2 +-
drivers/gpu/drm/drm_gpusvm.c | 4 +-
drivers/gpu/drm/drm_panel_backlight_quirks.c | 9 +
drivers/gpu/drm/i915/display/intel_bios.c | 36 +-
drivers/gpu/drm/i915/display/intel_dp.c | 8 +-
drivers/gpu/drm/i915/display/intel_hdcp.c | 12 +-
drivers/gpu/drm/i915/display/skl_watermark.c | 2 +-
drivers/gpu/drm/i915/gem/i915_gem_context.c | 25 +-
drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 3 +-
drivers/gpu/drm/i915/gt/intel_engine_user.c | 2 +-
drivers/gpu/drm/i915/gt/selftest_gt_pm.c | 8 +-
drivers/gpu/drm/i915/i915_active.c | 7 +-
drivers/gpu/drm/i915/i915_scatterlist.c | 10 +-
drivers/gpu/drm/i915/i915_ttm_buddy_manager.c | 59 +-
drivers/gpu/drm/i915/i915_ttm_buddy_manager.h | 4 +-
.../gpu/drm/i915/selftests/intel_memory_region.c | 20 +-
drivers/gpu/drm/imagination/pvr_context.c | 22 +-
drivers/gpu/drm/imagination/pvr_drv.c | 13 +-
drivers/gpu/drm/imagination/pvr_queue.c | 65 +-
drivers/gpu/drm/imagination/pvr_queue.h | 2 +-
drivers/gpu/drm/imagination/pvr_vm.c | 2 +
drivers/gpu/drm/nouveau/nouveau_exec.c | 4 +-
drivers/gpu/drm/nouveau/nouveau_uvmm.c | 4 +-
drivers/gpu/drm/nouveau/nvkm/subdev/acr/base.c | 1 +
drivers/gpu/drm/panel/Kconfig | 1 +
drivers/gpu/drm/panthor/panthor_device.c | 5 +-
drivers/gpu/drm/panthor/panthor_fw.c | 1 +
drivers/gpu/drm/radeon/r100.c | 13 +-
drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c | 18 +-
drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 2 +
drivers/gpu/drm/rockchip/cdn-dp-reg.c | 2 +
drivers/gpu/drm/sysfb/drm_sysfb_helper.h | 2 +-
drivers/gpu/drm/sysfb/drm_sysfb_screen_info.c | 13 +-
drivers/gpu/drm/sysfb/efidrm.c | 7 +-
drivers/gpu/drm/sysfb/vesadrm.c | 6 +-
drivers/gpu/drm/tests/Makefile | 1 -
drivers/gpu/drm/tests/drm_exec_test.c | 2 -
drivers/gpu/drm/tests/drm_gem_shmem_test.c | 16 +-
drivers/gpu/drm/tests/drm_mm_test.c | 2 -
drivers/gpu/drm/tidss/tidss_encoder.c | 2 +
drivers/gpu/drm/ttm/tests/ttm_bo_validate_test.c | 4 +-
drivers/gpu/drm/ttm/tests/ttm_mock_manager.c | 18 +-
drivers/gpu/drm/ttm/tests/ttm_mock_manager.h | 4 +-
drivers/gpu/drm/ttm/ttm_pool.c | 34 +-
drivers/gpu/drm/v3d/v3d_gem.c | 12 +
drivers/gpu/drm/vc4/vc4_bo.c | 12 +-
drivers/gpu/drm/virtio/virtgpu_gem.c | 14 +-
drivers/gpu/drm/virtio/virtgpu_kms.c | 5 +-
drivers/gpu/drm/virtio/virtgpu_vq.c | 6 +-
drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 22 +-
drivers/gpu/drm/xe/xe_bo.c | 58 +-
drivers/gpu/drm/xe/xe_bo.h | 3 +-
drivers/gpu/drm/xe/xe_bo_types.h | 2 +
drivers/gpu/drm/xe/xe_dma_buf.c | 2 +-
drivers/gpu/drm/xe/xe_guc_buf.c | 44 +-
drivers/gpu/drm/xe/xe_guc_buf.h | 1 +
drivers/gpu/drm/xe/xe_i2c.c | 5 +-
drivers/gpu/drm/xe/xe_migrate.c | 62 +-
drivers/gpu/drm/xe/xe_migrate.h | 4 +
drivers/gpu/drm/xe/xe_pt.c | 14 +-
drivers/gpu/drm/xe/xe_res_cursor.h | 34 +-
drivers/gpu/drm/xe/xe_sa.c | 67 +-
drivers/gpu/drm/xe/xe_sa.h | 20 +-
drivers/gpu/drm/xe/xe_sa_types.h | 3 +
drivers/gpu/drm/xe/xe_sriov_vf_ccs.c | 42 +-
drivers/gpu/drm/xe/xe_sriov_vf_ccs.h | 4 +-
drivers/gpu/drm/xe/xe_svm.c | 18 +-
drivers/gpu/drm/xe/xe_ttm_vram_mgr.c | 71 +-
drivers/gpu/drm/xe/xe_ttm_vram_mgr_types.h | 4 +-
drivers/gpu/drm/xe/xe_vm.c | 10 +-
drivers/gpu/drm/xe/xe_wopcm.c | 15 +-
drivers/gpu/host1x/bus.c | 4 +-
drivers/gpu/tests/Makefile | 4 +
.../drm_buddy_test.c => tests/gpu_buddy_test.c} | 358 +++---
.../{drm/lib/drm_random.c => tests/gpu_random.c} | 18 +-
.../{drm/lib/drm_random.h => tests/gpu_random.h} | 18 +-
drivers/hwmon/asus-ec-sensors.c | 18 +-
drivers/hwmon/corsair-cpro.c | 1 +
drivers/hwmon/corsair-psu.c | 1 +
drivers/hwmon/gigabyte_waterforce.c | 4 +-
drivers/hwmon/nzxt-kraken3.c | 6 +-
drivers/hwmon/nzxt-smart2.c | 2 +-
drivers/hwmon/occ/common.c | 38 +-
drivers/hwtracing/intel_th/core.c | 10 -
drivers/hwtracing/intel_th/msu.c | 2 +
drivers/i3c/master/mipi-i3c-hci/core.c | 16 +-
drivers/i3c/master/mipi-i3c-hci/hci.h | 1 +
drivers/infiniband/core/cma.c | 2 +-
drivers/infiniband/core/mad.c | 30 +
drivers/infiniband/core/umem_dmabuf.c | 61 +
drivers/infiniband/hw/erdma/erdma_qp.c | 2 +-
drivers/infiniband/hw/hns/hns_roce_hem.c | 2 +-
drivers/infiniband/hw/irdma/uk.c | 9 +-
drivers/infiniband/hw/irdma/user.h | 1 -
drivers/infiniband/hw/irdma/verbs.c | 33 +-
drivers/infiniband/hw/mana/wr.c | 2 +-
drivers/infiniband/sw/siw/siw_verbs.c | 44 +-
drivers/input/misc/ims-pcu.c | 32 +-
drivers/iommu/amd/init.c | 6 +
drivers/iommu/amd/iommu.c | 22 +-
drivers/iommu/intel/perf.c | 2 +-
drivers/iommu/intel/svm.c | 2 +-
drivers/md/dm-verity-fec.c | 110 +-
drivers/md/dm-verity-fec.h | 6 +-
drivers/md/dm.c | 11 +-
drivers/media/cec/platform/seco/seco-cec.c | 6 +-
drivers/media/common/videobuf2/videobuf2-core.c | 12 +-
drivers/media/dvb-frontends/rtl2832.c | 4 +-
drivers/media/dvb-frontends/rtl2832_sdr.c | 19 +-
drivers/media/i2c/alvium-csi2.c | 21 +-
drivers/media/i2c/imx219.c | 2 +-
drivers/media/pci/cx23885/cx23885-core.c | 14 +-
drivers/media/pci/dm1105/dm1105.c | 1 +
drivers/media/pci/intel/ipu6/ipu6-isys-dwc-phy.c | 24 +-
drivers/media/pci/saa7134/saa7134-video.c | 25 +-
.../media/platform/amlogic/c3/isp/c3-isp-params.c | 4 +
drivers/media/platform/aspeed/aspeed-video.c | 1 +
.../platform/chips-media/wave5/wave5-vpu-enc.c | 29 +-
drivers/media/platform/marvell/cafe-driver.c | 1 +
drivers/media/platform/nuvoton/npcm-video.c | 34 +-
.../media/platform/nxp/imx8-isi/imx8-isi-core.c | 2 +
.../media/platform/nxp/imx8-isi/imx8-isi-core.h | 16 +
.../platform/nxp/imx8-isi/imx8-isi-crossbar.c | 1 +
drivers/media/platform/nxp/imx8-isi/imx8-isi-hw.c | 9 +-
drivers/media/platform/nxp/imx8-isi/imx8-isi-m2m.c | 11 +-
.../media/platform/nxp/imx8-isi/imx8-isi-pipe.c | 20 +-
drivers/media/platform/qcom/camss/camss-csid-680.c | 30 +-
.../media/platform/qcom/camss/camss-csid-gen2.c | 47 +-
.../media/platform/qcom/camss/camss-csid-gen3.c | 28 +-
drivers/media/platform/qcom/iris/iris_probe.c | 6 +-
.../platform/renesas/rzg2l-cru/rzg2l-cru-regs.h | 1 +
.../media/platform/renesas/rzg2l-cru/rzg2l-video.c | 17 +-
drivers/media/platform/st/stm32/stm32-dcmi.c | 1 +
.../st/stm32/stm32-dcmipp/dcmipp-bytecap.c | 6 +-
drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c | 6 +-
.../media/platform/synopsys/hdmirx/snps_hdmirx.c | 4 +-
drivers/media/platform/ti/davinci/vpif_capture.c | 2 +-
drivers/media/platform/ti/vpe/vpe.c | 3 +-
drivers/media/platform/verisilicon/hantro_v4l2.c | 6 +-
drivers/media/radio/radio-si476x.c | 1 +
drivers/media/test-drivers/vidtv/vidtv_bridge.c | 4 +-
drivers/media/test-drivers/vimc/vimc-core.c | 1 +
drivers/media/test-drivers/vivid/vivid-core.c | 6 +-
drivers/media/test-drivers/vivid/vivid-ctrls.c | 15 +-
drivers/media/test-drivers/vivid/vivid-vid-cap.c | 38 +-
drivers/media/test-drivers/vivid/vivid-vid-cap.h | 1 +
drivers/media/test-drivers/vivid/vivid-vid-out.c | 6 +
drivers/media/usb/airspy/airspy.c | 8 +-
drivers/media/usb/cx231xx/cx231xx-cards.c | 16 +-
drivers/media/usb/msi2500/msi2500.c | 32 +-
drivers/media/usb/pwc/pwc-if.c | 13 +-
drivers/media/v4l2-core/v4l2-ctrls-core.c | 13 +
drivers/media/v4l2-core/v4l2-ctrls-request.c | 14 +-
drivers/media/v4l2-core/v4l2-fwnode.c | 6 +-
drivers/media/v4l2-core/v4l2-subdev.c | 4 +
drivers/misc/mei/bus.c | 16 +-
drivers/misc/nsm.c | 3 +-
drivers/mmc/host/vub300.c | 24 +-
drivers/mtd/maps/vmu-flash.c | 8 +-
drivers/mtd/mtdcore.c | 23 +-
drivers/mtd/mtdswap.c | 5 +-
drivers/mtd/nand/ecc-mtk.c | 16 +-
drivers/net/amt.c | 101 +-
drivers/net/bonding/bond_main.c | 3 +-
drivers/net/ethernet/airoha/airoha_eth.c | 3 +-
drivers/net/ethernet/airoha/airoha_npu.c | 4 +-
drivers/net/ethernet/airoha/airoha_ppe.c | 1 +
drivers/net/ethernet/amd/pds_core/adminq.c | 12 +-
drivers/net/ethernet/amd/pds_core/auxbus.c | 17 +-
drivers/net/ethernet/amd/pds_core/core.c | 22 +-
drivers/net/ethernet/amd/pds_core/devlink.c | 6 +
drivers/net/ethernet/amd/pds_core/main.c | 14 +-
drivers/net/ethernet/amd/xgbe/xgbe-mdio.c | 11 +-
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 1 +
.../net/ethernet/freescale/dpaa2/dpaa2-switch.c | 1 +
drivers/net/ethernet/freescale/fman/fman_dtsec.c | 17 +-
drivers/net/ethernet/google/gve/gve.h | 3 +
drivers/net/ethernet/google/gve/gve_rx_dqo.c | 34 +
drivers/net/ethernet/hisilicon/hip04_eth.c | 11 +-
drivers/net/ethernet/huawei/hinic/hinic_dev.h | 2 -
drivers/net/ethernet/huawei/hinic/hinic_ethtool.c | 21 -
drivers/net/ethernet/intel/ice/ice.h | 3 +
drivers/net/ethernet/intel/ice/ice_eswitch.c | 3 -
drivers/net/ethernet/intel/ice/ice_lag.c | 2 +-
drivers/net/ethernet/intel/ice/ice_parser.c | 3 +
drivers/net/ethernet/intel/ice/ice_ptp.c | 7 +-
drivers/net/ethernet/intel/ice/ice_sriov.c | 14 +-
drivers/net/ethernet/intel/ice/ice_vf_lib.c | 3 +-
drivers/net/ethernet/marvell/octeontx2/af/rvu.c | 2 +-
drivers/net/ethernet/marvell/octeontx2/af/rvu.h | 1 +
.../net/ethernet/marvell/octeontx2/af/rvu_cn10k.c | 9 +
.../net/ethernet/marvell/octeontx2/af/rvu_rep.c | 8 +
.../ethernet/marvell/octeontx2/nic/otx2_flows.c | 1 +
.../net/ethernet/marvell/octeontx2/nic/otx2_tc.c | 29 +-
drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 15 +
.../net/ethernet/mellanox/mlx5/core/en_ethtool.c | 19 +-
drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 4 +-
.../ethernet/mellanox/mlx5/core/esw/acl/helper.c | 2 +-
.../net/ethernet/mellanox/mlx5/core/mlx5_core.h | 4 +-
drivers/net/ethernet/mellanox/mlx5/core/port.c | 39 +-
drivers/net/ethernet/microsoft/mana/gdma_main.c | 78 +-
drivers/net/ethernet/microsoft/mana/mana_en.c | 13 +
.../ethernet/netronome/nfp/nfpcore/nfp_resource.c | 3 +
drivers/net/ethernet/realtek/rtase/rtase.h | 8 +
drivers/net/ethernet/realtek/rtase/rtase_main.c | 197 +++
drivers/net/ethernet/stmicro/stmmac/common.h | 3 -
drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c | 31 +
.../net/ethernet/stmicro/stmmac/dwmac-loongson.c | 5 +-
.../net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 162 ++-
drivers/net/ethernet/stmicro/stmmac/dwmac100.h | 9 +-
drivers/net/ethernet/stmicro/stmmac/dwmac1000.h | 16 +-
.../net/ethernet/stmicro/stmmac/dwmac1000_core.c | 49 +-
.../net/ethernet/stmicro/stmmac/dwmac1000_dma.c | 16 +-
.../net/ethernet/stmicro/stmmac/dwmac100_core.c | 2 +-
drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c | 3 +-
drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 49 +-
drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 53 +-
drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c | 44 +-
drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h | 16 +-
drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c | 2 +-
drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h | 10 +-
drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c | 10 +-
drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h | 34 +-
.../net/ethernet/stmicro/stmmac/dwxgmac2_core.c | 45 +-
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 75 +-
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 92 +-
drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c | 35 +
drivers/net/ethernet/wangxun/txgbe/txgbe_main.c | 1 +
drivers/net/geneve.c | 3 +
drivers/net/gtp.c | 17 +-
drivers/net/ipa/ipa_smp2p.c | 30 +-
drivers/net/mctp/mctp-i3c.c | 11 +-
drivers/net/mctp/mctp-serial.c | 2 +-
drivers/net/ovpn/io.c | 4 +-
drivers/net/ovpn/peer.c | 16 +-
drivers/net/ovpn/tcp.c | 6 +-
drivers/net/pcs/pcs-xpcs.c | 34 +-
drivers/net/phy/marvell.c | 2 +-
drivers/net/ppp/ppp_generic.c | 239 ++--
drivers/net/ppp/pppoe.c | 1 +
drivers/net/slip/slip.c | 4 +
drivers/net/vmxnet3/vmxnet3_drv.c | 22 +-
drivers/net/vxlan/vxlan_core.c | 3 +
drivers/net/vxlan/vxlan_mdb.c | 30 +-
drivers/net/wan/wanxl.c | 3 +-
drivers/net/wireless/ath/ath11k/ahb.c | 1 +
drivers/net/wireless/ath/ath11k/dp_rx.c | 3 +
drivers/net/wireless/ath/ath11k/pci.c | 4 +
drivers/net/wireless/ath/ath11k/qmi.c | 11 +-
drivers/net/wireless/ath/ath12k/pci.c | 4 +
drivers/net/wireless/ath/ath6kl/txrx.c | 12 +-
drivers/net/wireless/ath/ath6kl/wmi.c | 20 +
drivers/net/wireless/ath/ath9k/hif_usb.c | 7 +-
drivers/net/wireless/ath/carl9170/rx.c | 7 +-
drivers/net/wireless/ath/carl9170/tx.c | 2 +-
drivers/net/wireless/atmel/at76c50x-usb.c | 7 +-
.../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 1 +
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 2 +-
.../wireless/broadcom/brcm80211/brcmfmac/pcie.c | 8 +-
.../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 +-
drivers/net/wireless/intel/ipw2x00/ipw2100.c | 8 +-
drivers/net/wireless/intel/iwlwifi/fw/pnvm.c | 9 +-
drivers/net/wireless/intel/iwlwifi/fw/regulatory.c | 2 +-
drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 3 +-
drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 10 +
drivers/net/wireless/intersil/p54/txrx.c | 8 +
drivers/net/wireless/marvell/libertas/firmware.c | 1 +
drivers/net/wireless/marvell/mwifiex/sta_ioctl.c | 14 +-
drivers/net/wireless/marvell/mwifiex/tdls.c | 2 +-
drivers/net/wireless/marvell/mwifiex/uap_event.c | 24 +-
drivers/net/wireless/mediatek/mt76/mt7615/mac.c | 6 +
.../net/wireless/mediatek/mt76/mt76_connac_mcu.c | 2 +
drivers/net/wireless/mediatek/mt76/mt7915/mcu.c | 18 +-
drivers/net/wireless/mediatek/mt76/mt7921/mac.c | 10 +-
drivers/net/wireless/mediatek/mt76/mt7925/mac.c | 13 +-
drivers/net/wireless/mediatek/mt76/mt7925/main.c | 3 +
drivers/net/wireless/mediatek/mt76/mt7925/mcu.c | 2 +
drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 19 +-
drivers/net/wireless/microchip/wilc1000/hif.c | 5 +
drivers/net/wireless/virtual/mac80211_hwsim.c | 1 +
drivers/pinctrl/renesas/pinctrl-rzg2l.c | 8 +-
drivers/platform/loongarch/loongson-laptop.c | 1 +
.../uncore-frequency/uncore-frequency-common.c | 7 +-
drivers/pmdomain/imx/imx93-blk-ctrl.c | 126 +-
drivers/ptp/ptp_netc.c | 1 +
drivers/ptp/ptp_s390.c | 6 +-
drivers/regulator/mt6358-regulator.c | 2 +-
drivers/remoteproc/xlnx_r5_remoteproc.c | 50 +-
drivers/scsi/hosts.c | 2 +
drivers/scsi/scsi_error.c | 22 +-
drivers/scsi/scsi_priv.h | 1 +
drivers/staging/media/meson/vdec/vdec.c | 4 +-
drivers/staging/media/sunxi/cedrus/cedrus.c | 6 +-
drivers/staging/media/sunxi/cedrus/cedrus_h264.c | 3 +
drivers/staging/media/tegra-video/vi.c | 4 +-
drivers/staging/rtl8723bs/core/rtw_ieee80211.c | 9 +-
drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c | 2 +-
drivers/thunderbolt/debugfs.c | 2 +
drivers/thunderbolt/domain.c | 30 +
drivers/thunderbolt/icm.c | 5 +
drivers/thunderbolt/switch.c | 14 +
drivers/thunderbolt/tb.c | 59 +-
drivers/thunderbolt/tb.h | 2 +
drivers/thunderbolt/xdomain.c | 100 +-
drivers/tty/serial/8250/8250_mid.c | 14 +-
drivers/tty/serial/sc16is7xx.c | 12 +
drivers/uio/uio_hv_generic.c | 8 +-
drivers/usb/atm/ueagle-atm.c | 17 +
drivers/usb/chipidea/core.c | 1 +
drivers/usb/core/port.c | 2 +
drivers/usb/core/sysfs.c | 8 +-
drivers/usb/gadget/function/f_midi.c | 1 +
drivers/usb/gadget/function/f_ncm.c | 17 +-
drivers/usb/gadget/function/f_printer.c | 23 +-
drivers/usb/gadget/function/f_tcm.c | 192 ++-
drivers/usb/gadget/function/tcm.h | 13 +
drivers/usb/gadget/function/uvc_v4l2.c | 2 +
drivers/usb/gadget/udc/bdc/bdc_core.c | 20 +
drivers/usb/gadget/udc/bdc/bdc_udc.c | 7 +-
drivers/usb/gadget/udc/dummy_hcd.c | 40 +-
drivers/usb/gadget/udc/fsl_udc_core.c | 93 +-
drivers/usb/gadget/udc/fsl_usb2_udc.h | 1 +
drivers/usb/gadget/udc/snps_udc_core.c | 1 -
drivers/usb/host/xhci-pci.c | 1 +
drivers/usb/host/xhci.c | 15 +-
drivers/usb/host/xhci.h | 1 +
drivers/usb/musb/omap2430.c | 2 -
drivers/usb/serial/ftdi_sio.c | 2 +
drivers/usb/serial/ftdi_sio_ids.h | 5 +
drivers/usb/serial/io_edgeport.c | 3 +-
drivers/usb/serial/keyspan_pda.c | 44 +-
drivers/usb/serial/option.c | 1 +
drivers/usb/storage/unusual_devs.h | 7 +
drivers/usb/typec/ucsi/ucsi.c | 158 ++-
drivers/vdpa/vdpa_user/iova_domain.c | 29 +-
drivers/vdpa/vdpa_user/iova_domain.h | 8 +-
drivers/vdpa/vdpa_user/vduse_dev.c | 112 +-
drivers/vhost/net.c | 8 +-
drivers/video/Kconfig | 1 +
drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c | 2 +-
drivers/watchdog/airoha_wdt.c | 3 +
drivers/watchdog/s32g_wdt.c | 3 +-
drivers/watchdog/watchdog_pretimeout.c | 2 +
fs/afs/dir_edit.c | 2 +-
fs/binfmt_elf_fdpic.c | 4 +
fs/binfmt_misc.c | 5 +-
fs/btrfs/backref.c | 16 +-
fs/btrfs/block-group.c | 8 +-
fs/btrfs/ctree.c | 28 +-
fs/btrfs/ctree.h | 16 +-
fs/btrfs/defrag.c | 4 +-
fs/btrfs/dev-replace.c | 4 +-
fs/btrfs/extent-tree.c | 8 +-
fs/btrfs/extent_io.c | 4 +-
fs/btrfs/extent_map.c | 4 +-
fs/btrfs/file-item.c | 38 +-
fs/btrfs/free-space-cache.c | 7 +-
fs/btrfs/free-space-tree.c | 4 +-
fs/btrfs/inode-item.c | 2 +-
fs/btrfs/inode.c | 4 +-
fs/btrfs/qgroup.c | 4 +-
fs/btrfs/raid-stripe-tree.c | 4 +-
fs/btrfs/relocation.c | 10 +-
fs/btrfs/scrub.c | 20 +-
fs/btrfs/send.c | 14 +-
fs/btrfs/tree-log.c | 20 +-
fs/btrfs/volumes.c | 6 +-
fs/btrfs/xattr.c | 2 +-
fs/ceph/addr.c | 9 +
fs/ceph/caps.c | 1 +
fs/ceph/dir.c | 7 +-
fs/ceph/ioctl.c | 6 +
fs/crypto/inline_crypt.c | 57 +-
fs/crypto/keysetup_v1.c | 8 +-
fs/exec.c | 2 +-
fs/f2fs/super.c | 25 +-
fs/fuse/dev_uring.c | 22 +-
fs/fuse/file.c | 5 +-
fs/iomap/buffered-io.c | 34 +-
fs/nfsd/nfs4xdr.c | 8 +-
fs/nfsd/vfs.c | 15 +-
fs/nfsd/vfs.h | 2 +-
fs/overlayfs/copy_up.c | 12 +-
fs/overlayfs/file.c | 47 +-
fs/overlayfs/overlayfs.h | 5 +
fs/overlayfs/xattrs.c | 2 +-
fs/posix_acl.c | 7 +
fs/proc/namespaces.c | 4 +-
fs/proc/task_mmu.c | 14 +-
fs/resctrl/ctrlmondata.c | 6 +-
fs/resctrl/internal.h | 22 +-
fs/resctrl/monitor.c | 200 +--
fs/resctrl/rdtgroup.c | 75 +-
fs/smb/client/misc.c | 34 +-
fs/smb/client/smb2file.c | 21 +
fs/smb/client/smb2inode.c | 23 +-
fs/smb/client/smb2ops.c | 25 +-
fs/smb/server/oplock.c | 6 +-
fs/smb/server/smb2misc.c | 5 +
fs/smb/server/smb2pdu.c | 9 +-
fs/smb/server/smbacl.c | 42 +-
fs/super.c | 34 +-
fs/xfs/scrub/cow_repair.c | 203 +--
fs/xfs/scrub/trace.h | 28 +-
include/drm/drm_buddy.h | 165 +--
include/drm/drm_connector.h | 6 +-
include/drm/drm_utils.h | 1 +
include/linux/arm_ffa.h | 2 +-
include/linux/audit.h | 6 +-
include/linux/audit_arch.h | 12 +-
include/linux/bootconfig.h | 3 +
include/linux/cred.h | 15 +
include/linux/firmware/xlnx-zynqmp.h | 13 +
include/linux/fscrypt.h | 18 +-
include/linux/gpu_buddy.h | 177 +++
include/linux/mlx5/mlx5_ifc.h | 13 +-
include/linux/resctrl.h | 28 +-
include/linux/seqlock.h | 10 +-
include/linux/sunrpc/svcsock.h | 3 +
include/linux/sunrpc/xdr.h | 19 +-
include/linux/virtio.h | 6 +-
include/linux/vtime.h | 6 +
include/media/v4l2-async.h | 4 +-
include/media/videobuf2-core.h | 8 +-
include/net/bluetooth/rfcomm.h | 3 +
include/net/cfg80211.h | 2 +-
include/net/dropreason-core.h | 3 +
include/net/ip6_tunnel.h | 2 +-
include/net/netfilter/nf_tables.h | 32 -
include/net/netfilter/nft_fib.h | 2 -
include/net/netfilter/nft_meta.h | 3 -
include/net/sctp/structs.h | 3 +-
include/net/tcp.h | 2 +
include/rdma/ib_umem.h | 19 +
include/scsi/scsi_host.h | 3 +
include/uapi/linux/btrfs.h | 2 +-
init/Kconfig | 3 +
init/main.c | 45 -
io_uring/rw.c | 42 +-
kernel/audit.c | 2 +-
kernel/audit.h | 32 +-
kernel/audit_fsnotify.c | 36 +-
kernel/audit_tree.c | 2 +-
kernel/audit_watch.c | 35 +-
kernel/auditfilter.c | 17 +-
kernel/auditsc.c | 6 +-
kernel/bpf/verifier.c | 17 +
kernel/kexec_handover.c | 32 +-
kernel/sched/ext.c | 9 +-
kernel/trace/ftrace.c | 13 +
kernel/trace/trace.c | 2 +-
kernel/trace/trace_eprobe.c | 3 +-
kernel/trace/trace_events.c | 4 +-
kernel/trace/trace_mmiotrace.c | 4 +-
kernel/trace/trace_probe.c | 13 +-
lib/bootconfig.c | 65 +
lib/compat_audit.c | 12 +-
lib/rhashtable.c | 1 +
mm/damon/core.c | 13 +
mm/huge_memory.c | 12 +-
mm/kmemleak.c | 7 +-
mm/sparse.c | 32 +-
net/bluetooth/hci_sync.c | 55 +-
net/bluetooth/mgmt.c | 86 +-
net/bluetooth/rfcomm/core.c | 17 +
net/bluetooth/rfcomm/tty.c | 7 +-
net/bridge/br_netlink_tunnel.c | 3 +-
net/bridge/br_private.h | 6 +-
net/bridge/br_vlan.c | 10 +-
net/bridge/br_vlan_options.c | 3 +-
net/bridge/netfilter/nft_meta_bridge.c | 20 -
net/bridge/netfilter/nft_reject_bridge.c | 1 -
net/can/bcm.c | 528 ++++++--
net/can/j1939/transport.c | 18 +-
net/can/raw.c | 66 +-
net/ceph/auth_x.c | 9 +-
net/ceph/ceph_common.c | 4 +-
net/ceph/mon_client.c | 4 +-
net/ceph/osdmap.c | 12 +-
net/core/dev.c | 111 +-
net/core/filter.c | 6 +-
net/core/gro.c | 4 +-
net/core/sock.c | 10 +-
net/core/sock_map.c | 2 +
net/hsr/hsr_slave.c | 2 +
net/ipv4/datagram.c | 4 +-
net/ipv4/fib_trie.c | 2 +-
net/ipv4/icmp.c | 18 +-
net/ipv4/ip_gre.c | 4 +-
net/ipv4/ip_tunnel_core.c | 2 +-
net/ipv4/netfilter/nft_dup_ipv4.c | 1 -
net/ipv4/netfilter/nft_fib_ipv4.c | 2 -
net/ipv4/netfilter/nft_reject_ipv4.c | 1 -
net/ipv4/nexthop.c | 2 +-
net/ipv4/raw.c | 23 +-
net/ipv4/tcp_bpf.c | 2 +-
net/ipv4/tcp_input.c | 56 +-
net/ipv4/tcp_ipv4.c | 14 +-
net/ipv4/tcp_minisocks.c | 12 +-
net/ipv6/ila/ila_common.c | 12 +
net/ipv6/ip6_gre.c | 4 +-
net/ipv6/netfilter/nft_dup_ipv6.c | 1 -
net/ipv6/netfilter/nft_fib_ipv6.c | 2 -
net/ipv6/netfilter/nft_reject_ipv6.c | 1 -
net/ipv6/raw.c | 2 +-
net/ipv6/route.c | 4 +-
net/ipv6/tcp_ipv6.c | 8 +-
net/ipv6/xfrm6_policy.c | 1 +
net/iucv/af_iucv.c | 21 +-
net/mac80211/cfg.c | 11 +-
net/mac80211/iface.c | 8 +-
net/mac80211/link.c | 4 +
net/mac80211/mlme.c | 6 +-
net/mac80211/rx.c | 2 +
net/mac80211/sta_info.c | 15 +-
net/mac802154/llsec.c | 5 +
net/mac802154/scan.c | 11 +
net/mctp/device.c | 4 +-
net/mpls/af_mpls.c | 3 +
net/mptcp/options.c | 12 +-
net/mptcp/pm_userspace.c | 7 +-
net/mptcp/protocol.c | 1 +
net/netfilter/nf_conntrack_sip.c | 10 +-
net/netfilter/nf_tables_api.c | 315 +----
net/netfilter/nft_bitwise.c | 104 --
net/netfilter/nft_byteorder.c | 11 -
net/netfilter/nft_cmp.c | 3 -
net/netfilter/nft_compat.c | 10 -
net/netfilter/nft_connlimit.c | 1 -
net/netfilter/nft_counter.c | 21 +-
net/netfilter/nft_ct.c | 46 -
net/netfilter/nft_dup_netdev.c | 1 -
net/netfilter/nft_dynset.c | 1 -
net/netfilter/nft_exthdr.c | 34 -
net/netfilter/nft_fib.c | 51 +-
net/netfilter/nft_fib_inet.c | 1 -
net/netfilter/nft_fib_netdev.c | 30 +-
net/netfilter/nft_flow_offload.c | 1 -
net/netfilter/nft_fwd_netdev.c | 2 -
net/netfilter/nft_hash.c | 36 -
net/netfilter/nft_immediate.c | 12 -
net/netfilter/nft_last.c | 1 -
net/netfilter/nft_limit.c | 2 -
net/netfilter/nft_log.c | 1 -
net/netfilter/nft_lookup.c | 12 -
net/netfilter/nft_masq.c | 3 -
net/netfilter/nft_meta.c | 45 -
net/netfilter/nft_nat.c | 2 -
net/netfilter/nft_numgen.c | 22 -
net/netfilter/nft_objref.c | 2 -
net/netfilter/nft_osf.c | 25 -
net/netfilter/nft_payload.c | 47 -
net/netfilter/nft_queue.c | 2 -
net/netfilter/nft_quota.c | 14 +-
net/netfilter/nft_range.c | 1 -
net/netfilter/nft_redir.c | 3 -
net/netfilter/nft_reject_inet.c | 1 -
net/netfilter/nft_reject_netdev.c | 1 -
net/netfilter/nft_rt.c | 1 -
net/netfilter/nft_socket.c | 26 -
net/netfilter/nft_synproxy.c | 1 -
net/netfilter/nft_tproxy.c | 1 -
net/netfilter/nft_tunnel.c | 26 -
net/netfilter/nft_xfrm.c | 27 -
net/openvswitch/actions.c | 19 +-
net/openvswitch/datapath.c | 25 +-
net/openvswitch/datapath.h | 2 +-
net/openvswitch/vport.c | 2 +-
net/packet/af_packet.c | 6 +-
net/phonet/pep.c | 2 +
net/qrtr/af_qrtr.c | 8 +
net/qrtr/ns.c | 4 +-
net/rds/recv.c | 15 +
net/rds/tcp.c | 4 +-
net/rxrpc/ar-internal.h | 6 +-
net/sched/act_tunnel_key.c | 14 +-
net/sctp/auth.c | 2 +-
net/sctp/protocol.c | 21 +-
net/sctp/sm_make_chunk.c | 6 +
net/sctp/sm_statefuns.c | 2 +-
net/sctp/stream.c | 6 +-
net/sctp/sysctl.c | 9 +-
net/sunrpc/svcsock.c | 69 +-
net/sunrpc/xdr.c | 210 ++-
net/sunrpc/xprtrdma/rpc_rdma.c | 4 +
net/sunrpc/xprtrdma/verbs.c | 12 +-
net/tipc/netlink.c | 6 +-
net/tipc/netlink_compat.c | 4 +
net/tipc/socket.c | 1 +
net/tls/tls_device.c | 6 +-
net/vmw_vsock/virtio_transport_common.c | 165 ++-
net/wireless/core.c | 4 +-
net/wireless/core.h | 2 +-
net/wireless/nl80211.c | 22 +-
net/wireless/pmsr.c | 29 +-
net/wireless/scan.c | 13 +-
net/x25/af_x25.c | 8 +-
net/xfrm/xfrm_device.c | 12 +-
net/xfrm/xfrm_iptfs.c | 1 +
net/xfrm/xfrm_policy.c | 4 +-
net/xfrm/xfrm_state.c | 7 +-
net/xfrm/xfrm_user.c | 3 +-
rust/bindings/lib.rs | 4 +
rust/kernel/device.rs | 16 +-
rust/kernel/time.rs | 11 +-
rust/uapi/lib.rs | 4 +
security/landlock/domain.c | 8 +-
security/landlock/domain.h | 5 +-
security/landlock/ruleset.c | 7 +-
sound/core/seq/seq_timer.c | 13 +-
sound/core/timer.c | 21 +-
sound/hda/codecs/hdmi/hdmi.c | 3 +
sound/hda/codecs/hdmi/hdmi_local.h | 9 +
sound/hda/codecs/hdmi/intelhdmi.c | 36 +-
sound/hda/codecs/realtek/alc269.c | 9 +
sound/hda/codecs/side-codecs/cs35l41_hda.c | 11 +-
sound/soc/amd/ps/pci-ps.c | 33 +-
sound/soc/codecs/bt-sco.c | 10 +-
sound/soc/codecs/cs35l56-i2c.c | 4 +-
sound/soc/codecs/cs35l56-spi.c | 4 +-
sound/soc/codecs/cs35l56.c | 25 +-
sound/soc/codecs/cs42l43-jack.c | 3 +-
sound/soc/codecs/tas2562.c | 5 +-
sound/soc/codecs/tas2781-fmwlib.c | 63 +-
sound/soc/fsl/fsl_sai.c | 29 +-
sound/soc/fsl/imx-card.c | 12 +-
sound/soc/meson/aiu-fifo-spdif.c | 5 +
sound/soc/sunxi/sun4i-codec.c | 1 +
sound/usb/quirks.c | 2 +
tools/objtool/check.c | 1 +
tools/testing/cxl/Kbuild | 2 +-
tools/testing/selftests/alsa/mixer-test.c | 1 +
.../testing/selftests/bpf/progs/verifier_ld_ind.c | 142 +++
.../testing/selftests/bpf/progs/verifier_map_ptr.c | 36 +-
tools/testing/selftests/drivers/net/settings | 1 +
tools/testing/selftests/drivers/ntsync/config | 2 +-
tools/testing/selftests/ftrace/ftracetest | 1 +
tools/testing/selftests/net/af_unix/config | 1 +
tools/testing/selftests/net/openvswitch/config | 16 +
tools/testing/selftests/net/ovpn/config | 2 +
tools/testing/selftests/net/ovpn/ovpn-cli.c | 4 +-
tools/testing/selftests/net/ovpn/settings | 1 +
776 files changed, 10812 insertions(+), 6601 deletions(-)Greg Kroah-Hartman
maintainerPATCH 1/675 platform/x86/intel-uncore-freq: Fix current_freq_khz after CPU hotplug
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guixiong Wei <[email protected]>
commit 6b63520ed14b17bbe9c2103debbd2152dde1fba3 upstream.
When the last CPU of a legacy uncore die goes offline, uncore_freq_remove_die_entry() clears control_cpu. During CPU hotplug re-add, uncore_freq_add_entry() still populates sysfs attributes before assigning the new control CPU. As a result, the current frequency read returns -ENXIO and current_freq_khz is omitted from the recreated sysfs group.
Assign control_cpu before the initial read paths and before create_attr_group() so sysfs recreation uses the new online CPU. If sysfs creation fails, restore control_cpu to -1 to keep the error path state consistent.
--- .../x86/intel/uncore-frequency/uncore-frequency-common.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c +6 -1
@@ -274,15 +274,20 @@ int uncore_freq_add_entry(struct uncore_data *data, int cpu)sprintf (data->name,"package_%02d_die_%02d" , data->package_id, data->die_id); } +/* +* Set the control CPU before any read path so entry recreation after CPU +* hotplug can populate read-only attributes from the new online CPU. +*/ + data->control_cpu = cpu;uncore_read (data, &data->initial_min_freq_khz,UNCORE_INDEX_MIN_FREQ );uncore_read (data, &data->initial_max_freq_khz,UNCORE_INDEX_MAX_FREQ ); ret =create_attr_group (data, data->name);if (ret) { + data->control_cpu =-1 ;if (data->domain_id !=UNCORE_DOMAIN_ID_INVALID )ida_free (&intel_uncore_ida, data->instance_id); }else { - data->control_cpu = cpu; data->valid = true; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 2/675 bpf: Fix ld_{abs,ind} failure path analysis in subprogs
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Borkmann <[email protected]>
commit ee861486e377edc55361c08dcbceab3f6b6577bd upstream.
Usage of ld_{abs,ind} instructions got extended into subprogs some time ago via commit 09b28d76eac4 ("bpf: Add abnormal return checks."). These are only allowed in subprograms when the latter are BTF annotated and have scalar return types.
The code generator in bpf_gen_ld_abs() has an abnormal exit path (r0=0 + exit) from legacy cBPF times. While the enforcement is on scalar return types, the verifier must also simulate the path of abnormal exit if the packet data load via ld_{abs,ind} failed.
This is currently not the case. Fix it by having the verifier simulate both success and failure paths, and extend it in similar ways as we do for tail calls. The success path (r0=unknown, continue to next insn) is pushed onto stack for later validation and the r0=0 and return to the caller is done on the fall-through side.
[ Dropped visit_abnormal_return_insn changes: depends on 7.0 symbols from
e40f5a6bf88a ("bpf: correct stack liveness for tail calls");
Hunk1: adapted IS_ERR/PTR_ERR to !branch/-EFAULT to match push_stack() NULL-on-failure convention. ]
--- kernel/bpf/verifier.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
kernel/bpf/verifier.c +17 -0
@@ -17402,6 +17402,23 @@ static int check_ld_abs(struct bpf_verifier_env *env, struct bpf_insn *insn)mark_reg_unknown (env, regs,BPF_REG_0 );/* ld_abs load up to 32-bit skb data. */ regs[BPF_REG_0 ].subreg_def = env->insn_idx +1 ; +/* +* See bpf_gen_ld_abs() which emits a hidden BPF_EXIT with r0=0 +* which must be explored by the verifier when in a subprog. +*/ +if (env->cur_state->curframe) { +struct bpf_verifier_state *branch; + +mark_reg_scratched (env,BPF_REG_0 ); + branch =push_stack (env, env->insn_idx +1 , env->insn_idx, false); +if (!branch) +return -EFAULT ; +mark_reg_known_zero (env, regs,BPF_REG_0 ); + err =prepare_func_exit (env, &env->insn_idx); +if (err) +return err; + env->insn_idx--; + }return 0 ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 3/675 selftests/bpf: Add tests for ld_{abs,ind} failure path in subprogs
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Borkmann <[email protected]>
commit e0fcb42bc6f41bab2895757d6610616b3820eff7 upstream.
Extend the verifier_ld_ind BPF selftests with subprogs containing ld_{abs,ind} and craft the test in a way where the invalid register read is rejected in the fixed case. Also add a success case each, and add additional coverage related to the BTF return type enforcement.
# LDLIBS=-static PKG_CONFIG='pkg-config --static' ./vmtest.sh -- ./test_progs -t verifier_ld_ind [...]
#611/1 verifier_ld_ind/ld_ind: check calling conv, r1:OK #611/2 verifier_ld_ind/ld_ind: check calling conv, r1 @unpriv:OK #611/3 verifier_ld_ind/ld_ind: check calling conv, r2:OK #611/4 verifier_ld_ind/ld_ind: check calling conv, r2 @unpriv:OK #611/5 verifier_ld_ind/ld_ind: check calling conv, r3:OK #611/6 verifier_ld_ind/ld_ind: check calling conv, r3 @unpriv:OK #611/7 verifier_ld_ind/ld_ind: check calling conv, r4:OK #611/8 verifier_ld_ind/ld_ind: check calling conv, r4 @unpriv:OK #611/9 verifier_ld_ind/ld_ind: check calling conv, r5:OK #611/10 verifier_ld_ind/ld_ind: check calling conv, r5 @unpriv:OK #611/11 verifier_ld_ind/ld_ind: check calling conv, r7:OK #611/12 verifier_ld_ind/ld_ind: check calling conv, r7 @unpriv:OK #611/13 verifier_ld_ind/ld_abs: subprog early exit on ld_abs failure:OK #611/14 verifier_ld_ind/ld_ind: subprog early exit on ld_ind failure:OK #611/15 verifier_ld_ind/ld_abs: subprog with both paths safe:OK #611/16 verifier_ld_ind/ld_ind: subprog with both paths safe:OK #611/17 verifier_ld_ind/ld_abs: reject void return subprog:OK #611/18 verifier_ld_ind/ld_ind: reject void return subprog:OK #611 verifier_ld_ind:OK
Summary: 1/18 PASSED, 0 SKIPPED, 0 FAILED
--- .../selftests/bpf/progs/verifier_ld_ind.c | 142 ++++++++++++++++++ 1 file changed, 142 insertions(+)
tools/testing/selftests/bpf/progs/verifier_ld_ind.c +142 -0
@@ -107,4 +107,146 @@ __naked void ind_check_calling_conv_r7(void) : __clobber_all); } +/* +* ld_{abs,ind} subprog that always sets r0=1 on the success path. +* bpf_gen_ld_abs() emits a hidden exit with r0=0 when the load helper +* fails. The verifier must model this failure return so that callers +* account for r0=0 as a possible return value. +*/ +__naked __noinline __used +static int ldabs_subprog(void) +{ + asmvolatile ( +"r6 = r1;" +".8byte %[ld_abs];" +"r0 = 1;" +"exit;" + : + : __imm_insn(ld_abs, BPF_LD_ABS(BPF_W, 0)) + : __clobber_all); +} + +__naked __noinline __used +static int ldind_subprog(void) +{ + asmvolatile ( +"r6 = r1;" +"r7 = 0;" +".8byte %[ld_ind];" +"r0 = 1;" +"exit;" + : + : __imm_insn(ld_ind, BPF_LD_IND(BPF_W, BPF_REG_7, 0)) + : __clobber_all); +} + +SEC("socket") +__description("ld_abs: subprog early exit on ld_abs failure") +__failure __msg("R9 !read_ok") +__naked void ld_abs_subprog_early_exit(void) +{ + asmvolatile ( +"call ldabs_subprog;" +"if r0 != 0 goto l_exit_%=;" +"r0 = r9;" +"l_exit_%=:" +"r0 = 0;" +"exit;" + ::: __clobber_all); +} + +SEC("socket") +__description("ld_ind: subprog early exit on ld_ind failure") +__failure __msg("R9 !read_ok") +__naked void ld_ind_subprog_early_exit(void) +{ + asmvolatile ( +"call ldind_subprog;" +"if r0 != 0 goto l_exit_%=;" +"r0 = r9;" +"l_exit_%=:" +"r0 = 0;" +"exit;" + ::: __clobber_all); +} + +SEC("socket") +__description("ld_abs: subprog with both paths safe") +__success +__naked void ld_abs_subprog_both_paths_safe (void ) +{ + asmvolatile ( +"call ldabs_subprog;" +"r0 = 0;" +"exit;" + ::: __clobber_all); +} + +SEC("socket") +__description("ld_ind: subprog with both paths safe") +__success +__naked void ld_ind_subprog_both_paths_safe (void ) +{ + asmvolatile ( +"call ldind_subprog;" +"r0 = 0;" +"exit;" + ::: __clobber_all); +} + +/* +* ld_{abs,ind} in subprogs require scalar (int) return type in BTF. +* A test with void return must be rejected. +*/ +__naked __noinline __used +static void ldabs_void_subprog(void) +{ + asmvolatile ( +"r6 = r1;" +".8byte %[ld_abs];" +"r0 = 1;" +"exit;" + : + : __imm_insn(ld_abs, BPF_LD_ABS(BPF_W, 0)) + : __clobber_all); +} + +SEC("socket") +__description("ld_abs: reject void return subprog") +__failure __msg("LD_ABS is only allowed in functions that return 'int'") +__naked void ld_abs_void_subprog_reject(void) +{ + asmvolatile ( +"call ldabs_void_subprog;" +"r0 = 0;" +"exit;" + ::: __clobber_all); +} + +__naked __noinline __used +static void ldind_void_subprog(void) +{ + asmvolatile ( +"r6 = r1;" +"r7 = 0;" +".8byte %[ld_ind];" +"r0 = 1;" +"exit;" + : + : __imm_insn(ld_ind, BPF_LD_IND(BPF_W, BPF_REG_7, 0)) + : __clobber_all); +} + +SEC("socket") +__description("ld_ind: reject void return subprog") +__failure __msg("LD_ABS is only allowed in functions that return 'int'") +__naked void ld_ind_void_subprog_reject(void) +{ + asmvolatile ( +"call ldind_void_subprog;" +"r0 = 0;" +"exit;" + ::: __clobber_all); +} + char _license[] SEC("license") = "GPL";
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 4/675 netfilter: nft_counter: serialize reset with spinlock
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Brian Witte <[email protected]>
[ Upstream commit 779c60a5190c42689534172f4b49e927c9959e4e ]
Add a global static spinlock to serialize counter fetch+reset operations, preventing concurrent dump-and-reset from underrunning values.
The lock is taken before fetching the total so that two parallel resets cannot both read the same counter values and then both subtract them.
A global lock is used for simplicity since resets are infrequent. If this becomes a bottleneck, it can be replaced with a per-net lock later.
--- net/netfilter/nft_counter.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-)
net/netfilter/nft_counter.c +16 -4
@@ -32,6 +32,9 @@ struct nft_counter_percpu_priv { static DEFINE_PER_CPU(struct u64_stats_sync, nft_counter_sync); +/* control plane only: sync fetch+reset */ +static DEFINE_SPINLOCK (nft_counter_lock); +static inline void nft_counter_do_eval (struct nft_counter_percpu_priv *priv,struct nft_regs *regs,const struct nft_pktinfo *pkt)
@@ -148,13 +151,25 @@ static void nft_counter_fetch(struct nft_counter_percpu_priv *priv, } } +static void nft_counter_fetch_and_reset (struct nft_counter_percpu_priv *priv, +struct nft_counter_tot *total) +{ +spin_lock (&nft_counter_lock); +nft_counter_fetch (priv, total); +nft_counter_reset (priv, total); +spin_unlock (&nft_counter_lock); +} +static int nft_counter_do_dump (struct sk_buff *skb,struct nft_counter_percpu_priv *priv,bool reset) {struct nft_counter_tot total; -nft_counter_fetch (priv, &total); +if (unlikely (reset)) +nft_counter_fetch_and_reset (priv, &total); +else +nft_counter_fetch (priv, &total); if (nla_put_be64(skb, NFTA_COUNTER_BYTES, cpu_to_be64(total.bytes), NFTA_COUNTER_PAD) ||
@@ -162,9 +177,6 @@ static int nft_counter_do_dump(struct sk_buff *skb, NFTA_COUNTER_PAD)) goto nla_put_failure; -if (reset) -nft_counter_reset (priv, &total); -return 0 ; nla_put_failure:
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 5/675 netfilter: nft_quota: use atomic64_xchg for reset
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Brian Witte <[email protected]>
[ Upstream commit 30c4d7fb59ac4c8d7fa7937df11eed10b368fa11 ]
Use atomic64_xchg() to atomically read and zero the consumed value on reset, which is simpler than the previous read+sub pattern and doesn't require lock serialization.
--- net/netfilter/nft_quota.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
net/netfilter/nft_quota.c +7 -6
@@ -140,11 +140,16 @@ static int nft_quota_do_dump(struct sk_buff *skb, struct nft_quota *priv,u64 consumed, consumed_cap, quota;u32 flags = priv->flags; -/* Since we inconditionally increment consumed quota for each packet +/* Since we unconditionally increment consumed quota for each packet * that we see, don't go over the quota boundary in what we send to * userspace. */ - consumed =atomic64_read (priv->consumed); +if (reset) { + consumed =atomic64_xchg (priv->consumed,0 ); +clear_bit (NFT_QUOTA_DEPLETED_BIT , &priv->flags); + }else { + consumed =atomic64_read (priv->consumed); + } quota =atomic64_read (&priv->quota);if (consumed >= quota) { consumed_cap = quota;
@@ -160,10 +165,6 @@ static int nft_quota_do_dump(struct sk_buff *skb, struct nft_quota *priv, nla_put_be32(skb, NFTA_QUOTA_FLAGS, htonl(flags))) goto nla_put_failure; -if (reset) { -atomic64_sub (consumed, priv->consumed); -clear_bit (NFT_QUOTA_DEPLETED_BIT , &priv->flags); - }return 0 ; nla_put_failure:
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 6/675 netfilter: nf_tables: revert commit_mutex usage in reset path
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Brian Witte <[email protected]>
[ Upstream commit 7f261bb906bf527c4a6e2a646e2d5f3679f2a8bc ]
It causes circular lock dependency between commit_mutex, nfnl_subsys_ipset and nlk_cb_mutex when nft reset, ipset list, and iptables-nft with '-m set' rule run at the same time.
Previous patches made it safe to run individual reset handlers concurrently so commit_mutex is no longer required to prevent this.
--- net/netfilter/nf_tables_api.c | 248 ++++++---------------------------- 1 file changed, 42 insertions(+), 206 deletions(-)
net/netfilter/nf_tables_api.c +42 -206
@@ -3908,23 +3908,6 @@ static int nf_tables_dump_rules(struct sk_buff *skb,return skb->len; } -static int nf_tables_dumpreset_rules (struct sk_buff *skb, -struct netlink_callback *cb) -{ -struct nftables_pernet *nft_net =nft_pernet (sock_net (skb->sk)); -int ret; - -/* Mutex is held is to prevent that two concurrent dump-and-reset calls -* do not underrun counters and quotas. The commit_mutex is used for -* the lack a better lock, this is not transaction path. -*/ -mutex_lock (&nft_net->commit_mutex); - ret =nf_tables_dump_rules (skb, cb); -mutex_unlock (&nft_net->commit_mutex); - -return ret; -} -static int nf_tables_dump_rules_start (struct netlink_callback *cb) {struct nft_rule_dump_ctx *ctx = (void *)cb->ctx;
@@ -3944,16 +3927,10 @@ static int nf_tables_dump_rules_start(struct netlink_callback *cb)return -ENOMEM ; } } -return 0 ; -} - -static int nf_tables_dumpreset_rules_start (struct netlink_callback *cb) -{ -struct nft_rule_dump_ctx *ctx = (void *)cb->ctx; - - ctx->reset = true; +if (NFNL_MSG_TYPE (cb->nlh->nlmsg_type) ==NFT_MSG_GETRULE_RESET ) + ctx->reset = true; -return nf_tables_dump_rules_start (cb); +return 0 ; }static int nf_tables_dump_rules_done (struct netlink_callback *cb)
@@ -4019,6 +3996,8 @@ static int nf_tables_getrule(struct sk_buff *skb, const struct nfnl_info *info,u32 portid =NETLINK_CB (skb).portid;struct net *net = info->net;struct sk_buff *skb2; +bool reset = false; +char *buf;if (info->nlh->nlmsg_flags &NLM_F_DUMP ) {struct netlink_dump_control c = {
@@ -4032,47 +4011,16 @@ static int nf_tables_getrule(struct sk_buff *skb, const struct nfnl_info *info,return nft_netlink_dump_start_rcu (info->sk, skb, info->nlh, &c); } - skb2 =nf_tables_getrule_single (portid, info, nla, false); -if (IS_ERR (skb2)) -return PTR_ERR (skb2); - -return nfnetlink_unicast (skb2, net, portid); -} - -static int nf_tables_getrule_reset (struct sk_buff *skb, -const struct nfnl_info *info, -const struct nlattr *const nla[]) -{ -struct nftables_pernet *nft_net =nft_pernet (info->net); -u32 portid =NETLINK_CB (skb).portid; -struct net *net = info->net; -struct sk_buff *skb2; -char *buf; - -if (info->nlh->nlmsg_flags &NLM_F_DUMP ) { -struct netlink_dump_control c = { - .start= nf_tables_dumpreset_rules_start, - .dump = nf_tables_dumpreset_rules, - .done = nf_tables_dump_rules_done, - .module =THIS_MODULE , - .data = (void *)nla, - }; - -return nft_netlink_dump_start_rcu (info->sk, skb, info->nlh, &c); - } - -if (!try_module_get (THIS_MODULE )) -return -EINVAL ; -rcu_read_unlock (); -mutex_lock (&nft_net->commit_mutex); - skb2 =nf_tables_getrule_single (portid, info, nla, true); -mutex_unlock (&nft_net->commit_mutex); -rcu_read_lock (); -module_put (THIS_MODULE ); +if (NFNL_MSG_TYPE (info->nlh->nlmsg_type) ==NFT_MSG_GETRULE_RESET ) + reset = true; + skb2 =nf_tables_getrule_single (portid, info, nla, reset);if (IS_ERR (skb2))return PTR_ERR (skb2); +if (!reset) +return nfnetlink_unicast (skb2, net, portid); + buf = kasprintf(GFP_ATOMIC, "%.*s:%u", nla_len(nla[NFTA_RULE_TABLE]), (char *)nla_data(nla[NFTA_RULE_TABLE]),
@@ -6332,6 +6280,10 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)nla_nest_end (skb, nest);nlmsg_end (skb, nlh); +if (dump_ctx->reset && args.iter.count > args.iter.skip) +audit_log_nft_set_reset (table, cb->seq, + args.iter.count - args.iter.skip); +rcu_read_unlock ();if (args.iter.err && args.iter.err != -EMSGSIZE )
@@ -6347,26 +6299,6 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)return -ENOSPC ; } -static int nf_tables_dumpreset_set (struct sk_buff *skb, -struct netlink_callback *cb) -{ -struct nftables_pernet *nft_net =nft_pernet (sock_net (skb->sk)); -struct nft_set_dump_ctx *dump_ctx = cb->data; -int ret, skip = cb->args[0 ]; - -mutex_lock (&nft_net->commit_mutex); - - ret =nf_tables_dump_set (skb, cb); - -if (cb->args[0 ] > skip) -audit_log_nft_set_reset (dump_ctx->ctx.table, cb->seq, - cb->args[0 ] - skip); - -mutex_unlock (&nft_net->commit_mutex); - -return ret; -} -static int nf_tables_dump_set_start (struct netlink_callback *cb) {struct nft_set_dump_ctx *dump_ctx = cb->data;
@@ -6613,8 +6545,13 @@ static int nf_tables_getsetelem(struct sk_buff *skb, {struct netlink_ext_ack *extack = info->extack;struct nft_set_dump_ctx dump_ctx; +int rem, err =0 , nelems =0 ; +struct net *net = info->net;struct nlattr *attr; -int rem, err =0 ; +bool reset = false; + +if (NFNL_MSG_TYPE (info->nlh->nlmsg_type) ==NFT_MSG_GETSETELEM_RESET ) + reset = true;if (info->nlh->nlmsg_flags &NLM_F_DUMP ) { struct netlink_dump_control c = {
@@ -6624,7 +6561,7 @@ static int nf_tables_getsetelem(struct sk_buff *skb, .module = THIS_MODULE, }; - err =nft_set_dump_ctx_init (&dump_ctx, skb, info, nla, false); + err =nft_set_dump_ctx_init (&dump_ctx, skb, info, nla, reset);if (err)return err;
@@ -6635,75 +6572,21 @@ static int nf_tables_getsetelem(struct sk_buff *skb,if (!nla[NFTA_SET_ELEM_LIST_ELEMENTS ])return -EINVAL ; - err =nft_set_dump_ctx_init (&dump_ctx, skb, info, nla, false); + err =nft_set_dump_ctx_init (&dump_ctx, skb, info, nla, reset);if (err)return err;nla_for_each_nested (attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS ], rem) { - err =nft_get_set_elem (&dump_ctx.ctx, dump_ctx.set, attr, false); -if (err <0 ) { -NL_SET_BAD_ATTR (extack, attr); -break ; - } - } - -return err; -} - -static int nf_tables_getsetelem_reset (struct sk_buff *skb, -const struct nfnl_info *info, -const struct nlattr *const nla[]) -{ -struct nftables_pernet *nft_net =nft_pernet (info->net); -struct netlink_ext_ack *extack = info->extack; -struct nft_set_dump_ctx dump_ctx; -int rem, err =0 , nelems =0 ; -struct nlattr *attr; - -if (info->nlh->nlmsg_flags &NLM_F_DUMP ) { -struct netlink_dump_control c = { - .start = nf_tables_dump_set_start, - .dump = nf_tables_dumpreset_set, - .done = nf_tables_dump_set_done, - .module =THIS_MODULE , - }; - - err =nft_set_dump_ctx_init (&dump_ctx, skb, info, nla, true); -if (err) -return err; - - c.data = &dump_ctx; -return nft_netlink_dump_start_rcu (info->sk, skb, info->nlh, &c); - } - -if (!nla[NFTA_SET_ELEM_LIST_ELEMENTS ]) -return -EINVAL ; - -if (!try_module_get (THIS_MODULE )) -return -EINVAL ; -rcu_read_unlock (); -mutex_lock (&nft_net->commit_mutex); -rcu_read_lock (); - - err =nft_set_dump_ctx_init (&dump_ctx, skb, info, nla, true); -if (err) - goto out_unlock; - -nla_for_each_nested (attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS ], rem) { - err =nft_get_set_elem (&dump_ctx.ctx, dump_ctx.set, attr, true); + err =nft_get_set_elem (&dump_ctx.ctx, dump_ctx.set, attr, reset);if (err <0 ) {NL_SET_BAD_ATTR (extack, attr);break ; } nelems++; } -audit_log_nft_set_reset (dump_ctx.ctx.table,nft_base_seq (info->net), nelems); - -out_unlock: -rcu_read_unlock (); -mutex_unlock (&nft_net->commit_mutex); -rcu_read_lock (); -module_put (THIS_MODULE ); +if (reset) +audit_log_nft_set_reset (dump_ctx.ctx.table,nft_base_seq (net), + nelems);return err; }
@@ -8567,19 +8450,6 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb)return skb->len; } -static int nf_tables_dumpreset_obj (struct sk_buff *skb, -struct netlink_callback *cb) -{ -struct nftables_pernet *nft_net =nft_pernet (sock_net (skb->sk)); -int ret; - -mutex_lock (&nft_net->commit_mutex); - ret =nf_tables_dump_obj (skb, cb); -mutex_unlock (&nft_net->commit_mutex); - -return ret; -} -static int nf_tables_dump_obj_start (struct netlink_callback *cb) {struct nft_obj_dump_ctx *ctx = (void *)cb->ctx;
@@ -8596,16 +8466,10 @@ static int nf_tables_dump_obj_start(struct netlink_callback *cb)if (nla[NFTA_OBJ_TYPE ]) ctx->type =ntohl (nla_get_be32 (nla[NFTA_OBJ_TYPE ])); -return 0 ; -} - -static int nf_tables_dumpreset_obj_start (struct netlink_callback *cb) -{ -struct nft_obj_dump_ctx *ctx = (void *)cb->ctx; - - ctx->reset = true; +if (NFNL_MSG_TYPE (cb->nlh->nlmsg_type) ==NFT_MSG_GETOBJ_RESET ) + ctx->reset = true; -return nf_tables_dump_obj_start (cb); +return 0 ; }static int nf_tables_dump_obj_done (struct netlink_callback *cb)
@@ -8667,42 +8531,16 @@ nf_tables_getobj_single(u32 portid, const struct nfnl_info *info,static int nf_tables_getobj (struct sk_buff *skb,const struct nfnl_info *info,const struct nlattr *const nla[]) { -u32 portid =NETLINK_CB (skb).portid; -struct sk_buff *skb2; - -if (info->nlh->nlmsg_flags &NLM_F_DUMP ) { -struct netlink_dump_control c = { - .start = nf_tables_dump_obj_start, - .dump = nf_tables_dump_obj, - .done = nf_tables_dump_obj_done, - .module =THIS_MODULE , - .data = (void *)nla, - }; - -return nft_netlink_dump_start_rcu (info->sk, skb, info->nlh, &c); - } - - skb2 =nf_tables_getobj_single (portid, info, nla, false); -if (IS_ERR (skb2)) -return PTR_ERR (skb2); - -return nfnetlink_unicast (skb2, info->net, portid); -} - -static int nf_tables_getobj_reset (struct sk_buff *skb, -const struct nfnl_info *info, -const struct nlattr *const nla[]) -{ -struct nftables_pernet *nft_net =nft_pernet (info->net);u32 portid =NETLINK_CB (skb).portid;struct net *net = info->net;struct sk_buff *skb2; +bool reset = false;char *buf;if (info->nlh->nlmsg_flags &NLM_F_DUMP ) {struct netlink_dump_control c = { - .start = nf_tables_dumpreset_obj_start, - .dump = nf_tables_dumpreset_obj, + .start = nf_tables_dump_obj_start, + .dump = nf_tables_dump_obj, .done = nf_tables_dump_obj_done, .module =THIS_MODULE , .data = (void *)nla,
@@ -8711,18 +8549,16 @@ static int nf_tables_getobj_reset(struct sk_buff *skb,return nft_netlink_dump_start_rcu (info->sk, skb, info->nlh, &c); } -if (!try_module_get (THIS_MODULE )) -return -EINVAL ; -rcu_read_unlock (); -mutex_lock (&nft_net->commit_mutex); - skb2 =nf_tables_getobj_single (portid, info, nla, true); -mutex_unlock (&nft_net->commit_mutex); -rcu_read_lock (); -module_put (THIS_MODULE ); +if (NFNL_MSG_TYPE (info->nlh->nlmsg_type) ==NFT_MSG_GETOBJ_RESET ) + reset = true; + skb2 =nf_tables_getobj_single (portid, info, nla, reset);if (IS_ERR (skb2))return PTR_ERR (skb2); +if (!reset) +return nfnetlink_unicast (skb2, net,NETLINK_CB (skb).portid); + buf = kasprintf(GFP_ATOMIC, "%.*s:%u", nla_len(nla[NFTA_OBJ_TABLE]), (char *)nla_data(nla[NFTA_OBJ_TABLE]),
@@ -10030,7 +9866,7 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = { .policy = nft_rule_policy, }, [NFT_MSG_GETRULE_RESET] = { - .call = nf_tables_getrule_reset, + .call = nf_tables_getrule, .type = NFNL_CB_RCU, .attr_count = NFTA_RULE_MAX, .policy = nft_rule_policy,
@@ -10084,7 +9920,7 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = { .policy = nft_set_elem_list_policy, }, [NFT_MSG_GETSETELEM_RESET] = { - .call = nf_tables_getsetelem_reset, + .call = nf_tables_getsetelem, .type = NFNL_CB_RCU, .attr_count = NFTA_SET_ELEM_LIST_MAX, .policy = nft_set_elem_list_policy,
@@ -10130,7 +9966,7 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = { .policy = nft_obj_policy, }, [NFT_MSG_GETOBJ_RESET] = { - .call = nf_tables_getobj_reset, + .call = nf_tables_getobj, .type = NFNL_CB_RCU, .attr_count = NFTA_OBJ_MAX, .policy = nft_obj_policy,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 7/675 drm/virtio: fix deadlock in display_info_cb by removing hotplug from dequeue worker
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ryosuke Yasuoka <[email protected]>
[ Upstream commit d1b894c5bbb3fee0012bd14356286dc2384e8213 ]
A probe-time deadlock can occur between the dequeue worker and drm_client_register(). During probe, drm_client_register() holds clientlist_mutex and calls the fbdev hotplug callback, which triggers an atomic commit that ends up sleeping in virtio_gpu_queue_ctrl_sgs() waiting for virtqueue space. The dequeue worker that would free that space calls virtio_gpu_cmd_get_display_info_cb(), which invokes drm_kms_helper_hotplug_event() -> drm_client_dev_hotplug(), attempting to acquire the same clientlist_mutex. Since wake_up() is only called after the resp_cb loop, the probe thread is never woken and both threads deadlock.
Fix this by removing the hotplug notification from virtio_gpu_cmd_get_display_info_cb(). The display data (outputs[i].info) is still updated synchronously in the callback.
For the init path, drm_client_register() already fires an initial hotplug when the client is registered, which picks up the connector state updated by display_info_cb.
For the runtime config_changed path, add a wait_event_timeout() in config_changed_work_func() so that display_info_cb updates the connector data before the hotplug notification is sent. Also replace drm_helper_hpd_irq_event() with drm_kms_helper_hotplug_event() since virtio-gpu never calls drm_kms_helper_poll_init() and thus drm_helper_hpd_irq_event() always returns false without doing anything.
--- drivers/gpu/drm/virtio/virtgpu_kms.c | 5 ++++- drivers/gpu/drm/virtio/virtgpu_vq.c | 3 --- 2 files changed, 4 insertions(+), 4 deletions(-)
drivers/gpu/drm/virtio/virtgpu_kms.c +4 -1
@@ -48,7 +48,10 @@ static void virtio_gpu_config_changed_work_func(struct work_struct *work)virtio_gpu_cmd_get_edids (vgdev);virtio_gpu_cmd_get_display_info (vgdev);virtio_gpu_notify (vgdev); -drm_helper_hpd_irq_event (vgdev->ddev); +wait_event_timeout (vgdev->resp_wq, + !vgdev->display_info_pending, +5 *HZ ); +drm_kms_helper_hotplug_event (vgdev->ddev); } events_clear |=VIRTIO_GPU_EVENT_DISPLAY ; }
drivers/gpu/drm/virtio/virtgpu_vq.c +0 -3
@@ -839,9 +839,6 @@ static void virtio_gpu_cmd_get_display_info_cb(struct virtio_gpu_device *vgdev, vgdev->display_info_pending = false;spin_unlock (&vgdev->display_info_lock);wake_up (&vgdev->resp_wq); - -if (!drm_helper_hpd_irq_event (vgdev->ddev)) -drm_kms_helper_hotplug_event (vgdev->ddev); } static void virtio_gpu_cmd_get_capset_info_cb(struct virtio_gpu_device *vgdev,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 8/675 fs/proc/task_mmu: fix make_uffd_wp_huge_pte() prot-update race
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kiryl Shutsemau <[email protected]>
commit 04718f7c9290f95385f0dd328758753dc1c36dec upstream.
Patch series "userfaultfd/pagemap: pre-existing fixes".
These are pre-existing bug fixes that were carried at the front of the userfaultfd RWP working-set-tracking series up to v5 [1]. Per review feedback that fixes should not sit in the middle of a feature series, they are split out and sent on their own; the RWP series is reposted rebased on top of this.
All six were flagged by the Sashiko AI review of the RWP series and carry
independent of RWP, apply to mm-new directly, and carry Cc: stable@.
1: fs/proc/task_mmu: a missing huge_ptep_modify_prot_start() in
make_uffd_wp_huge_pte() can lose hardware Dirty/Accessed updates when PAGEMAP_SCAN write-protects a hugetlb PTE.
2: fs/proc/task_mmu: pagemap_scan_hugetlb_entry() compares the range
against HPAGE_SIZE rather than the hstate page size, so it never write-protects gigantic hugetlb pages.
3: fs/proc/task_mmu: PAGEMAP_SCAN with PM_SCAN_WP_MATCHING over an
unpopulated hugetlb range self-deadlocks -- pagemap_scan_pte_hole() calls uffd_wp_range() while walk_hugetlb_range() holds the hugetlb vma lock for read, and hugetlb_change_protection() then takes it for write. Install the marker inline instead.
4: mm/huge_memory: change_non_present_huge_pmd() drops pmd_swp_uffd_wp
on a device-private PMD permission downgrade, silently losing the uffd-wp marker.
5: userfaultfd: must_wait() applies pte_write() to a locklessly read
PTE without checking pte_present(), so swap/migration entries decode random offset bits and a thread can stay parked on a stale fault.
6: userfaultfd: __VMA_UFFD_FLAGS feeds VMA_UFFD_MINOR_BIT (41) to
mk_vma_flags() unconditionally, an out-of-bounds write into the single-word vma_flags_t on 32-bit. Build the mask from config-gated per-mode masks so an unavailable bit is never materialised.
This patch (of 6):
make_uffd_wp_huge_pte() arms the UFFD_WP bit on a present HugeTLB PTE by calling huge_ptep_modify_prot_commit() with a ptent snapshot that was fetched without the corresponding huge_ptep_modify_prot_start(). The start helper is what atomically clears the entry so the kernel-owned snapshot stays consistent until the commit; without it, the hardware may set Dirty or Accessed in the live PTE between the original read and the commit, and huge_ptep_modify_prot_commit() (whose generic implementation just calls set_huge_pte_at()) then writes the stale snapshot back over the live hardware bits, losing the update.
The non-hugetlb sibling make_uffd_wp_pte() does this correctly via ptep_modify_prot_start() / ptep_modify_prot_commit(). Mirror that pattern for the present-PTE branch. The migration case stays as-is -- migration entries are non-present, so there's no hardware update to race against.
[ kas: adapt to the pre-softleaf idiom; apply the
huge_ptep_modify_prot_start()/commit() fix to the present-PTE (!huge_pte_none()) branch ]
--- fs/proc/task_mmu.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
fs/proc/task_mmu.c +9 -5
@@ -2485,15 +2485,19 @@ static void make_uffd_wp_huge_pte(struct vm_area_struct *vma, psize =huge_page_size (hstate_vma (vma)); -if (is_hugetlb_entry_migration (ptent)) +if (is_hugetlb_entry_migration (ptent)) {set_huge_pte_at (vma->vm_mm, addr, ptep,pte_swp_mkuffd_wp (ptent), psize); -else if (!huge_pte_none (ptent)) -huge_ptep_modify_prot_commit (vma, addr, ptep, ptent, -huge_pte_mkuffd_wp (ptent)); -else + }else if (!huge_pte_none (ptent)) { +pte_t old_pte, new_pte; + + old_pte =huge_ptep_modify_prot_start (vma, addr, ptep); + new_pte =huge_pte_mkuffd_wp (old_pte); +huge_ptep_modify_prot_commit (vma, addr, ptep, old_pte, new_pte); + }else {set_huge_pte_at (vma->vm_mm, addr, ptep,make_pte_marker (PTE_MARKER_UFFD_WP ), psize); + } }#endif /* CONFIG_HUGETLB_PAGE */
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 9/675 seqlock: Cure some more scoped_seqlock() optimization fails
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Zijlstra <[email protected]>
commit 90dfeef1cd38dff19f8b3a752d13bfd79f0f7694 upstream.
Arnd reported an x86 randconfig using gcc-15 tripped over __scoped_seqlock_bug(). Turns out GCC chose not to inline the scoped_seqlock helper functions and as such was not able to optimize properly.
[ mingo: Clang fails the build too in some circumstances. ]
--- include/linux/seqlock.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
include/linux/seqlock.h +2 -2
@@ -1224,7 +1224,7 @@ struct ss_tmp {spinlock_t *lock_irqsave; }; -static inline void __scoped_seqlock_cleanup (struct ss_tmp *sst) +static __always_inline void __scoped_seqlock_cleanup(struct ss_tmp *sst) {if (sst->lock)spin_unlock (sst->lock);
@@ -1249,7 +1249,7 @@ static inline void __scoped_seqlock_bug(extern void __scoped_seqlock_bug (void );#endif -static inline void +static __always_inline void__scoped_seqlock_next (struct ss_tmp *sst,seqlock_t *lock,enum ss_state target) {switch (sst->state) {
Greg Kroah-Hartman
maintainerPATCH 10/675 seqlock: Allow KASAN to fail optimizing
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Zijlstra <[email protected]>
commit b94d45b6bbb42571ec225d3be0e7457c8765a5b4 upstream.
Some KASAN builds are failing to properly optimize this code -- luckily we don't care about core quality for KASAN builds, so just exclude it.
--- include/linux/seqlock.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
include/linux/seqlock.h +4 -1
@@ -1234,11 +1234,14 @@ static __always_inline void __scoped_seqextern void __scoped_seqlock_invalid_target (void ); -#if defined(CONFIG_CC_IS_GCC ) &&CONFIG_GCC_VERSION <90000 +#if (defined(CONFIG_CC_IS_GCC ) &&CONFIG_GCC_VERSION <90000 ) || defined(CONFIG_KASAN )/* * For some reason some GCC-8 architectures (nios2, alpha) have trouble * determining that the ss_done state is impossible in __scoped_seqlock_next() * below. +* +* Similarly KASAN is known to confuse compilers enough to break this. But we +* don't care about code quality for KASAN builds anyway. */ static inline void __scoped_seqlock_bug (void ) { }#else
Greg Kroah-Hartman
maintainerPATCH 11/675 seqlock: Allow UBSAN_ALIGNMENT to fail optimizing
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heiko Carstens <[email protected]>
commit 88331c4ec23a28c1006ec532fa64763d4c695e90 upstream.
With gcc-15 and gcc-16 with UBSAN_ALIGNMENT enabled the compiler fails to inline and optimize __scoped_seqlock_bug() away on s390:
s390x-16.1.0-ld: kernel/sched/build_policy.o: in function `__scoped_seqlock_next':
/.../seqlock.h:1286:(.text+0x22030): undefined reference to `__scoped_seqlock_bug'
Fix this by adding UBSAN_ALIGNMENT to the list of config options where a not inlined empty __scoped_seqlock_bug() is allowed.
--- include/linux/seqlock.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
include/linux/seqlock.h +4 -3
@@ -1234,14 +1234,15 @@ static __always_inline void __scoped_seqextern void __scoped_seqlock_invalid_target (void ); -#if (defined(CONFIG_CC_IS_GCC ) &&CONFIG_GCC_VERSION <90000 ) || defined(CONFIG_KASAN ) +#if (defined(CONFIG_CC_IS_GCC ) &&CONFIG_GCC_VERSION <90000 ) || \ + defined(CONFIG_KASAN ) || defined(CONFIG_UBSAN_ALIGNMENT )/* * For some reason some GCC-8 architectures (nios2, alpha) have trouble * determining that the ss_done state is impossible in __scoped_seqlock_next() * below. * -* Similarly KASAN is known to confuse compilers enough to break this. But we -* don't care about code quality for KASAN builds anyway. +* Similarly KASAN and UBSAN_ALIGNMENT are known to confuse compilers enough +* to break this. But we don't care about code quality for such builds anyway. */ static inline void __scoped_seqlock_bug (void ) { }#else
Greg Kroah-Hartman
maintainerPATCH 12/675 KVM: x86: Check for invalid/obsolete root *after* making MMU pages available
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <[email protected]>
commit 2abd5287f08319fa35764566b15c6e22cb1068db upstream.
Check for a "stale" page fault, i.e. for an invalid and/or obsolete root, after making MMU pages available for the shadow MMU. If reclaiming shadow pages zaps an in-use root, i.e. marks it invalid, then KVM will attempt to map memory into an invalid root. On its own, populating an invalid root is "fine", but because child shadow pages inherit their parent's role, any children created during the map/fetch will be created as invalid pages, thus violating KVM's invariant that invalid pages are never on the list of active MMU pages.
Note, the underlying flaw has existed since KVM first started tracking invalid roots in 2008 (commit 2e53d63acba7, "KVM: MMU: ignore zapped root pagetables"), but the true badness only came along in 2020 (Linux 5.9) with the invariant that invalid shadow pages can't be on the list of active pages.
Note #2, inheriting role.invalid when creating child shadow pages is also far from ideal; that flaw will be addressed separately.
--- arch/x86/kvm/mmu/mmu.c | 9 +++++---- arch/x86/kvm/mmu/paging_tmpl.h | 10 ++++++---- 2 files changed, 11 insertions(+), 8 deletions(-)
arch/x86/kvm/mmu/mmu.c +5 -4
@@ -4806,16 +4806,17 @@ static int direct_page_fault(struct kvm_if (r !=RET_PF_CONTINUE )return r; - r =RET_PF_RETRY ;write_lock (&vcpu->kvm->mmu_lock); -if (is_page_fault_stale (vcpu, fault)) - goto out_unlock; - r =make_mmu_pages_available (vcpu);if (r) goto out_unlock; +if (is_page_fault_stale (vcpu, fault)) { + r =RET_PF_RETRY ; + goto out_unlock; + } + r =direct_map (vcpu, fault); out_unlock:
arch/x86/kvm/mmu/paging_tmpl.h +6 -4
@@ -827,15 +827,17 @@ static int FNAME(page_fault)(struct kvm_ }#endif - r =RET_PF_RETRY ;write_lock (&vcpu->kvm->mmu_lock); -if (is_page_fault_stale (vcpu, fault)) - goto out_unlock; - r =make_mmu_pages_available (vcpu);if (r) goto out_unlock; + +if (is_page_fault_stale (vcpu, fault)) { + r =RET_PF_RETRY ; + goto out_unlock; + } + r =FNAME (fetch)(vcpu, fault, &walker); out_unlock:
Greg Kroah-Hartman
maintainerPATCH 13/675 KVM: x86: Only reset TSC Deadline Timer in apic_timer_expired on KVM_RUN
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Venkatesh Srinivas <[email protected]>
commit e800decd9c0ac4349bcd8f8f9b29fd21fe93165e upstream.
On Intel platforms with a VMX preemption timer and APICv, if a VMM calls KVM_GET_LAPIC before KVM_GET_MSRS to save the vCPU state, it is possible to lose a pending timer interrupt.
If the thread running these ioctls is migrated to another core after calling KVM_GET_LAPIC but before KVM_GET_MSRS and the guest is using their LAPIC timer in TSC-deadline mode, not only does the save LAPIC state not carry the pending interrupt, the TSCDEADLINE MSR will be zeroed.
After migration across CPUs, KVM_GET_MSRS calls vcpu_load, posting the interrupt and clearing the MSR:vcpu_load() ->
kvm_arch_vcpu_load() ->
kvm_lapic_restart_hv_timer() ->
start_hv_timer() ->
apic_timer_expired() ->
kvm_apic_inject_pending_timer_irqs()
. post interrupt into the LAPIC state
. clear IA32_TSCDEADLINEThe saved LAPIC state will be missing the pending interrupt and the saved MSR will be zero. Oops.
Fix by only posting an interrupt when we're attempting to enter the guest (vcpu->wants_to_run == true), not for vcpu_load from other paths.
Message-ID: <[email protected]>
--- arch/x86/kvm/lapic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kvm/lapic.c +1 -1
@@ -2065,7 +2065,7 @@ static void apic_timer_expired(struct kvif (apic_lvtt_tscdeadline (apic) || ktimer->hv_timer_in_use) ktimer->expired_tscdeadline = ktimer->tscdeadline; -if (!from_timer_fn && apic->apicv_active) { +if (!from_timer_fn && apic->apicv_active && vcpu->wants_to_run) {WARN_ON (kvm_get_running_vcpu () != vcpu);kvm_apic_inject_pending_timer_irqs (apic);return ;
Greg Kroah-Hartman
maintainerPATCH 14/675 KVM: nVMX: Hide shadow VMCS right after VMCLEAR
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 622ebfac01ba4f9c0060cebd41257fe46fc4a0b3 upstream.
free_nested() frees the shadow VMCS while vmcs01 still points to it. But because it is asynchronous with respect to loaded_vmcs_clear(), the vCPU might migrate before the pointer is cleared and __loaded_vmcs_clear() may then execute VMCLEAR.
The VMCS needs to stay attached until its explicit VMCLEAR completes, but then it can be hidden and the page safely freed.
--- arch/x86/kvm/vmx/nested.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
arch/x86/kvm/vmx/nested.c +9 -2
@@ -333,6 +333,7 @@ static void nested_put_vmcs12_pages(strustatic void free_nested (struct kvm_vcpu *vcpu) {struct vcpu_vmx *vmx =to_vmx (vcpu); +struct vmcs *shadow_vmcs;if (WARN_ON_ONCE (vmx->loaded_vmcs != &vmx->vmcs01))vmx_switch_vmcs (vcpu, &vmx->vmcs01);
@@ -350,9 +351,15 @@ static void free_nested(struct kvm_vcpu vmx->nested.current_vmptr =INVALID_GPA ;if (enable_shadow_vmcs) {vmx_disable_shadow_vmcs (vmx); -vmcs_clear (vmx->vmcs01.shadow_vmcs); -free_vmcs (vmx->vmcs01.shadow_vmcs); + +/* +* Keep the pointer visible until after VMCLEAR, so migration +* can clear an active shadow VMCS on the old CPU. +*/ + shadow_vmcs = vmx->vmcs01.shadow_vmcs; +vmcs_clear (shadow_vmcs); vmx->vmcs01.shadow_vmcs =NULL ; +free_vmcs (shadow_vmcs); }kfree (vmx->nested.cached_vmcs12); vmx->nested.cached_vmcs12 =NULL ;
Greg Kroah-Hartman
maintainerPATCH 15/675 KVM: x86/mmu: Fix use-after-free on vendor module reload
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Phil Rosenthal <[email protected]>
commit 52f2f7c30126037975389aa04d24c506a5177c35 upstream.
mmu_destroy_caches() destroys pte_list_desc_cache and mmu_page_header_cache, but leaves both pointers unchanged. The pointers live in kvm.ko, and therefore survive when a vendor module is unloaded while kvm.ko remains loaded.
If creation of pte_list_desc_cache fails during a subsequent vendor module load, its assignment sets pte_list_desc_cache to NULL and the error path calls mmu_destroy_caches(). mmu_page_header_cache still points to the cache destroyed during the preceding vendor module unload. Passing that stale pointer to kmem_cache_destroy() causes a slab use-after-free.
Reproduce the issue on a v7.1.3 kernel with CONFIG_KASAN=y, CONFIG_KASAN_GENERIC=y, CONFIG_KVM=m, and CONFIG_KVM_INTEL=m. A one-shot test hook forces pte_list_desc_cache to NULL on the second invocation of kvm_mmu_vendor_module_init():
1. Load kvm.ko and kvm-intel.ko, creating both caches.
2. Unload only kvm_intel, leaving kvm.ko loaded.
3. Reload kvm_intel and force initialization through the -ENOMEM path.
KASAN reports:
BUG: KASAN: slab-use-after-free in kvm_mmu_vendor_module_init+0x5b/0x170 [kvm] ... kmem_cache_destroy+0x21/0x1d0 kvm_mmu_vendor_module_init+0x5b/0x170 [kvm] ... Allocated by task 16817: __kmem_cache_create_args+0x12c/0x3b0 __kmem_cache_create.constprop.0+0xb6/0xf0 [kvm] kvm_mmu_vendor_module_init+0x13b/0x170 [kvm] ... Freed by task 16820: kmem_cache_destroy+0x117/0x1d0 kvm_mmu_vendor_module_exit+0x21/0x30 [kvm]
Clear both pointers immediately after destroying their caches so that the stored state reflects the caches' lifetime and repeated cleanup is safe.
With the fix applied, the same injected vendor module reload fails with -ENOMEM as expected and produces no KASAN report.
Message-ID: <[email protected]>
--- arch/x86/kvm/mmu/mmu.c | 2 ++ 1 file changed, 2 insertions(+)
arch/x86/kvm/mmu/mmu.c +2 -0
@@ -7393,7 +7393,9 @@ void kvm_mmu_invalidate_mmio_sptes(strucstatic void mmu_destroy_caches (void ) {kmem_cache_destroy (pte_list_desc_cache); + pte_list_desc_cache =NULL ;kmem_cache_destroy (mmu_page_header_cache); + mmu_page_header_cache =NULL ; }static void kvm_wake_nx_recovery_thread (struct kvm *kvm)
Greg Kroah-Hartman
maintainerPATCH 16/675 can: bcm: add locking when updating filter and timer values
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Hartkopp <[email protected]>
commit 749179c2e25b95d22499ed29096b3e02d6dfd2b4 upstream.
KCSAN detected a simultaneous access to timer values that can be overwritten in bcm_rx_setup() when updating timer and filter content while bcm_rx_handler(), bcm_rx_timeout_handler() or bcm_rx_thr_handler() run concurrently on incoming CAN traffic.
Protect the timer (ival1/ival2/kt_ival1/kt_ival2/kt_lastmsg) and filter (nframes/flags/frames/last_frames) updates in bcm_rx_setup() with a new per-op bcm_rx_update_lock, taken with the matching scope in the RX handlers. memcpy_from_msg() is staged into a temporary buffer before the lock is taken, since it can sleep and must not run under a spinlock.
hrtimer_cancel() is always called without bcm_rx_update_lock held, since bcm_rx_timeout_handler()/bcm_rx_thr_handler() take the same lock and a running callback would otherwise deadlock against the canceller.
Also close a related race: bcm_rx_setup() cleared the RTR flag in the stored reply frame's can_id as a separate, unprotected step after the frame content was already installed, so a concurrent bcm_rx_handler() could transmit a stale reply with CAN_RTR_FLAG still set. Fold that normalization into the initial frame preparation instead (on the staged buffer for updates, directly on op->frames pre-registration for new ops), so the installed frame is always atomically self-consistent.
bcm_rx_handler()'s RX_RTR_FRAME check now takes a lock-protected snapshot of op->flags before deciding whether to call bcm_can_tx(), but does not hold the lock across that call.
Also take a lock-protected snapshot of the currframe in bcm_can_tx() to avoid partly overwrites by content updates in bcm_tx_setup(). Finally check if a TX_RESET_MULTI_IDX/SETTIMER might have reset op->currframe between the two locked sections in bcm_can_tx().
Omit calling hrtimer_forward() with zero interval in bcm_rx_thr_handler(). kt_ival2 may have been concurrently cleared by bcm_rx_setup() before it cancels this timer, so check kt_ival2 inside the bcm_rx_update_lock.
--- net/can/bcm.c | 176 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 133 insertions(+), 43 deletions(-)
net/can/bcm.c +133 -43
@@ -128,6 +128,7 @@ struct bcm_op {struct sock *sk;struct net_device *rx_reg_dev;spinlock_t bcm_tx_lock;/* protect currframe/count in runtime updates */ +spinlock_t bcm_rx_update_lock;/* protect filter/timer data updates */ };struct bcm_sock {
@@ -292,21 +293,27 @@ static int bcm_proc_show(struct seq_file *m, void *v)* bcm_can_tx - send the (next) CAN frame to the appropriate CAN interface * of the given bcm tx op */ -static void bcm_can_tx (struct bcm_op *op) +static void bcm_can_tx (struct bcm_op *op,struct canfd_frame *cf) {struct sk_buff *skb;struct net_device *dev; -struct canfd_frame *cf; +struct canfd_frame cframe; +bool cyclic = !cf; +unsigned int idx =0 ;int err;/* no target device? => exit */ if (!op->ifindex)return ; -/* read currframe under lock protection */ -spin_lock_bh (&op->bcm_tx_lock); - cf = op->frames + op->cfsiz * op->currframe; -spin_unlock_bh (&op->bcm_tx_lock); +if (cyclic) { +/* read currframe under lock protection */ +spin_lock_bh (&op->bcm_tx_lock); + idx = op->currframe; +memcpy (&cframe, op->frames + op->cfsiz * idx, op->cfsiz); + cf = &cframe; +spin_unlock_bh (&op->bcm_tx_lock); + } dev =dev_get_by_index (sock_net (op->sk), op->ifindex);if (!dev) {
@@ -335,14 +342,20 @@ static void bcm_can_tx(struct bcm_op *op)if (!err) op->frames_abs++; - op->currframe++; +/* only advance the cyclic sequence if nothing reset currframe while +* we were sending - a concurrent TX_RESET_MULTI_IDX means this +* frame's bookkeeping belongs to a sequence that no longer exists +*/ +if (!cyclic || op->currframe == idx) { + op->currframe++; -/* reached last frame? */ -if (op->currframe >= op->nframes) - op->currframe =0 ; +/* reached last frame? */ +if (op->currframe >= op->nframes) + op->currframe =0 ; -if (op->count >0 ) - op->count--; +if (op->count >0 ) + op->count--; + }spin_unlock_bh (&op->bcm_tx_lock); out:
@@ -456,7 +469,7 @@ static enum hrtimer_restart bcm_tx_timeout_handler(struct hrtimer *hrtimer)struct bcm_msg_head msg_head;if (op->kt_ival1 && (op->count >0 )) { -bcm_can_tx (op); +bcm_can_tx (op,NULL );if (!op->count && (op->flags &TX_COUNTEVT )) {/* create notification to user */
@@ -473,7 +486,7 @@ static enum hrtimer_restart bcm_tx_timeout_handler(struct hrtimer *hrtimer) } }else if (op->kt_ival2) { -bcm_can_tx (op); +bcm_can_tx (op,NULL ); } return bcm_tx_set_expiry(op, &op->timer) ?
@@ -617,6 +630,8 @@ static enum hrtimer_restart bcm_rx_timeout_handler(struct hrtimer *hrtimer) struct bcm_op *op = container_of(hrtimer, struct bcm_op, timer);struct bcm_msg_head msg_head; +spin_lock_bh (&op->bcm_rx_update_lock); +/* if user wants to be informed, when cyclic CAN-Messages come back */ if ((op->flags &RX_ANNOUNCE_RESUME ) && op->last_frames) {/* clear received CAN frames to indicate 'nothing received' */
@@ -633,6 +648,8 @@ static enum hrtimer_restart bcm_rx_timeout_handler(struct hrtimer *hrtimer) msg_head.can_id = op->can_id; msg_head.nframes =0 ; +spin_unlock_bh (&op->bcm_rx_update_lock); +bcm_send_to_user (op, &msg_head,NULL ,0 );return HRTIMER_NORESTART ;
@@ -681,15 +698,26 @@ static int bcm_rx_thr_flush(struct bcm_op *op)static enum hrtimer_restart bcm_rx_thr_handler (struct hrtimer *hrtimer) { struct bcm_op *op = container_of(hrtimer, struct bcm_op, thrtimer); +enum hrtimer_restart ret; -if (bcm_rx_thr_flush (op)) { +spin_lock_bh (&op->bcm_rx_update_lock); + +/* kt_ival2 may have been concurrently cleared by bcm_rx_setup() +* before it cancels this timer - never forward with a zero +* interval in that case. +*/ +if (bcm_rx_thr_flush (op) && op->kt_ival2) {hrtimer_forward_now (hrtimer, op->kt_ival2); -return HRTIMER_RESTART ; + ret =HRTIMER_RESTART ; }else {/* rearm throttle handling */ op->kt_lastmsg =0 ; -return HRTIMER_NORESTART ; + ret =HRTIMER_NORESTART ; } + +spin_unlock_bh (&op->bcm_rx_update_lock); + +return ret; }/*
@@ -699,8 +727,10 @@ static void bcm_rx_handler(struct sk_buff *skb, void *data) {struct bcm_op *op = (struct bcm_op *)data;const struct canfd_frame *rxframe = (struct canfd_frame *)skb->data; +struct canfd_frame rtrframe;unsigned int i;unsigned char traffic_flags; +bool rtr_frame;if (op->can_id != rxframe->can_id)return ;
@@ -724,9 +754,18 @@ static void bcm_rx_handler(struct sk_buff *skb, void *data)/* update statistics */ op->frames_abs++; -if (op->flags &RX_RTR_FRAME ) { +/* snapshot the flag under lock: op->flags/op->frames may be updated +* concurrently by bcm_rx_setup(). +*/ +spin_lock_bh (&op->bcm_rx_update_lock); + rtr_frame = op->flags &RX_RTR_FRAME ; +if (rtr_frame) +memcpy (&rtrframe, op->frames, op->cfsiz); +spin_unlock_bh (&op->bcm_rx_update_lock); + +if (rtr_frame) {/* send reply for RTR-request (placed in op->frames[0]) */ -bcm_can_tx (op); +bcm_can_tx (op, &rtrframe);return ; }
@@ -738,6 +777,8 @@ static void bcm_rx_handler(struct sk_buff *skb, void *data) traffic_flags |=RX_OWN ; } +spin_lock_bh (&op->bcm_rx_update_lock); +if (op->flags &RX_FILTER_ID ) {/* the easiest case */ bcm_rx_update_and_send(op, op->last_frames, rxframe,
@@ -773,6 +814,8 @@ static void bcm_rx_handler(struct sk_buff *skb, void *data) rx_starttimer:bcm_rx_starttimer (op); + +spin_unlock_bh (&op->bcm_rx_update_lock); }/*
@@ -1115,7 +1158,7 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,list_add_rcu (&op->list, &bo->tx_ops);if (op->flags &TX_ANNOUNCE ) -bcm_can_tx (op); +bcm_can_tx (op,NULL );if (op->flags &STARTTIMER )bcm_tx_start_timer (op);
@@ -1129,6 +1172,24 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,return err; } +static void bcm_rx_setup_rtr_check (struct bcm_msg_head *msg_head, +struct bcm_op *op,void *new_frames) +{ +/* funny feature in RX(!)_SETUP only for RTR-mode: +* copy can_id into frame BUT without RTR-flag to +* prevent a full-load-loopback-test ... ;-] +* normalize this on the staged buffer, before it is +* ever installed into op->frames. +*/ +if (msg_head->flags &RX_RTR_FRAME ) { +struct canfd_frame *frame0 = new_frames; + +if ((msg_head->flags &TX_CP_CAN_ID ) || + frame0->can_id == op->can_id) + frame0->can_id = op->can_id & ~CAN_RTR_FLAG ; + } +} +/* * bcm_rx_setup - create or update a bcm rx op (for bcm_sendmsg) */
@@ -1163,6 +1224,8 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,/* check the given can_id */ op =bcm_find_op (&bo->rx_ops, msg_head, ifindex);if (op) { +void *new_frames =NULL ; +/* update existing BCM operation */ /*
@@ -1174,19 +1237,48 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,return -E2BIG ;if (msg_head->nframes) { -/* update CAN frames content */ - err =memcpy_from_msg (op->frames, msg, +/* get new CAN frames content before locking */ + new_frames =kmalloc (msg_head->nframes * op->cfsiz, +GFP_KERNEL ); +if (!new_frames) +return -ENOMEM ; + + err =memcpy_from_msg (new_frames, msg, msg_head->nframes * op->cfsiz); -if (err <0 ) +if (err <0 ) { +kfree (new_frames);return err; + } -/* clear last_frames to indicate 'nothing received' */ -memset (op->last_frames,0 , msg_head->nframes * op->cfsiz); +bcm_rx_setup_rtr_check (msg_head, op, new_frames); } +spin_lock_bh (&op->bcm_rx_update_lock); op->nframes = msg_head->nframes; op->flags = msg_head->flags; +if (msg_head->nframes) { +/* update CAN frames content */ +memcpy (op->frames, new_frames, + msg_head->nframes * op->cfsiz); + +/* clear last_frames to indicate 'nothing received' */ +memset (op->last_frames,0 , + msg_head->nframes * op->cfsiz); + } + +if (msg_head->flags &SETTIMER ) { + op->ival1 = msg_head->ival1; + op->ival2 = msg_head->ival2; + op->kt_ival1 =bcm_timeval_to_ktime (msg_head->ival1); + op->kt_ival2 =bcm_timeval_to_ktime (msg_head->ival2); + op->kt_lastmsg =0 ; + } +spin_unlock_bh (&op->bcm_rx_update_lock); + +/* free temporary frames / kfree(NULL) is safe */ +kfree (new_frames); +/* Only an update -> do not call can_rx_register() */ do_rx_register =0 ;
@@ -1197,6 +1289,7 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,return -ENOMEM ;spin_lock_init (&op->bcm_tx_lock); +spin_lock_init (&op->bcm_rx_update_lock); op->can_id = msg_head->can_id; op->nframes = msg_head->nframes; op->cfsiz =CFSIZ (msg_head->flags);
@@ -1238,6 +1331,8 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,kfree (op);return err; } + +bcm_rx_setup_rtr_check (msg_head, op, op->frames); }/* bcm_can_tx / bcm_tx_timeout_handler needs this */
@@ -1262,29 +1357,22 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,/* check flags */ if (op->flags &RX_RTR_FRAME ) { -struct canfd_frame *frame0 = op->frames; -/* no timers in RTR-mode */ hrtimer_cancel (&op->thrtimer);hrtimer_cancel (&op->timer); - -/* -* funny feature in RX(!)_SETUP only for RTR-mode: -* copy can_id into frame BUT without RTR-flag to -* prevent a full-load-loopback-test ... ;-] -*/ -if ((op->flags &TX_CP_CAN_ID ) || - (frame0->can_id == op->can_id)) - frame0->can_id = op->can_id & ~CAN_RTR_FLAG ; - }else {if (op->flags &SETTIMER ) { -/* set timer value */ - op->ival1 = msg_head->ival1; - op->ival2 = msg_head->ival2; - op->kt_ival1 =bcm_timeval_to_ktime (msg_head->ival1); - op->kt_ival2 =bcm_timeval_to_ktime (msg_head->ival2); +/* set timers (locked) for newly created op */ +if (do_rx_register) { +spin_lock_bh (&op->bcm_rx_update_lock); + op->ival1 = msg_head->ival1; + op->ival2 = msg_head->ival2; + op->kt_ival1 =bcm_timeval_to_ktime (msg_head->ival1); + op->kt_ival2 =bcm_timeval_to_ktime (msg_head->ival2); + op->kt_lastmsg =0 ; +spin_unlock_bh (&op->bcm_rx_update_lock); + }/* disable an active timer due to zero value? */ if (!op->kt_ival1)
@@ -1294,9 +1382,11 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,* In any case cancel the throttle timer, flush * potentially blocked msgs and reset throttle handling */ - op->kt_lastmsg =0 ;hrtimer_cancel (&op->thrtimer); + +spin_lock_bh (&op->bcm_rx_update_lock);bcm_rx_thr_flush (op); +spin_unlock_bh (&op->bcm_rx_update_lock); }if ((op->flags &STARTTIMER ) && op->kt_ival1)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 17/675 can: bcm: fix CAN frame rx/tx statistics
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Hartkopp <[email protected]>
commit e6c24ba95fc3f1b5e1dcd28b1c6e59ef61a9daa5 upstream.
KCSAN detected a data race within the bcm_rx_handler() when two CAN frames have been simultaneously received and processed in a single rx op by two different CPUs.
Use atomic operations with (signed) long data types to access the statistics in the hot path to fix the KCSAN complaint.
Additionally simplify the update and check of statistics overflow by using the atomic operations in separate bcm_update_[rx|tx]_stats() functions. The rx variant runs under bcm_rx_update_lock to prevent races when resetting the two rx counters; the tx variant runs under bcm_tx_lock and only needs to guard its own counter's overflow.
As the rx path resets its values already at LONG_MAX / 100, there is no conflict between the two locking domains (bcm_rx_update_lock vs. bcm_tx_lock) even for ops that use both paths.
The rx statistics update and the frames_filtered update in bcm_rx_changed() were previously performed in two separate bcm_rx_update_lock sections. For an rx op subscribed on all interfaces (ifindex == 0), bcm_rx_handler() can run concurrently on different CPUs, so a counter reset by one CPU between these two sections could leave frames_filtered larger than frames_abs on another CPU, producing a bogus (even negative) reduction percentage in procfs. Update the statistics in the same critical section as bcm_rx_changed() to close this gap, which also removes the now unneeded extra lock/unlock pair around the traffic_flags calculation.
--- net/can/bcm.c | 69 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 46 insertions(+), 23 deletions(-)
net/can/bcm.c +46 -23
@@ -111,7 +111,7 @@ struct bcm_op {int ifindex;canid_t can_id;u32 flags; -unsigned long frames_abs, frames_filtered; +atomic_long_t frames_abs, frames_filtered;struct bcm_timeval ival1, ival2;struct hrtimer timer, thrtimer;ktime_t rx_stamp, kt_ival1, kt_ival2, kt_lastmsg;
@@ -228,10 +228,13 @@ static int bcm_proc_show(struct seq_file *m, void *v)list_for_each_entry_rcu (op, &bo->rx_ops, list) { -unsigned long reduction; +long reduction, frames_filtered, frames_abs; + + frames_filtered =atomic_long_read (&op->frames_filtered); + frames_abs =atomic_long_read (&op->frames_abs);/* print only active entries & prevent division by zero */ -if (!op->frames_abs) +if (!frames_abs)continue ; seq_printf(m, "rx_op: %03X %-5s ", op->can_id,
@@ -253,9 +256,9 @@ static int bcm_proc_show(struct seq_file *m, void *v) (long long)ktime_to_us(op->kt_ival2));seq_printf (m,"# recv %ld (%ld) => reduction: " , - op->frames_filtered, op->frames_abs); + frames_filtered, frames_abs); - reduction =100 - (op->frames_filtered *100 ) / op->frames_abs; + reduction =100 - (frames_filtered *100 ) / frames_abs;seq_printf (m,"%s%ld%%\n" , (reduction ==100 ) ?"near " :"" , reduction);
@@ -279,7 +282,8 @@ static int bcm_proc_show(struct seq_file *m, void *v)seq_printf (m,"t2=%lld " , (long long )ktime_to_us (op->kt_ival2)); -seq_printf (m,"# sent %ld\n" , op->frames_abs); +seq_printf (m,"# sent %ld\n" , +atomic_long_read (&op->frames_abs)); }seq_putc (m,'\n' );
@@ -289,6 +293,24 @@ static int bcm_proc_show(struct seq_file *m, void *v) }#endif /* CONFIG_PROC_FS */ +static void bcm_update_rx_stats (struct bcm_op *op) +{ +/* prevent overflow of the reduction% calculation in bcm_proc_show() */ +if (atomic_long_inc_return (&op->frames_abs) >LONG_MAX /100 ) { +atomic_long_set (&op->frames_filtered,0 ); +atomic_long_set (&op->frames_abs,0 ); + } +} + +static void bcm_update_tx_stats (struct bcm_op *op) +{ +/* tx_op has no reduction% calculation - use the full range and +* just keep the displayed counter non-negative on overflow +*/ +if (atomic_long_inc_return (&op->frames_abs) ==LONG_MAX ) +atomic_long_set (&op->frames_abs,0 ); +} +/* * bcm_can_tx - send the (next) CAN frame to the appropriate CAN interface * of the given bcm tx op
@@ -340,7 +362,7 @@ static void bcm_can_tx(struct bcm_op *op, struct canfd_frame *cf)spin_lock_bh (&op->bcm_tx_lock);if (!err) - op->frames_abs++; +bcm_update_tx_stats (op);/* only advance the cyclic sequence if nothing reset currframe while * we were sending - a concurrent TX_RESET_MULTI_IDX means this
@@ -500,12 +522,9 @@ static void bcm_rx_changed(struct bcm_op *op, struct canfd_frame *data) {struct bcm_msg_head head; -/* update statistics */ - op->frames_filtered++; - -/* prevent statistics overflow */ -if (op->frames_filtered >ULONG_MAX /100 ) - op->frames_filtered = op->frames_abs =0 ; +/* update statistics (frames_filtered <= frames_abs) */ +if (atomic_long_read (&op->frames_abs)) +atomic_long_inc (&op->frames_filtered);/* this element is not throttled anymore */ data->flags &= ~RX_THR ;
@@ -751,24 +770,30 @@ static void bcm_rx_handler(struct sk_buff *skb, void *data) op->rx_stamp = skb->tstamp;/* save originator for recvfrom() */ op->rx_ifindex = skb->dev->ifindex; -/* update statistics */ - op->frames_abs++; -/* snapshot the flag under lock: op->flags/op->frames may be updated -* concurrently by bcm_rx_setup(). -*/ +/* op->flags/op->frames may be updated concurrently by bcm_rx_setup() */ spin_lock_bh (&op->bcm_rx_update_lock); + rtr_frame = op->flags &RX_RTR_FRAME ; -if (rtr_frame) +if (rtr_frame) { +bcm_update_rx_stats (op); +/* snapshot RTR content under lock */ memcpy (&rtrframe, op->frames, op->cfsiz); -spin_unlock_bh (&op->bcm_rx_update_lock); +spin_unlock_bh (&op->bcm_rx_update_lock); -if (rtr_frame) {/* send reply for RTR-request (placed in op->frames[0]) */ bcm_can_tx (op, &rtrframe);return ; } +/* update statistics in the same critical section as bcm_rx_changed() +* below: frames_filtered must never be checked/incremented against a +* frames_abs snapshot from a concurrent bcm_rx_handler() call on +* another CPU for the same (wildcard) op, or frames_filtered can end +* up larger than frames_abs. +*/ +bcm_update_rx_stats (op); +/* compute flags to distinguish between own/local/remote CAN traffic */ traffic_flags =0 ;if (skb->sk) {
@@ -777,8 +802,6 @@ static void bcm_rx_handler(struct sk_buff *skb, void *data) traffic_flags |=RX_OWN ; } -spin_lock_bh (&op->bcm_rx_update_lock); -if (op->flags &RX_FILTER_ID ) {/* the easiest case */ bcm_rx_update_and_send(op, op->last_frames, rxframe,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 18/675 can: bcm: extend bcm_tx_lock usage for data and timer updates
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Hartkopp <[email protected]>
commit 12ce799f7ab1e05bd8fbf79e46f403bfe5597ebc upstream.
Stage new CAN frame content for an existing tx op into a kmalloc()'d buffer and validate it there, mirroring the approach already used in bcm_rx_setup(). Only copy the validated data into op->frames while holding op->bcm_tx_lock, so bcm_can_tx() and bcm_tx_timeout_handler() can no longer observe a partially updated or unvalidated frame.
Add a missing error path for memcpy_from_msg() when copying CAN frame data from userspace.
Also move the kt_ival1/kt_ival2/ival1/ival2 updates in bcm_tx_setup() under op->bcm_tx_lock, and read kt_ival1/kt_ival2/count under the same lock in bcm_tx_set_expiry() and bcm_tx_timeout_handler(), closing the torn 64-bit ktime_t read on 32-bit platforms.
--- net/can/bcm.c | 104 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 75 insertions(+), 29 deletions(-)
net/can/bcm.c +75 -29
@@ -127,7 +127,7 @@ struct bcm_op {struct canfd_frame last_sframe;struct sock *sk;struct net_device *rx_reg_dev; -spinlock_t bcm_tx_lock;/* protect currframe/count in runtime updates */ +spinlock_t bcm_tx_lock;/* protect tx data and timer updates */ spinlock_t bcm_rx_update_lock;/* protect filter/timer data updates */ };
@@ -467,12 +467,18 @@ static bool bcm_tx_set_expiry(struct bcm_op *op, struct hrtimer *hrt) {ktime_t ival; +spin_lock_bh (&op->bcm_tx_lock); +if (op->kt_ival1 && op->count) ival = op->kt_ival1; -else if (op->kt_ival2) +else if (op->kt_ival2) { ival = op->kt_ival2; -else + }else { +spin_unlock_bh (&op->bcm_tx_lock);return false; + } + +spin_unlock_bh (&op->bcm_tx_lock);hrtimer_set_expires (hrt,ktime_add (ktime_get (), ival));return true;
@@ -489,25 +495,47 @@ static enum hrtimer_restart bcm_tx_timeout_handler(struct hrtimer *hrtimer) { struct bcm_op *op = container_of(hrtimer, struct bcm_op, timer);struct bcm_msg_head msg_head; +bool tx_ival1, tx_ival2; + +/* snapshot kt_ival1/kt_ival2/count under lock to avoid torn +* ktime_t reads racing with concurrent bcm_tx_setup() updates +*/ +spin_lock_bh (&op->bcm_tx_lock); + tx_ival1 = op->kt_ival1 && (op->count >0 ); + tx_ival2 = !!op->kt_ival2; +spin_unlock_bh (&op->bcm_tx_lock); + +if (tx_ival1) { +u32 flags, count; +struct bcm_timeval ival1, ival2; -if (op->kt_ival1 && (op->count >0 )) {bcm_can_tx (op,NULL ); -if (!op->count && (op->flags &TX_COUNTEVT )) { +/* snapshot variables under lock to avoid torn reads racing +* with concurrent bcm_tx_setup() updates +*/ +spin_lock_bh (&op->bcm_tx_lock); + flags = op->flags; + count = op->count; + ival1 = op->ival1; + ival2 = op->ival2; +spin_unlock_bh (&op->bcm_tx_lock); + +if (!count && (flags &TX_COUNTEVT )) {/* create notification to user */ memset (&msg_head,0 ,sizeof (msg_head)); msg_head.opcode =TX_EXPIRED ; - msg_head.flags = op->flags; - msg_head.count = op->count; - msg_head.ival1 = op->ival1; - msg_head.ival2 = op->ival2; + msg_head.flags = flags; + msg_head.count = count; + msg_head.ival1 = ival1; + msg_head.ival2 = ival2; msg_head.can_id = op->can_id; msg_head.nframes =0 ;bcm_send_to_user (op, &msg_head,NULL ,0 ); } - }else if (op->kt_ival2) { + }else if (tx_ival2) {bcm_can_tx (op,NULL ); }
@@ -1031,6 +1059,8 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,/* check the given can_id */ op =bcm_find_op (&bo->tx_ops, msg_head, ifindex);if (op) { +void *new_frames; +/* update existing BCM operation */ /*
@@ -1041,11 +1071,23 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,if (msg_head->nframes > op->nframes)return -E2BIG ; -/* update CAN frames content */ +/* get new CAN frames content into a staging buffer before +* locking: validate and normalize the frames there so that +* bcm_can_tx() / bcm_tx_timeout_handler() never observe a +* partially updated or unvalidated frame in op->frames +*/ + new_frames =kmalloc (msg_head->nframes * op->cfsiz,GFP_KERNEL ); +if (!new_frames) +return -ENOMEM ; +for (i =0 ; i < msg_head->nframes; i++) { - cf = op->frames + op->cfsiz * i; + cf = new_frames + op->cfsiz * i; err =memcpy_from_msg ((u8 *)cf, msg, op->cfsiz); +if (err <0 ) { +kfree (new_frames); +return err; + }if (op->flags &CAN_FD_FRAME ) {if (cf->len >64 )
@@ -1055,36 +1097,38 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, err = -EINVAL ; } -if (err <0 ) +if (err <0 ) { +kfree (new_frames);return err; + }if (msg_head->flags &TX_CP_CAN_ID ) {/* copy can_id into frame */ cf->can_id = msg_head->can_id; } } + +spin_lock_bh (&op->bcm_tx_lock); + +/* update CAN frames content */ +memcpy (op->frames, new_frames, msg_head->nframes * op->cfsiz); + op->flags = msg_head->flags; -/* only lock for unlikely count/nframes/currframe changes */ if (op->nframes != msg_head->nframes || - op->flags &TX_RESET_MULTI_IDX || - op->flags &SETTIMER ) { - -spin_lock_bh (&op->bcm_tx_lock); + op->flags &TX_RESET_MULTI_IDX ) { +/* potentially update changed nframes */ + op->nframes = msg_head->nframes; +/* restart multiple frame transmission */ + op->currframe =0 ; + } -if (op->nframes != msg_head->nframes || - op->flags &TX_RESET_MULTI_IDX ) { -/* potentially update changed nframes */ - op->nframes = msg_head->nframes; -/* restart multiple frame transmission */ - op->currframe =0 ; - } +if (op->flags &SETTIMER ) + op->count = msg_head->count; -if (op->flags &SETTIMER ) - op->count = msg_head->count; +spin_unlock_bh (&op->bcm_tx_lock); -spin_unlock_bh (&op->bcm_tx_lock); - } +kfree (new_frames); }else {/* insert new BCM operation for the given can_id */
@@ -1160,10 +1204,12 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,if (op->flags &SETTIMER ) {/* set timer values */ +spin_lock_bh (&op->bcm_tx_lock); op->ival1 = msg_head->ival1; op->ival2 = msg_head->ival2; op->kt_ival1 =bcm_timeval_to_ktime (msg_head->ival1); op->kt_ival2 =bcm_timeval_to_ktime (msg_head->ival2); +spin_unlock_bh (&op->bcm_tx_lock);/* disable an active timer due to zero values? */ if (!op->kt_ival1 && !op->kt_ival2)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 19/675 can: bcm: validate frame length in bcm_rx_setup() for RTR replies
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Hartkopp <[email protected]>
commit 62ec41f364648be79d54d94d0d240ee326948afd upstream.
bcm_tx_setup() validates cf->len against the CAN/CAN FD DLC limits before installing frames for TX_SETUP, but bcm_rx_setup() never did the same for the RTR-reply frame configured via RX_SETUP with RX_RTR_FRAME.
--- net/can/bcm.c | 59 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 18 deletions(-)
net/can/bcm.c +41 -18
@@ -1241,22 +1241,37 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,return err; } -static void bcm_rx_setup_rtr_check (struct bcm_msg_head *msg_head, -struct bcm_op *op,void *new_frames) +static int bcm_rx_setup_rtr_check (struct bcm_msg_head *msg_head, +struct bcm_op *op,void *new_frames) { +struct canfd_frame *frame0 = new_frames; + +if (!(msg_head->flags &RX_RTR_FRAME )) +return 0 ; + +/* this frame is sent out as-is by bcm_can_tx() whenever a matching +* remote request is received, so validate its length the same way +* bcm_tx_setup() validates TX_SETUP frames before installing it +*/ +if (msg_head->flags &CAN_FD_FRAME ) { +if (frame0->len >64 ) +return -EINVAL ; + }else { +if (frame0->len >8 ) +return -EINVAL ; + } +/* funny feature in RX(!)_SETUP only for RTR-mode: * copy can_id into frame BUT without RTR-flag to * prevent a full-load-loopback-test ... ;-] * normalize this on the staged buffer, before it is * ever installed into op->frames. */ -if (msg_head->flags &RX_RTR_FRAME ) { -struct canfd_frame *frame0 = new_frames; +if ((msg_head->flags &TX_CP_CAN_ID ) || + frame0->can_id == op->can_id) + frame0->can_id = op->can_id & ~CAN_RTR_FLAG ; -if ((msg_head->flags &TX_CP_CAN_ID ) || - frame0->can_id == op->can_id) - frame0->can_id = op->can_id & ~CAN_RTR_FLAG ; - } +return 0 ; }/*
@@ -1319,7 +1334,11 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,return err; } -bcm_rx_setup_rtr_check (msg_head, op, new_frames); + err =bcm_rx_setup_rtr_check (msg_head, op, new_frames); +if (err <0 ) { +kfree (new_frames); +return err; + } }spin_lock_bh (&op->bcm_rx_update_lock);
@@ -1392,16 +1411,12 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,if (msg_head->nframes) { err =memcpy_from_msg (op->frames, msg, msg_head->nframes * op->cfsiz); -if (err <0 ) { -if (op->frames != &op->sframe) -kfree (op->frames); -if (op->last_frames != &op->last_sframe) -kfree (op->last_frames); -kfree (op); -return err; - } +if (err <0 ) + goto free_op; -bcm_rx_setup_rtr_check (msg_head, op, op->frames); + err =bcm_rx_setup_rtr_check (msg_head, op, op->frames); +if (err <0 ) + goto free_op; }/* bcm_can_tx / bcm_tx_timeout_handler needs this */
@@ -1500,6 +1515,14 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, }return msg_head->nframes * op->cfsiz +MHSIZ ; + +free_op: +if (op->frames != &op->sframe) +kfree (op->frames); +if (op->last_frames != &op->last_sframe) +kfree (op->last_frames); +kfree (op); +return err; }/*
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 20/675 can: bcm: add missing device refcount for CAN filter removal
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Hartkopp <[email protected]>
commit d59948293ea34b6337ce2b5febab8510de70048c upstream.
sashiko-bot remarked a problem with a concurrent device unregistration in isotp.c which also is present in the bcm.c code. A former fix for raw.c commit c275a176e4b6 ("can: raw: add missing refcount for memory leak fix") introduced a netdevice_tracker which solves the issue for bcm.c too.
bcm_release(), bcm_delete_rx_op() and bcm_notifier() relied on dev_get_by_index(ifindex) to re-find the device for an rx_op before unregistering its filter. If a concurrent NETDEV_UNREGISTER has already unlisted the device from the ifindex table, that lookup fails and can_rx_unregister() is silently skipped, leaving a stale CAN filter pointing at the soon-to-be-freed bcm_op/socket.
Hold a netdev_hold()/netdev_put() tracked reference on op->rx_reg_dev from the moment the rx filter is registered in bcm_rx_setup() until it is unregistered in bcm_rx_unreg(), and use that reference directly in bcm_release() and bcm_delete_rx_op() instead of re-looking the device up by ifindex.
--- net/can/bcm.c | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-)
net/can/bcm.c +24 -20
@@ -932,6 +932,7 @@ static void bcm_rx_unreg(struct net_device *dev, struct bcm_op *op)/* mark as removed subscription */ op->rx_reg_dev =NULL ; +dev_put (dev); }else printk (KERN_ERR "can-bcm: bcm_rx_unreg: registered device " "mismatch %p %p\n" , op->rx_reg_dev, dev);
@@ -962,17 +963,14 @@ static int bcm_delete_rx_op(struct list_head *ops, struct bcm_msg_head *mh,* Only remove subscriptions that had not * been removed due to NETDEV_UNREGISTER * in bcm_notifier() +* +* op->rx_reg_dev is a tracked reference taken +* when the subscription was registered, so it +* stays valid here even if a concurrent +* NETDEV_UNREGISTER already unlisted the dev. */ -if (op->rx_reg_dev) { -struct net_device *dev; - - dev =dev_get_by_index (sock_net (op->sk), - op->ifindex); -if (dev) { -bcm_rx_unreg (dev, op); -dev_put (dev); - } - } +if (op->rx_reg_dev) +bcm_rx_unreg (op->rx_reg_dev, op); }else can_rx_unregister(sock_net(op->sk), NULL, op->can_id,
@@ -1491,7 +1489,15 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, bcm_rx_handler, op, "bcm", sk); - op->rx_reg_dev = dev; +/* keep a reference so that a later +* unregister can safely reach the device even +* if a concurrent NETDEV_UNREGISTER has +* already unlisted it by ifindex +*/ +if (!err) { + op->rx_reg_dev = dev; +dev_hold (dev); + }dev_put (dev); }else {/* the requested device is gone - do not
@@ -1864,16 +1870,14 @@ static int bcm_release(struct socket *sock)* Only remove subscriptions that had not * been removed due to NETDEV_UNREGISTER * in bcm_notifier() +* +* op->rx_reg_dev is a tracked reference taken +* when the subscription was registered, so it +* stays valid here even if a concurrent +* NETDEV_UNREGISTER already unlisted the device. */ -if (op->rx_reg_dev) { -struct net_device *dev; - - dev =dev_get_by_index (net, op->ifindex); -if (dev) { -bcm_rx_unreg (dev, op); -dev_put (dev); - } - } +if (op->rx_reg_dev) +bcm_rx_unreg (op->rx_reg_dev, op); }else can_rx_unregister(net, NULL, op->can_id, REGMASK(op->can_id),
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 21/675 can: bcm: fix stale rx/tx ops after device removal
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Hartkopp <[email protected]>
commit 3b762c0d950383ab7a002686c9136b9aa55d2d70 upstream.
RX: an RX_SETUP update(!) for an existing op skipped can_rx_register() unconditionally, even when a concurrent NETDEV_UNREGISTER had already torn down its registration (op->rx_reg_dev == NULL). This silently did not re-enable frame delivery for that updated filter. bcm_rx_setup() now re-registers in that case, while leaving rx_ops with ifindex = 0 (all CAN devices) which never carry a tracked rx_reg_dev registered as-is.
TX: bcm_notify() only handled bo->rx_ops on NETDEV_UNREGISTER, leaving tx_ops with an active cyclic transmission re-arming its hrtimer indefinitely to execute bcm_tx_timeout_handler(). Cancelling the hrtimer prevents the runaway timer and any injection into a later reused ifindex, since nothing else calls bcm_can_tx() for the op until an explicit TX_SETUP update re-arms it.
Unlike bcm_rx_unreg(), which clears the tracked rx_reg_dev for rx_ops, the ifindex is intentionally left unchanged for tx_ops. bcm_tx_setup() always rejects ifindex 0, so clearing it would strand the op: neither a later TX_SETUP (bcm_find_op()) nor TX_DELETE (bcm_delete_tx_op()) could ever find it again, since both require an exact ifindex match.
--- net/can/bcm.c | 54 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 10 deletions(-)
net/can/bcm.c +44 -10
@@ -1281,6 +1281,7 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,struct bcm_sock *bo =bcm_sk (sk);struct bcm_op *op;int do_rx_register; +int new_op =0 ;int err =0 ;if ((msg_head->flags &RX_FILTER_ID ) || (!(msg_head->nframes))) {
@@ -1365,8 +1366,15 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,/* free temporary frames / kfree(NULL) is safe */ kfree (new_frames); -/* Only an update -> do not call can_rx_register() */ - do_rx_register =0 ; +/* Don't register a new CAN filter for the rx_op update unless +* a concurrent NETDEV_UNREGISTER notifier already tore down +* the previous registration. In this case the receiver needs +* to be re-registered here so that this update doesn't +* silently stop delivering frames for the given ifindex. +* Ops with ifindex = 0 (all CAN interfaces) never carry a +* tracked rx_reg_dev and stay registered as-is. +*/ + do_rx_register = (ifindex && !op->rx_reg_dev) ?1 :0 ; }else {/* insert new BCM operation for the given can_id */
@@ -1433,6 +1441,7 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,/* call can_rx_register() */ do_rx_register =1 ; + new_op =1 ; }/* if ((op = bcm_find_op(&bo->rx_ops, msg_head->can_id, ifindex))) */
@@ -1446,7 +1455,7 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,if (op->flags &SETTIMER ) {/* set timers (locked) for newly created op */ -if (do_rx_register) { +if (new_op) {spin_lock_bh (&op->bcm_rx_update_lock); op->ival1 = msg_head->ival1; op->ival2 = msg_head->ival2;
@@ -1476,7 +1485,10 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, HRTIMER_MODE_REL_SOFT); } -/* now we can register for can_ids, if we added a new bcm_op */ +/* now we can register for can_ids, if we added a new bcm_op +* or need to re-register after a NETDEV_UNREGISTER tore down +* the previous registration of an existing op +*/ if (do_rx_register) {if (ifindex) {struct net_device *dev;
@@ -1506,18 +1518,32 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, err = -ENODEV ; } - }else + }else { err =can_rx_register (sock_net (sk),NULL , op->can_id,REGMASK (op->can_id), bcm_rx_handler, op,"bcm" , sk); + } +if (err) { -/* this bcm rx op is broken -> remove it */ -bcm_remove_op (op); +/* newly created bcm rx op is broken -> remove it */ +if (new_op) { +bcm_remove_op (op); +return err; + } + +/* an existing op just stays unregistered. +* Cancel op->timer and (defensively) op->thrtimer. +* Other settings can't be reached until the next +* successful RX_SETUP. +*/ +hrtimer_cancel (&op->timer); +hrtimer_cancel (&op->thrtimer);return err; } -/* add this bcm_op to the list of the rx_ops */ -list_add_rcu (&op->list, &bo->rx_ops); +/* add a new bcm_op to the list of the rx_ops */ +if (new_op) +list_add_rcu (&op->list, &bo->rx_ops); }return msg_head->nframes * op->cfsiz +MHSIZ ;
@@ -1733,11 +1759,19 @@ static void bcm_notify(struct bcm_sock *bo, unsigned long msg,case NETDEV_UNREGISTER :lock_sock (sk); -/* remove device specific receive entries */ +/* rx_ops: remove device specific receive entries */ list_for_each_entry (op, &bo->rx_ops, list)if (op->rx_reg_dev == dev)bcm_rx_unreg (dev, op); +/* tx_ops: stop device specific cyclic transmissions on the +* vanishing ifindex. Cancelling the timer is enough to stop +* cyclic bcm_can_tx() calls as there is no re-arming. +*/ +list_for_each_entry (op, &bo->tx_ops, list) +if (op->ifindex == dev->ifindex) +hrtimer_cancel (&op->timer); +/* remove device reference, if this is our bound device */ if (bo->bound && bo->ifindex == dev->ifindex) {#if IS_ENABLED (CONFIG_PROC_FS )
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 22/675 can: bcm: fix data race on rx_stamp/rx_ifindex in bcm_rx_handler()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Hartkopp <[email protected]>
commit 58fd6cbc8541216af1d7ed272ea7ac2b66d50fd8 upstream.
For an rx op subscribed on all interfaces (ifindex == 0), the same op is registered once in the shared per-netns wildcard filter list, so bcm_rx_handler() can run concurrently on different CPUs for frames arriving on different net devices.
op->rx_stamp and op->rx_ifindex were written before bcm_rx_update_lock was taken, allowing concurrent writers to race each other - including a torn store of the 64-bit rx_stamp on 32-bit platforms.
Beyond a torn store bcm_send_to_user() must report the timestamp/ifindex of the very same frame whose content it is delivering. So the assignment is placed in the same unbroken bcm_rx_update_lock section as the content comparison.
As a side effect, the RTR-request frame feature (which never reach bcm_send_to_user()) no longer updates rx_stamp/rx_ifindex, since only the notification path needs them.
--- net/can/bcm.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
net/can/bcm.c +8 -5
@@ -794,11 +794,6 @@ static void bcm_rx_handler(struct sk_buff *skb, void *data)/* disable timeout */ hrtimer_cancel (&op->timer); -/* save rx timestamp */ - op->rx_stamp = skb->tstamp; -/* save originator for recvfrom() */ - op->rx_ifindex = skb->dev->ifindex; -/* op->flags/op->frames may be updated concurrently by bcm_rx_setup() */ spin_lock_bh (&op->bcm_rx_update_lock);
@@ -830,6 +825,14 @@ static void bcm_rx_handler(struct sk_buff *skb, void *data) traffic_flags |=RX_OWN ; } +/* save rx timestamp and originator for recvfrom() under lock. +* For an op subscribed on all interfaces (ifindex == 0) +* bcm_rx_handler() can run concurrently on different CPUs so +* the CAN content and the meta data must be bundled correctly. +*/ + op->rx_stamp = skb->tstamp; + op->rx_ifindex = skb->dev->ifindex; +if (op->flags &RX_FILTER_ID ) {/* the easiest case */ bcm_rx_update_and_send(op, op->last_frames, rxframe,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 23/675 can: bcm: track a single source interface for ANYDEV timeout/throttle ops
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Hartkopp <[email protected]>
commit 2f5976f54a04e9f18b25283036ac3136be453b17 upstream.
An ANYDEV rx op (ifindex == 0) with an active RX timeout and/or throttle timer has no defined semantics when matching frames arrive from several interfaces: bcm_rx_handler() can run concurrently for the same op on different CPUs, racing hrtimer_cancel()/ bcm_rx_starttimer() against bcm_rx_timeout_handler() and causing spurious RX_TIMEOUT notifications and last_frames corruption. The same concurrency lets throttled multiplex frames from different interfaces clobber the single rx_ifindex/rx_stamp fields shared by the op.
Add op->if_detected to track the first interface that delivers a matching frame while a timeout/throttle timer is configured, and reject frames from any other interface for that op. The claim is decided in bcm_rx_handler() before hrtimer_cancel() touches op->timer, so a rejected frame can never disturb the claimed interface's watchdog. RTR-mode ops are excluded via RX_RTR_FRAME, independent of kt_ival1/kt_ival2, since those may briefly hold a stale value from an earlier non-RTR configuration.
The claim is released in bcm_notify() on NETDEV_UNREGISTER and in bcm_rx_setup() when SETTIMER reconfigures the timer values.
A (re-)claim is only possible on CAN devices in NETREG_REGISTERED dev->reg_state to cover the release in bcm_notify() where reg_state becomes NETREG_UNREGISTERING until synchronize_net().
--- net/can/bcm.c | 49 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 5 deletions(-)
net/can/bcm.c +44 -5
@@ -116,6 +116,7 @@ struct bcm_op {struct hrtimer timer, thrtimer;ktime_t rx_stamp, kt_ival1, kt_ival2, kt_lastmsg;int rx_ifindex; +int if_detected;/* first received ifindex in ANYDEV rx_op mode */ int cfsiz;u32 count;u32 nframes;
@@ -791,6 +792,33 @@ static void bcm_rx_handler(struct sk_buff *skb, void *data)return ; } +/* An ANYDEV op with an active RX timeout and/or throttle timer +* tracks a single source interface: claim the first interface that +* delivers a matching frame and reject frames from any other one, +* before hrtimer_cancel() below can touch op->timer - this avoids +* racing bcm_rx_timeout_handler() across concurrent interfaces. +* RX_RTR_FRAME ops are excluded, as kt_ival1/kt_ival2 may briefly +* hold a stale value from an earlier non-RTR configuration. +*/ +if (!op->ifindex) { +spin_lock_bh (&op->bcm_rx_update_lock); + +if (!(op->flags &RX_RTR_FRAME ) && + (op->kt_ival1 || op->kt_ival2)) { +/* don't claim to vanishing interface */ +if (!op->if_detected && + skb->dev->reg_state ==NETREG_REGISTERED ) + op->if_detected = skb->dev->ifindex; + +if (op->if_detected != skb->dev->ifindex) { +spin_unlock_bh (&op->bcm_rx_update_lock); +return ; + } + } + +spin_unlock_bh (&op->bcm_rx_update_lock); + } +/* disable timeout */ hrtimer_cancel (&op->timer);
@@ -825,10 +853,9 @@ static void bcm_rx_handler(struct sk_buff *skb, void *data) traffic_flags |=RX_OWN ; } -/* save rx timestamp and originator for recvfrom() under lock. -* For an op subscribed on all interfaces (ifindex == 0) -* bcm_rx_handler() can run concurrently on different CPUs so -* the CAN content and the meta data must be bundled correctly. +/* save rx timestamp and originator for recvfrom() under lock: an +* ANYDEV op without an active timer can still run concurrently on +* different CPUs, so content and meta data must be bundled here. */ op->rx_stamp = skb->tstamp; op->rx_ifindex = skb->dev->ifindex;
@@ -1363,6 +1390,7 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, op->kt_ival1 =bcm_timeval_to_ktime (msg_head->ival1); op->kt_ival2 =bcm_timeval_to_ktime (msg_head->ival2); op->kt_lastmsg =0 ; + op->if_detected =0 ;/* reclaim ifindex in ANYDEV mode */ }spin_unlock_bh (&op->bcm_rx_update_lock);
@@ -1763,10 +1791,21 @@ static void bcm_notify(struct bcm_sock *bo, unsigned long msg,lock_sock (sk);/* rx_ops: remove device specific receive entries */ -list_for_each_entry (op, &bo->rx_ops, list) +list_for_each_entry (op, &bo->rx_ops, list) {if (op->rx_reg_dev == dev)bcm_rx_unreg (dev, op); +/* release an ANYDEV op's claim (see bcm_rx_handler()) +* on this now confirmed-gone interface. +*/ +if (!op->ifindex) { +spin_lock_bh (&op->bcm_rx_update_lock); +if (op->if_detected == dev->ifindex) + op->if_detected =0 ; +spin_unlock_bh (&op->bcm_rx_update_lock); + } + } +/* tx_ops: stop device specific cyclic transmissions on the * vanishing ifindex. Cancelling the timer is enough to stop * cyclic bcm_can_tx() calls as there is no re-arming.
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 24/675 dmaengine: sh: rz-dmac: Move interrupt request after everything is set up
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Claudiu Beznea <[email protected]>
commit 731712403ddb39d1a76a11abf339a0615bc85de7 upstream.
Once the interrupt is requested, the interrupt handler may run immediately. Since the IRQ handler can access channel->ch_base, which is initialized only after requesting the IRQ, this may lead to invalid memory access. Likewise, the IRQ thread may access uninitialized data (the ld_free, ld_queue, and ld_active lists), which may also lead to issues.
Request the interrupts only after everything is set up. To keep the error path simpler, use dmam_alloc_coherent() instead of dma_alloc_coherent().
[tm: Kept the channel->irq field in rz_dmac_chan_probe() instead of
upstream's local irq variable, as commit 04e227718ab8 ("dmaengine: sh: rz-dmac: Make channel irq local") is not present in this tree. Likewise kept platform_get_irq_byname() instead of platform_get_irq_byname_optional() for the error IRQ in rz_dmac_probe(), as commit 6b3a6b6dc074 ("dmaengine: sh: rz_dmac: make error interrupt optional") is not present in this tree either; its early return on failure becomes a goto err jump to match the new call order.]
--- drivers/dma/sh/rz-dmac.c | 96 ++++++++++++++++------------------------ 1 file changed, 38 insertions(+), 58 deletions(-)
drivers/dma/sh/rz-dmac.c +38 -58
@@ -811,27 +811,6 @@ static int rz_dmac_chan_probe(struct rz_dmac *dmac, channel->index = index; channel->mid_rid = -EINVAL ; -/* Request the channel interrupt. */ -scnprintf (pdev_irqname,sizeof (pdev_irqname),"ch%u" , index); - channel->irq =platform_get_irq_byname (pdev, pdev_irqname); -if (channel->irq <0 ) -return channel->irq; - - irqname =devm_kasprintf (dmac->dev,GFP_KERNEL ,"%s:%u" , -dev_name (dmac->dev), index); -if (!irqname) -return -ENOMEM ; - - ret =devm_request_threaded_irq (dmac->dev, channel->irq, - rz_dmac_irq_handler, - rz_dmac_irq_handler_thread,0 , - irqname, channel); -if (ret) { -dev_err (dmac->dev,"failed to request IRQ %u (%d)\n" , - channel->irq, ret); -return ret; - } -/* Set io base address for each channel */ if (index <8 ) { channel->ch_base = dmac->base + CHANNEL_0_7_OFFSET +
@@ -844,9 +823,9 @@ static int rz_dmac_chan_probe(struct rz_dmac *dmac, }/* Allocate descriptors */ - lmdesc =dma_alloc_coherent (&pdev->dev, -sizeof (struct rz_lmdesc ) *DMAC_NR_LMDESC , - &channel->lmdesc.base_dma,GFP_KERNEL ); + lmdesc =dmam_alloc_coherent (&pdev->dev, +sizeof (struct rz_lmdesc ) *DMAC_NR_LMDESC , + &channel->lmdesc.base_dma,GFP_KERNEL );if (!lmdesc) {dev_err (&pdev->dev,"Can't allocate memory (lmdesc)\n" );return -ENOMEM ;
@@ -862,7 +841,26 @@ static int rz_dmac_chan_probe(struct rz_dmac *dmac,INIT_LIST_HEAD (&channel->ld_free);INIT_LIST_HEAD (&channel->ld_active); -return 0 ; +/* Request the channel interrupt. */ +scnprintf (pdev_irqname,sizeof (pdev_irqname),"ch%u" , index); + channel->irq =platform_get_irq_byname (pdev, pdev_irqname); +if (channel->irq <0 ) +return channel->irq; + + irqname =devm_kasprintf (dmac->dev,GFP_KERNEL ,"%s:%u" , +dev_name (dmac->dev), index); +if (!irqname) +return -ENOMEM ; + + ret =devm_request_threaded_irq (dmac->dev, channel->irq, + rz_dmac_irq_handler, + rz_dmac_irq_handler_thread,0 , + irqname, channel); +if (ret) +dev_err (dmac->dev,"failed to request IRQ %u (%d)\n" , + channel->irq, ret); + +return ret; }static void rz_dmac_put_device (void *_dev)
@@ -932,7 +930,6 @@ static int rz_dmac_probe(struct platform_device *pdev)const char *irqname ="error" ;struct dma_device *engine;struct rz_dmac *dmac; -int channel_num;int ret;int irq;u8 i;
@@ -964,19 +961,6 @@ static int rz_dmac_probe(struct platform_device *pdev)return PTR_ERR (dmac->ext_base); } -/* Register interrupt handler for error */ - irq =platform_get_irq_byname (pdev, irqname); -if (irq <0 ) -return irq; - - ret =devm_request_irq (&pdev->dev, irq, rz_dmac_irq_handler,0 , - irqname,NULL ); -if (ret) { -dev_err (&pdev->dev,"failed to request IRQ %u (%d)\n" , - irq, ret); -return ret; - } -/* Initialize the channels. */ INIT_LIST_HEAD (&dmac->engine.channels);
@@ -1002,6 +986,21 @@ static int rz_dmac_probe(struct platform_device *pdev) goto err; } +/* Register interrupt handler for error */ + irq =platform_get_irq_byname (pdev, irqname); +if (irq <0 ) { + ret = irq; + goto err; + } + + ret =devm_request_irq (&pdev->dev, irq, rz_dmac_irq_handler,0 , + irqname,NULL ); +if (ret) { +dev_err (&pdev->dev,"failed to request IRQ %u (%d)\n" , + irq, ret); + goto err; + } +/* Register the DMAC as a DMA provider for DT. */ ret =of_dma_controller_register (pdev->dev.of_node, rz_dmac_of_xlate,NULL );
@@ -1040,16 +1039,6 @@ static int rz_dmac_probe(struct platform_device *pdev) dma_register_err:of_dma_controller_free (pdev->dev.of_node); err: - channel_num = i ? i -1 :0 ; -for (i =0 ; i < channel_num; i++) { -struct rz_dmac_chan *channel = &dmac->channels[i]; - -dma_free_coherent (&pdev->dev, -sizeof (struct rz_lmdesc ) *DMAC_NR_LMDESC , - channel->lmdesc.base, - channel->lmdesc.base_dma); - } -reset_control_assert (dmac->rstc); err_pm_runtime_put:pm_runtime_put (&pdev->dev);
@@ -1062,18 +1051,9 @@ static int rz_dmac_probe(struct platform_device *pdev)static void rz_dmac_remove (struct platform_device *pdev) {struct rz_dmac *dmac =platform_get_drvdata (pdev); -unsigned int i;dma_async_device_unregister (&dmac->engine);of_dma_controller_free (pdev->dev.of_node); -for (i =0 ; i < dmac->n_channels; i++) { -struct rz_dmac_chan *channel = &dmac->channels[i]; - -dma_free_coherent (&pdev->dev, -sizeof (struct rz_lmdesc ) *DMAC_NR_LMDESC , - channel->lmdesc.base, - channel->lmdesc.base_dma); - }reset_control_assert (dmac->rstc);pm_runtime_put (&pdev->dev);pm_runtime_disable (&pdev->dev);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 25/675 gpu: host1x: Fix use-after-free in host1x_bo_clear_cached_mappings
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikko Perttunen <[email protected]>
[ Upstream commit 266cddf7bd0f6c79b6c0633aef742a22bf70265b ]
__host1x_bo_unpin() drops the last reference to the mapping and frees it, so we can't dereference mapping afterwards. The cache itself outlives the mapping, so use the cache local variable instead.
--- drivers/gpu/host1x/bus.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/host1x/bus.c +2 -2
@@ -1001,10 +1001,10 @@ void host1x_bo_clear_cached_mappings(struct host1x_bo *bo)if (WARN_ON (!cache))continue ; -mutex_lock (&mapping->cache->lock); +mutex_lock (&cache->lock);WARN_ON (kref_read (&mapping->ref) !=1 );__host1x_bo_unpin (&mapping->ref); -mutex_unlock (&mapping->cache->lock); +mutex_unlock (&cache->lock); } }EXPORT_SYMBOL (host1x_bo_clear_cached_mappings);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 26/675 crypto: tegra - Dont touch bo refcount in host1x bo pin/unpin
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikko Perttunen <[email protected]>
[ Upstream commit f8c9c57d750346abd213ffed2ae3cacb0268e9f1 ]
Since commit "gpu: host1x: Allow entries in BO caches to be freed", host1x_bo_pin() and host1x_bo_unpin() handle the bo's refcount themselves. .pin/.unpin callbacks should not adjust it.
--- drivers/crypto/tegra/tegra-se-main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/crypto/tegra/tegra-se-main.c +1 -2
@@ -52,7 +52,7 @@ tegra_se_cmdbuf_pin(struct device *dev, struct host1x_bo *bo, enum dma_data_direreturn ERR_PTR (-ENOMEM );kref_init (&map->ref); - map->bo =host1x_bo_get (bo); + map->bo = bo; map->direction = direction; map->dev = dev;
@@ -93,7 +93,6 @@ static void tegra_se_cmdbuf_unpin(struct host1x_bo_mapping *map)dma_unmap_sgtable (map->dev, map->sgt, map->direction,0 );sg_free_table (map->sgt);kfree (map->sgt); -host1x_bo_put (map->bo);kfree (map); }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 27/675 xprtrdma: Clear receive-side ownership pointers on release
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 2ae8e7afbc63bf84243367f89eb43571f0345a74 ]
Three small ownership-state cleanups land the transport in a state that lets future reviewers reason about each pointer locally rather than tracing the whole reply path:
rpcrdma_rep_put() clears rep->rr_rqst before the rep enters rb_free_reps so that no rep on the free list still carries a stale rqst pointer. rpcrdma_reply_handler() and rpcrdma_unpin_rqst() are the only sites that set rr_rqst; rpcrdma_reply_handler() hands the rep through rpcrdma_rep_put(), and rpcrdma_unpin_rqst() NULLs rr_rqst directly because its error path abandons the rep for teardown cleanup rather than returning it to rb_free_reps.
rpcrdma_reply_put() NULLs req->rl_reply before calling rpcrdma_rep_put(). The previous order placed the rep on rb_free_reps while req->rl_reply still pointed at it; the window was harmless because xprt_rdma_free_slot() holds the req exclusively across the pair, but closing it makes the invariant 'rep on rb_free_reps implies no req references it' strictly checkable.
rpcrdma_sendctx_unmap() and rpcrdma_sendctx_cancel() clear req->rl_sendctx after dropping the sendctx pointer in the sendctx ring. Without this, req->rl_sendctx survives across Send completion and points at a sendctx that may already have been reassigned by rpcrdma_sendctx_get_locked() to a different req. No caller dereferences the stale pointer today -- rpcrdma_prepare_send_sges() overwrites it before the next Send -- but a NULL is a more honest representation of 'the Send is no longer outstanding' and lets the assertion patch that follows trip on any future regression.
--- net/sunrpc/xprtrdma/rpc_rdma.c | 4 ++++ net/sunrpc/xprtrdma/verbs.c | 12 ++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-)
net/sunrpc/xprtrdma/rpc_rdma.c +4 -0
@@ -542,6 +542,7 @@ void rpcrdma_sendctx_unmap(struct rpcrdma_sendctx *sc)rpcrdma_sendctx_dma_unmap (sc); sc->sc_req =NULL ; + req->rl_sendctx =NULL ;rpcrdma_req_put (req); }
@@ -550,8 +551,11 @@ void rpcrdma_sendctx_unmap(struct rpcrdma_sendctx *sc)*/ static void rpcrdma_sendctx_cancel (struct rpcrdma_sendctx *sc) { +struct rpcrdma_req *req = sc->sc_req; +rpcrdma_sendctx_dma_unmap (sc); sc->sc_req =NULL ; + req->rl_sendctx =NULL ; }/* Prepare an SGE for the RPC-over-RDMA transport header.
net/sunrpc/xprtrdma/verbs.c +10 -2
@@ -1080,9 +1080,15 @@ static struct rpcrdma_rep *rpcrdma_rep_get_locked(struct rpcrdma_buffer *buf)* @buf: buffer pool * @rep: rep to release * +* The rep's transient association with an rpc_rqst, established +* by rpcrdma_reply_handler() and torn down here, must not survive +* onto rb_free_reps: rpcrdma_post_recvs() pulls reps from the free +* list to re-post them, and a non-NULL rr_rqst on a free-listed rep +* would imply the rep is still referenced by a req. */ void rpcrdma_rep_put (struct rpcrdma_buffer *buf,struct rpcrdma_rep *rep) { + rep->rr_rqst =NULL ;llist_add (&rep->rr_node, &buf->rb_free_reps); }
@@ -1265,9 +1271,11 @@ rpcrdma_mr_get(struct rpcrdma_xprt *r_xprt)*/ void rpcrdma_reply_put (struct rpcrdma_buffer *buffers,struct rpcrdma_req *req) { -if (req->rl_reply) { -rpcrdma_rep_put (buffers, req->rl_reply); +struct rpcrdma_rep *rep = req->rl_reply; + +if (rep) { req->rl_reply =NULL ; +rpcrdma_rep_put (buffers, rep); }/* I2: rl_reply NULL after the put closes the * 'rep on rb_free_reps still referenced by req' window.
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 28/675 Input: ims-pcu - fix heap-buffer-overflow in ims_pcu_process_data()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Seungjin Bae <[email protected]>
[ Upstream commit 875115b82c295277b81b6dfee7debc725f44e854 ]
The ims_pcu_process_data() processes incoming URB data byte by byte. However, it fails to check if the read_pos index exceeds IMS_PCU_BUF_SIZE.
If a malicious USB device sends a packet larger than IMS_PCU_BUF_SIZE, read_pos will increment indefinitely. Moreover, since read_pos is located immediately after read_buf, the attacker can overwrite read_pos itself to arbitrarily control the index.
This manipulated read_pos is subsequently used in ims_pcu_handle_response() to copy data into cmd_buf, leading to a heap buffer overflow.
Specifically, an attacker can overwrite the cmd_done.wait.head located at offset 136 relative to cmd_buf in the ims_pcu_handle_response(). Consequently, when the driver calls complete(&pcu->cmd_done), it triggers a control flow hijack by using the manipulated pointer.
Fix this by adding a bounds check for read_pos before writing to read_buf. If the packet is too long, discard it, log a warning, and reset the parser state.
--- drivers/input/misc/ims-pcu.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-)
drivers/input/misc/ims-pcu.c +26 -6
@@ -448,6 +448,14 @@ static void ims_pcu_handle_response(struct ims_pcu *pcu) } } +static void ims_pcu_reset_packet (struct ims_pcu *pcu) +{ + pcu->have_stx = true; + pcu->have_dle = false; + pcu->read_pos =0 ; + pcu->check_sum =0 ; +} +static void ims_pcu_process_data (struct ims_pcu *pcu,struct urb *urb) {int i;
@@ -460,6 +468,14 @@ static void ims_pcu_process_data(struct ims_pcu *pcu, struct urb *urb)continue ;if (pcu->have_dle) { +if (pcu->read_pos >=IMS_PCU_BUF_SIZE ) { +dev_warn (pcu->dev, +"Packet too long (%d bytes), discarding\n" , + pcu->read_pos); +ims_pcu_reset_packet (pcu); +continue ; + } + pcu->have_dle = false; pcu->read_buf[pcu->read_pos++] = data; pcu->check_sum += data;
@@ -472,10 +488,8 @@ static void ims_pcu_process_data(struct ims_pcu *pcu, struct urb *urb)dev_warn (pcu->dev,"Unexpected STX at byte %d, discarding old data\n" , pcu->read_pos); +ims_pcu_reset_packet (pcu); pcu->have_stx = true; - pcu->have_dle = false; - pcu->read_pos =0 ; - pcu->check_sum =0 ;break ;case IMS_PCU_PROTOCOL_DLE :
@@ -495,12 +509,18 @@ static void ims_pcu_process_data(struct ims_pcu *pcu, struct urb *urb)ims_pcu_handle_response (pcu); } - pcu->have_stx = false; - pcu->have_dle = false; - pcu->read_pos =0 ; +ims_pcu_reset_packet (pcu);break ;default : +if (pcu->read_pos >=IMS_PCU_BUF_SIZE ) { +dev_warn (pcu->dev, +"Packet too long (%d bytes), discarding\n" , + pcu->read_pos); +ims_pcu_reset_packet (pcu); +continue ; + } + pcu->read_buf[pcu->read_pos++] = data; pcu->check_sum += data;break ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 29/675 Input: ims-pcu - fix logic error in packet reset
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Torokhov <[email protected]>
[ Upstream commit 2c9b85a14abb4811e8d4773ccd13559e59792efb ]
ims_pcu_reset_packet() incorrectly sets have_stx to true, which implies that the start-of-packet delimiter has already been received. This causes the protocol parser to skip waiting for the next STX byte and potentially process garbage data.
Correctly set have_stx to false when resetting the packet state.
--- drivers/input/misc/ims-pcu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/input/misc/ims-pcu.c +1 -1
@@ -450,7 +450,7 @@ static void ims_pcu_handle_response(struct ims_pcu *pcu)static void ims_pcu_reset_packet (struct ims_pcu *pcu) { - pcu->have_stx = true; + pcu->have_stx = false; pcu->have_dle = false; pcu->read_pos =0 ; pcu->check_sum =0 ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 30/675 fuse: fix writeback array overflow when max_pages is one
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junxi Qian <[email protected]>
[ Upstream commit c3880a7b10e487e033dc6f388bda118436566f7a ]
fuse_iomap_writeback_range() appends one folio pointer and one fuse_folio_desc for every dirty range that is merged into the current writeback request. The merge decision checks the byte budget against fc->max_pages and fc->max_write, but it does not check whether the folio and descriptor arrays still have another free slot.
This is not sufficient for fuseblk, where the filesystem block size can be smaller than PAGE_SIZE. With writeback cache enabled and max_pages negotiated as one, contiguous sub-page dirty ranges can fit within the byte budget while spanning more than one folio. The next append can then write past the one-slot folios and descs arrays.
Split the request when the number of already attached folios has reached fc->max_pages. This keeps the folio/descriptor slot accounting in sync with the send decision.
--- fs/fuse/file.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
fs/fuse/file.c +4 -1
@@ -2140,7 +2140,10 @@ static bool fuse_writepage_need_send(struct fuse_conn *fc, loff_t pos,WARN_ON (!ap->num_folios); -/* Reached max pages */ +/* Reached max pages or max folio slots */ +if (ap->num_folios >= fc->max_pages) +return true; +if ((bytes +PAGE_SIZE -1 ) >>PAGE_SHIFT > fc->max_pages)return true;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 31/675 arm64: tegra: Remove fallback compatible for GPCDMA
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Akhil R <[email protected]>
[ Upstream commit ee7863e43228a3143398dc5bbb943c9a735a8fca ]
Remove the fallback compatible string "nvidia,tegra186-gpcdma" for GPCDMA in Tegra264. Tegra186 compatible cannot work on Tegra264 because of the register offset changes and absence of the reset property.
--- arch/arm64/boot/dts/nvidia/tegra264.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/nvidia/tegra264.dtsi +1 -1
@@ -50,7 +50,7 @@ timer@8000000 { }; gpcdma: dma-controller@8400000 { - compatible = "nvidia,tegra264-gpcdma", "nvidia,tegra186-gpcdma"; + compatible = "nvidia,tegra264-gpcdma"; reg = <0x0 0x08400000 0x0 0x210000>; interrupts = <GIC_SPI 584 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 585 IRQ_TYPE_LEVEL_HIGH>,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 32/675 arm64: tegra: Fix CPU compatible string to cortex-a78ae on Tegra234
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sumit Gupta <[email protected]>
[ Upstream commit 0dfa1e960f86e032007882b032c5cc7d14ebe73e ]
The Tegra234 SoC uses Cortex-A78AE cores, not Cortex-A78. Update the compatible string for all CPU nodes to match the actual hardware.
Tegra234 hardware reports:
# head /proc/cpuinfo | egrep 'implementer|part' CPU implementer : 0x41 CPU part : 0xd42
Which maps to (from arch/arm64/include/asm/cputype.h):
#define ARM_CPU_IMP_ARM 0x41
#define ARM_CPU_PART_CORTEX_A78AE 0xD42
--- arch/arm64/boot/dts/nvidia/tegra234.dtsi | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-)
arch/arm64/boot/dts/nvidia/tegra234.dtsi +12 -12
@@ -5345,7 +5345,7 @@ cpus { #size-cells = <0>; cpu0_0: cpu@0 { - compatible = "arm,cortex-a78"; + compatible = "arm,cortex-a78ae"; device_type = "cpu"; reg = <0x00000>;
@@ -5364,7 +5364,7 @@ cpu0_0: cpu@0 { }; cpu0_1: cpu@100 { - compatible = "arm,cortex-a78"; + compatible = "arm,cortex-a78ae"; device_type = "cpu"; reg = <0x00100>;
@@ -5383,7 +5383,7 @@ cpu0_1: cpu@100 { }; cpu0_2: cpu@200 { - compatible = "arm,cortex-a78"; + compatible = "arm,cortex-a78ae"; device_type = "cpu"; reg = <0x00200>;
@@ -5402,7 +5402,7 @@ cpu0_2: cpu@200 { }; cpu0_3: cpu@300 { - compatible = "arm,cortex-a78"; + compatible = "arm,cortex-a78ae"; device_type = "cpu"; reg = <0x00300>;
@@ -5421,7 +5421,7 @@ cpu0_3: cpu@300 { }; cpu1_0: cpu@10000 { - compatible = "arm,cortex-a78"; + compatible = "arm,cortex-a78ae"; device_type = "cpu"; reg = <0x10000>;
@@ -5440,7 +5440,7 @@ cpu1_0: cpu@10000 { }; cpu1_1: cpu@10100 { - compatible = "arm,cortex-a78"; + compatible = "arm,cortex-a78ae"; device_type = "cpu"; reg = <0x10100>;
@@ -5459,7 +5459,7 @@ cpu1_1: cpu@10100 { }; cpu1_2: cpu@10200 { - compatible = "arm,cortex-a78"; + compatible = "arm,cortex-a78ae"; device_type = "cpu"; reg = <0x10200>;
@@ -5478,7 +5478,7 @@ cpu1_2: cpu@10200 { }; cpu1_3: cpu@10300 { - compatible = "arm,cortex-a78"; + compatible = "arm,cortex-a78ae"; device_type = "cpu"; reg = <0x10300>;
@@ -5497,7 +5497,7 @@ cpu1_3: cpu@10300 { }; cpu2_0: cpu@20000 { - compatible = "arm,cortex-a78"; + compatible = "arm,cortex-a78ae"; device_type = "cpu"; reg = <0x20000>;
@@ -5516,7 +5516,7 @@ cpu2_0: cpu@20000 { }; cpu2_1: cpu@20100 { - compatible = "arm,cortex-a78"; + compatible = "arm,cortex-a78ae"; device_type = "cpu"; reg = <0x20100>;
@@ -5535,7 +5535,7 @@ cpu2_1: cpu@20100 { }; cpu2_2: cpu@20200 { - compatible = "arm,cortex-a78"; + compatible = "arm,cortex-a78ae"; device_type = "cpu"; reg = <0x20200>;
@@ -5554,7 +5554,7 @@ cpu2_2: cpu@20200 { }; cpu2_3: cpu@20300 { - compatible = "arm,cortex-a78"; + compatible = "arm,cortex-a78ae"; device_type = "cpu"; reg = <0x20300>;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 33/675 net: dropreason: add SKB_DROP_REASON_RECURSION_LIMIT
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit d15d3de94a4766fb43d7fe7a72ed0479fb268131 ]
ip[6]tunnel_xmit() can drop packets if a too deep recursion level is detected.
Add SKB_DROP_REASON_RECURSION_LIMIT drop reason.
We will use this reason later in __dev_queue_xmit().
Stable-dep-of: 6860b467f569 ("xfrm: propagate -EINPROGRESS from validate_xmit_xfrm()")
--- include/net/dropreason-core.h | 3 +++ include/net/ip6_tunnel.h | 2 +- net/ipv4/ip_tunnel_core.c | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-)
include/net/dropreason-core.h +3 -0
@@ -129,6 +129,7 @@ FN(DUALPI2_STEP_DROP) \ FN(PSP_INPUT) \ FN(PSP_OUTPUT) \ + FN(RECURSION_LIMIT) \ FNe(MAX)/**
@@ -616,6 +617,8 @@ enum skb_drop_reason {SKB_DROP_REASON_PSP_INPUT ,/** @SKB_DROP_REASON_PSP_OUTPUT: PSP output checks failed */ SKB_DROP_REASON_PSP_OUTPUT , +/** @SKB_DROP_REASON_RECURSION_LIMIT: Dead loop on virtual device. */ + SKB_DROP_REASON_RECURSION_LIMIT,/** * @SKB_DROP_REASON_MAX: the maximum of core drop reasons, which * shouldn't be used as a real 'reason' - only for tracing code gen
include/net/ip6_tunnel.h +1 -1
@@ -162,7 +162,7 @@ static inline void ip6tunnel_xmit(struct sock *sk, struct sk_buff *skb, dev->name);DEV_STATS_INC (dev, tx_errors); } -kfree_skb (skb); +kfree_skb_reason (skb,SKB_DROP_REASON_RECURSION_LIMIT );return ; }
net/ipv4/ip_tunnel_core.c +1 -1
@@ -65,7 +65,7 @@ void iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb,DEV_STATS_INC (dev, tx_errors); }ip_rt_put (rt); -kfree_skb (skb); +kfree_skb_reason (skb,SKB_DROP_REASON_RECURSION_LIMIT );return ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 34/675 net: plumb drop reasons to __dev_queue_xmit()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 045f977dd4ebdd3ad8e96cf684917adfc5805adb ]
Add drop reasons to __dev_queue_xmit():
- SKB_DROP_REASON_DEV_READY : device is not UP.
- SKB_DROP_REASON_RECURSION_LIMIT : recursion limit on virtual device is hit.
Also add an unlikely() for the SKB_DROP_REASON_DEV_READY case, and reduce indentation level.
Stable-dep-of: 6860b467f569 ("xfrm: propagate -EINPROGRESS from validate_xmit_xfrm()")
--- net/core/dev.c | 83 ++++++++++++++++++++++++++------------------------ 1 file changed, 43 insertions(+), 40 deletions(-)
net/core/dev.c +43 -40
@@ -4702,9 +4702,10 @@ int __dev_queue_xmit(struct sk_buff *skb, struct net_device *sb_dev) {struct net_device *dev = skb->dev;struct netdev_queue *txq =NULL ; -struct Qdisc *q; -int rc = -ENOMEM ; +enum skb_drop_reason reason; +int cpu, rc = -ENOMEM ;bool again = false; +struct Qdisc *q;skb_reset_mac_header (skb);skb_assert_len (skb);
@@ -4773,59 +4774,61 @@ int __dev_queue_xmit(struct sk_buff *skb, struct net_device *sb_dev)* Check this and shot the lock. It is not prone from deadlocks. *Either shot noqueue qdisc, it is even simpler 8) */ -if (dev->flags &IFF_UP ) { -int cpu =smp_processor_id ();/* ok because BHs are off */ +if (unlikely (!(dev->flags &IFF_UP ))) { + reason =SKB_DROP_REASON_DEV_READY ; + goto drop; + } -if (!netif_tx_owned (txq, cpu)) { -bool is_list = false; + cpu =smp_processor_id ();/* ok because BHs are off */ -if (dev_xmit_recursion ()) - goto recursion_alert; +if (likely (!netif_tx_owned (txq, cpu))) { +bool is_list = false; - skb =validate_xmit_skb (skb, dev, &again); -if (!skb) - goto out; +if (dev_xmit_recursion ()) + goto recursion_alert; -HARD_TX_LOCK (dev, txq, cpu); + skb =validate_xmit_skb (skb, dev, &again); +if (!skb) + goto out; -if (!netif_xmit_stopped (txq)) { - is_list = !!skb->next; +HARD_TX_LOCK (dev, txq, cpu); -dev_xmit_recursion_inc (); - skb =dev_hard_start_xmit (skb, dev, txq, &rc); -dev_xmit_recursion_dec (); +if (!netif_xmit_stopped (txq)) { + is_list = !!skb->next; -/* GSO segments a single SKB into -* a list of frames. TCP expects error -* to mean none of the data was sent. -*/ -if (is_list) - rc =NETDEV_TX_OK ; - } -HARD_TX_UNLOCK (dev, txq); -if (!skb)/* xmit completed */ - goto out; +dev_xmit_recursion_inc (); + skb =dev_hard_start_xmit (skb, dev, txq, &rc); +dev_xmit_recursion_dec (); -net_crit_ratelimited ("Virtual device %s asks to queue packet!\n" , - dev->name); -/* NETDEV_TX_BUSY or queue was stopped */ -if (!is_list) - rc = -ENETDOWN ; - }else { -/* Recursion is detected! It is possible, -* unfortunately +/* GSO segments a single SKB into a list of frames. +* TCP expects error to mean none of the data was sent. */ -recursion_alert: -net_crit_ratelimited ("Dead loop on virtual device %s, fix it urgently!\n" , - dev->name); - rc = -ENETDOWN ; +if (is_list) + rc =NETDEV_TX_OK ; } +HARD_TX_UNLOCK (dev, txq); +if (!skb)/* xmit completed */ + goto out; + +net_crit_ratelimited ("Virtual device %s asks to queue packet!\n" , + dev->name); +/* NETDEV_TX_BUSY or queue was stopped */ +if (!is_list) + rc = -ENETDOWN ; + }else { +/* Recursion is detected! It is possible unfortunately. */ +recursion_alert: +net_crit_ratelimited ("Dead loop on virtual device %s, fix it urgently!\n" , + dev->name); + rc = -ENETDOWN ; } + reason =SKB_DROP_REASON_RECURSION_LIMIT ; +drop:rcu_read_unlock_bh ();dev_core_stats_tx_dropped_inc (dev); -kfree_skb_list (skb); +kfree_skb_list_reason (skb, reason);return rc; out:rcu_read_unlock_bh ();
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 35/675 xfrm: propagate -EINPROGRESS from validate_xmit_xfrm()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Petr Wozniak <[email protected]>
[ Upstream commit 6860b467f569f732b11cbc588ae7e195e90e7e23 ]
validate_xmit_xfrm() returns NULL both when a packet is dropped and when it is stolen by async crypto (-EINPROGRESS from ->xmit()). Callers cannot distinguish the two cases.
f53c723902d1 ("net: Add asynchronous callbacks for xfrm on layer 2.") changed the semantics of a NULL return from "dropped" to "stolen or dropped", but __dev_queue_xmit() was not updated. On virtual/bridge interfaces (noqueue qdisc) __dev_queue_xmit() initialises rc=-ENOMEM and jumps to out: when skb is NULL, returning -ENOMEM to the caller even though the packet will be delivered correctly via xfrm_dev_resume().
Return ERR_PTR(-EINPROGRESS) from validate_xmit_xfrm() for the async case so callers can tell it apart from a real drop. Update __dev_queue_xmit() to handle ERR_PTR(-EINPROGRESS) from validate_xmit_skb() correctly. Update validate_xmit_skb_list() to use IS_ERR_OR_NULL() so that ERR_PTR(-EINPROGRESS) is not mistakenly added to the transmitted list.
--- net/core/dev.c | 10 ++++++++-- net/xfrm/xfrm_device.c | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-)
net/core/dev.c +8 -2
@@ -4005,6 +4005,9 @@ static struct sk_buff *validate_xmit_unreadable_skb(struct sk_buff *skb,return NULL ; } +/* Returns the skb on success, NULL if dropped, or ERR_PTR(-EINPROGRESS) +* if stolen by async xfrm crypto (delivered via xfrm_dev_resume()). +*/ static struct sk_buff *validate_xmit_skb (struct sk_buff *skb,struct net_device *dev,bool *again) {netdev_features_t features;
@@ -4076,7 +4079,7 @@ struct sk_buff *validate_xmit_skb_list(struct sk_buff *skb, struct net_device *d skb->prev = skb; skb =validate_xmit_skb (skb, dev, again); -if (!skb) +if (IS_ERR_OR_NULL (skb))continue ;if (!head)
@@ -4788,8 +4791,11 @@ int __dev_queue_xmit(struct sk_buff *skb, struct net_device *sb_dev) goto recursion_alert; skb =validate_xmit_skb (skb, dev, &again); -if (!skb) +if (IS_ERR_OR_NULL (skb)) { +if (PTR_ERR (skb) == -EINPROGRESS ) + rc =NET_XMIT_SUCCESS ; goto out; + }HARD_TX_LOCK (dev, txq, cpu);
net/xfrm/xfrm_device.c +2 -2
@@ -182,7 +182,7 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur err = x->type_offload->xmit (x, skb, esp_features);if (err) {if (err == -EINPROGRESS ) -return NULL ; +return ERR_PTR (-EINPROGRESS );XFRM_INC_STATS (xs_net (x),LINUX_MIB_XFRMOUTSTATEPROTOERROR );kfree_skb (skb);
@@ -224,7 +224,7 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur pskb = skb2; } -return skb; +return skb ? skb :ERR_PTR (-EINPROGRESS ); }EXPORT_SYMBOL_GPL (validate_xmit_xfrm);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 36/675 xfrm: fix stale skb->prev after async crypto steals a GSO segment
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Petr Wozniak <[email protected]>
[ Upstream commit 3f4c3919baf0944ad96580467c302bc6c7758b00 ]
skb_gso_segment() leaves the segment list head with ->prev pointing at the last segment, an invariant validate_xmit_skb_list() relies on when it sets its tail pointer (tail = skb->prev).
When validate_xmit_xfrm() walks a GSO list and some segments are stolen by async crypto (->xmit() returns -EINPROGRESS), those segments are unlinked from the list but the head ->prev is never updated. If the last segment is the one stolen, the returned head still has ->prev pointing at it, even though it is now owned by the crypto engine and may be freed. validate_xmit_skb_list() later does tail->next = skb, writing through that stale pointer -- a use-after-free.
Repoint skb->prev at the last retained segment before returning.
--- net/xfrm/xfrm_device.c | 8 ++++++++ 1 file changed, 8 insertions(+)
net/xfrm/xfrm_device.c +8 -0
@@ -224,6 +224,14 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur pskb = skb2; } +/* skb_gso_segment() set skb->prev to the last segment, but async +* crypto may have stolen it above without updating ->prev. Repoint +* it at the last retained segment so validate_xmit_skb_list() does +* not chain onto a segment now owned by the crypto engine. +*/ +if (skb) + skb->prev = pskb; +return skb ? skb :ERR_PTR (-EINPROGRESS ); }EXPORT_SYMBOL_GPL (validate_xmit_xfrm);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 37/675 firmware: arm_ffa: Respect firmware advertised RX/TX buffer size limits
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Seth Forshee <[email protected]>
[ Upstream commit 53716a4d745f1dac7aff33f3d1494b701eb2f888 ]
FFA_FEATURES reports the minimum size and alignment boundary required for RXTX_MAP. In FF-A v1.2 and later it can also report a maximum buffer size, with zero meaning that no maximum is enforced.
The driver only used the minimum value and then rounded it up to PAGE_SIZE before invoking RXTX_MAP after commit 83210251fd70 ("firmware: arm_ffa:
Use the correct buffer size during RXTX_MAP"). On systems where PAGE_SIZE is larger than the advertised minimum, this can exceed a non-zero maximum reported by firmware. Older implementations do not advertise a maximum and may also reject the rounded-up size.
Decode the maximum size and clamp the page-aligned minimum to it when it is present. If no maximum is advertised and RXTX_MAP rejects the rounded size with INVALID_PARAMETERS, retry with the advertised minimum size. Record drv_info->rxtx_bufsz only after RXTX_MAP succeeds so it reflects the size registered with firmware.
While there, also update RXTX_MAP_MIN_BUFSZ() to use FIELD_GET() for consistency.
(sudeep.holla: Minor rewording subject and commit message)
--- drivers/firmware/arm_ffa/driver.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-)
drivers/firmware/arm_ffa/driver.c +20 -7
@@ -32,6 +32,7 @@#include <linux/interrupt.h> #include <linux/io.h> #include <linux/kernel.h> +#include <linux/minmax.h> #include <linux/module.h> #include <linux/mm.h> #include <linux/mutex.h>
@@ -55,7 +56,9 @@ (FIELD_PREP(SENDER_ID_MASK, (s)) | FIELD_PREP(RECEIVER_ID_MASK, (r)))#define RXTX_MAP_MIN_BUFSZ_MASK GENMASK(1, 0) -#define RXTX_MAP_MIN_BUFSZ (x) ((x) & RXTX_MAP_MIN_BUFSZ_MASK) +#define RXTX_MAP_MAX_BUFSZ_MASK GENMASK(31, 16) +#define RXTX_MAP_MIN_BUFSZ (x) (FIELD_GET(RXTX_MAP_MIN_BUFSZ_MASK, (x))) +#define RXTX_MAP_MAX_BUFSZ (x) (FIELD_GET(RXTX_MAP_MAX_BUFSZ_MASK, (x)))#define FFA_MAX_NOTIFICATIONS 64
@@ -2088,7 +2091,7 @@ static int __init ffa_init(void) {int ret;u32 buf_sz; -size_t rxtx_bufsz =SZ_4K ; +size_t rxtx_min_bufsz =SZ_4K , rxtx_max_bufsz =0 , rxtx_bufsz; ret =ffa_transport_init (&invoke_ffa_fn);if (ret)
@@ -2111,15 +2114,18 @@ static int __init ffa_init(void) ret =ffa_features (FFA_FN_NATIVE (RXTX_MAP ),0 , &buf_sz,NULL );if (!ret) {if (RXTX_MAP_MIN_BUFSZ (buf_sz) ==1 ) - rxtx_bufsz =SZ_64K ; + rxtx_min_bufsz =SZ_64K ;else if (RXTX_MAP_MIN_BUFSZ (buf_sz) ==2 ) - rxtx_bufsz =SZ_16K ; + rxtx_min_bufsz =SZ_16K ;else - rxtx_bufsz =SZ_4K ; + rxtx_min_bufsz =SZ_4K ; + + rxtx_max_bufsz =RXTX_MAP_MAX_BUFSZ (buf_sz) *SZ_4K ; +if (rxtx_max_bufsz !=0 && rxtx_max_bufsz < rxtx_min_bufsz) + rxtx_max_bufsz = rxtx_min_bufsz; } - rxtx_bufsz =PAGE_ALIGN (rxtx_bufsz); - drv_info->rxtx_bufsz = rxtx_bufsz; + rxtx_bufsz =min_not_zero (PAGE_ALIGN (rxtx_min_bufsz), rxtx_max_bufsz); drv_info->rx_buffer =alloc_pages_exact (rxtx_bufsz,GFP_KERNEL );if (!drv_info->rx_buffer) { ret = -ENOMEM ;
@@ -2135,10 +2141,17 @@ static int __init ffa_init(void) ret =ffa_rxtx_map (virt_to_phys (drv_info->tx_buffer),virt_to_phys (drv_info->rx_buffer), rxtx_bufsz /FFA_PAGE_SIZE ); +if (ret == -EINVAL && !rxtx_max_bufsz && rxtx_min_bufsz < rxtx_bufsz) { + rxtx_bufsz = rxtx_min_bufsz; + ret =ffa_rxtx_map (virt_to_phys (drv_info->tx_buffer), +virt_to_phys (drv_info->rx_buffer), + rxtx_bufsz /FFA_PAGE_SIZE ); + }if (ret) {pr_err ("failed to register FFA RxTx buffers\n" ); goto free_pages; } + drv_info->rxtx_bufsz = rxtx_bufsz;mutex_init (&drv_info->rx_lock);mutex_init (&drv_info->tx_lock);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 38/675 IB/mad: Drop unmatched RMPP responses before reassembly
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Bommarito <[email protected]>
[ Upstream commit d2e52d610b9b09694261632340b801a421e0b0c5 ]
Kernel-handled RMPP receive processing starts reassembly for active DATA responses before the response is matched to an outstanding send. The normal match happens later, after ib_process_rmpp_recv_wc() has either assembled a complete message or consumed the segment.
That ordering lets an unsolicited response that routes to a kernel RMPP agent by the high TID bits allocate or extend RMPP receive state before the full TID and source address are checked against a real request. A reordered burst can therefore reach the receive-side insertion path even though the response would not match any send.
For kernel-handled RMPP DATA responses, require the existing ib_find_send_mad() match before entering RMPP reassembly. The matcher already checks the full TID, management class and source address/GID against the agent wait, backlog and in-flight send lists. If there is no match, drop the response without creating RMPP state.
This leaves the RMPP window behavior unchanged and only rejects responses that have no corresponding request.
--- drivers/infiniband/core/mad.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
drivers/infiniband/core/mad.c +30 -0
@@ -2031,6 +2031,24 @@ void ib_mark_mad_done(struct ib_mad_send_wr_private *mad_send_wr)change_mad_state (mad_send_wr,IB_MAD_STATE_EARLY_RESP ); } +static bool is_kernel_rmpp_data_response (struct ib_mad_agent_private *agent, +struct ib_mad_recv_wc *mad_recv_wc) +{ +const struct ib_mad_hdr *mad_hdr = &mad_recv_wc->recv_buf.mad->mad_hdr; +struct ib_rmpp_mad *rmpp_mad; + +if (!ib_mad_kernel_rmpp_agent (&agent->agent) || + !ib_response_mad (mad_hdr) || + !ib_is_mad_class_rmpp (mad_hdr->mgmt_class)) +return false; + + rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad; + +return (ib_get_rmpp_flags (&rmpp_mad->rmpp_hdr) & +IB_MGMT_RMPP_FLAG_ACTIVE ) && + rmpp_mad->rmpp_hdr.rmpp_type ==IB_MGMT_RMPP_TYPE_DATA ; +} +static void ib_mad_complete_recv (struct ib_mad_agent_private *mad_agent_priv,struct ib_mad_recv_wc *mad_recv_wc) {
@@ -2050,6 +2068,18 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv, }list_add (&mad_recv_wc->recv_buf.list, &mad_recv_wc->rmpp_list); +if (is_kernel_rmpp_data_response (mad_agent_priv, mad_recv_wc)) { +spin_lock_irqsave (&mad_agent_priv->lock, flags); + mad_send_wr =ib_find_send_mad (mad_agent_priv, mad_recv_wc); +spin_unlock_irqrestore (&mad_agent_priv->lock, flags); + +if (!mad_send_wr) { +ib_free_recv_mad (mad_recv_wc); +deref_mad_agent (mad_agent_priv); +return ; + } + } +if (ib_mad_kernel_rmpp_agent (&mad_agent_priv->agent)) { mad_recv_wc =ib_process_rmpp_recv_wc (mad_agent_priv, mad_recv_wc);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 39/675 mtd: mtdswap: remove debugfs stats file on teardown
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pengpeng Hou <[email protected]>
[ Upstream commit 66fb31358108d10245b9e4ef0eef3e7d9747055e ]
mtdswap_add_debugfs() creates an mtdswap_stats debugfs file under the per-MTD debugfs directory, but mtdswap_remove_dev() never removes it before freeing the mtdswap_dev.
Store the returned dentry and remove it during device teardown before the driver-private state is freed.
--- drivers/mtd/mtdswap.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/mtd/mtdswap.c +4 -1
@@ -125,6 +125,7 @@ struct mtdswap_dev {char *page_buf;char *oob_buf; +struct dentry *debugfs_stats; };struct mtdswap_oobdata {
@@ -1262,7 +1263,8 @@ static int mtdswap_add_debugfs(struct mtdswap_dev *d)if (IS_ERR_OR_NULL (root))return -1 ; -debugfs_create_file ("mtdswap_stats" ,S_IRUSR , root, d, &mtdswap_fops); + d->debugfs_stats =debugfs_create_file ("mtdswap_stats" ,0400 , root, + d, &mtdswap_fops);return 0 ; }
@@ -1463,6 +1465,7 @@ static void mtdswap_remove_dev(struct mtd_blktrans_dev *dev) {struct mtdswap_dev *d =MTDSWAP_MBD_TO_MTDSWAP (dev); +debugfs_remove (d->debugfs_stats);del_mtd_blktrans_dev (dev);mtdswap_cleanup (d);kfree (d);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 40/675 mtd: nand: mtk-ecc: stop on ECC idle timeouts
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pengpeng Hou <[email protected]>
[ Upstream commit 16f7ec8d5dc100eafd2c8e06cd30340a30b104a1 ]
mtk_ecc_wait_idle() logs when the encoder or decoder does not become idle, but returns void. Callers can therefore configure a non-idle ECC engine or read parity bytes after an unconfirmed encoder idle state.
Return the idle poll result and propagate it from the enable and encode paths that require the engine to be idle before continuing.
--- drivers/mtd/nand/ecc-mtk.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
drivers/mtd/nand/ecc-mtk.c +12 -4
@@ -123,8 +123,8 @@ static int mt7622_ecc_regs[] = { [ECC_DECIRQ_STA] = 0x144, }; -static inline void mtk_ecc_wait_idle (struct mtk_ecc *ecc, -enum mtk_ecc_operation op) +static inline int mtk_ecc_wait_idle (struct mtk_ecc *ecc, +enum mtk_ecc_operation op) {struct device *dev = ecc->dev;u32 val;
@@ -136,6 +136,8 @@ static inline void mtk_ecc_wait_idle(struct mtk_ecc *ecc,if (ret)dev_warn (dev,"%s NOT idle\n" , op ==ECC_ENCODE ?"encoder" :"decoder" ); + +return ret; }static irqreturn_t mtk_ecc_irq (int irq,void *id)
@@ -312,7 +314,11 @@ int mtk_ecc_enable(struct mtk_ecc *ecc, struct mtk_ecc_config *config)return ret; } -mtk_ecc_wait_idle (ecc, op); + ret =mtk_ecc_wait_idle (ecc, op); +if (ret) { +mutex_unlock (&ecc->lock); +return ret; + } ret =mtk_ecc_config (ecc, config);if (ret) {
@@ -412,7 +418,9 @@ int mtk_ecc_encode(struct mtk_ecc *ecc, struct mtk_ecc_config *config,if (ret) goto timeout; -mtk_ecc_wait_idle (ecc,ECC_ENCODE ); + ret =mtk_ecc_wait_idle (ecc,ECC_ENCODE ); +if (ret) + goto timeout;/* Program ECC bytes to OOB: per sector oob = FDM + ECC + SPARE */ len = (config->strength * ecc->caps->parity_bits +7 ) >>3 ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 41/675 btrfs: reject free space cache with more entries than pages
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiang Mei <[email protected]>
[ Upstream commit a2d8d5647ed854e38f941741aea45b9eb15a6350 ]
When loading a v1 free space cache, __load_free_space_cache() takes num_entries and num_bitmaps straight from the on-disk btrfs_free_space_header. That header is stored in the tree_root under a key with type 0, which the tree-checker has no case for, so neither count is validated before the load trusts it.
The load loops num_entries times and maps the next page whenever the current one runs out, going through io_ctl_check_crc() -> io_ctl_map_page(), which does io_ctl->pages[io_ctl->index++]. But pages[] is allocated in io_ctl_init() from the cache inode's i_size, not from num_entries:
num_pages = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE); io_ctl->pages = kcalloc(num_pages, sizeof(struct page *), GFP_NOFS);
So if num_entries claims more records than the pages can hold, io_ctl->index runs off the end of pages[]. The write side never hits this because io_ctl_add_entry() and io_ctl_add_bitmap() both stop once io_ctl->index >= io_ctl->num_pages; the read side just never had the same check.
To trigger it, take a clean cache (num_entries = <N> here), set num_entries in the header to 0x10000, and fix up the leaf checksum so it still passes the tree-checker. The cache inode has i_size = 65536, so num_pages is 16 and pages[] is a 16-pointer (kmalloc-128) array. The load now tries to read 65536 entries, io_ctl->index walks up to 16, and pages[16] is read past the array:
BUG: KASAN: slab-out-of-bounds in io_ctl_check_crc (fs/btrfs/free-space-cache.c:420 fs/btrfs/free-space-cache.c:565) Read of size 8 at addr ffff88800c833a80 by task kworker/u8:3/58 io_ctl_check_crc (fs/btrfs/free-space-cache.c:420 fs/btrfs/free-space-cache.c:565) __load_free_space_cache (fs/btrfs/free-space-cache.c:655 fs/btrfs/free-space-cache.c:820) load_free_space_cache (fs/btrfs/free-space-cache.c:1017) caching_thread (fs/btrfs/block-group.c:880) btrfs_work_helper (fs/btrfs/async-thread.c:312) process_one_work worker_thread kthread ret_from_fork
free-space-cache.c:420 is io_ctl_map_page(), inlined into io_ctl_check_crc() at line 565, which is why that is the frame KASAN names. The out-of-bounds slot is then treated as a struct page and handed to crc32c(), so the bad read turns into a GP fault.
Add the missing check to io_ctl_check_crc(), which is where both the entry loop and the bitmap loop end up. When num_entries is too large the load now fails like any corrupt cache: __load_free_space_cache() drops it and rebuilds the free space from the extent tree, so a valid cache is never rejected.
--- fs/btrfs/free-space-cache.c | 3 +++ 1 file changed, 3 insertions(+)
fs/btrfs/free-space-cache.c +3 -0
@@ -554,6 +554,9 @@ static int io_ctl_check_crc(struct btrfs_io_ctl *io_ctl, int index)u32 crc = ~(u32 )0 ;unsigned offset =0 ; +if (index >= io_ctl->num_pages) +return -EIO ; +if (index ==0 ) offset =sizeof (u32) * io_ctl->num_pages;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 42/675 btrfs: fix root leak if its reloc root is unexpected in merge_reloc_roots()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
[ Upstream commit ce6050bafb4e33377dc17fcc357736bfc351180c ]
If we have an unexpected reloc_root for our root, we jump to the out label but never drop the reference we obtained for root, resulting in a leak. Add a missing btrfs_put_root() call.
--- fs/btrfs/relocation.c | 1 + 1 file changed, 1 insertion(+)
fs/btrfs/relocation.c +1 -0
@@ -1857,6 +1857,7 @@ void merge_reloc_roots(struct reloc_control *rc)* corruption, e.g. bad reloc tree key offset. */ ret = -EINVAL ; +btrfs_put_root (root); goto out; } ret =merge_reloc_root (rc, root);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 43/675 btrfs: use bool type for btrfs_path members used as booleans
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
[ Upstream commit d7fe41044b3ac8f9b5965de499a13ac9ae947e79 ]
Many fields of struct btrfs_path are used as booleans but their type is an unsigned int (of one 1 bit width to save space). Change the type to bool keeping the :1 suffix so that they combine with the previous u8 fields in order to save space. This makes the code more clear by using explicit true/false and more in line with the preferred style, preserving the size of the structure.
Stable-dep-of: 3dcd50730814 ("btrfs: fallback to transaction csum tree on a commit root csum miss")
--- fs/btrfs/backref.c | 16 ++++++++-------- fs/btrfs/block-group.c | 8 ++++---- fs/btrfs/ctree.c | 28 ++++++++++++++-------------- fs/btrfs/ctree.h | 16 ++++++++-------- fs/btrfs/defrag.c | 4 ++-- fs/btrfs/dev-replace.c | 4 ++-- fs/btrfs/extent-tree.c | 8 ++++---- fs/btrfs/file-item.c | 12 ++++++------ fs/btrfs/free-space-cache.c | 4 ++-- fs/btrfs/free-space-tree.c | 4 ++-- fs/btrfs/inode-item.c | 2 +- fs/btrfs/inode.c | 4 ++-- fs/btrfs/qgroup.c | 4 ++-- fs/btrfs/raid-stripe-tree.c | 4 ++-- fs/btrfs/relocation.c | 8 ++++---- fs/btrfs/scrub.c | 20 ++++++++++---------- fs/btrfs/send.c | 14 +++++++------- fs/btrfs/tree-log.c | 20 ++++++++++---------- fs/btrfs/volumes.c | 6 +++--- fs/btrfs/xattr.c | 2 +- 20 files changed, 94 insertions(+), 94 deletions(-)
fs/btrfs/backref.c +8 -8
@@ -1408,12 +1408,12 @@ static int find_parent_nodes(struct btrfs_backref_walk_ctx *ctx,if (!path)return -ENOMEM ;if (!ctx->trans) { - path->search_commit_root =1 ; - path->skip_locking =1 ; + path->search_commit_root = true; + path->skip_locking = true; }if (ctx->time_seq ==BTRFS_SEQ_LAST ) - path->skip_locking =1 ; + path->skip_locking = true; again: head =NULL ;
@@ -1560,7 +1560,7 @@ static int find_parent_nodes(struct btrfs_backref_walk_ctx *ctx,btrfs_release_path (path); - ret =add_missing_keys (ctx->fs_info, &preftrees, path->skip_locking ==0 ); + ret =add_missing_keys (ctx->fs_info, &preftrees, !path->skip_locking);if (ret) goto out;
@@ -2833,8 +2833,8 @@ struct btrfs_backref_iter *btrfs_backref_iter_alloc(struct btrfs_fs_info *fs_inf }/* Current backref iterator only supports iteration in commit root */ - ret->path->search_commit_root =1 ; - ret->path->skip_locking =1 ; + ret->path->search_commit_root = true; + ret->path->skip_locking = true; ret->fs_info = fs_info;return ret;
@@ -3307,8 +3307,8 @@ static int handle_indirect_tree_backref(struct btrfs_trans_handle *trans, level = cur->level +1 ;/* Search the tree to find parent blocks referring to the block */ - path->search_commit_root =1 ; - path->skip_locking =1 ; + path->search_commit_root = true; + path->skip_locking = true; path->lowest_level = level; ret =btrfs_search_slot (NULL , root, tree_key, path,0 ,0 ); path->lowest_level =0 ;
fs/btrfs/block-group.c +4 -4
@@ -613,8 +613,8 @@ static int sample_block_group_extent_item(struct btrfs_caching_control *caching_ extent_root =btrfs_extent_root (fs_info,max_t (u64, block_group->start,BTRFS_SUPER_INFO_OFFSET )); - path->skip_locking =1 ; - path->search_commit_root =1 ; + path->skip_locking = true; + path->search_commit_root = true; path->reada =READA_FORWARD ; search_offset = index *div_u64 (block_group->length, max_index);
@@ -744,8 +744,8 @@ static int load_extent_tree_free(struct btrfs_caching_control *caching_ctl)* root to add free space. So we skip locking and search the commit * root, since its read-only */ - path->skip_locking =1 ; - path->search_commit_root =1 ; + path->skip_locking = true; + path->search_commit_root = true; path->reada =READA_FORWARD ; key.objectid = last;
fs/btrfs/ctree.c +14 -14
@@ -1709,9 +1709,9 @@ static struct extent_buffer *btrfs_search_slot_get_root(struct btrfs_root *root, level =btrfs_header_level (b);/* * Ensure that all callers have set skip_locking when -* p->search_commit_root = 1. +* p->search_commit_root is true. */ -ASSERT (p->skip_locking ==1 ); +ASSERT (p->skip_locking); goto out; }
@@ -3858,10 +3858,10 @@ static noinline int setup_leaf_for_split(struct btrfs_trans_handle *trans, }btrfs_release_path (path); - path->keep_locks =1 ; - path->search_for_split =1 ; + path->keep_locks = true; + path->search_for_split = true; ret =btrfs_search_slot (trans, root, &key, path,0 ,1 ); - path->search_for_split =0 ; + path->search_for_split = false;if (ret >0 ) ret = -EAGAIN ;if (ret <0 )
@@ -3888,11 +3888,11 @@ static noinline int setup_leaf_for_split(struct btrfs_trans_handle *trans,if (ret) goto err; - path->keep_locks =0 ; + path->keep_locks = false;btrfs_unlock_up_safe (path,1 );return 0 ; err: - path->keep_locks =0 ; + path->keep_locks = false;return ret; }
@@ -4610,11 +4610,11 @@ int btrfs_search_forward(struct btrfs_root *root, struct btrfs_key *min_key,u32 nritems;int level;int ret =1 ; -int keep_locks = path->keep_locks; +const bool keep_locks = path->keep_locks;ASSERT (!path->nowait);ASSERT (path->lowest_level ==0 ); - path->keep_locks =1 ; + path->keep_locks = true; again: cur =btrfs_read_lock_root_node (root); level =btrfs_header_level (cur);
@@ -4704,7 +4704,7 @@ int btrfs_search_forward(struct btrfs_root *root, struct btrfs_key *min_key,* 0 is returned if another key is found, < 0 if there are any errors * and 1 is returned if there are no higher keys in the tree * -* path->keep_locks should be set to 1 on the search made before +* path->keep_locks should be set to true on the search made before * calling this function. */ int btrfs_find_next_key(struct btrfs_root *root, struct btrfs_path *path,
@@ -4803,13 +4803,13 @@ int btrfs_next_old_leaf(struct btrfs_root *root, struct btrfs_path *path, next =NULL ;btrfs_release_path (path); - path->keep_locks =1 ; + path->keep_locks = true;if (time_seq) { ret =btrfs_search_old_slot (root, &key, path, time_seq); }else {if (path->need_commit_sem) { - path->need_commit_sem =0 ; + path->need_commit_sem = false; need_commit_sem = true;if (path->nowait) {if (!down_read_trylock (&fs_info->commit_root_sem)) {
@@ -4822,7 +4822,7 @@ int btrfs_next_old_leaf(struct btrfs_root *root, struct btrfs_path *path, } ret =btrfs_search_slot (NULL , root, &key, path,0 ,0 ); } - path->keep_locks =0 ; + path->keep_locks = false;if (ret <0 ) goto done;
@@ -4961,7 +4961,7 @@ int btrfs_next_old_leaf(struct btrfs_root *root, struct btrfs_path *path,if (need_commit_sem) {int ret2; - path->need_commit_sem =1 ; + path->need_commit_sem = true; ret2 =finish_need_commit_sem_search (path);up_read (&fs_info->commit_root_sem);if (ret2)
fs/btrfs/ctree.h +8 -8
@@ -65,21 +65,21 @@ struct btrfs_path {* set by btrfs_split_item, tells search_slot to keep all locks * and to force calls to keep space in the nodes */ - unsigned int search_for_split:1; + bool search_for_split:1;/* Keep some upper locks as we walk down. */ - unsigned int keep_locks:1; - unsigned int skip_locking:1; - unsigned int search_commit_root:1; - unsigned int need_commit_sem:1; - unsigned int skip_release_on_error:1; + bool keep_locks:1; + bool skip_locking:1; + bool search_commit_root:1; + bool need_commit_sem:1; + bool skip_release_on_error:1;/* * Indicate that new item (btrfs_search_slot) is extending already * existing item and ins_len contains only the data size and not item * header (ie. sizeof(struct btrfs_item) is not included). */ - unsigned int search_for_extension:1; + bool search_for_extension:1;/* Stop search if any locks need to be taken (for read) */ - unsigned int nowait:1; + bool nowait:1; };#define BTRFS_PATH_AUTO_FREE (path_name) \
fs/btrfs/defrag.c +2 -2
@@ -472,7 +472,7 @@ static int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,memcpy (&key, &root->defrag_progress,sizeof (key)); } - path->keep_locks =1 ; + path->keep_locks = true; ret =btrfs_search_forward (root, &key, path,BTRFS_OLDEST_GENERATION );if (ret <0 )
@@ -515,7 +515,7 @@ static int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,/* * Now that we reallocated the node we can find the next key. Note that * btrfs_find_next_key() can release our path and do another search -* without COWing, this is because even with path->keep_locks = 1, +* without COWing, this is because even with path->keep_locks == true, * btrfs_search_slot() / ctree.c:unlock_up() does not keeps a lock on a * node when path->slots[node_level - 1] does not point to the last * item or a slot beyond the last item (ctree.c:unlock_up()). Therefore
fs/btrfs/dev-replace.c +2 -2
@@ -489,8 +489,8 @@ static int mark_block_group_to_copy(struct btrfs_fs_info *fs_info, } path->reada =READA_FORWARD ; - path->search_commit_root =1 ; - path->skip_locking =1 ; + path->search_commit_root = true; + path->skip_locking = true; key.objectid = src_dev->devid; key.type =BTRFS_DEV_EXTENT_KEY ;
fs/btrfs/extent-tree.c +4 -4
@@ -788,7 +788,7 @@ int lookup_inline_extent_backref(struct btrfs_trans_handle *trans, want =extent_ref_type (parent, owner);if (insert) { extra_size =btrfs_extent_inline_ref_size (want); - path->search_for_extension =1 ; + path->search_for_extension = true; }else extra_size =-1 ;
@@ -954,7 +954,7 @@ int lookup_inline_extent_backref(struct btrfs_trans_handle *trans,if (!path->keep_locks) {btrfs_release_path (path); - path->keep_locks =1 ; + path->keep_locks = true; goto again; }
@@ -975,11 +975,11 @@ int lookup_inline_extent_backref(struct btrfs_trans_handle *trans, *ref_ret = (struct btrfs_extent_inline_ref *)ptr; out:if (path->keep_locks) { - path->keep_locks =0 ; + path->keep_locks = false;btrfs_unlock_up_safe (path,1 ); }if (insert) - path->search_for_extension =0 ; + path->search_for_extension = false;return ret; }
fs/btrfs/file-item.c +6 -6
@@ -394,8 +394,8 @@ int btrfs_lookup_bio_sums(struct btrfs_bio *bbio)* between reading the free space cache and updating the csum tree. */ if (btrfs_is_free_space_inode (inode)) { - path->search_commit_root =1 ; - path->skip_locking =1 ; + path->search_commit_root = true; + path->skip_locking = true; }/*
@@ -423,8 +423,8 @@ int btrfs_lookup_bio_sums(struct btrfs_bio *bbio)* from across transactions. */ if (bbio->csum_search_commit_root) { - path->search_commit_root =1 ; - path->skip_locking =1 ; + path->search_commit_root = true; + path->skip_locking = true;down_read (&fs_info->commit_root_sem); }
@@ -1168,10 +1168,10 @@ int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans, }btrfs_release_path (path); - path->search_for_extension =1 ; + path->search_for_extension = true; ret =btrfs_search_slot (trans, root, &file_key, path, csum_size,1 ); - path->search_for_extension =0 ; + path->search_for_extension = false;if (ret <0 ) goto out;
fs/btrfs/free-space-cache.c +2 -2
@@ -971,8 +971,8 @@ int load_free_space_cache(struct btrfs_block_group *block_group) path =btrfs_alloc_path ();if (!path)return 0 ; - path->search_commit_root =1 ; - path->skip_locking =1 ; + path->search_commit_root = true; + path->skip_locking = true;/* * We must pass a path with search_commit_root set to btrfs_iget in
fs/btrfs/free-space-tree.c +2 -2
@@ -1699,8 +1699,8 @@ int btrfs_load_free_space_tree(struct btrfs_caching_control *caching_ctl)* Just like caching_thread() doesn't want to deadlock on the extent * tree, we don't want to deadlock on the free space tree. */ - path->skip_locking =1 ; - path->search_commit_root =1 ; + path->skip_locking = true; + path->search_commit_root = true; path->reada =READA_FORWARD ; info =btrfs_search_free_space_info (NULL , block_group, path,0 );
fs/btrfs/inode-item.c +1 -1
@@ -312,7 +312,7 @@ int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans,if (!path)return -ENOMEM ; - path->skip_release_on_error =1 ; + path->skip_release_on_error = true; ret =btrfs_insert_empty_item (trans, root, path, &key, ins_len);if (ret == -EEXIST ) {
fs/btrfs/inode.c +2 -2
@@ -7170,8 +7170,8 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,* point the commit_root has everything we need. */ if (btrfs_is_free_space_inode (inode)) { - path->search_commit_root =1 ; - path->skip_locking =1 ; + path->search_commit_root = true; + path->skip_locking = true; } ret =btrfs_lookup_file_extent (NULL , root, path, objectid, start,0 );
fs/btrfs/qgroup.c +2 -2
@@ -3882,8 +3882,8 @@ static void btrfs_qgroup_rescan_worker(struct btrfs_work *work)* Rescan should only search for commit root, and any later difference * should be recorded by qgroup */ - path->search_commit_root =1 ; - path->skip_locking =1 ; + path->search_commit_root = true; + path->skip_locking = true;while (!ret && !(stopped =rescan_should_stop (fs_info))) { trans =btrfs_start_transaction (fs_info->fs_root,0 );
fs/btrfs/raid-stripe-tree.c +2 -2
@@ -394,8 +394,8 @@ int btrfs_get_raid_extent_offset(struct btrfs_fs_info *fs_info,return -ENOMEM ;if (stripe->rst_search_commit_root) { - path->skip_locking =1 ; - path->search_commit_root =1 ; + path->skip_locking = true; + path->search_commit_root = true; } ret =btrfs_search_slot (NULL , stripe_root, &stripe_key, path,0 ,0 );
fs/btrfs/relocation.c +4 -4
@@ -3176,8 +3176,8 @@ static int __add_tree_block(struct reloc_control *rc, key.offset = blocksize; } - path->search_commit_root =1 ; - path->skip_locking =1 ; + path->search_commit_root = true; + path->skip_locking = true; ret =btrfs_search_slot (NULL , rc->extent_root, &key, path,0 ,0 );if (ret <0 )return ret;
@@ -3369,8 +3369,8 @@ int find_next_extent(struct reloc_control *rc, struct btrfs_path *path, key.type =BTRFS_EXTENT_ITEM_KEY ; key.offset =0 ; - path->search_commit_root =1 ; - path->skip_locking =1 ; + path->search_commit_root = true; + path->skip_locking = true; ret =btrfs_search_slot (NULL , rc->extent_root, &key, path,0 ,0 );if (ret <0 )
fs/btrfs/scrub.c +10 -10
@@ -463,10 +463,10 @@ static noinline_for_stack struct scrub_ctx *scrub_setup_ctx(refcount_set (&sctx->refs,1 ); sctx->is_dev_replace = is_dev_replace; sctx->fs_info = fs_info; - sctx->extent_path.search_commit_root =1 ; - sctx->extent_path.skip_locking =1 ; - sctx->csum_path.search_commit_root =1 ; - sctx->csum_path.skip_locking =1 ; + sctx->extent_path.search_commit_root = true; + sctx->extent_path.skip_locking = true; + sctx->csum_path.search_commit_root = true; + sctx->csum_path.skip_locking = true;for (i =0 ; i <SCRUB_TOTAL_STRIPES ; i++) {int ret;
@@ -2103,10 +2103,10 @@ static int scrub_raid56_parity_stripe(struct scrub_ctx *sctx,* as the data stripe bytenr may be smaller than previous extent. Thus * we have to use our own extent/csum paths. */ - extent_path.search_commit_root =1 ; - extent_path.skip_locking =1 ; - csum_path.search_commit_root =1 ; - csum_path.skip_locking =1 ; + extent_path.search_commit_root = true; + extent_path.skip_locking = true; + csum_path.search_commit_root = true; + csum_path.skip_locking = true;for (int i =0 ; i < data_stripes; i++) {int stripe_index;
@@ -2630,8 +2630,8 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx,return -ENOMEM ; path->reada =READA_FORWARD ; - path->search_commit_root =1 ; - path->skip_locking =1 ; + path->search_commit_root = true; + path->skip_locking = true; key.objectid = scrub_dev->devid; key.type =BTRFS_DEV_EXTENT_KEY ;
fs/btrfs/send.c +7 -7
@@ -633,9 +633,9 @@ static struct btrfs_path *alloc_path_for_send(void) path =btrfs_alloc_path ();if (!path)return NULL ; - path->search_commit_root =1 ; - path->skip_locking =1 ; - path->need_commit_sem =1 ; + path->search_commit_root = true; + path->skip_locking = true; + path->need_commit_sem = true;return path; }
@@ -7643,10 +7643,10 @@ static int btrfs_compare_trees(struct btrfs_root *left_root, goto out; } - left_path->search_commit_root =1 ; - left_path->skip_locking =1 ; - right_path->search_commit_root =1 ; - right_path->skip_locking =1 ; + left_path->search_commit_root = true; + left_path->skip_locking = true; + right_path->search_commit_root = true; + right_path->skip_locking = true;/* * Strategy: Go to the first items of both trees. Then do
fs/btrfs/tree-log.c +10 -10
@@ -602,9 +602,9 @@ static int overwrite_item(struct walk_control *wc) insert:btrfs_release_path (wc->subvol_path);/* try to insert the key into the destination tree */ - wc->subvol_path->skip_release_on_error =1 ; + wc->subvol_path->skip_release_on_error = true; ret =btrfs_insert_empty_item (trans, root, wc->subvol_path, &wc->log_key, item_size); - wc->subvol_path->skip_release_on_error =0 ; + wc->subvol_path->skip_release_on_error = false; dst_eb = wc->subvol_path->nodes[0 ]; dst_slot = wc->subvol_path->slots[0 ];
@@ -5734,8 +5734,8 @@ static int btrfs_check_ref_name_override(struct extent_buffer *eb, search_path =btrfs_alloc_path ();if (!search_path)return -ENOMEM ; - search_path->search_commit_root =1 ; - search_path->skip_locking =1 ; + search_path->search_commit_root = true; + search_path->skip_locking = true;while (cur_offset < item_size) {u64 parent;
@@ -6052,8 +6052,8 @@ static int conflicting_inode_is_dir(struct btrfs_root *root, u64 ino, key.type =BTRFS_INODE_ITEM_KEY ; key.offset =0 ; - path->search_commit_root =1 ; - path->skip_locking =1 ; + path->search_commit_root = true; + path->skip_locking = true; ret =btrfs_search_slot (NULL , root, &key, path,0 ,0 );if (WARN_ON_ONCE (ret >0 )) {
@@ -6073,8 +6073,8 @@ static int conflicting_inode_is_dir(struct btrfs_root *root, u64 ino, }btrfs_release_path (path); - path->search_commit_root =0 ; - path->skip_locking =0 ; + path->search_commit_root = false; + path->skip_locking = false;return ret; }
@@ -7232,8 +7232,8 @@ static int btrfs_log_all_parents(struct btrfs_trans_handle *trans, path =btrfs_alloc_path ();if (!path)return -ENOMEM ; - path->skip_locking =1 ; - path->search_commit_root =1 ; + path->skip_locking = true; + path->search_commit_root = true; key.objectid = ino; key.type =BTRFS_INODE_REF_KEY ;
fs/btrfs/volumes.c +3 -3
@@ -1839,8 +1839,8 @@ static int find_free_dev_extent(struct btrfs_device *device, u64 num_bytes, } path->reada =READA_FORWARD ; - path->search_commit_root =1 ; - path->skip_locking =1 ; + path->search_commit_root = true; + path->skip_locking = true; key.objectid = device->devid; key.type =BTRFS_DEV_EXTENT_KEY ;
@@ -7627,7 +7627,7 @@ int btrfs_read_chunk_tree(struct btrfs_fs_info *fs_info)* chunk tree, to keep it simple, just skip locking on the chunk tree. */ ASSERT (!test_bit (BTRFS_FS_OPEN , &fs_info->flags)); - path->skip_locking =1 ; + path->skip_locking = true;/* * Read all device items, and then all the chunk items. All
fs/btrfs/xattr.c +1 -1
@@ -97,7 +97,7 @@ int btrfs_setxattr(struct btrfs_trans_handle *trans, struct inode *inode, path =btrfs_alloc_path ();if (!path)return -ENOMEM ; - path->skip_release_on_error =1 ; + path->skip_release_on_error = true;if (!value) { di = btrfs_lookup_xattr(trans, root, path,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 44/675 btrfs: fallback to transaction csum tree on a commit root csum miss
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Boris Burkov <[email protected]>
[ Upstream commit 3dcd50730814e5220072d2b26d0587af6bfb6dbe ]
We have been running with commit root csums enabled for some time and have noticed a slight uptick in zero csum errors. Investigating those revealed that they were same transaction reads of extents that were just relocated, but the extent map generation was long ago.
It turns out that relocation intentionally does not update the extent generation (replace_file_extents()), but must write a new csum since the data has moved, so we must account for this with commit root csum reading.
Luckily this is a short lived condition: after the relocation transaction the commit root will once again have the csum. So we can add a generic fallback to the lookup to try again with the transaction csum root.
--- fs/btrfs/file-item.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-)
fs/btrfs/file-item.c +25 -1
@@ -350,6 +350,7 @@ int btrfs_lookup_bio_sums(struct btrfs_bio *bbio)const unsigned int nblocks = orig_len >> fs_info->sectorsize_bits;int ret =0 ;u32 bio_offset =0 ; +bool using_commit_root = false;if ((inode->flags &BTRFS_INODE_NODATASUM ) ||test_bit (BTRFS_FS_STATE_NO_DATA_CSUMS , &fs_info->fs_state))
@@ -423,6 +424,7 @@ int btrfs_lookup_bio_sums(struct btrfs_bio *bbio)* from across transactions. */ if (bbio->csum_search_commit_root) { + using_commit_root = true; path->search_commit_root = true; path->skip_locking = true;down_read (&fs_info->commit_root_sem);
@@ -455,6 +457,28 @@ int btrfs_lookup_bio_sums(struct btrfs_bio *bbio)* assume this is the case. */ if (count ==0 ) { +/* +* If an extent is relocated in the current transaction +* then relocation writes a new csum without updating +* the extent map generation. Until the next commit, we +* will see a hole in that case, so we need to fallback +* to searching the transaction csum root. +* +* Note that a commit root lookup of a referenced extent can +* only miss, not return a stale csum. A freed extent's csum +* is deleted in the same transaction and its bytenr is not +* reusable until that transaction has committed and the +* extent is unpinned. +*/ +if (using_commit_root) { +up_read (&fs_info->commit_root_sem); + using_commit_root = false; + path->search_commit_root = false; + path->skip_locking = false; +btrfs_release_path (path); +continue ; + } +memset (csum_dst,0 , csum_size); count =1 ;
@@ -473,7 +497,7 @@ int btrfs_lookup_bio_sums(struct btrfs_bio *bbio) bio_offset += count * sectorsize; } -if (bbio->csum_search_commit_root) +if (using_commit_root)up_read (&fs_info->commit_root_sem);return ret; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 45/675 firmware: arm_ffa: Fix NULL dereference in ffa_partition_info_get()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Unnathi Chalicheemala <[email protected]>
[ Upstream commit 8ae5f8e4836667fcaffdf2e3c6068b0a8b364dd8 ]
ffa_partition_info_get() passes uuid_str directly to uuid_parse() without a NULL check. When a caller passes NULL, uuid_parse() -> __uuid_parse() -> uuid_is_valid() dereferences the pointer, causing a kernel panic:
| Unable to handle kernel NULL pointer dereference at virtual address | 0000000000000040 | pc : uuid_parse+0x40/0xac | lr : ffa_partition_info_get+0x1c/0x94 [arm_ffa]
Add a NULL guard before uuid_parse() so a NULL argument returns -ENODEV instead of crashing. Callers are expected to always supply a valid partition UUID, so NULL is not a supported input.
--- drivers/firmware/arm_ffa/driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/firmware/arm_ffa/driver.c +1 -1
@@ -1133,7 +1133,7 @@ static int ffa_partition_info_get(const char *uuid_str,uuid_t uuid;struct ffa_partition_info *pbuf; -if (uuid_parse (uuid_str, &uuid)) { +if (!uuid_str ||uuid_parse (uuid_str, &uuid)) {pr_err ("invalid uuid (%s)\n" , uuid_str);return -ENODEV ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 46/675 sched/ext: Avoid null ptr traversal when ->put_prev_task() is called with NULL next
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Stultz <[email protected]>
[ Upstream commit 12b5cd99a05f7cbc2ceb88b3b9601d404ef2236a ]
Early when trying to get sched_ext and proxy-exe working together, I kept tripping over NULL ptr in put_prev_task_scx() on the line:
if (sched_class_above(&ext_sched_class, next->sched_class)) {
Which was due to put_prev_task() passes a NULL next, calling:
prev->sched_class->put_prev_task(rq, prev, NULL);
put_prev_task_scx() already guards for a NULL next in the switch_class case, but doesn't seem to have a guard for sched_class_above() check.
I can't say I understand why this doesn't trip usually without proxy-exec. And in newer kernels there are way fewer put_prev_task(), and I can't easily reproduce the issue now even with proxy-exec.
But we still have one put_prev_task() call left in core.c that seems like it could trip this, so I wanted to send this out for consideration.
tj: put_prev_task() can be called with NULL @next; however, when @p is queued, that doesn't happen, so this condition shouldn't currently be triggerable. The connection isn't straightforward or necessarily reliable, so add the NULL check even if it can't currently be triggered.
Stable-dep-of: b7d9c359e5cf ("sched_ext: Don't warn on core-sched forced idle in put_prev_task_scx()")
--- kernel/sched/ext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/sched/ext.c +1 -1
@@ -2396,7 +2396,7 @@ static void put_prev_task_scx(struct rq *rq, struct task_struct *p,* ops.enqueue() that @p is the only one available for this cpu, * which should trigger an explicit follow-up scheduling event. */ -if (sched_class_above (&ext_sched_class, next->sched_class)) { +if (next &&sched_class_above (&ext_sched_class, next->sched_class)) {WARN_ON_ONCE (!(sch->ops.flags &SCX_OPS_ENQ_LAST ));do_enqueue_task (rq, p,SCX_ENQ_LAST ,-1 ); }else {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 47/675 sched_ext: Dont warn on core-sched forced idle in put_prev_task_scx()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tejun Heo <[email protected]>
[ Upstream commit b7d9c359e5cf867f7eb23df3bb1c6b9e58af24da ]
put_prev_task_scx() warns when a runnable task drops to a lower sched_class without SCX_OPS_ENQ_LAST, on the assumption that balance_one() would have kept it running. Core scheduling breaks that: a forced-idle SMT sibling reschedules through the core_pick fast path in pick_next_task(), which skips pick_task_scx() and thus balance_one(), so a runnable task can drop to idle with ENQ_LAST unset.
Gate the warning on sched_cpu_cookie_match(): a cookie mismatch means core scheduling forced the idle, while a match (or core scheduling off) still catches a genuine missing-ENQ_LAST drop.
--- kernel/sched/ext.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
kernel/sched/ext.c +6 -1
@@ -2395,9 +2395,14 @@ static void put_prev_task_scx(struct rq *rq, struct task_struct *p,* sched_class, %SCX_OPS_ENQ_LAST must be set. Tell * ops.enqueue() that @p is the only one available for this cpu, * which should trigger an explicit follow-up scheduling event. +* +* Core scheduling can force this CPU idle while @p stays +* runnable. @p's cookie then won't match the core's, so skip +* the warning in that case. */ if (next &&sched_class_above (&ext_sched_class, next->sched_class)) { -WARN_ON_ONCE (!(sch->ops.flags &SCX_OPS_ENQ_LAST )); +WARN_ON_ONCE (sched_cpu_cookie_match (rq, p) && + !(sch->ops.flags &SCX_OPS_ENQ_LAST ));do_enqueue_task (rq, p,SCX_ENQ_LAST ,-1 ); }else {do_enqueue_task (rq, p,0 ,-1 );
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 48/675 xfrm: reject optional IPTFS templates in outbound policies
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Antony Antony <[email protected]>
[ Upstream commit ea528f18231ec0f33317be57f8866913b19aba6e ]
syzbot reported a stack-out-of-bounds read in xfrm_state_find() which flows from xfrm_tmpl_resolve_one().
Commit 3d776e31c841 ("xfrm: Reject optional tunnel/BEET mode templates in outbound policies") disallowed optional tunnel and BEET in outbound policies to prevent this. Later when IPTFS added, it was not covered by that fix and can still trigger the out-of-bounds read;
Extend the check to disallow optional IPTFS in outbound policies as well. IPTFS should be identical to tunnel mode.
IN and FWD policies are not affected: xfrm_tmpl_resolve_one() is only reachable via the outbound path.
Reproducer, before:
ip link add dummy0 type dummy
ip link set dummy0 up
ip addr add 10.1.1.1/24 dev dummy0
ip xfrm policy add src 10.1.1.1/32 dst 10.1.1.2/32 dir out tmpl
src fc00::dead:1 dst fc00::dead:2 proto esp reqid 1 mode iptfs level use tmpl src fc00::dead:1 dst fc00::dead:2 proto esp reqid 2 mode transport
ping -W 1 -c 1 10.1.1.2
PING 10.1.1.2 (10.1.1.2) 56(84) bytes of data.
[ 64.168420] ================================================================== [ 64.169977] BUG: KASAN: stack-out-of-bounds in __xfrm6_addr_hash+0x11e/0x170 [ 64.169977] Read of size 4 at addr ffff88800e1ffd20 by task ping/2844
[ 64.169977] CPU: 2 UID: 0 PID: 2844 Comm: ping Not tainted 7.1.0-rc7-00180-geb23b588430a #98 PREEMPT(full) [ 64.169977] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 [ 64.169977] Call Trace: [ 64.169977] <TASK> [ 64.169977] dump_stack_lvl+0x47/0x70 [ 64.169977] ? __xfrm6_addr_hash+0x11e/0x170 [ 64.169977] print_report+0x152/0x4b0 [ 64.169977] ? ksys_mmap_pgoff+0x6d/0xa0 [ 64.169977] ? entry_SYSCALL_64_after_hwframe+0x76/0x7e [ 64.169977] ? rcu_read_unlock_sched+0xa/0x20 [ 64.169977] ? __virt_addr_valid+0x21b/0x230 [ 64.169977] ? __xfrm6_addr_hash+0x11e/0x170 [ 64.169977] kasan_report+0xa8/0xd0 [ 64.169977] ? __xfrm6_addr_hash+0x11e/0x170 [ 64.169977] __xfrm6_addr_hash+0x11e/0x170 [ 64.169977] __xfrm_dst_hash+0x24/0xc0 [ 64.169977] xfrm_state_find+0xa2d/0x2f90 [ 64.169977] ? __pfx_xfrm_state_find+0x10/0x10 [ 64.169977] ? __pfx_ftrace_graph_ret_addr+0x10/0x10 [ 64.169977] ? __pfx_ftrace_graph_ret_addr+0x10/0x10 [ 64.169977] xfrm_tmpl_resolve_one+0x210/0x570 [ 64.169977] ? __pfx_xfrm_tmpl_resolve_one+0x10/0x10 [ 64.169977] ? __pfx_stack_trace_consume_entry+0x10/0x10 [ 64.169977] ? kernel_text_address+0x5b/0x80 [ 64.169977] ? __kernel_text_address+0xe/0x30 [ 64.169977] ? unwind_get_return_address+0x5e/0x90 [ 64.169977] ? arch_stack_walk+0x8c/0xe0 [ 64.169977] xfrm_tmpl_resolve+0x130/0x200 [ 64.169977] ? __pfx_xfrm_tmpl_resolve+0x10/0x10 [ 64.169977] ? __pfx_xfrm_policy_inexact_lookup_rcu+0x10/0x10 [ 64.169977] ? __refcount_add_not_zero.constprop.0+0xb2/0x110 [ 64.169977] ? __pfx___refcount_add_not_zero.constprop.0+0x10/0x10 [ 64.169977] xfrm_resolve_and_create_bundle+0xd5/0x310 [ 64.169977] ? __pfx_xfrm_resolve_and_create_bundle+0x10/0x10 [ 64.169977] ? __pfx_xfrm_policy_lookup_bytype+0x10/0x10 [ 64.169977] ? __pfx_xfrm_policy_lookup_bytype+0x10/0x10 [ 64.169977] xfrm_lookup_with_ifid+0x3d8/0xb80 [ 64.169977] ? __pfx_xfrm_lookup_with_ifid+0x10/0x10 [ 64.169977] ? ip_route_output_key_hash+0xc6/0x110 [ 64.169977] ? kasan_save_track+0x10/0x30 [ 64.169977] xfrm_lookup_route+0x18/0xe0 [ 64.169977] ip4_datagram_release_cb+0x4c9/0x530 [ 64.169977] ? __pfx_ip4_datagram_release_cb+0x10/0x10 [ 64.169977] ? do_raw_spin_lock+0x71/0xc0 [ 64.169977] ? __pfx_do_raw_spin_lock+0x10/0x10 [ 64.169977] release_sock+0xb0/0x170 [ 64.169977] udp_connect+0x43/0x50 [ 64.169977] __sys_connect+0xa6/0x100 [ 64.169977] ? alloc_fd+0x2e9/0x300 [ 64.169977] ? __pfx___sys_connect+0x10/0x10 [ 64.169977] ? preempt_latency_start+0x1f/0x70 [ 64.169977] ? fd_install+0x7e/0x150 [ 64.169977] ? rcu_read_unlock_sched+0xa/0x20 [ 64.169977] ? __sys_socket+0xdf/0x130 [ 64.169977] ? __pfx___sys_socket+0x10/0x10 [ 64.169977] ? vma_refcount_put+0x43/0xa0 [ 64.169977] __x64_sys_connect+0x7e/0x90 [ 64.169977] do_syscall_64+0x11b/0x2b0 [ 64.169977] entry_SYSCALL_64_after_hwframe+0x76/0x7e [ 64.169977] RIP: 0033:0x7f4851ecb570 [ 64.169977] Code: 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 80 3d f9 ca 0d 00 00 74 17 b8 2a 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 58 c3 0f 1f 80 00 00 00 00 48 83 ec 18 89 54 [ 64.169977] RSP: 002b:00007ffc830e3498 EFLAGS: 00000202 ORIG_RAX: 000000000000002a [ 64.169977] RAX: ffffffffffffffda RBX: 00007ffc830e34d0 RCX: 00007f4851ecb570 [ 64.169977] RDX: 0000000000000010 RSI: 00007ffc830e34d0 RDI: 0000000000000005 [ 64.169977] RBP: 0000000000000000 R08: 0000000000000003 R09: 0000000000000000 [ 64.169977] R10: 0000000000000006 R11: 0000000000000202 R12: 0000000000000005 [ 64.169977] R13: 0000000000000000 R14: 00005619a863f340 R15: 0000000000000000 [ 64.169977] </TASK>
[ 64.169977] The buggy address belongs to stack of task ping/2844 [ 64.169977] and is located at offset 88 in frame: [ 64.169977] ip4_datagram_release_cb+0x0/0x530
[ 64.169977] This frame has 1 object: [ 64.169977] [32, 88) 'fl4'
[ 64.169977] The buggy address belongs to the physical page: [ 64.169977] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0xe1ff [ 64.169977] flags: 0x4000000000000000(zone=1) [ 64.169977] raw: 4000000000000000 0000000000000000 ffffea0000387fc8 0000000000000000 [ 64.169977] raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000 [ 64.169977] page dumped because: kasan: bad access detected
[ 64.169977] Memory state around the buggy address: [ 64.169977] ffff88800e1ffc00: f2 f2 00 00 f3 f3 00 00 00 00 00 00 00 00 00 00 [ 64.169977] ffff88800e1ffc80: 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00 00 [ 64.169977] >ffff88800e1ffd00: 00 00 00 00 f3 f3 f3 f3 f3 00 00 00 00 00 00 00 [ 64.169977] ^ [ 64.169977] ffff88800e1ffd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 [ 64.169977] ffff88800e1ffe00: f1 f1 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 64.169977] ================================================================== [ 64.245153] Disabling lock debugging due to kernel taint
After the fix:
ip xfrm policy add src 10.1.1.1/32 dst 10.1.1.2/32 dir out tmpl \
src fc00::dead:1 dst fc00::dead:2 proto esp reqid 1 mode iptfs \
level use tmpl src fc00::dead:1 dst fc00::dead:2 proto esp reqid 2 \
mode transport
Error: Mode in optional template not allowed in outbound policy.
--- net/xfrm/xfrm_user.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
net/xfrm/xfrm_user.c +1 -2
@@ -2068,13 +2068,12 @@ static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family,switch (ut[i].mode) {case XFRM_MODE_TUNNEL :case XFRM_MODE_BEET : +case XFRM_MODE_IPTFS :if (ut[i].optional && dir ==XFRM_POLICY_OUT ) {NL_SET_ERR_MSG (extack,"Mode in optional template not allowed in outbound policy" );return -EINVAL ; }break ; -case XFRM_MODE_IPTFS : -break ;default :if (ut[i].family != prev_family) {NL_SET_ERR_MSG (extack,"Mode in template doesn't support a family change" );
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 49/675 RDMA/cma: Fix hardware address comparison length in netevent callback
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Or Gerlitz <[email protected]>
[ Upstream commit 18313833e2c6de222a4f6c072da759d0d5888528 ]
The cited commit hardcoded the hardware address comparison len to ETH_ALEN.
This breaks IPoIB, which uses 20-byte addresses. By truncating the memcmp, the CMA may incorrectly assume the target address is unchanged and fails to abort the stalled connection.
Fix this by replacing ETH_ALEN with the dynamic neigh->dev->addr_len to correctly evaluate the full address regardless of the link layer.
--- drivers/infiniband/core/cma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/core/cma.c +1 -1
@@ -5237,7 +5237,7 @@ static int cma_netevent_callback(struct notifier_block *self,list_for_each_entry (current_id, &ips_node->id_list, id_list_entry) {if (!memcmp (current_id->id.route.addr.dev_addr.dst_dev_addr, - neigh->ha,ETH_ALEN )) + neigh->ha, neigh->dev->addr_len))continue ;cma_id_get (current_id);if (!queue_work (cma_wq, ¤t_id->id.net_work))
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 50/675 RDMA/umem: Add pinned revocable dmabuf import interface
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jacob Moroni <[email protected]>
[ Upstream commit ff85a2ebacbdaec9f28c4660c991295ace93cd1c ]
Added an interface for importing a pinned but revocable dmabuf. This interface can be used by drivers that are capable of revocation so that they can import dmabufs from exporters that may require it, such as VFIO.
This interface implements a two step process, where drivers will first call ib_umem_dmabuf_get_pinned_revocable_and_lock() which will pin and map the dmabuf (and provide a functional move_notify/invalidate_mappings callback), but will return with the lock still held so that the driver can then populate the callback via ib_umem_dmabuf_set_revoke_locked() without races from concurrent revocations. This scheme also allows for easier integration with drivers that may not have actually allocated their internal MR objects at the time of the get_pinned_revocable* call.
Stable-dep-of: a846aecb931b ("RDMA/irdma: Prevent rereg_mr for non-mem regions")
--- drivers/infiniband/core/umem_dmabuf.c | 61 +++++++++++++++++++++++++++ include/rdma/ib_umem.h | 19 +++++++++ 2 files changed, 80 insertions(+)
drivers/infiniband/core/umem_dmabuf.c +61 -0
@@ -206,6 +206,10 @@ static void ib_umem_dmabuf_revoke_locked(struct dma_buf_attachment *attach)if (umem_dmabuf->revoked)return ; + +if (umem_dmabuf->pinned_revoke) + umem_dmabuf->pinned_revoke (umem_dmabuf->private); +ib_umem_dmabuf_unmap_pages (umem_dmabuf);if (umem_dmabuf->pinned) {dma_buf_unpin (umem_dmabuf->attach);
@@ -214,6 +218,11 @@ static void ib_umem_dmabuf_revoke_locked(struct dma_buf_attachment *attach) umem_dmabuf->revoked =1 ; } +static struct dma_buf_attach_ops ib_umem_dmabuf_attach_pinned_revocable_ops = { + .allow_peer2peer = true, + .move_notify = ib_umem_dmabuf_revoke_locked, +}; +static struct ib_umem_dmabuf * ib_umem_dmabuf_get_pinned_and_lock(struct ib_device *device, struct device *dma_device,
@@ -266,6 +275,58 @@ ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device, }EXPORT_SYMBOL (ib_umem_dmabuf_get_pinned_with_dma_device); +/** +* ib_umem_dmabuf_get_pinned_revocable_and_lock - Map & pin a revocable dmabuf +* @device: IB device. +* @offset: Start offset. +* @size: Length. +* @fd: dmabuf fd. +* @access: Access flags. +* +* Obtains a umem from a dmabuf for drivers/devices that can support revocation. +* +* Returns with dma_resv_lock held upon success. The driver must set the revoke +* callback prior to unlock by calling ib_umem_dmabuf_set_revoke_locked(). +* +* When a revocation occurs, the revoke callback will be called. The driver must +* ensure that the region is no longer accessed when the callback returns. Any +* subsequent access attempts should also probably cause an AE for MRs. +* +* If the umem is used for an MR, the driver must ensure that the key remains in +* use such that it cannot be obtained by a new region until this region is +* fully deregistered (i.e., ibv_dereg_mr). If a driver needs to serialize with +* revoke calls, it can use dma_resv_lock. +* +* If successful, then the revoke callback may be called at any time and will +* also be called automatically upon ib_umem_release (serialized). The revoke +* callback will be called one time at most. +* +* Return: A pointer to ib_umem_dmabuf on success, or an ERR_PTR on failure. +*/ +struct ib_umem_dmabuf * +ib_umem_dmabuf_get_pinned_revocable_and_lock (struct ib_device *device, +unsigned long offset,size_t size, +int fd,int access) +{ +const struct dma_buf_attach_ops *ops = + &ib_umem_dmabuf_attach_pinned_revocable_ops; + +return ib_umem_dmabuf_get_pinned_and_lock (device, device->dma_device, + offset, size, fd, access, + ops); +} +EXPORT_SYMBOL (ib_umem_dmabuf_get_pinned_revocable_and_lock); + +void ib_umem_dmabuf_set_revoke_locked (struct ib_umem_dmabuf *umem_dmabuf, +void (*revoke)(void *priv),void *priv) +{ +dma_resv_assert_held (umem_dmabuf->attach->dmabuf->resv); + + umem_dmabuf->pinned_revoke = revoke; + umem_dmabuf->private = priv; +} +EXPORT_SYMBOL (ib_umem_dmabuf_set_revoke_locked); + struct ib_umem_dmabuf *ib_umem_dmabuf_get_pinned(struct ib_device *device, unsigned long offset, size_t size, int fd,
include/rdma/ib_umem.h +19 -0
@@ -36,6 +36,7 @@ struct ib_umem_dmabuf {struct scatterlist *last_sg;unsigned long first_sg_offset;unsigned long last_sg_trim; +void (*pinned_revoke)(void *priv);void *private; u8 pinned : 1; u8 revoked : 1;
@@ -141,6 +142,12 @@ struct ib_umem_dmabuf *ib_umem_dmabuf_get_pinned(struct ib_device *device, size_t size, int fd, int access);struct ib_umem_dmabuf * +ib_umem_dmabuf_get_pinned_revocable_and_lock (struct ib_device *device, +unsigned long offset,size_t size, +int fd,int access); +void ib_umem_dmabuf_set_revoke_locked (struct ib_umem_dmabuf *umem_dmabuf, +void (*revoke)(void *priv),void *priv); +struct ib_umem_dmabuf * ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device, struct device *dma_device, unsigned long offset, size_t size,
@@ -201,6 +208,18 @@ ib_umem_dmabuf_get_pinned(struct ib_device *device, unsigned long offset,return ERR_PTR (-EOPNOTSUPP ); } +static inline struct ib_umem_dmabuf * +ib_umem_dmabuf_get_pinned_revocable_and_lock (struct ib_device *device, +unsigned long offset,size_t size, +int fd,int access) +{ +return ERR_PTR (-EOPNOTSUPP ); +} + +static inline void +ib_umem_dmabuf_set_revoke_locked (struct ib_umem_dmabuf *umem_dmabuf, +void (*revoke)(void *priv),void *priv) {} +static inline struct ib_umem_dmabuf * ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device, struct device *dma_device,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 51/675 RDMA/irdma: Prevent rereg_mr for non-mem regions
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jacob Moroni <[email protected]>
[ Upstream commit a846aecb931b4d65d5eafa92a0623545af46d4f2 ]
When a QP/CQ/SRQ is created, a two step process is used where the buffer is allocated in userspace and explicitly registered with the normal reg_mr mechanism prior to creating the actual QP/CQ/SRQ object.
These special registrations are indicated via an ABI field so the driver knows that they do not have a valid mkey and to skip the actual CQP command submission.
Since these are real MR objects from the core's perspective, it is possible for a user application to invoke rereg_mr on them and cause a real CQP op to be emitted with the zero-initialized mkey value of 0.
Fix this by preventing rereg_mr on these special regions.
--- drivers/infiniband/hw/irdma/verbs.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/infiniband/hw/irdma/verbs.c +3 -0
@@ -3756,6 +3756,9 @@ static struct ib_mr *irdma_rereg_user_mr(struct ib_mr *ib_mr, int flags,if (flags & ~(IB_MR_REREG_TRANS |IB_MR_REREG_PD |IB_MR_REREG_ACCESS ))return ERR_PTR (-EOPNOTSUPP ); +if (iwmr->type !=IRDMA_MEMREG_TYPE_MEM ) +return ERR_PTR (-EINVAL ); + ret =ib_umem_check_rereg (iwmr->region, flags, new_access);if (ret)return ERR_PTR (ret);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 52/675 RDMA/irdma: Remove redundant legacy_mode checks
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jacob Moroni <[email protected]>
[ Upstream commit ed8621be482bf18dcd217aa024e95758bf9d28f2 ]
The driver has the following invariants:
1. legacy_mode is only allowed on GEN_1 hardware (enforced in irdma_alloc_ucontext).
2. GEN_1 hardware does not set IRDMA_FEATURE_CQ_RESIZE or IRDMA_FEATURE_RTS_AE. These feature flags are only set for GEN_2 and GEN_3 hardware.
Therefore, legacy_mode is always false if IRDMA_FEATURE_CQ_RESIZE or IRDMA_FEATURE_RTS_AE is set, so remove the redundant checks.
Stable-dep-of: b9b088907156 ("RDMA/irdma: Prevent user-triggered null deref on QP create")
--- drivers/infiniband/hw/irdma/uk.c | 9 +++------ drivers/infiniband/hw/irdma/user.h | 1 - drivers/infiniband/hw/irdma/verbs.c | 7 +------ 3 files changed, 4 insertions(+), 13 deletions(-)
drivers/infiniband/hw/irdma/uk.c +3 -6
@@ -1540,15 +1540,12 @@ static const struct irdma_wqe_uk_ops iw_wqe_uk_ops_gen_1 = {* irdma_setup_connection_wqes - setup WQEs necessary to complete * connection. * @qp: hw qp (user and kernel) -* @info: qp initialization info */ -static void irdma_setup_connection_wqes (struct irdma_qp_uk *qp, -struct irdma_qp_uk_init_info *info) +static void irdma_setup_connection_wqes (struct irdma_qp_uk *qp) {u16 move_cnt =1 ; -if (!info->legacy_mode && - (qp->uk_attrs->feature_flags &IRDMA_FEATURE_RTS_AE )) +if (qp->uk_attrs->feature_flags &IRDMA_FEATURE_RTS_AE ) move_cnt =3 ; qp->conn_wqes = move_cnt;
@@ -1699,7 +1696,7 @@ int irdma_uk_qp_init(struct irdma_qp_uk *qp, struct irdma_qp_uk_init_info *info) sq_ring_size = qp->sq_size << info->sq_shift;IRDMA_RING_INIT (qp->sq_ring, sq_ring_size);if (info->first_sq_wq) { -irdma_setup_connection_wqes (qp, info); +irdma_setup_connection_wqes (qp); qp->swqe_polarity =1 ; qp->first_sq_wq = true; }else {
drivers/infiniband/hw/irdma/user.h +0 -1
@@ -560,7 +560,6 @@ struct irdma_qp_uk_init_info {u8 sq_shift;u8 rq_shift;int abi_ver; -bool legacy_mode;struct irdma_srq_uk *srq_uk; };
drivers/infiniband/hw/irdma/verbs.c +1 -6
@@ -632,7 +632,6 @@ static int irdma_setup_umode_qp(struct ib_udata *udata, iwqp->ctx_info.qp_compl_ctx = req.user_compl_ctx; iwqp->user_mode =1 ;if (req.user_wqe_bufs) { - info->qp_uk_init_info.legacy_mode = ucontext->legacy_mode;spin_lock_irqsave (&ucontext->qp_reg_mem_list_lock, flags); iwqp->iwpbl =irdma_get_pbl ((unsigned long )req.user_wqe_bufs, &ucontext->qp_reg_mem_list);
@@ -2068,10 +2067,6 @@ static int irdma_resize_cq(struct ib_cq *ibcq, int entries, rdma_udata_to_drv_context(udata, struct irdma_ucontext, ibucontext); -/* CQ resize not supported with legacy GEN_1 libi40iw */ -if (ucontext->legacy_mode) -return -EOPNOTSUPP ; -if (ib_copy_from_udata (&req, udata,min (sizeof (req), udata->inlen)))return -EINVAL ;
@@ -2550,7 +2545,7 @@ static int irdma_create_cq(struct ib_cq *ibcq, cqmr = &iwpbl->cq_mr;if (rf->sc_dev.hw_attrs.uk_attrs.feature_flags & -IRDMA_FEATURE_CQ_RESIZE && !ucontext->legacy_mode) { +IRDMA_FEATURE_CQ_RESIZE ) {spin_lock_irqsave (&ucontext->cq_reg_mem_list_lock, flags); iwpbl_shadow = irdma_get_pbl( (unsigned long)req.user_shadow_area,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 53/675 RDMA/irdma: Prevent user-triggered null deref on QP create
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jacob Moroni <[email protected]>
[ Upstream commit b9b0889071569d43623c260074e159cd8f26adb1 ]
Previously, the user QP creation path would only attempt to populate iwqp->iwpbl if the user-provided req.user_wqe_bufs field was non-zero. The problem is that iwqp->iwpbl is unconditionally dereferenced later on in irdma_setup_virt_qp.
While there was a check for iwqp->iwpbl != NULL, this check would only occur if req.user_wqe_bufs was non-zero. The end result is that a user could send a zero user_wqe_bufs value and trigger a null ptr deref.
Fix this by unconditionally calling irdma_get_pbl and bailing if it fails, similar to the CQ and SRQ paths.
--- drivers/infiniband/hw/irdma/verbs.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-)
drivers/infiniband/hw/irdma/verbs.c +9 -10
@@ -631,17 +631,16 @@ static int irdma_setup_umode_qp(struct ib_udata *udata, iwqp->ctx_info.qp_compl_ctx = req.user_compl_ctx; iwqp->user_mode =1 ; -if (req.user_wqe_bufs) { -spin_lock_irqsave (&ucontext->qp_reg_mem_list_lock, flags); - iwqp->iwpbl =irdma_get_pbl ((unsigned long )req.user_wqe_bufs, - &ucontext->qp_reg_mem_list); -spin_unlock_irqrestore (&ucontext->qp_reg_mem_list_lock, flags); -if (!iwqp->iwpbl) { - ret = -ENODATA ; -ibdev_dbg (&iwdev->ibdev,"VERBS: no pbl info\n" ); -return ret; - } +spin_lock_irqsave (&ucontext->qp_reg_mem_list_lock, flags); + iwqp->iwpbl =irdma_get_pbl ((unsigned long )req.user_wqe_bufs, + &ucontext->qp_reg_mem_list); +spin_unlock_irqrestore (&ucontext->qp_reg_mem_list_lock, flags); + +if (!iwqp->iwpbl) { + ret = -ENODATA ; +ibdev_dbg (&iwdev->ibdev,"VERBS: no pbl info\n" ); +return ret; }if (!ucontext->use_raw_attrs) {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 54/675 RDMA/erdma: initialize ret for empty receive WR lists
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ruoyu Wang <[email protected]>
[ Upstream commit 2815a277c53e9a84784d6410cd55a9da5b33068d ]
erdma_post_recv() returns ret after walking the receive work request list. If the caller passes an empty list, the loop is skipped and ret is not assigned.
Initialize ret to 0 so an empty receive work request list returns success instead of stack data.
--- drivers/infiniband/hw/erdma/erdma_qp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/hw/erdma/erdma_qp.c +1 -1
@@ -734,7 +734,7 @@ int erdma_post_recv(struct ib_qp *ibqp, const struct ib_recv_wr *recv_wr,const struct ib_recv_wr *wr = recv_wr;struct erdma_qp *qp =to_eqp (ibqp);unsigned long flags; -int ret; +int ret =0 ;spin_lock_irqsave (&qp->lock, flags);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 55/675 RDMA/mana_ib: initialize err for empty send WR lists
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ruoyu Wang <[email protected]>
[ Upstream commit 155fd5ce2382b0ffbec0d7ee7b3a6818a27a5aed ]
mana_ib_post_send() returns err after walking the send work request list. If the caller passes an empty list, the loop is skipped and err is not assigned.
Initialize err to 0 so an empty send work request list returns success instead of stack data.
--- drivers/infiniband/hw/mana/wr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/hw/mana/wr.c +1 -1
@@ -144,7 +144,7 @@ static int mana_ib_post_send_ud(struct mana_ib_qp *qp, const struct ib_ud_wr *wrint mana_ib_post_send (struct ib_qp *ibqp,const struct ib_send_wr *wr,const struct ib_send_wr **bad_wr) { -int err; +int err =0 ; struct mana_ib_qp *qp = container_of(ibqp, struct mana_ib_qp, ibqp);for (; wr; wr = wr->next) {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 56/675 RDMA/hns: Fix potential integer overflow in mhop hem cleanup
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Danila Chernetsov <[email protected]>
[ Upstream commit 9f0f2d2121f16d420199a82ac5bbc242269133b3 ]
In hns_roce_cleanup_mhop_hem_table(), the expression:
obj = i * buf_chunk_size / table->obj_size;
is evaluated using 32-bit unsigned arithmetic because 'buf_chunk_size' is u32 and the usual arithmetic conversions convert 'i' to unsigned int. The result is assigned to a u64 variable, but the multiplication may overflow before the assignment.
For sufficiently large HEM tables, this produces an incorrect object index passed to hns_roce_table_mhop_put().
Cast 'i' to u64 before the multiplication so that the intermediate calculation is performed with 64-bit arithmetic.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/infiniband/hw/hns/hns_roce_hem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/hw/hns/hns_roce_hem.c +1 -1
@@ -842,7 +842,7 @@ static void hns_roce_cleanup_mhop_hem_table(struct hns_roce_dev *hr_dev, mhop.bt_chunk_size;for (i =0 ; i < table->num_hem; ++i) { - obj = i * buf_chunk_size / table->obj_size; + obj = (u64 )i * buf_chunk_size / table->obj_size;if (table->hem[i])hns_roce_table_mhop_put (hr_dev, table, obj,0 ); }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 57/675 RDMA/siw: publish QP after initialization
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ruoyu Wang <[email protected]>
[ Upstream commit bb27fcc67c429d97f785c92c35a6c5adebb05d7f ]
siw_create_qp() currently calls siw_qp_add() before the queues, CQ pointers, state, completion, and device list entry are ready. A QPN lookup can therefore reach a QP that is still being constructed.
Move siw_qp_add() to the end of siw_create_qp(), after QP initialization and before adding the QP to the siw device list.
--- drivers/infiniband/sw/siw/siw_verbs.c | 44 +++++++++++++++------------ 1 file changed, 24 insertions(+), 20 deletions(-)
drivers/infiniband/sw/siw/siw_verbs.c +24 -20
@@ -316,6 +316,7 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,struct siw_ucontext *uctx = rdma_udata_to_drv_context(udata, struct siw_ucontext, base_ucontext); +struct siw_uresp_create_qp uresp = {};unsigned long flags;int num_sqe, num_rqe, rv =0 ;size_t length;
@@ -369,11 +370,6 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,spin_lock_init (&qp->rq_lock);spin_lock_init (&qp->orq_lock); - rv =siw_qp_add (sdev, qp); -if (rv) - goto err_atomic; - -/* All queue indices are derived from modulo operations * on a free running 'get' (consumer) and 'put' (producer) * unsigned counter. Having queue sizes at power of two
@@ -391,14 +387,14 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,if (qp->sendq ==NULL ) { rv = -ENOMEM ; - goto err_out_xa; + goto err_out; }if (attrs->sq_sig_type !=IB_SIGNAL_REQ_WR ) {if (attrs->sq_sig_type ==IB_SIGNAL_ALL_WR ) qp->attrs.flags |=SIW_SIGNAL_ALL_WR ;else { rv = -EINVAL ; - goto err_out_xa; + goto err_out; } } qp->pd = pd;
@@ -424,7 +420,7 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,if (qp->recvq ==NULL ) { rv = -ENOMEM ; - goto err_out_xa; + goto err_out; } qp->attrs.rq_size = num_rqe; }
@@ -439,11 +435,8 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs, qp->attrs.state =SIW_QP_STATE_IDLE ;if (udata) { -struct siw_uresp_create_qp uresp = {}; - uresp.num_sqe = num_sqe; uresp.num_rqe = num_rqe; - uresp.qp_id =qp_id (qp);if (qp->sendq) { length = num_sqe *sizeof (struct siw_sqe );
@@ -452,7 +445,7 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs, length, &uresp.sq_key);if (!qp->sq_entry) { rv = -ENOMEM ; - goto err_out_xa; + goto err_out; } }
@@ -464,9 +457,23 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,if (!qp->rq_entry) { uresp.sq_key =SIW_INVAL_UOBJ_KEY ; rv = -ENOMEM ; - goto err_out_xa; + goto err_out; } } + } + qp->tx_cpu =siw_get_tx_cpu (sdev); +if (qp->tx_cpu <0 ) { + rv = -EINVAL ; + goto err_out; + } +init_completion (&qp->qp_free); + + rv =siw_qp_add (sdev, qp); +if (rv) + goto err_out_tx; + +if (udata) { + uresp.qp_id =qp_id (qp);if (udata->outlen <sizeof (uresp)) { rv = -EINVAL ;
@@ -476,22 +483,19 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,if (rv) goto err_out_xa; } - qp->tx_cpu =siw_get_tx_cpu (sdev); -if (qp->tx_cpu <0 ) { - rv = -EINVAL ; - goto err_out_xa; - } +INIT_LIST_HEAD (&qp->devq);spin_lock_irqsave (&sdev->lock, flags);list_add_tail (&qp->devq, &sdev->qp_list);spin_unlock_irqrestore (&sdev->lock, flags); -init_completion (&qp->qp_free); -return 0 ; err_out_xa:xa_erase (&sdev->qp_xa,qp_id (qp)); +err_out_tx: +siw_put_tx_cpu (qp->tx_cpu); +err_out:if (uctx) {rdma_user_mmap_entry_remove (qp->sq_entry);rdma_user_mmap_entry_remove (qp->rq_entry);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 58/675 mtd: fix double free and WARN_ON in add_mtd_device() error paths
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xue Lei <[email protected]>
[ Upstream commit 9d4af746af8ce27eefc2338b2feaa1e01f28b6c3 ]
When device_register() or mtd_nvmem_add() fails inside add_mtd_device() for a partition, the error handling triggers mtd_release() via put_device() or device_unregister(). mtd_release() calls release_mtd_partition() which frees the mtd_info structure. However, callers such as mtd_add_partition() and add_mtd_partitions() also call free_partition() in their error paths, resulting in a double free.
Additionally, release_mtd_partition() hits WARN_ON(!list_empty( &mtd->part.node)) because the partition node is still linked in the parent's partitions list when the release callback fires from the add_mtd_device() error path.
Fix this by overriding dev->type and dev->release before put_device() in the error paths, so that device_release() invokes a no-op function instead of mtd_release(). For the mtd_nvmem_add() failure case, device_unregister() is replaced with device_del() to separate the device removal from the final kobject reference drop, allowing the override to take effect before put_device() is called.
The callers' error paths (list_del + free_partition) remain the sole owners of mtd_info lifetime on add_mtd_device() failure, which is the expected contract.
The normal partition teardown path is not affected: del_mtd_device() goes through kref_put() -> mtd_device_release() -> device_unregister() with dev->type still set to &mtd_devtype, so mtd_release() -> release_mtd_partition() continues to work correctly for the regular removal case.
--- drivers/mtd/mtdcore.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-)
drivers/mtd/mtdcore.c +19 -4
@@ -104,6 +104,15 @@ static void mtd_release(struct device *dev)device_destroy (&mtd_class, index +1 ); } +/* +* No-op device release used in add_mtd_device() error paths. +* Prevents mtd_release() from being called via device_release(), +* which would free the mtd_info that the caller still manages. +*/ +static void mtd_dev_release_nop (struct device *dev) +{ +} +static void mtd_device_release (struct kref *kref) { struct mtd_info *mtd = container_of(kref, struct mtd_info, refcnt);
@@ -798,10 +807,8 @@ int add_mtd_device(struct mtd_info *mtd)mtd_check_of_node (mtd);of_node_get (mtd_get_of_node (mtd)); error =device_register (&mtd->dev); -if (error) { -put_device (&mtd->dev); +if (error) goto fail_added; - }/* Add the nvmem provider */ error =mtd_nvmem_add (mtd);
@@ -839,8 +846,16 @@ int add_mtd_device(struct mtd_info *mtd)return 0 ; fail_nvmem_add: -device_unregister (&mtd->dev); +device_del (&mtd->dev); fail_added: +/* +* Clear type and set nop release to prevent mtd_release() -> +* release_mtd_partition() -> free_partition() from freeing mtd. +* The caller handles cleanup on failure. +*/ + mtd->dev.type =NULL ; + mtd->dev.release = mtd_dev_release_nop; +put_device (&mtd->dev);of_node_put (mtd_get_of_node (mtd)); fail_devname:idr_remove (&mtd_idr, i);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 59/675 selftests/alsa: Fix memory leak in find_controls error path
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Malaya Kumar Rout <[email protected]>
[ Upstream commit cb89f0c1aed02eb233c4271f76f830b37e222ff6 ]
In find_controls(), card_data is allocated with malloc() but when snd_ctl_open_lconf() fails, the code jumps to next_card without freeing the allocated memory. This results in a memory leak for each card where snd_ctl_open_lconf() fails.
Add free(card_data) before goto next_card to ensure proper cleanup of the allocated memory in the error path.
--- tools/testing/selftests/alsa/mixer-test.c | 1 + 1 file changed, 1 insertion(+)
tools/testing/selftests/alsa/mixer-test.c +1 -0
@@ -84,6 +84,7 @@ static void find_controls(void)if (err <0 ) {ksft_print_msg ("Failed to get hctl for card %d: %s\n" , card,snd_strerror (err)); +free (card_data); goto next_card; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 60/675 RDMA/irdma: Prevent overflows in memory contiguity checks
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksandrova Alyona <[email protected]>
[ Upstream commit 3cda0dfe8c651dcbb9e38977905d3d3b1750c4ab ]
irdma_check_mem_contiguous() and irdma_check_mr_contiguous() verify that PBL entries describe physically contiguous memory ranges.
Both functions calculate byte offsets using 32-bit operands. For example, with 4 KiB pages, pg_size * pg_idx overflows 32-bit arithmetic when pg_idx reaches 1048576. In the level-2 check, PBLE_PER_PAGE is 512, so i * pg_size * PBLE_PER_PAGE overflows when i reaches 2048.
These values are reachable in the driver. For MRs, palloc->total_cnt comes from iwmr->page_cnt, which is calculated by ib_umem_num_dma_blocks(). The MR size is limited by IRDMA_MAX_MR_SIZE, so a 4 GiB MR with 4 KiB pages can reach page_cnt of 1048576. PBLE resources do not exclude this value either: for gen3, the limit is based on avail_sds * MAX_PBLE_PER_SD, and MAX_PBLE_PER_SD is 0x40000, so 4 SDs are enough for 1048576 PBLEs.
Cast one operand to u64 before the multiplications so that the offset calculations are performed in 64-bit arithmetic.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/infiniband/hw/irdma/verbs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/infiniband/hw/irdma/verbs.c +2 -2
@@ -2800,7 +2800,7 @@ static bool irdma_check_mem_contiguous(u64 *arr, u32 npages, u32 pg_size)u32 pg_idx;for (pg_idx =0 ; pg_idx < npages; pg_idx++) { -if ((*arr + (pg_size * pg_idx)) != arr[pg_idx]) +if ((*arr + ((u64 )pg_size * pg_idx)) != arr[pg_idx])return false; }
@@ -2833,7 +2833,7 @@ static bool irdma_check_mr_contiguous(struct irdma_pble_alloc *palloc,for (i =0 ; i < lvl2->leaf_cnt; i++, leaf++) { arr = leaf->addr; -if ((*start_addr + (i * pg_size *PBLE_PER_PAGE )) != *arr) +if ((*start_addr + ((u64 )i * pg_size *PBLE_PER_PAGE )) != *arr)return false; ret =irdma_check_mem_contiguous (arr, leaf->cnt, pg_size);if (!ret)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 61/675 xfrm: clear mode callbacks after failed mode setup
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cen Zhang <[email protected]>
[ Upstream commit 2538bd3cd1ff5af655908469544ac7b7ae259386 ]
xfrm_state_gc_task can run long after a failed IPTFS state setup. In the reproduced case, __xfrm_init_state() cached x->mode_cbs, IPTFS setup returned -ENOMEM before publishing mode_data, and the temporary module reference from xfrm_get_mode_cbs() was dropped immediately. The dead state then kept x->mode_cbs until deferred GC ran after xfrm_iptfs had been unloaded.
Clear x->mode_cbs when mode init or clone fails before publishing mode_data. Those states never installed mode-specific state or the long-term IPTFS module pin, so deferred GC has nothing mode-specific to destroy and must not retain a callback table pointer past the temporary lookup reference.
The buggy scenario involves two paths, with each column showing the order within that path:
failed setup path:
1. cache x->mode_cbs
2. mode setup fails before mode_data
3. drop the temporary module ref
4. dead state keeps x->mode_cbs cached
GC/unload path:
1. xfrm_state_put() queues GC work
2. xfrm_iptfs unloads later
3. xfrm_state_gc_task runs
4. GC dereferences stale x->mode_cbs
This also covers the failed clone path where clone_state() returns before publishing mode_data.
Validation reproduced this kernel report:
Kernel panic - not syncing: Fatal exception
CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y failslab_stacktrace_filter matched xfrm_iptfs frames ack_error=-12FAULT_INJECTION: forcing a failure
BUG: unable to handle page fault Workqueue: events xfrm_state_gc_task RIP: xfrm_state_gc_task+0x142/0x650 Modules linked in: esp4_offload xfrm_user [last unloaded: xfrm_iptfs] Kernel panic - not syncing: Fatal exception
--- net/xfrm/xfrm_state.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
net/xfrm/xfrm_state.c +6 -1
@@ -2070,8 +2070,11 @@ static struct xfrm_state *xfrm_state_clone_and_setup(struct xfrm_state *orig, x->mode_cbs = orig->mode_cbs;if (x->mode_cbs && x->mode_cbs->clone_state) { -if (x->mode_cbs->clone_state (x, orig)) +if (x->mode_cbs->clone_state (x, orig)) { +if (!x->mode_data) + x->mode_cbs =NULL ; goto error; + } }
@@ -3253,6 +3256,8 @@ int __xfrm_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)if (x->mode_cbs->init_state) err = x->mode_cbs->init_state (x);module_put (x->mode_cbs->owner); +if (err && !x->mode_data) + x->mode_cbs =NULL ; } error:return err;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 62/675 xfrm: iptfs: propagate SKBFL_SHARED_FRAG in iptfs_skb_add_frags()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen YanJun <[email protected]>
[ Upstream commit 430ea57d6daf765e88f90046afbfd1e071cb7200 ]
When iptfs_skb_add_frags() copies frag references from the source frag walk into a new SKB, it increments the page reference count via __skb_frag_ref() but does not propagate SKBFL_SHARED_FRAG to the destination SKB's skb_shinfo->flags.
If the source SKB carries shared frags (e.g. from a page-pool backed receive path), the new inner SKB will appear to ESP as having privately owned frags. A subsequent esp_input() call for a nested transport-mode SA then takes the no-COW fast path and decrypts in place, writing over pages that are still referenced by the outer IPTFS SKB. This causes kernel-visible memory corruption and can trigger a panic.
All other frag-transfer helpers in the kernel (skb_try_coalesce, skb_gro_receive, __pskb_copy_fclone, skb_shift, skb_segment) correctly propagate SKBFL_SHARED_FRAG; align iptfs_skb_add_frags() with this convention by setting the flag inside the loop immediately after __skb_frag_ref() and nr_frags++, so every exit path that attaches a frag unconditionally propagates SKBFL_SHARED_FRAG.
--- net/xfrm/xfrm_iptfs.c | 1 + 1 file changed, 1 insertion(+)
net/xfrm/xfrm_iptfs.c +1 -0
@@ -480,6 +480,7 @@ static int iptfs_skb_add_frags(struct sk_buff *skb, }__skb_frag_ref (tofrag); shinfo->nr_frags++; + shinfo->flags |=SKBFL_SHARED_FRAG ;/* see if we are done */ fraglen = tofrag->len;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 63/675 xfrm6: clear dst.dev on error to avoid double netdev_put in xfrm6_fill_dst()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiang Mei (Microsoft) <[email protected]>
[ Upstream commit 136992de9bb91871084ae52d172610541c76e4d2 ]
On the error path where in6_dev_get(dev) returns NULL, xfrm6_fill_dst() releases the device reference with netdev_put() but leaves xdst->u.dst.dev set. dst_destroy() later calls netdev_put(dst->dev) again, so the same net_device reference is released twice, underflowing its refcount (ref_tracker WARNING + "unregister_netdevice: waiting for <dev> to become free").
Clear xdst->u.dst.dev after the netdev_put(), the same way the XFRM device-offload paths xfrm_dev_state_add() and xfrm_dev_policy_add() in net/xfrm/xfrm_device.c NULL ->dev when releasing the reference on error.
ref_tracker: reference already released.
ref_tracker: allocated in:
xfrm6_fill_dst (net/ipv6/xfrm6_policy.c:86)
...
udpv6_sendmsg (net/ipv6/udp.c:1696)
...
ref_tracker: freed in:
xfrm6_fill_dst (net/ipv6/xfrm6_policy.c:90)
...
WARNING: lib/ref_tracker.c:322 at ref_tracker_free+0x58b/0x780 dst_destroy (net/core/dst.c:115) rcu_core handle_softirqs ...
--- net/ipv6/xfrm6_policy.c | 1 + 1 file changed, 1 insertion(+)
net/ipv6/xfrm6_policy.c +1 -0
@@ -88,6 +88,7 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, xdst->u.rt6.rt6i_idev =in6_dev_get (dev);if (!xdst->u.rt6.rt6i_idev) {netdev_put (dev, &xdst->u.dst.dev_tracker); + xdst->u.dst.dev =NULL ;return -ENODEV ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 64/675 xfrm: policy: preallocate inexact bins before xfrm_hash_rebuild reinsert
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiang Mei (Microsoft) <[email protected]>
[ Upstream commit f38f8cce2f7e79775b3db7e8a5eacda04ac908e4 ]
xfrm_hash_rebuild()'s first loop preallocates the bins/chains the reinsert loop needs, so the reinsert (after hlist_del_rcu()) cannot allocate or fail. But its guard is inverted: it skips policies with prefixlen < threshold and preallocates for the rest.
prefixlen < threshold is exactly when policy_hash_bysel() returns NULL and the reinsert takes the allocating xfrm_policy_inexact_insert() path. So the loop preallocates for the exact policies (which never allocate) and skips the inexact ones, whose bin/node is then allocated GFP_ATOMIC during reinsert. On failure the error path only WARN_ONCE()s and continues, leaving a poisoned bydst node; the next rebuild's hlist_del_rcu() dereferences LIST_POISON2 and takes a GPF. Reachable under memory pressure, deterministic via failslab.
Invert the guard so preallocation covers exactly the reinserted policies; the reinsert then allocates nothing and cannot fail.
Crash:
Oops: general protection fault, probably for non-canonical address 0xfbd59c0000000024: 0000 [#1] SMP KASAN NOPTI KASAN: maybe wild-memory-access in range [0xdead...] ... Workqueue: events xfrm_hash_rebuild RIP: 0010:xfrm_hash_rebuild+0x5b3/0x1190 RAX: dead000000000122 (LIST_POISON2 + offset) ... Call Trace: hlist_del_rcu (include/linux/rculist.h:599) xfrm_hash_rebuild (net/xfrm/xfrm_policy.c:1365) process_one_work (kernel/workqueue.c:3322) worker_thread (kernel/workqueue.c:3486) kthread (kernel/kthread.c:436) ret_from_fork (arch/x86/kernel/process.c:158) ret_from_fork_asm (arch/x86/entry/entry_64.S:245) ... Kernel panic - not syncing: Fatal exception in interrupt
--- net/xfrm/xfrm_policy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/xfrm/xfrm_policy.c +2 -2
@@ -1329,8 +1329,8 @@ static void xfrm_hash_rebuild(struct work_struct *work) } } -if (policy->selector.prefixlen_d < dbits || - policy->selector.prefixlen_s < sbits) +if (policy->selector.prefixlen_d >= dbits && + policy->selector.prefixlen_s >= sbits)continue ; bin =xfrm_policy_inexact_alloc_bin (policy, dir);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 65/675 wifi: cfg80211: cancel sched scan results work on unregister
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cen Zhang <[email protected]>
[ Upstream commit edf0730be33696a1bd142792830d392129e495cc ]
cfg80211_sched_scan_results() can queue rdev->sched_scan_res_wk from a driver result notification while a scheduled scan request is present. The work callback recovers the containing cfg80211_registered_device and then locks the wiphy and walks the scheduled-scan request list.
wiphy_unregister() already makes the wiphy unreachable and drains rdev work items before cfg80211_dev_free() can release the object, but it does not drain sched_scan_res_wk. A queued or running result work item can therefore cross the unregister/free boundary and access freed rdev state.
The buggy scenario involves two paths, with each column showing the order within that path:
scheduled-scan result path: unregister/free path:
1. cfg80211_sched_scan_results() 1. interface teardown stops and
queues rdev->sched_scan_res_wk. removes the scheduled scan request.
2. cfg80211_wq starts the work 2. wiphy_unregister() drains other
item and recovers rdev. rdev work items.
3. The worker locks rdev->wiphy 3. cfg80211_dev_free() destroys and
and walks rdev state. frees rdev.
Cancel sched_scan_res_wk in wiphy_unregister() alongside the other rdev work items. cancel_work_sync() removes a pending result notification and waits for an already running callback, so cfg80211_dev_free() cannot free rdev while this work item is still active.
Validation reproduced this kernel report:
BUG: KASAN: use-after-free in cfg80211_sched_scan_results_wk+0x4a6/0x530 Workqueue: cfg80211 cfg80211_sched_scan_results_wk [cfg80211] Read of size 8 Call trace: dump_stack_lvl+0x66/0xa0 print_report+0xce/0x630 cfg80211_sched_scan_results_wk+0x4a6/0x530 srso_alias_return_thunk+0x5/0xfbef5 __virt_addr_valid+0x224/0x430 kasan_report+0xac/0xe0 lockdep_hardirqs_on_prepare+0xea/0x1a0 process_one_work+0x8d0/0x18f0 (kernel/workqueue.c:3212) lock_is_held_type+0x8f/0x100 worker_thread+0x5ad/0xfd0 __kthread_parkme+0xc6/0x200 kthread+0x31e/0x410 trace_hardirqs_on+0x1a/0x170 ret_from_fork+0x576/0x810 __switch_to+0x57e/0xe20 __switch_to_asm+0x33/0x70 ret_from_fork_asm+0x1a/0x30
--- net/wireless/core.c | 1 + 1 file changed, 1 insertion(+)
net/wireless/core.c +1 -0
@@ -1195,6 +1195,7 @@ void wiphy_unregister(struct wiphy *wiphy)/* this has nothing to do now but make sure it's gone */ cancel_work_sync (&rdev->wiphy_work); +cancel_work_sync (&rdev->sched_scan_res_wk);cancel_work_sync (&rdev->rfkill_block);cancel_work_sync (&rdev->conn_work);flush_work (&rdev->event_work);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 66/675 wifi: ipw2100: fix potential memory leak in ipw2100_pci_init_one()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Abdun Nihaal <[email protected]>
[ Upstream commit 0d388f62031dbabcba0f44bb91b59f10e88cac17 ]
The memory allocated in the ipw2100_alloc_device() function is not freed in some of the error paths in ipw2100_pci_init_one(). Fix that by converting the direct return into a goto to the error path return.
The error path when pci_enable_device() fails cannot jump to fail, since at this point priv is not set, so perform error handling inline.
--- drivers/net/wireless/intel/ipw2x00/ipw2100.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/net/wireless/intel/ipw2x00/ipw2100.c +4 -4
@@ -6162,6 +6162,8 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,if (err) { printk(KERN_WARNING DRV_NAME "Error calling pci_enable_device.\n"); +free_libipw (dev,0 ); +pci_iounmap (pci_dev, ioaddr);return err; }
@@ -6174,16 +6176,14 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,if (err) { printk(KERN_WARNING DRV_NAME "Error calling pci_set_dma_mask.\n"); -pci_disable_device (pci_dev); -return err; + goto fail; } err =pci_request_regions (pci_dev,DRV_NAME );if (err) { printk(KERN_WARNING DRV_NAME "Error calling pci_request_regions.\n"); -pci_disable_device (pci_dev); -return err; + goto fail; }/* We disable the RETRY_TIMEOUT register (0x41) to keep
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 67/675 wifi: cfg80211: Fix an error handling path in cfg80211_wext_siwscan()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe JAILLET <[email protected]>
[ Upstream commit c6659f66d4ee4841aafae5659d2ef5e4c5c63cb6 ]
If the test against IEEE80211_MAX_SSID_LEN fails, then 'creq' leaks. Use the existing error handling path to fix it.
--- net/wireless/scan.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
net/wireless/scan.c +4 -2
@@ -3627,8 +3627,10 @@ int cfg80211_wext_siwscan(struct net_device *dev,/* translate "Scan for SSID" request */ if (wreq) {if (wrqu->data.flags &IW_SCAN_THIS_ESSID ) { -if (wreq->essid_len >IEEE80211_MAX_SSID_LEN ) -return -EINVAL ; +if (wreq->essid_len >IEEE80211_MAX_SSID_LEN ) { + err = -EINVAL ; + goto out; + }memcpy (creq->req.ssids[0 ].ssid, wreq->essid, wreq->essid_len); creq->req.ssids[0 ].ssid_len = wreq->essid_len;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 68/675 wifi: mac80211_hwsim: clamp virtio RX length before skb_put
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 10a2b430f8f06ae14b9590b6f6faa6b588ef0654 ]
hwsim_virtio_rx_work() passes the virtqueue used-ring length reported by the device straight to skb_put() on a fixed-size receive skb. A backend reporting a length larger than the skb tailroom drives skb_put() past the buffer end and hits skb_over_panic() -- a host-triggerable guest panic (denial of service).
Clamp the length to the skb's available room before skb_put(). A conforming device never reports more than the posted buffer size, so valid frames are unaffected; a truncated over-report then fails the length/header checks in hwsim_virtio_handle_cmd() and is dropped, so truncating rather than dropping here cannot be turned into a parsing problem.
--- drivers/net/wireless/virtual/mac80211_hwsim.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/wireless/virtual/mac80211_hwsim.c +1 -0
@@ -6898,6 +6898,7 @@ static void hwsim_virtio_rx_work(struct work_struct *work) skb->data = skb->head;skb_reset_tail_pointer (skb); + len =min (len,skb_end_offset (skb));skb_put (skb, len);hwsim_virtio_handle_cmd (skb);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 69/675 wifi: mac80211: fix unsol_bcast_probe_resp double free on alloc failure
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiang Mei <[email protected]>
[ Upstream commit 1d067abcd37062426c59ec73dbc4e87a63f33fea ]
ieee80211_set_unsol_bcast_probe_resp() calls kfree_rcu() on the old template before allocating the replacement. If the kzalloc() then fails, it returns -ENOMEM while link->u.ap.unsol_bcast_probe_resp still points at the object already queued for freeing. A later update or AP teardown re-queues that same rcu_head; the second free is caught by KASAN when the RCU sheaf is processed in softirq:
BUG: KASAN: double-free in rcu_free_sheaf (mm/slub.c:5850) Free of addr ffff88800d06f300 by task exploit/145 ... __rcu_free_sheaf_prepare (mm/slub.c:2634 mm/slub.c:2940) rcu_free_sheaf (mm/slub.c:5850) rcu_core (kernel/rcu/tree.c:2617 kernel/rcu/tree.c:2869) handle_softirqs (kernel/softirq.c:622) The buggy address belongs to the cache kmalloc-128 of size 128
Queue the old object for kfree_rcu() only after the new one is published, matching ieee80211_set_probe_resp() and ieee80211_set_s1g_short_beacon().
--- net/mac80211/cfg.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
net/mac80211/cfg.c +3 -2
@@ -1157,8 +1157,6 @@ ieee80211_set_unsol_bcast_probe_resp(struct ieee80211_sub_if_data *sdata, link_conf->unsol_bcast_probe_resp_interval = params->interval; old =sdata_dereference (link->u.ap.unsol_bcast_probe_resp, sdata); -if (old) -kfree_rcu (old, rcu_head);if (params->tmpl && params->tmpl_len) { new =kzalloc (sizeof (*new) + params->tmpl_len,GFP_KERNEL );
@@ -1171,6 +1169,9 @@ ieee80211_set_unsol_bcast_probe_resp(struct ieee80211_sub_if_data *sdata,RCU_INIT_POINTER (link->u.ap.unsol_bcast_probe_resp,NULL ); } +if (old) +kfree_rcu (old, rcu_head); + *changed |=BSS_CHANGED_UNSOL_BCAST_PROBE_RESP ;return 0 ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 70/675 wifi: mac80211: fix fils_discovery double free on alloc failure
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiang Mei <[email protected]>
[ Upstream commit 286e52a799fa158bdbd77da1426c4d93f9a6e7ad ]
ieee80211_set_fils_discovery() calls kfree_rcu() on the old template before allocating the replacement. If the kzalloc() then fails, it returns -ENOMEM while link->u.ap.fils_discovery still points at the object already queued for freeing. A later update or AP teardown (ieee80211_stop_ap()) re-queues that same rcu_head; the second free is caught by KASAN when the RCU sheaf is processed in softirq:
BUG: KASAN: double-free in rcu_free_sheaf (mm/slub.c:5850) Free of addr ffff88800c065280 by task swapper/0/0 ... __rcu_free_sheaf_prepare (mm/slub.c:2634 mm/slub.c:2940) rcu_free_sheaf (mm/slub.c:5850) rcu_core (kernel/rcu/tree.c:2617 kernel/rcu/tree.c:2869) handle_softirqs (kernel/softirq.c:622) The buggy address belongs to the cache kmalloc-96 of size 96
Queue the old object for kfree_rcu() only after the new one is published, matching ieee80211_set_probe_resp() and ieee80211_set_s1g_short_beacon().
--- net/mac80211/cfg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
net/mac80211/cfg.c +3 -3
@@ -1124,9 +1124,6 @@ static int ieee80211_set_fils_discovery(struct ieee80211_sub_if_data *sdata, fd->max_interval = params->max_interval; old =sdata_dereference (link->u.ap.fils_discovery, sdata); -if (old) -kfree_rcu (old, rcu_head); -if (params->tmpl && params->tmpl_len) { new =kzalloc (sizeof (*new) + params->tmpl_len,GFP_KERNEL );if (!new)
@@ -1138,6 +1135,9 @@ static int ieee80211_set_fils_discovery(struct ieee80211_sub_if_data *sdata,RCU_INIT_POINTER (link->u.ap.fils_discovery,NULL ); } +if (old) +kfree_rcu (old, rcu_head); + *changed |=BSS_CHANGED_FILS_DISCOVERY ;return 0 ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 71/675 wifi: libertas: fix memory leak in helper_firmware_cb()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dawei Feng <[email protected]>
[ Upstream commit 63c2391deefb31e1b801b7f32bd502ca4808639b ]
helper_firmware_cb() neglects to free the single-stage firmware image after a successful async load, leading to a memory leak in the USB firmware-download path.
Fix this memory leak by calling release_firmware() immediately after lbs_fw_loaded() returns.
The bug was first flagged by an experimental analysis tool we are developing for kernel memory-management bugs while analyzing v6.13-rc1. The tool is still under development and is not yet publicly available. Manual inspection confirms that the bug is still present in the current wireless tree.
An x86_64 allyesconfig build showed no new warnings. As we do not have compatible Libertas USB hardware for exercising this firmware-download path, no runtime testing was able to be performed.
--- drivers/net/wireless/marvell/libertas/firmware.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/wireless/marvell/libertas/firmware.c +1 -0
@@ -78,6 +78,7 @@ static void helper_firmware_cb(const struct firmware *firmware, void *context) }else {/* No main firmware needed for this helper --> success! */ lbs_fw_loaded (priv,0 , firmware,NULL ); +release_firmware (firmware); } }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 72/675 wifi: mac80211: defer link RX stats percpu free to RCU
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maoyi Xie <[email protected]>
[ Upstream commit aa2eb62525188269cdd402a583b9a8ed94657ff0 ]
sta_remove_link() frees a removed MLO link's RX stats percpu buffer right away, but defers only the link container to RCU:
sta_info_free_link(&alloc->info); kfree_rcu(alloc, rcu_head);
The RX fast path reads link_sta under rcu_read_lock and writes the percpu stats. A reader that resolved link_sta before the removal keeps the pointer. The container stays alive from the kfree_rcu, so the read still works. But the percpu block it points to is already freed. This needs uses_rss. That is when pcpu_rx_stats exists.
The full STA teardown frees the deflink stats only after synchronize_net(). The link removal path had no such barrier. The race is hard to win in practice, but the free should still wait for RCU.
Free the link together with its data from a single RCU callback, so the percpu block is reclaimed only after readers drain.
--- net/mac80211/sta_info.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
net/mac80211/sta_info.c +11 -4
@@ -355,6 +355,15 @@ static void sta_info_free_link(struct link_sta_info *link_sta)free_percpu (link_sta->pcpu_rx_stats); } +static void sta_link_free_rcu (struct rcu_head *head) +{ +struct sta_link_alloc *alloc = + container_of(head, struct sta_link_alloc, rcu_head); + +sta_info_free_link (&alloc->info); +kfree (alloc); +} +static void sta_accumulate_removed_link_stats (struct sta_info *sta,int link_id) { struct link_sta_info *link_sta = wiphy_dereference(sta->local->hw.wiphy,
@@ -427,10 +436,8 @@ static void sta_remove_link(struct sta_info *sta, unsigned int link_id,RCU_INIT_POINTER (sta->link[link_id],NULL );RCU_INIT_POINTER (sta->sta.link[link_id],NULL ); -if (alloc) { -sta_info_free_link (&alloc->info); -kfree_rcu (alloc, rcu_head); - } +if (alloc) +call_rcu (&alloc->rcu_head, sta_link_free_rcu);ieee80211_sta_recalc_aggregates (&sta->sta); }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 73/675 wifi: p54: validate RX frame length in p54_rx_eeprom_readback()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiang Mei <[email protected]>
[ Upstream commit ebd6d37fa94bee929e0b4c9ca19fdf9b1dcf6cea ]
p54_rx_eeprom_readback() copies the requested EEPROM slice out of a device-supplied readback frame without checking that the skb actually holds that many bytes. Commit da1b9a55ff11 ("wifi: p54: prevent buffer-overflow in p54_rx_eeprom_readback()") closed the destination overflow by copying a fixed priv->eeprom_slice_size (and rejecting a mismatched advertised len), but the source side is still unbounded: nothing verifies the frame is long enough to supply that many bytes.
A malicious USB device can send a short frame whose advertised len matches priv->eeprom_slice_size while the payload is truncated. The equality check passes and memcpy() reads past the end of the skb, leaking adjacent heap:
BUG: KASAN: slab-out-of-bounds in p54_rx (drivers/net/wireless/intersil/p54/txrx.c:507) Read of size 1016 at addr ffff88800f077114 by task swapper/0/0 Call Trace: <IRQ> ... __asan_memcpy (mm/kasan/shadow.c:105) p54_rx (drivers/net/wireless/intersil/p54/txrx.c:507) p54u_rx_cb (drivers/net/wireless/intersil/p54/p54usb.c:163) __usb_hcd_giveback_urb (drivers/usb/core/hcd.c:1657) dummy_timer (drivers/usb/gadget/udc/dummy_hcd.c:2005) ... </IRQ> The buggy address belongs to the object at ffff88800f0770c0 which belongs to the cache skbuff_small_head of size 704 The buggy address is located 84 bytes inside of allocated 704-byte region [ffff88800f0770c0, ffff88800f077380)
Check that the slice fits in the skb before copying.
--- drivers/net/wireless/intersil/p54/txrx.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/net/wireless/intersil/p54/txrx.c +8 -0
@@ -499,11 +499,19 @@ static void p54_rx_eeprom_readback(struct p54_common *priv,if (le16_to_cpu (eeprom->v2.len) != priv->eeprom_slice_size)return ; +if (eeprom->v2.data + priv->eeprom_slice_size > +skb_tail_pointer (skb)) +return ; +memcpy (priv->eeprom, eeprom->v2.data, priv->eeprom_slice_size); }else {if (le16_to_cpu (eeprom->v1.len) != priv->eeprom_slice_size)return ; +if (eeprom->v1.data + priv->eeprom_slice_size > +skb_tail_pointer (skb)) +return ; +memcpy (priv->eeprom, eeprom->v1.data, priv->eeprom_slice_size); }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 74/675 wifi: cfg80211: convert pmsr_free_wk to wiphy_work to fix deadlock
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peddolla Harshavardhan Reddy <[email protected]>
[ Upstream commit 2b0eab425e1f658d8fe1df7590e3b9af5959505e ]
When a netlink socket that owns a PMSR session is closed, cfg80211_release_pmsr() clears the request's nl_portid and queues pmsr_free_wk to call cfg80211_pmsr_process_abort() asynchronously.
If the interface tears down concurrently, cfg80211_pmsr_wdev_down() is called under wiphy_lock and calls cancel_work_sync(&pmsr_free_wk) to wait for any running work. The work function acquires wiphy_lock via guard(wiphy) before calling process_abort.
This is a deadlock: wdev_down holds wiphy_lock and blocks inside cancel_work_sync(); pmsr_free_wk blocks trying to acquire that same wiphy_lock. Neither thread can proceed.
The same deadlock is reachable from cfg80211_leave_locked(), which calls cfg80211_pmsr_wdev_down() for all interface types under wiphy_lock.
Fix this by converting pmsr_free_wk from a plain work_struct to a wiphy_work. The wiphy_work dispatcher holds wiphy_lock when running work items, so the explicit guard(wiphy) in the work function is no longer needed. wiphy_work_cancel() can be called safely while holding wiphy_lock - since wiphy_lock prevents the work from running concurrently, wiphy_work_cancel() never blocks, eliminating the deadlock.
Remove the cancel_work_sync() for pmsr_free_wk from the NETDEV_GOING_DOWN handler. cfg80211_leave(), called unconditionally just before it, already cancels any pending work under wiphy_lock via wiphy_work_cancel() inside cfg80211_pmsr_wdev_down().
--- include/net/cfg80211.h | 2 +- net/wireless/core.c | 3 +-- net/wireless/core.h | 2 +- net/wireless/pmsr.c | 8 +++----- 4 files changed, 6 insertions(+), 9 deletions(-)
include/net/cfg80211.h +1 -1
@@ -6740,7 +6740,7 @@ struct wireless_dev {struct list_head pmsr_list;spinlock_t pmsr_lock; -struct work_struct pmsr_free_wk; +struct wiphy_work pmsr_free_wk;unsigned long unprot_beacon_reported;
net/wireless/core.c +1 -2
@@ -1444,7 +1444,7 @@ void cfg80211_init_wdev(struct wireless_dev *wdev)INIT_LIST_HEAD (&wdev->mgmt_registrations);INIT_LIST_HEAD (&wdev->pmsr_list);spin_lock_init (&wdev->pmsr_lock); -INIT_WORK (&wdev->pmsr_free_wk, cfg80211_pmsr_free_wk); +wiphy_work_init (&wdev->pmsr_free_wk, cfg80211_pmsr_free_wk);#ifdef CONFIG_CFG80211_WEXT wdev->wext.default_key =-1 ;
@@ -1579,7 +1579,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, }/* since we just did cfg80211_leave() nothing to do there */ cancel_work_sync (&wdev->disconnect_wk); -cancel_work_sync (&wdev->pmsr_free_wk);break ;case NETDEV_DOWN :wiphy_lock (&rdev->wiphy);
net/wireless/core.h +1 -1
@@ -566,7 +566,7 @@ cfg80211_get_6ghz_power_type(const u8 *elems, size_t elems_len);void cfg80211_release_pmsr (struct wireless_dev *wdev,u32 portid);void cfg80211_pmsr_wdev_down (struct wireless_dev *wdev); -void cfg80211_pmsr_free_wk (struct work_struct *work); +void cfg80211_pmsr_free_wk (struct wiphy *wiphy,struct wiphy_work *work);void cfg80211_remove_link (struct wireless_dev *wdev,unsigned int link_id);void cfg80211_remove_links (struct wireless_dev *wdev);
net/wireless/pmsr.c +3 -5
@@ -625,13 +625,11 @@ static void cfg80211_pmsr_process_abort(struct wireless_dev *wdev) } } -void cfg80211_pmsr_free_wk (struct work_struct *work) +void cfg80211_pmsr_free_wk (struct wiphy *wiphy,struct wiphy_work *work) { struct wireless_dev *wdev = container_of(work, struct wireless_dev, pmsr_free_wk); -guard (wiphy)(wdev->wiphy); -cfg80211_pmsr_process_abort (wdev); }
@@ -647,7 +645,7 @@ void cfg80211_pmsr_wdev_down(struct wireless_dev *wdev) }spin_unlock_bh (&wdev->pmsr_lock); -cancel_work_sync (&wdev->pmsr_free_wk); +wiphy_work_cancel (wdev->wiphy, &wdev->pmsr_free_wk);if (found)cfg80211_pmsr_process_abort (wdev);
@@ -662,7 +660,7 @@ void cfg80211_release_pmsr(struct wireless_dev *wdev, u32 portid)list_for_each_entry (req, &wdev->pmsr_list, list) {if (req->nl_portid == portid) { req->nl_portid =0 ; -schedule_work (&wdev->pmsr_free_wk); +wiphy_work_queue (wdev->wiphy, &wdev->pmsr_free_wk); } }spin_unlock_bh (&wdev->pmsr_lock);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 75/675 wifi: nl80211: free RNR data on MBSSID mismatch
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhao Li <[email protected]>
[ Upstream commit 07a95ec2b54774201fdf4ef7ffb0ca2ab19ed29c ]
nl80211_parse_beacon() rejects EMA RNR data when there are fewer RNR entries than MBSSID entries.
The rejected RNR allocation has not been attached to the beacon data yet, so free it before returning the error.
--- net/wireless/nl80211.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
net/wireless/nl80211.c +3 -1
@@ -6232,8 +6232,10 @@ static int nl80211_parse_beacon(struct cfg80211_registered_device *rdev,if (IS_ERR (rnr))return PTR_ERR (rnr); -if (rnr && rnr->cnt < bcn->mbssid_ies->cnt) +if (rnr && rnr->cnt < bcn->mbssid_ies->cnt) { +kfree (rnr);return -EINVAL ; + } bcn->rnr_ies = rnr; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 76/675 wifi: cfg80211: derive S1G beacon TSF from S1G fields
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhao Li <[email protected]>
[ Upstream commit 4e5a4641e7b4763656336b7891d01359aaf363cd ]
cfg80211_inform_bss_frame_data() parses S1G beacons with the extension frame layout, but still reads the TSF from the regular probe response layout after the S1G branch. For S1G beacons that reads bytes at the regular management-frame timestamp offset instead of the S1G timestamp.
Use the 32-bit S1G beacon timestamp and the S1G Beacon Compatibility element's TSF completion field when informing an S1G BSS. Keep the regular management-frame timestamp read in the non-S1G branch.
--- net/wireless/scan.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
net/wireless/scan.c +3 -2
@@ -3326,14 +3326,15 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy, bssid = ext->u.s1g_beacon.sa; capability =le16_to_cpu (compat->compat_info); beacon_interval =le16_to_cpu (compat->beacon_int); + tsf =le32_to_cpu (ext->u.s1g_beacon.timestamp); + tsf |= (u64 )le32_to_cpu (compat->tsf_completion) <<32 ; }else { bssid = mgmt->bssid; beacon_interval =le16_to_cpu (mgmt->u.probe_resp.beacon_int); capability =le16_to_cpu (mgmt->u.probe_resp.capab_info); + tsf =le64_to_cpu (mgmt->u.probe_resp.timestamp); } - tsf =le64_to_cpu (mgmt->u.probe_resp.timestamp); -if (ieee80211_is_probe_resp (mgmt->frame_control)) ftype =CFG80211_BSS_FTYPE_PRESP ;else if (ext)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 77/675 wifi: nl80211: validate nested MBSSID IE blobs
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhao Li <[email protected]>
[ Upstream commit 7f4b01812323443b55e4c65381c9dc851ff009e3 ]
Validate each nested NL80211_ATTR_MBSSID_ELEMS entry as a well-formed information-element stream before storing it for beacon construction.
RNR parsing already validates each nested blob with validate_ie_attr() before storing it. Apply the same syntactic IE validation to MBSSID entries before counting and copying their data and length pointers.
--- net/wireless/nl80211.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
net/wireless/nl80211.c +10 -2
@@ -6034,7 +6034,8 @@ static int nl80211_parse_mbssid_config(struct wiphy *wiphy, }static struct cfg80211_mbssid_elems * -nl80211_parse_mbssid_elems (struct wiphy *wiphy,struct nlattr *attrs) +nl80211_parse_mbssid_elems (struct wiphy *wiphy,struct nlattr *attrs, +struct netlink_ext_ack *extack) {struct nlattr *nl_elems;struct cfg80211_mbssid_elems *elems;
@@ -6045,6 +6046,12 @@ nl80211_parse_mbssid_elems(struct wiphy *wiphy, struct nlattr *attrs)return ERR_PTR (-EINVAL );nla_for_each_nested (nl_elems, attrs, rem_elems) { +int ret; + + ret =validate_ie_attr (nl_elems, extack); +if (ret) +return ERR_PTR (ret); +if (num_elems >=255 )return ERR_PTR (-EINVAL ); num_elems++;
@@ -6216,7 +6223,8 @@ static int nl80211_parse_beacon(struct cfg80211_registered_device *rdev,if (attrs[NL80211_ATTR_MBSSID_ELEMS ]) {struct cfg80211_mbssid_elems *mbssid =nl80211_parse_mbssid_elems (&rdev->wiphy, - attrs[NL80211_ATTR_MBSSID_ELEMS ]); + attrs[NL80211_ATTR_MBSSID_ELEMS ], + extack);if (IS_ERR (mbssid))return PTR_ERR (mbssid);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 78/675 wifi: nl80211: constrain MBSSID TX link ID range
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhao Li <[email protected]>
[ Upstream commit 172f06023669f0a96d32511669ff45c600731380 ]
MBSSID transmitted-profile link IDs are valid only in the range 0..IEEE80211_MLD_MAX_NUM_LINKS - 1. Constrain the nl80211 policy to reject out-of-range values during attribute validation.
--- net/wireless/nl80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/wireless/nl80211.c +1 -1
@@ -501,7 +501,7 @@ nl80211_mbssid_config_policy[NL80211_MBSSID_CONFIG_ATTR_MAX + 1] = { [NL80211_MBSSID_CONFIG_ATTR_TX_IFINDEX] = { .type = NLA_U32 }, [NL80211_MBSSID_CONFIG_ATTR_EMA] = { .type = NLA_FLAG }, [NL80211_MBSSID_CONFIG_ATTR_TX_LINK_ID ] = - NLA_POLICY_MAX(NLA_U8, IEEE80211_MLD_MAX_NUM_LINKS), + NLA_POLICY_RANGE(NLA_U8, 0, IEEE80211_MLD_MAX_NUM_LINKS - 1), }; static const struct nla_policy
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 79/675 wifi: cfg80211: validate PMSR measurement type data
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhao Li <[email protected]>
[ Upstream commit 41aa973eb05922848dded26875c55ef982ac1c49 ]
PMSR request parsing accepts missing or duplicated measurement type entries in NL80211_PMSR_REQ_ATTR_DATA.
Track whether one measurement type was already provided, reject a second one immediately, and return an error if the request data block contains no measurement type at all.
--- net/wireless/pmsr.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-)
net/wireless/pmsr.c +17 -2
@@ -196,6 +196,7 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev, {struct nlattr *tb[NL80211_PMSR_PEER_ATTR_MAX +1 ];struct nlattr *req[NL80211_PMSR_REQ_ATTR_MAX +1 ]; +bool have_measurement_type = false;struct nlattr *treq;int err, rem;
@@ -248,6 +249,14 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev, }nla_for_each_nested (treq, req[NL80211_PMSR_REQ_ATTR_DATA ], rem) { +if (have_measurement_type) { +NL_SET_ERR_MSG_ATTR (info->extack, treq, +"multiple measurement types in request data" ); +return -EINVAL ; + } + + have_measurement_type = true; +switch (nla_type (treq)) {case NL80211_PMSR_TYPE_FTM : err =pmsr_parse_ftm (rdev, treq, out, info);
@@ -257,10 +266,16 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev, "unsupported measurement type"); err = -EINVAL ; } +if (err) +return err; } -if (err) -return err; +if (!have_measurement_type) { +NL_SET_ERR_MSG_ATTR (info->extack, + req[NL80211_PMSR_REQ_ATTR_DATA ], +"missing measurement type in request data" ); +return -EINVAL ; + }return 0 ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 80/675 wifi: cfg80211: validate PMSR FTM preamble range
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhao Li <[email protected]>
[ Upstream commit 36230936468f0ba4930e94aef496fc229d4bb951 ]
PMSR FTM request parsing accepts preamble values outside the enumerated nl80211 preamble range.
Reject out-of-range values before using them in the parser capability bit test using the policy.
--- net/wireless/nl80211.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
net/wireless/nl80211.c +3 -1
@@ -347,7 +347,9 @@ nl80211_ftm_responder_policy[NL80211_FTM_RESP_ATTR_MAX + 1] = {static const struct nla_policy nl80211_pmsr_ftm_req_attr_policy[NL80211_PMSR_FTM_REQ_ATTR_MAX +1 ] = { [NL80211_PMSR_FTM_REQ_ATTR_ASAP ] = { .type =NLA_FLAG }, - [NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE ] = { .type =NLA_U32 }, + [NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE ] = +NLA_POLICY_RANGE (NLA_U32 ,NL80211_PREAMBLE_LEGACY , +NL80211_PREAMBLE_HE ), [NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP ] =NLA_POLICY_MAX (NLA_U8 ,15 ), [NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD ] = { .type =NLA_U16 },
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 81/675 wifi: cfg80211: reject unsupported PMSR FTM location requests
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhao Li <[email protected]>
[ Upstream commit 69ef6a7ec277f16d216be8da2b3cbe872786c999 ]
PMSR FTM location request flags are syntactically valid, but they must be rejected when the device capability does not advertise support for them.
Return an error immediately after rejecting unsupported LCI or civic location request bits so the request cannot reach the driver.
--- net/wireless/pmsr.c | 2 ++ 1 file changed, 2 insertions(+)
net/wireless/pmsr.c +2 -0
@@ -114,6 +114,7 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev,NL_SET_ERR_MSG_ATTR (info->extack, tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI ],"FTM: LCI request not supported" ); +return -EOPNOTSUPP ; } out->ftm.request_civicloc =
@@ -122,6 +123,7 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev,NL_SET_ERR_MSG_ATTR (info->extack, tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC ],"FTM: civic location request not supported" ); +return -EOPNOTSUPP ; } out->ftm.trigger_based =
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 82/675 wifi: mac80211: avoid non-S1G AID fallback for S1G assoc
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhao Li <[email protected]>
[ Upstream commit 035ed430ce6a2c35b01e211844a9f0a7643e57a4 ]
When assoc_data->s1g is set and no AID Response element is present, falling back to mgmt->u.assoc_resp.aid reads the non-S1G association-response layout.
Keep the fallback for non-S1G only. If a successful S1G association response omits the AID Response element, abandon the association instead of proceeding with AID 0. Initialize aid to 0 for other S1G responses so the later mask and logging flow keeps a defined value without reading the non-S1G layout.
--- net/mac80211/mlme.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
net/mac80211/mlme.c +4 -2
@@ -6476,7 +6476,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, {struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data; -u16 capab_info, status_code, aid; +u16 capab_info, status_code, aid =0 ;struct ieee80211_elems_parse_params parse_params = { .bss =NULL , .link_id =-1 ,
@@ -6553,8 +6553,10 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,if (elems->aid_resp) aid =le16_to_cpu (elems->aid_resp->aid); -else +else if (!assoc_data->s1g) aid =le16_to_cpu (mgmt->u.assoc_resp.aid); +else if (status_code ==WLAN_STATUS_SUCCESS ) + goto abandon_assoc;/* * The 5 MSB of the AID field are reserved for a non-S1G STA. For
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 83/675 wifi: mac80211: free AP_VLAN bc_buf SKBs outside IRQ lock
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cen Zhang <[email protected]>
[ Upstream commit f3858d5b1432098c1936e03d6e03dd0e33facf60 ]
ieee80211_do_stop() removes AP_VLAN packets from the parent AP ps->bc_buf while holding ps->bc_buf.lock with IRQs disabled. It then calls ieee80211_free_txskb() before dropping the lock.
ieee80211_free_txskb() is not just a passive SKB release. For SKBs with TX status state it can report a dropped frame through cfg80211/nl80211, and that path can reach netlink tap transmit. This is the same reason the pending queue cleanup in ieee80211_do_stop() already unlinks SKBs under the queue lock and frees them after IRQ state is restored.
The buggy scenario involves two paths, with each column showing the order within that path:
AP_VLAN management TX: AP_VLAN stop: 1. attach ACK-status state 1. clear the running state 2. queue a multicast SKB on 2. take ps->bc_buf.lock with IRQs
parent ps->bc_buf disabled
3. unlink the AP_VLAN SKB
4. call ieee80211_free_txskb()
Unlink matching AP_VLAN SKBs from ps->bc_buf under the existing lock, but move them to a local free queue. Drop the lock and restore IRQ state before calling ieee80211_free_txskb().
WARNING: kernel/softirq.c:430 at __local_bh_enable_ip
--- net/mac80211/iface.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
net/mac80211/iface.c +7 -1
@@ -581,6 +581,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_doWARN_ON (!list_empty (&sdata->u.ap.vlans)); }else if (sdata->vif.type ==NL80211_IFTYPE_AP_VLAN ) {/* remove all packets in parent bc_buf pointing to this dev */ +__skb_queue_head_init (&freeq); ps = &sdata->bss->ps;spin_lock_irqsave (&ps->bc_buf.lock, flags);
@@ -588,10 +589,15 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_doif (skb->dev == sdata->dev) {__skb_unlink (skb, &ps->bc_buf); local->total_ps_buffered--; -ieee80211_free_txskb (&local->hw, skb); +__skb_queue_tail (&freeq, skb); } }spin_unlock_irqrestore (&ps->bc_buf.lock, flags); + + skb_queue_walk_safe(&freeq, skb, tmp) { +__skb_unlink (skb, &freeq); +ieee80211_free_txskb (&local->hw, skb); + } }if (going_down)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 84/675 wifi: brcmfmac: initialize SDIO data work before cleanup
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Runyu Xiao <[email protected]>
[ Upstream commit 2a665946e0407a05a3f81bd56a08553c446498e0 ]
brcmf_sdio_probe() stores the newly allocated bus in sdiodev->bus before allocating the ordered workqueue. If that allocation fails, the function jumps to fail and calls brcmf_sdio_remove().
brcmf_sdio_remove() unconditionally cancels bus->datawork. Initialize the work item before the first failure path that can reach brcmf_sdio_remove(), so the cleanup path always observes a valid work object.
This issue was found by our static analysis tool and then confirmed by manual review of the probe error path and the remove-time work drain. The problem pattern is an early setup failure that reaches a cleanup helper which cancels an embedded work item before its initializer has run.
A QEMU PoC forced alloc_ordered_workqueue() to fail at the same point in brcmf_sdio_probe(), before INIT_WORK(&bus->datawork) is reached. The resulting fail path calls brcmf_sdio_remove(), and DEBUG_OBJECTS reports the invalid work drain with brcmf_sdio_probe() and brcmf_sdio_remove() in the stack.
--- drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +1 -1
@@ -4465,6 +4465,7 @@ int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) bus->sdiodev = sdiodev; sdiodev->bus = bus;skb_queue_head_init (&bus->glom); +INIT_WORK (&bus->datawork, brcmf_sdio_dataworker); bus->txbound =BRCMF_TXBOUND ; bus->rxbound =BRCMF_RXBOUND ; bus->txminmax =BRCMF_TXMINMAX ;
@@ -4479,7 +4480,6 @@ int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) goto fail; }brcmf_sdiod_freezer_count (sdiodev); -INIT_WORK (&bus->datawork, brcmf_sdio_dataworker); bus->brcmf_wq = wq;/* attempt to attach to the dongle */
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 85/675 wifi: cfg80211: bound element ID read when checking non-inheritance
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: HE WEI (ギカク) <[email protected]>
[ Upstream commit cb8afea4655ff004fa7feee825d5c79783525383 ]
cfg80211_is_element_inherited() reads the first data octet of the candidate element (id = elem->data[0]) to look it up in an extension non-inheritance list. It does so after testing elem->id, but without verifying that the element actually has a data octet. A zero-length extension element (WLAN_EID_EXTENSION with length 0) therefore makes it read one octet past the end of the element.
_ieee802_11_parse_elems_full() runs this check for every element of a frame once a non-inheritance context exists -- e.g. while parsing a per-STA profile of a Multi-Link element in a (re)association response, or a non-transmitted BSS profile -- so a crafted frame from an AP can trigger a one-octet slab-out-of-bounds read during element parsing:
BUG: KASAN: slab-out-of-bounds in cfg80211_is_element_inherited Read of size 1 ... in net/wireless/scan.c
Return early (treat the element as inherited) when an extension element carries no data, mirroring the existing handling of empty ID lists.
The bug was found by fuzzing ieee802_11_parse_elems_full() under KASAN.
--- net/wireless/scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/wireless/scan.c +1 -1
@@ -205,7 +205,7 @@ bool cfg80211_is_element_inherited(const struct element *elem,return true;if (elem->id ==WLAN_EID_EXTENSION ) { -if (!ext_id_len) +if (!ext_id_len || !elem->datalen)return true; loop_len = ext_id_len; list = &non_inherit_elem->data[3 + id_len];
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 86/675 firmware: arm_ffa: Fix out-of-bound writes in ffa_setup_and_transmit()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mostafa Saleh <[email protected]>
[ Upstream commit 3383ffb7ef937317361713ffcc21921a7848511a ]
Sashiko (locally) reports multiple out-of-bound issues in ffa_setup_and_transmit:
1) Writing ep_mem_access->reserved can write out of bounds for FFA versions < 1.2 as ffa_emad_size_get() returns 16 bytes in that case while reserved has an offset of 24.
Instead of zeroing fields, memset the struct to zero first based on the FFA version.
2) Make sure there is enough size to write constituents.
While at it, convert the only sizeof() in the driver that uses a type instead of variable.
--- drivers/firmware/arm_ffa/driver.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
drivers/firmware/arm_ffa/driver.c +3 -4
@@ -719,11 +719,10 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize,for (idx =0 ; idx < args->nattrs; idx++) { ep_mem_access = buffer +ffa_mem_desc_offset (buffer, idx, drv_info->version); +memset (ep_mem_access,0 ,ffa_emad_size_get (drv_info->version)); ep_mem_access->receiver = args->attrs[idx].receiver; ep_mem_access->attrs = args->attrs[idx].attrs; ep_mem_access->composite_off = composite_offset; - ep_mem_access->flag =0 ; - ep_mem_access->reserved =0 ;ffa_emad_impdef_value_init (drv_info->version, ep_mem_access->impdef_val, args->attrs[idx].impdef_val);
@@ -763,7 +762,7 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize, constituents = buffer; } -if ((void *)constituents - buffer > max_fragsize) { +if ((void *)constituents +sizeof (*constituents) - buffer > max_fragsize) {pr_err ("Memory Region Fragment > Tx Buffer size\n" );return -EFAULT ; }
@@ -772,7 +771,7 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize, constituents->pg_cnt = args->sg->length /FFA_PAGE_SIZE ; constituents->reserved =0 ; constituents++; - frag_len +=sizeof (struct ffa_mem_region_addr_range ); + frag_len +=sizeof (*constituents); }while ((args->sg =sg_next (args->sg))); return ffa_transmit_fragment(func_id, addr, buf_sz, frag_len,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 87/675 firmware: arm_ffa: Fix Endpoint Memory Access Descriptor offset calculation
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Ene <[email protected]>
[ Upstream commit b4d961351aa84fdf0148783fb1f3a1391b8a0adb ]
Use the descriptor's ep_mem_offset to calculate the start of the endpoint memory access array and to comply with the FF-A spec instead of defaulting to sizeof(struct ffa_mem_region).
This requires moving ffa_mem_region_additional_setup() earlier in the setup flow.
Also, add sanity checks to ensure the calculated descriptor offsets do not exceed max_fragsize.
--- drivers/firmware/arm_ffa/driver.c | 20 +++++++++++++++----- include/linux/arm_ffa.h | 2 +- 2 files changed, 16 insertions(+), 6 deletions(-)
drivers/firmware/arm_ffa/driver.c +15 -5
@@ -707,19 +707,30 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize,struct ffa_composite_mem_region *composite;struct ffa_mem_region_addr_range *constituents;struct ffa_mem_region_attributes *ep_mem_access; -u32 idx, frag_len, length, buf_sz =0 , num_entries =sg_nents (args->sg); +u32 idx, frag_len, length, buf_sz =0 , num_entries =sg_nents (args->sg), ep_offset; +u32 emad_end, emad_size =ffa_emad_size_get (drv_info->version); mem_region->tag = args->tag; mem_region->flags = args->flags; mem_region->sender_id = drv_info->vm_id; mem_region->attributes =ffa_memory_attributes_get (func_id); + +ffa_mem_region_additional_setup (drv_info->version, mem_region); composite_offset =ffa_mem_desc_offset (buffer, args->nattrs, drv_info->version); +if (composite_offset +sizeof (*composite) > max_fragsize) +return -ENXIO ;for (idx =0 ; idx < args->nattrs; idx++) { - ep_mem_access = buffer + -ffa_mem_desc_offset (buffer, idx, drv_info->version); -memset (ep_mem_access,0 ,ffa_emad_size_get (drv_info->version)); + ep_offset =ffa_mem_desc_offset (buffer, idx, drv_info->version); +if (check_add_overflow (ep_offset, emad_size, &emad_end)) +return -ENXIO ; + +if (emad_end > max_fragsize) +return -ENXIO ; + + ep_mem_access = buffer + ep_offset; +memset (ep_mem_access,0 , emad_size); ep_mem_access->receiver = args->attrs[idx].receiver; ep_mem_access->attrs = args->attrs[idx].attrs; ep_mem_access->composite_off = composite_offset;
@@ -729,7 +740,6 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize, } mem_region->handle =0 ; mem_region->ep_count = args->nattrs; -ffa_mem_region_additional_setup (drv_info->version, mem_region); composite = buffer + composite_offset; composite->total_pg_cnt =ffa_get_num_pages_sg (args->sg);
include/linux/arm_ffa.h +1 -1
@@ -445,7 +445,7 @@ ffa_mem_desc_offset(struct ffa_mem_region *buf, int count, u32 ffa_version)if (!FFA_MEM_REGION_HAS_EP_MEM_OFFSET (ffa_version)) offset += offsetof(struct ffa_mem_region , ep_mem_offset);else - offset +=sizeof (struct ffa_mem_region ); + offset += buf->ep_mem_offset;return offset; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 88/675 ASoC: meson: aiu: fifo-spdif: soft reset the S/PDIF datapath on start/stop
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Hewitt <[email protected]>
[ Upstream commit 6b59c53c8adc2b522327407af5e1793a65b67e4b ]
The I2S FIFO soft-resets its fast domain on start (AIU_RST_SOFT bit 0 + AIU_I2S_SYNC read in aiu_fifo_i2s_trigger), mirroring the downstream vendor driver's audio_out_i2s_enable(). The S/PDIF FIFO has no equivalent:
it only toggles the IEC958 DCU, so a stale datapath FIFO can be replayed, producing the "machine gun noise" buffer underrun - on start when switching outputs, and on stop when playback ends. The latter is audible on devices with an always-on S/PDIF-fed DAC (e.g. the ES7144 on the WeTek Play2).
The vendor driver resets the IEC958 fast domain (AIU_RST_SOFT bit 2) on both enable and disable (audio_hw_958_enable), and when reconfiguring (audio_hw_958_reset clears AIU_958_DCU_FF_CTRL then resets). Do the same:
reset before enabling the DCU on start, and before disabling on stop.
--- sound/soc/meson/aiu-fifo-spdif.c | 5 +++++ 1 file changed, 5 insertions(+)
sound/soc/meson/aiu-fifo-spdif.c +5 -0
@@ -24,6 +24,7 @@#define AIU_MEM_IEC958_CONTROL_MODE_16BIT BIT(7)#define AIU_MEM_IEC958_CONTROL_MODE_LINEAR BIT(8)#define AIU_MEM_IEC958_BUF_CNTL_INIT BIT(0) +#define AIU_RST_SOFT_958_FAST BIT(2)#define AIU_FIFO_SPDIF_BLOCK 8
@@ -68,11 +69,15 @@ static int fifo_spdif_trigger(struct snd_pcm_substream *substream, int cmd,case SNDRV_PCM_TRIGGER_START :case SNDRV_PCM_TRIGGER_RESUME :case SNDRV_PCM_TRIGGER_PAUSE_RELEASE : +snd_soc_component_write (component,AIU_RST_SOFT , +AIU_RST_SOFT_958_FAST );fifo_spdif_dcu_enable (component, true);break ;case SNDRV_PCM_TRIGGER_SUSPEND :case SNDRV_PCM_TRIGGER_PAUSE_PUSH :case SNDRV_PCM_TRIGGER_STOP : +snd_soc_component_write (component,AIU_RST_SOFT , +AIU_RST_SOFT_958_FAST );fifo_spdif_dcu_enable (component, false);break ;default :
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 89/675 ASoC: amd: ps: disable MSI on resume in ACP PCI driver
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vijendar Mukunda <[email protected]>
[ Upstream commit 5893013efabb056399a01e267f410cf76eba25eb ]
BIOS/firmware may re-enable MSI in PCI config space during system level resume even though this driver only uses legacy INTx interrupts. If MSI is left enabled with stale address/data registers, the device will write interrupts to a bogus address causing IOMMU IO_PAGE_FAULT and interrupt delivery failure.
Clear the MSI Enable bit before reinitializing the ACP hardware on system level resume.
--- sound/soc/amd/ps/pci-ps.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
sound/soc/amd/ps/pci-ps.c +29 -0
@@ -683,8 +683,37 @@ static int snd_acp_runtime_resume(struct device *dev)return acp_hw_runtime_resume (dev); } +static void acp_disable_msi_on_resume (struct pci_dev *pdev) +{ +u16 control; + +if (!pdev->msi_cap) +return ; + +pci_read_config_word (pdev, pdev->msi_cap +PCI_MSI_FLAGS , &control); +if (control &PCI_MSI_FLAGS_ENABLE ) { +dev_warn (&pdev->dev, +"ACP: MSI unexpectedly enabled after resume (flags=0x%04x), disabling\n" , + control); + control &= ~PCI_MSI_FLAGS_ENABLE ; +pci_write_config_word (pdev, pdev->msi_cap +PCI_MSI_FLAGS , control); + } +} +static int snd_acp_resume (struct device *dev) { +struct pci_dev *pdev =to_pci_dev (dev); + +/* +* BIOS/firmware may re-enable MSI in PCI config space during +* system resume even though this driver only uses legacy INTx +* interrupts. If MSI is left enabled with stale address/data +* registers, the device will write interrupts to a bogus address +* causing IOMMU IO_PAGE_FAULT and interrupt delivery failure. +* Explicitly clear the MSI Enable bit before reinitializing +* the ACP hardware. +*/ +acp_disable_msi_on_resume (pdev);return acp_hw_resume (dev); }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 90/675 ASoC: amd: ps: fix wrong ACP version string in pci_request_regions()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vijendar Mukunda <[email protected]>
[ Upstream commit f7697ecf6eab9d4887dd731038b3dc405c7e755e ]
The driver handles ACP6.3/7.0/7.1/7.2 platforms but the region was claimed with the stale name "AMD ACP6.2 audio" left over from the original ACP6.2 driver. Correct it to "AMD ACP6.3 audio".
--- sound/soc/amd/ps/pci-ps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/amd/ps/pci-ps.c +1 -1
@@ -595,7 +595,7 @@ static int snd_acp63_probe(struct pci_dev *pci,return -ENODEV ; } - ret =pci_request_regions (pci,"AMD ACP6.2 audio" ); + ret =pci_request_regions (pci,"AMD ACP6.3 audio" );if (ret <0 ) {dev_err (&pci->dev,"pci_request_regions failed\n" ); goto disable_pci;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 91/675 ASoC: amd: ps: replace bitwise OR with logical OR in IRQ return check
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vijendar Mukunda <[email protected]>
[ Upstream commit dec5aaa27603e1d7b426ce3504af6d1a62e4d444 ]
The condition 'irq_flag | wake_irq_flag' uses bitwise OR to combine two integer flags that are used as booleans. Replace with logical OR '||' to correctly express the intended boolean check.
--- sound/soc/amd/ps/pci-ps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/amd/ps/pci-ps.c +1 -1
@@ -248,7 +248,7 @@ static irqreturn_t acp63_irq_handler(int irq, void *dev_id)if (sdw_dma_irq_flag)return IRQ_WAKE_THREAD ; -if (irq_flag | wake_irq_flag) +if (irq_flag || wake_irq_flag)return IRQ_HANDLED ;else return IRQ_NONE ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 92/675 ASoC: cs42l43: Correct report for forced microphone jack
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Charles Keepax <[email protected]>
[ Upstream commit f74e6e15485b68b92b2807071e822db6309b7e38 ]
Currently if the jack is forced to the microphone mode, it will report as line in. Correct the report to microphone.
--- sound/soc/codecs/cs42l43-jack.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
sound/soc/codecs/cs42l43-jack.c +2 -1
@@ -310,6 +310,7 @@ irqreturn_t cs42l43_bias_detect_clamp(int irq, void *data)#define CS42L43_JACK_ABSENT 0x0#define CS42L43_JACK_OPTICAL (SND_JACK_MECHANICAL | SND_JACK_AVOUT) +#define CS42L43_JACK_MICROPHONE (SND_JACK_MECHANICAL | SND_JACK_MICROPHONE)#define CS42L43_JACK_HEADPHONE (SND_JACK_MECHANICAL | SND_JACK_HEADPHONE)#define CS42L43_JACK_HEADSET (SND_JACK_MECHANICAL | SND_JACK_HEADSET)#define CS42L43_JACK_LINEOUT (SND_JACK_MECHANICAL | SND_JACK_LINEOUT)
@@ -871,7 +872,7 @@ static const struct cs42l43_jack_override_mode { .hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES, .mic_ctrl = (0x3 <<CS42L43_JACK_STEREO_CONFIG_SHIFT ) | CS42L43_HS1_BIAS_EN_MASK | CS42L43_HS2_BIAS_EN_MASK, - .report = CS42L43_JACK_LINEIN, + .report = CS42L43_JACK_MICROPHONE, }, [CS42L43_JACK_RAW_OPTICAL] = { .hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 93/675 ASoC: tas2562: fix deprecated shut-down GPIO always cleared after lookup
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uday Khare <[email protected]>
[ Upstream commit 3238c634725afbb2a137fdda762208510828f71d ]
In tas2562_parse_dt(), the fallback lookup for the deprecated "shut-down" GPIO property is broken due to a missing pair of braces.
The code intends to reset sdz_gpio to NULL only when the lookup returns an error that is not -EPROBE_DEFER (so the driver gracefully continues without a GPIO). However, without braces the statement:
tas2562->sdz_gpio = NULL;
falls outside the IS_ERR() check and is executed unconditionally for every path through the if block, including a successful GPIO lookup.
This means any device using the deprecated 'shut-down' DT property will always have sdz_gpio == NULL after probe, making the GPIO completely non-functional.
Fix this by adding the missing braces to scope the NULL assignment inside the IS_ERR() branch, matching the pattern already used for the primary 'shutdown' GPIO lookup above.
--- sound/soc/codecs/tas2562.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
sound/soc/codecs/tas2562.c +3 -2
@@ -675,11 +675,12 @@ static int tas2562_parse_dt(struct tas2562_data *tas2562)if (tas2562->sdz_gpio ==NULL ) { tas2562->sdz_gpio =devm_gpiod_get_optional (dev,"shut-down" ,GPIOD_OUT_HIGH ); -if (IS_ERR (tas2562->sdz_gpio)) +if (IS_ERR (tas2562->sdz_gpio)) {if (PTR_ERR (tas2562->sdz_gpio) == -EPROBE_DEFER )return -EPROBE_DEFER ; - tas2562->sdz_gpio =NULL ; + tas2562->sdz_gpio =NULL ; + } }if (tas2562->model_id ==TAS2110 )
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 94/675 firmware: arm_scmi: Rate-limit queue-full warnings in IRQ context
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pushpendra Singh <[email protected]>
[ Upstream commit a4447c0693830d5ecadd6e755cb7fdc55d86aacc ]
The scmi_notify() function is called from interrupt context to queue received notification events onto a per-protocol kfifo. When the kfifo is full, it logs a warning via dev_warn() for every dropped event.
Under conditions where the platform sends a burst of SCMI notifications faster than the deferred worker can drain the queue, this results in a flood of dev_warn() calls from IRQ context. Each call acquires the console lock and may execute blocking console writes, causing the CPU to be held in interrupt context for an extended period and leading to observable system stalls.
Fix this by switching to dev_warn_ratelimited() to limit the frequency of log messages when the notification queue is full. This reduces console overhead in interrupt context and prevents CPU stalls caused by excessive logging, while still preserving diagnostic visibility.
--- drivers/firmware/arm_scmi/notify.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/firmware/arm_scmi/notify.c +3 -3
@@ -600,9 +600,9 @@ int scmi_notify(const struct scmi_handle *handle, u8 proto_id, u8 evt_id,return -EINVAL ; }if (kfifo_avail (&r_evt->proto->equeue.kfifo) <sizeof (eh) + len) { -dev_warn (handle->dev, -"queue full, dropping proto_id:%d evt_id:%d ts:%lld\n" , - proto_id, evt_id,ktime_to_ns (ts)); +dev_warn_ratelimited (handle->dev, +"queue full, dropping proto_id:%d evt_id:%d ts:%lld\n" , + proto_id, evt_id,ktime_to_ns (ts));return -ENOMEM ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 95/675 cpufreq: Make cpufreq_update_pressure() fall back to cpuinfo.max_freq
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]>
[ Upstream commit d2d5c129d07ea8eb91cd8a8633b5774116c4d171 ]
If arch_scale_freq_ref() is not defined for a given arch (like x86, for example), cpufreq_update_pressure() will always set cpufreq_pressure to zero for all CPUs in the system, which is generally problematic on systems with asymmetric capacity [1].
However, in the absence of arch_scale_freq_ref(), it is reasonable to assume that cpuinfo.max_freq is the maximum sustainable frequency for the given cpufreq policy. Moreover, there are cases in which arch_scale_freq_ref() would need to be defined to return essentially the cpuinfo.max_freq value anyway (for example, intel_pstate on hybrid platforms).
For the above reasons, update cpufreq_update_pressure() to fall back to using cpuinfo.max_freq as the reference frequency if zero is returned by arch_scale_freq_ref().
--- drivers/cpufreq/cpufreq.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/cpufreq/cpufreq.c +3 -0
@@ -2584,6 +2584,9 @@ static void cpufreq_update_pressure(struct cpufreq_policy *policy) cpu =cpumask_first (policy->related_cpus); max_freq =arch_scale_freq_ref (cpu); +if (!max_freq) + max_freq = policy->cpuinfo.max_freq; + capped_freq = policy->max;/*
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 96/675 ppp: defer channel free to an RCU grace period to fix pppol2tp RX UAF
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Norbert Szetei <[email protected]>
[ Upstream commit ec4215683e47424c9c4762fd3c60f552a3119142 ]
pppol2tp_recv() runs in the L2TP UDP-encap softirq RX path:
l2tp_udp_encap_recv() -> l2tp_recv_common() -> pppol2tp_recv()
-> ppp_input(&po->chan)
It runs under rcu_read_lock() holding only an l2tp_session reference and takes NO reference on the internal PPP channel (struct channel, chan->ppp) that ppp_input() dereferences.
The pppox socket is SOCK_RCU_FREE, so 'po' and the embedded ppp_channel are RCU-safe. But the internal struct channel is a separate allocation that ppp_release_channel() frees with a plain kfree():
close(data socket) -> pppol2tp_release() -> pppox_unbind_sock()
-> ppp_unregister_channel() -> ppp_release_channel() -> kfree(pch)
For a channel that is bound (PPPIOCGCHAN) but not attached to a ppp unit (no PPPIOCCONNECT, pch->ppp == NULL) and not bridged, teardown skips both ppp_disconnect_channel()'s synchronize_net() and ppp_unbridge_channels()'s synchronize_rcu(), so the kfree() has no grace period. rcu_read_lock() in pppol2tp_recv() does not protect against a plain kfree(), so an in-flight ppp_input() on one CPU can dereference the channel just freed by close() on another CPU.
The bug is reachable by an unprivileged user.
Defer the channel free to an RCU callback via call_rcu() so the grace period fences any in-flight ppp_input(). The disconnect and unbridge teardown paths already fence with synchronize_net()/synchronize_rcu(); call_rcu() does the same here without stalling the close() path.
--- drivers/net/ppp/ppp_generic.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
drivers/net/ppp/ppp_generic.c +15 -3
@@ -185,6 +185,7 @@ struct channel {struct list_head clist;/* link in list of channels per unit */ spinlock_t upl;/* protects `ppp' and 'bridge' */ struct channel __rcu *bridge;/* "bridged" ppp channel */ +struct rcu_head rcu;/* for RCU-deferred free of the channel */ #ifdef CONFIG_PPP_MULTILINK u8 avail;/* flag used in multilink stuff */ u8 had_frag;/* >= 1 fragments have been sent */
@@ -3570,6 +3571,18 @@ ppp_disconnect_channel(struct channel *pch)return err; } +/* Purge after the grace period: a late ppp_input() may still queue an +* skb on pch->file.rq before the last RCU reader drains. +*/ +static void ppp_release_channel_free (struct rcu_head *rcu) +{ + struct channel *pch = container_of(rcu, struct channel, rcu); + +skb_queue_purge (&pch->file.xq); +skb_queue_purge (&pch->file.rq); +kfree (pch); +} +/* * Free up the resources used by a ppp channel. */
@@ -3585,9 +3598,7 @@ static void ppp_destroy_channel(struct channel *pch)pr_err ("ppp: destroying undead channel %p !\n" , pch);return ; } -skb_queue_purge (&pch->file.xq); -skb_queue_purge (&pch->file.rq); -kfree (pch); +call_rcu (&pch->rcu, ppp_release_channel_free); } static void __exit ppp_cleanup(void)
@@ -3600,6 +3611,7 @@ static void __exit ppp_cleanup(void)device_destroy (&ppp_class,MKDEV (PPP_MAJOR ,0 ));class_unregister (&ppp_class);unregister_pernet_device (&ppp_net_ops); +rcu_barrier ();/* wait for RCU callbacks before module unload */ }/*
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 97/675 ipv4: fib: free fib_alias with kfree_rcu() on insert error path
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weiming Shi <[email protected]>
[ Upstream commit f2f152e94a67bc746afaf05a1b2702c195553112 ]
fib_table_insert() publishes new_fa into the leaf's fa_list with fib_insert_alias() before calling the fib entry notifiers. When a notifier fails, the error path removes new_fa with fib_remove_alias() (hlist_del_rcu) and frees it right away with kmem_cache_free().
fib_table_lookup() walks that list under rcu_read_lock() only, so a concurrent lookup that already reached new_fa keeps reading it after the free:
BUG: KASAN: slab-use-after-free in fib_table_lookup (net/ipv4/fib_trie.c:1601) Read of size 1 at addr ffff88810676d4eb by task exploit/297 Call Trace: fib_table_lookup (net/ipv4/fib_trie.c:1601) ip_route_output_key_hash_rcu (net/ipv4/route.c:2814) ip_route_output_key_hash (net/ipv4/route.c:2705) __ip4_datagram_connect (net/ipv4/datagram.c:49) udp_connect (net/ipv4/udp.c:2144) __sys_connect (net/socket.c:2167) __x64_sys_connect (net/socket.c:2173) do_syscall_64 entry_SYSCALL_64_after_hwframe which belongs to the cache ip_fib_alias of size 56
Triggering the error path needs CAP_NET_ADMIN and a registered fib notifier that can reject a route; a netdevsim device whose IPv4 FIB resource is exhausted is enough.
Free new_fa with alias_free_mem_rcu(), as fib_table_delete() already does for a fib_alias removed from the trie.
--- net/ipv4/fib_trie.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv4/fib_trie.c +1 -1
@@ -1385,7 +1385,7 @@ int fib_table_insert(struct net *net, struct fib_table *tb, out_remove_new_fa:fib_remove_alias (t, tp, l, new_fa); out_free_new_fa: -kmem_cache_free (fn_alias_kmem, new_fa); +alias_free_mem_rcu (new_fa); out:fib_release_info (fi); err:
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 98/675 net/iucv: take a reference on the socket found in afiucv_hs_rcv()
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 4fa349156043dc119721d067329714179f501749 ]
afiucv_hs_rcv() looks up the destination socket under iucv_sk_list.lock, drops the lock, and then passes the socket to the afiucv_hs_callback_*() handlers without holding a reference. AF_IUCV sockets are not RCU-protected and are freed synchronously by iucv_sock_kill() -> sock_put(), so a concurrent close can free the socket in the window between read_unlock() and the handler, which then dereferences freed memory (for example sk->sk_data_ready() in afiucv_hs_callback_syn()).
Take a reference with sock_hold() while the socket is still on the list and release it with sock_put() once the handler has run.
--- net/iucv/af_iucv.c | 4 ++++ 1 file changed, 4 insertions(+)
net/iucv/af_iucv.c +4 -0
@@ -2089,6 +2089,8 @@ static int afiucv_hs_rcv(struct sk_buff *skb, struct net_device *dev, } } } +if (sk) +sock_hold (sk);read_unlock (&iucv_sk_list.lock);if (!iucv) sk =NULL ;
@@ -2138,6 +2140,8 @@ static int afiucv_hs_rcv(struct sk_buff *skb, struct net_device *dev,kfree_skb (skb); } +if (sk) +sock_put (sk);return err; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 99/675 udmabuf: Ensure to perform cache synchronisation in begin_cpu_udmabuf()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Robert Mader <[email protected]>
[ Upstream commit 1d0e25c1ddf2063c499264fb2ba0fa6a3e4f8a00 ]
The message of commit 504e2b4ab97a ("dma-buf/udmabuf: skip redundant cpu sync to fix cacheline EEXIST warning") says:
Quoted 4 lines
The CPU sync at map/unmap time is also redundant for udmabuf:
begin_cpu_udmabuf()andend_cpu_udmabuf()already perform explicit cache synchronization via dma_sync_sgtable_for_cpu/device() when CPU access is requested through the dma-buf interface.
This, however, does not apply to the first time begin_cpu_udmabuf() is called on an udmabuf, in which case the implementation previously relied on get_sg_table() to perform the cache synchronisation.
Ensure to call dma_sync_sgtable_for_cpu() in that case as well.
--- drivers/dma-buf/udmabuf.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/dma-buf/udmabuf.c +5 -4
@@ -249,21 +249,22 @@ static int begin_cpu_udmabuf(struct dma_buf *buf, {struct udmabuf *ubuf = buf->priv;struct device *dev = ubuf->device->this_device; -int ret =0 ;if (!ubuf->sg) { ubuf->sg =get_sg_table (dev, buf, direction);if (IS_ERR (ubuf->sg)) { +int ret; + ret =PTR_ERR (ubuf->sg); ubuf->sg =NULL ; +return ret; }else { ubuf->sg_dir = direction; } - }else { -dma_sync_sgtable_for_cpu (dev, ubuf->sg, direction); } -return ret; +dma_sync_sgtable_for_cpu (dev, ubuf->sg, direction); +return 0 ; } static int end_cpu_udmabuf(struct dma_buf *buf,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 100/675 scsi: core: wake eh reliably when using scsi_schedule_eh
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Jeffery <[email protected]>
[ Upstream commit dccf3b1798b70f94e958b3d00b83010399e6fb05 ]
Drivers which use the scsi_schedule_eh function to run the error handler currently risk the error handler thread never waking once all commands are timed out or inactive. There is no enforced memory order between setting the host into error recovery state and counting busy commands. This can result in a race with scsi_dec_host_busy where neither CPU sees both conditions of all commands inactive and the host error state to request waking the error handler.
To fix this, run the scsi_schedule_eh's scsi_eh_wakeup from a new work item which will use rcu to ensure scsi_schedule_eh's call to scsi_host_busy will occur after the error state is globally visible and will be seen by any current scsi_dec_host_busy callers.
--- drivers/scsi/hosts.c | 2 ++ drivers/scsi/scsi_error.c | 22 +++++++++++++++++++++- drivers/scsi/scsi_priv.h | 1 + include/scsi/scsi_host.h | 3 +++ 4 files changed, 27 insertions(+), 1 deletion(-)
drivers/scsi/hosts.c +2 -0
@@ -343,6 +343,7 @@ static void scsi_host_dev_release(struct device *dev)/* Wait for functions invoked through call_rcu(&scmd->rcu, ...) */ rcu_barrier (); +cancel_work_sync (&shost->eh_work);if (shost->tmf_work_q)destroy_workqueue (shost->tmf_work_q);if (shost->ehandler)
@@ -408,6 +409,7 @@ struct Scsi_Host *scsi_host_alloc(const struct scsi_host_template *sht, int privINIT_LIST_HEAD (&shost->starved_list);init_waitqueue_head (&shost->host_wait);mutex_init (&shost->scan_mutex); +INIT_WORK (&shost->eh_work, scsi_rcu_eh_wakeup); index =ida_alloc (&host_index_ida,GFP_KERNEL );if (index <0 ) {
drivers/scsi/scsi_error.c +21 -1
@@ -73,6 +73,26 @@ void scsi_eh_wakeup(struct Scsi_Host *shost, unsigned int busy) } } +void scsi_rcu_eh_wakeup (struct work_struct *work) +{ + struct Scsi_Host *shost = container_of(work, struct Scsi_Host, eh_work); +unsigned long flags; +unsigned int busy; + +/* +* Ensure any running scsi_dec_host_busy has completed its rcu section +* so changes to host state and host_eh_scheduled are visible to all +* future calls of scsi_dec_host_busy +*/ +synchronize_rcu (); + + busy =scsi_host_busy (shost); + +spin_lock_irqsave (shost->host_lock, flags); +scsi_eh_wakeup (shost, busy); +spin_unlock_irqrestore (shost->host_lock, flags); +} +/** * scsi_schedule_eh - schedule EH for SCSI host * @shost: SCSI host to invoke error handling on.
@@ -88,7 +108,7 @@ void scsi_schedule_eh(struct Scsi_Host *shost)if (scsi_host_set_state (shost,SHOST_RECOVERY ) ==0 ||scsi_host_set_state (shost,SHOST_CANCEL_RECOVERY ) ==0 ) { shost->host_eh_scheduled++; -scsi_eh_wakeup (shost,scsi_host_busy (shost)); +queue_work (shost->tmf_work_q, &shost->eh_work); }spin_unlock_irqrestore (shost->host_lock, flags);
drivers/scsi/scsi_priv.h +1 -0
@@ -91,6 +91,7 @@ extern enum blk_eh_timer_return scsi_timeout(struct request *req);extern int scsi_error_handler (void *host);extern enum scsi_disposition scsi_decide_disposition (struct scsi_cmnd *cmd);extern void scsi_eh_wakeup (struct Scsi_Host *shost,unsigned int busy); +extern void scsi_rcu_eh_wakeup (struct work_struct *work);extern void scsi_eh_scmd_add (struct scsi_cmnd *); void scsi_eh_ready_devs(struct Scsi_Host *shost, struct list_head *work_q,
include/scsi/scsi_host.h +3 -0
@@ -714,6 +714,9 @@ struct Scsi_Host {*/ struct device *dma_dev; +/* Used for an rcu-synchronizing eh wakeup */ +struct work_struct eh_work; +/* Delay for runtime autosuspend */ int rpm_autosuspend_delay;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 101/675 ata: sata_dwc_460ex: enable SATA interrupts only after IRQ handler is registered
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rosen Penev <[email protected]>
[ Upstream commit 4bbc16a353a98023e5ddfca7c1fc0e49971cf4d0 ]
sata_dwc_enable_interrupts() is called before platform_get_irq() and ata_host_activate(), leaving the SATA controller's interrupt mask enabled without a registered handler. If a later step fails (irq request, phy init, etc.) or if the controller asserts an interrupt during probe, the irq line may fire with no handler, causing a spurious interrupt storm.
Move sata_dwc_enable_interrupts() after ata_host_activate() so that interrupts are only unmasked once the handler is registered and the core is fully initialized.
--- drivers/ata/sata_dwc_460ex.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/ata/sata_dwc_460ex.c +2 -3
@@ -1168,9 +1168,6 @@ static int sata_dwc_probe(struct platform_device *ofdev)/* Save dev for later use in dev_xxx() routines */ hsdev->dev = dev; -/* Enable SATA Interrupts */ -sata_dwc_enable_interrupts (hsdev); -/* Get SATA interrupt number */ irq =irq_of_parse_and_map (np,0 );if (!irq) {
@@ -1203,6 +1200,8 @@ static int sata_dwc_probe(struct platform_device *ofdev)if (err)dev_err (dev,"failed to activate host" ); +/* Enable SATA Interrupts */ +sata_dwc_enable_interrupts (hsdev);return 0 ; error_out:
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 102/675 ata: sata_dwc_460ex: use platform_get_irq()
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rosen Penev <[email protected]>
[ Upstream commit a4af122106f73ea510bb35a9ea1dedd980fc0db7 ]
Replace irq_of_parse_and_map() with platform_get_irq() in both sata_dwc_dma_init_old() and sata_dwc_probe(). This is the preferred way to obtain IRQs for platform devices and provides better error reporting. Remove the now-unnecessary #include <linux/of_irq.h>.
irq_of_parse_and_map() requires irq_dispose_mapping(), which is missing.
Also fix unused variable when CONFIG_SATA_DWC_OLD_DMA is disabled.
--- drivers/ata/sata_dwc_460ex.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-)
drivers/ata/sata_dwc_460ex.c +7 -14
@@ -19,7 +19,6 @@#include <linux/device.h> #include <linux/dmaengine.h> #include <linux/of.h> -#include <linux/of_irq.h> #include <linux/platform_device.h> #include <linux/phy/phy.h> #include <linux/libata.h>
@@ -226,7 +225,6 @@ static int sata_dwc_dma_init_old(struct platform_device *pdev, struct sata_dwc_device *hsdev) {struct device *dev = &pdev->dev; -struct device_node *np = dev->of_node; hsdev->dma =devm_kzalloc (dev,sizeof (*hsdev->dma),GFP_KERNEL );if (!hsdev->dma)
@@ -236,11 +234,9 @@ static int sata_dwc_dma_init_old(struct platform_device *pdev, hsdev->dma->id = pdev->id;/* Get SATA DMA interrupt number */ - hsdev->dma->irq =irq_of_parse_and_map (np,1 ); -if (!hsdev->dma->irq) { -dev_err (dev,"no SATA DMA irq\n" ); -return -ENODEV ; - } + hsdev->dma->irq =platform_get_irq (pdev,1 ); +if (hsdev->dma->irq <0 ) +return hsdev->dma->irq;/* Get physical SATA DMA register base address */ hsdev->dma->regs =devm_platform_ioremap_resource (pdev,1 );
@@ -1125,7 +1121,6 @@ static const struct ata_port_info sata_dwc_port_info[] = {static int sata_dwc_probe (struct platform_device *ofdev) {struct device *dev = &ofdev->dev; -struct device_node *np = dev->of_node;struct sata_dwc_device *hsdev;u32 idr, versionr;char *ver = (char *)&versionr;
@@ -1169,14 +1164,12 @@ static int sata_dwc_probe(struct platform_device *ofdev) hsdev->dev = dev;/* Get SATA interrupt number */ - irq =irq_of_parse_and_map (np,0 ); -if (!irq) { -dev_err (dev,"no SATA DMA irq\n" ); -return -ENODEV ; - } + irq =platform_get_irq (ofdev,0 ); +if (irq <0 ) +return irq;#ifdef CONFIG_SATA_DWC_OLD_DMA -if (!of_property_present (np,"dmas" )) { +if (!of_property_present (dev->of_node,"dmas" )) { err =sata_dwc_dma_init_old (ofdev, hsdev);if (err)return err;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 103/675 ata: sata_dwc_460ex: fix clear_interrupt_bit() clearing all pending interrupts
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rosen Penev <[email protected]>
[ Upstream commit 66c4e310ad71f41e41736d33dd8a1fb5eaaec7f3 ]
clear_interrupt_bit() ignores the bit argument and performs a read-write-back of the entire INTPR register. If INTPR uses standard Write-1-to-Clear semantics, this clears every pending interrupt bit, not just the intended one. Coalesced interrupts (e.g. DMAT + NEWFP) would be cleared together, silently losing the second event.
Write only the specific bit to clear so that other pending interrupts are preserved.
--- drivers/ata/sata_dwc_460ex.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/ata/sata_dwc_460ex.c +1 -2
@@ -394,8 +394,7 @@ static void clear_serror(struct ata_port *ap)static void clear_interrupt_bit (struct sata_dwc_device *hsdev,u32 bit) { -sata_dwc_writel (&hsdev->sata_dwc_regs->intpr, -sata_dwc_readl (&hsdev->sata_dwc_regs->intpr)); +sata_dwc_writel (&hsdev->sata_dwc_regs->intpr, bit); }static u32 qcmd_tag_to_mask (u8 tag)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 104/675 ata: sata_dwc_460ex: fix infinite loop in NCQ tag completion bit-scanning
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rosen Penev <[email protected]>
[ Upstream commit c2130f6553f4a5cbdc259de069600117a995f197 ]
The hand-rolled bit-scanning loop in the NCQ completion path has an infinite loop bug. When tag_mask has only high bits set (e.g. 0x80000000), the inner while loop left-shifts tag_mask until it overflows to 0. At that point !(0 & 1) is always true and 0 <<= 1 stays 0, causing an infinite loop in hardirq context with a spinlock held.
Replace the open-coded bit-scanning with __ffs() which correctly finds the least significant set bit and is bounded by the width of the argument.
--- drivers/ata/sata_dwc_460ex.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-)
drivers/ata/sata_dwc_460ex.c +2 -7
@@ -607,14 +607,9 @@ static irqreturn_t sata_dwc_isr(int irq, void *dev_instance) status = ap->ops->sff_check_status (ap);dev_dbg (ap->dev,"%s ATA status register=0x%x\n" , __func__, status); - tag =0 ;while (tag_mask) { -while (!(tag_mask &0x00000001 )) { - tag++; - tag_mask <<=1 ; - } - - tag_mask &= (~0x00000001 ); + tag =__ffs (tag_mask); + tag_mask &= ~(1U << tag); qc =ata_qc_from_tag (ap, tag);if (unlikely (!qc)) {dev_err (ap->dev,"failed to get qc" );
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 105/675 accel/ivpu: Fix wrong register read in LNL failure diagnostics
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karol Wachowski <[email protected]>
[ Upstream commit e4159045c2704dfe146f0ccb0445d9d074cd6882 ]
diagnose_failure_lnl() read VPU_HW_BTRS_MTL_INTERRUPT_STAT instead of VPU_HW_BTRS_LNL_INTERRUPT_STAT, which on LNL and newer parts is a different register with a different bit layout, so failure diagnostics decoded the wrong register and reported a bogus error cause. Read the LNL interrupt status register instead.
--- drivers/accel/ivpu/ivpu_hw_btrs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/accel/ivpu/ivpu_hw_btrs.c +1 -1
@@ -845,7 +845,7 @@ static void diagnose_failure_mtl(struct ivpu_device *vdev)static void diagnose_failure_lnl (struct ivpu_device *vdev) { -u32 reg =REGB_RD32 (VPU_HW_BTRS_MTL_INTERRUPT_STAT ) &BTRS_LNL_IRQ_MASK ; +u32 reg =REGB_RD32 (VPU_HW_BTRS_LNL_INTERRUPT_STAT ) &BTRS_LNL_IRQ_MASK ;if (REG_TEST_FLD (VPU_HW_BTRS_LNL_INTERRUPT_STAT ,ATS_ERR , reg)) { ivpu_err(vdev, "ATS_ERR_LOG1 0x%08x ATS_ERR_LOG2 0x%08x\n",
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 106/675 ALSA: usb-audio: Skip DSD quirk for Musical Fidelity M6s DAC
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit 93b47e66cc6d6c6382d44b44f5e7f6fc3a7b38c3 ]
Salvador reported that the recent fix for applying the DSD quirk to Musical Fidelity devices broke for his M6s DAC model (2772:0502).
Although this is basically a firmware bug, the model in question is fairly old, and no further firmware update can be expected, so it'd be better to address in the driver side.
As an ad hoc workaround, skip the DSD quirk for this device by adding an empty quirk entry of 2772:0502; this essentially skips the later DSD quirk entry by the match with the vendor 2772.
--- sound/usb/quirks.c | 2 ++ 1 file changed, 2 insertions(+)
sound/usb/quirks.c +2 -0
@@ -2380,6 +2380,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { QUIRK_FLAG_DSD_RAW),DEVICE_FLG (0x2708 ,0x0002 ,/* Audient iD14 */ QUIRK_FLAG_IGNORE_CTL_ERROR ), +DEVICE_FLG (0x2772 ,0x0502 ,/* Musical Fidelity M6s DAC */ +0 ),/* for avoiding QUIRK_FLAG_DSD_RAW with vendor match */ DEVICE_FLG (0x2912 ,0x30c8 ,/* Audioengine D1 */ QUIRK_FLAG_GET_SAMPLE_RATE ), DEVICE_FLG(0x2a70, 0x1881, /* OnePlus Technology (Shenzhen) Co., Ltd. BE02T */
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 107/675 Bluetooth: qca: fix NVM tag length underflow in TLV parser
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiang Mei <[email protected]>
[ Upstream commit c90164ca0f7036942ba088eb7ea8d3f6c2352020 ]
In the TLV_TYPE_NVM branch of qca_tlv_check_data() the tag loop bound is "while (idx < length - sizeof(struct tlv_type_nvm))". "length" is a signed int from the firmware TLV header and sizeof(struct tlv_type_nvm) is a size_t (12), so "length" is converted to size_t and any firmware-supplied "length" < 12 makes the subtraction wrap to a huge value. The loop body then reads a 12-byte struct tlv_type_nvm past the end of the short vmalloc'd firmware buffer (and the EDL_TAG_ID_* handlers can write past it).
Rewrite the bound as "idx + sizeof(struct tlv_type_nvm) <= length"; both operands are non-negative, so it no longer underflows and a "length" too small for one record correctly skips the loop.
BUG: KASAN: vmalloc-out-of-bounds in qca_download_firmware.isra.0 (drivers/bluetooth/btqca.c:421) Read of size 2 at addr ffffc900000e5004 by task kworker/u9:0/52 Workqueue: hci0 hci_power_on Call Trace: ... kasan_report (mm/kasan/report.c:595) qca_download_firmware.isra.0 (drivers/bluetooth/btqca.c:421 drivers/bluetooth/btqca.c:617) qca_uart_setup (drivers/bluetooth/btqca.c:948) qca_setup (drivers/bluetooth/hci_qca.c:2029) hci_uart_setup (drivers/bluetooth/hci_ldisc.c:438) hci_dev_open_sync (net/bluetooth/hci_sync.c:5227) hci_power_on (net/bluetooth/hci_core.c:920) process_one_work (kernel/workqueue.c:3322) worker_thread (kernel/workqueue.c:3486) kthread (kernel/kthread.c:436) ret_from_fork (arch/x86/kernel/process.c:158) ret_from_fork_asm (arch/x86/entry/entry_64.S:245)
--- drivers/bluetooth/btqca.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/bluetooth/btqca.c +1 -1
@@ -413,7 +413,7 @@ static int qca_tlv_check_data(struct hci_dev *hdev, idx =0 ; data = tlv->data; -while (idx < length -sizeof (struct tlv_type_nvm )) { +while (idx +sizeof (struct tlv_type_nvm ) <= length) { tlv_nvm = (struct tlv_type_nvm *)(data + idx); tag_id =le16_to_cpu (tlv_nvm->tag_id);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 108/675 Bluetooth: MGMT: revalidate LOAD_CONN_PARAM queued update
In reply to Greg Kroah-Hartman6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cen Zhang <[email protected]>
[ Upstream commit 2bf282f8f715f5d05d6f4c49ffb3bd241c5e667e ]
MGMT_OP_LOAD_CONN_PARAM queues conn_update_sync() when a single parameter update changes an existing LE central connection. The queued work currently stores a borrowed hci_conn_params entry from hdev->le_conn_params. A later LOAD_CONN_PARAM request can clear disabled parameters and free that entry before hci_cmd_sync_work() runs the queued callback.
Do not keep the borrowed hci_conn_params pointer in queued work. Queue the hci_conn instead and hold a reference until the queued callback completes. When the work runs, revalidate that the connection is still present, look up the current hci_conn_params entry, and cancel the update if userspace removed that entry while the work was pending.
Copy the interval values from the current params entry under hdev->lock, then drop the lock and keep using hci_le_conn_update_sync() to issue the update.
Validation reproduced this kernel report:
BUG: KASAN: slab-use-after-free in conn_update_sync+0x2a/0xf0 [bluetooth] Read of size 1 at addr ffff88810c697126 by task kworker/u17:0/377 Workqueue: hci0 hci_cmd_sync_work [bluetooth] Call Trace: <TASK> dump_stack_lvl+0x66/0xa0 print_report+0xce/0x5f0 kasan_report+0xe0/0x110 conn_update_sync+0x2a/0xf0 [bluetooth] hci_cmd_sync_work+0x187/0x210 [bluetooth] process_one_work+0x4fd/0xbc0 worker_thread+0x2d8/0x570 kthread+0x1ad/0x1f0 ret_from_fork+0x3c9/0x540 ret_from_fork_asm+0x1a/0x30 Allocated by task 466: hci_conn_params_add+0xa6/0x240 [bluetooth] load_conn_param+0x4e1/0x850 [bluetooth] hci_sock_sendmsg+0x96b/0xf80 [bluetooth] Freed by task 474: kfree+0x313/0x590 hci_conn_params_clear_disabled+0x9b/0xc0 [bluetooth] load_conn_param+0x4bf/0x850 [bluetooth] hci_sock_sendmsg+0x96b/0xf80 [bluetooth]
--- net/bluetooth/mgmt.c | 44 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 9 deletions(-)
net/bluetooth/mgmt.c +35 -9
@@ -7924,14 +7924,36 @@ static int remove_device(struct sock *sk, struct hci_dev *hdev,static int conn_update_sync (struct hci_dev *hdev,void *data) { -struct hci_conn_params *params = data; -struct hci_conn *conn; +struct hci_conn *conn = data; +struct hci_conn_params *params; +struct hci_conn_params local = {}; - conn =hci_conn_hash_lookup_le (hdev, ¶ms->addr, params->addr_type); -if (!conn) -return -ECANCELED ; +hci_dev_lock (hdev); + +if (!hci_conn_valid (hdev, conn) || conn->role !=HCI_ROLE_MASTER ) + goto cancel; + + params =hci_conn_params_lookup (hdev, &conn->dst, conn->dst_type); +if (!params) + goto cancel; + + local.conn_min_interval = params->conn_min_interval; + local.conn_max_interval = params->conn_max_interval; + local.conn_latency = params->conn_latency; + local.supervision_timeout = params->supervision_timeout; -return hci_le_conn_update_sync (hdev, conn, params); +hci_dev_unlock (hdev); + +return hci_le_conn_update_sync (hdev, conn, &local); + +cancel: +hci_dev_unlock (hdev); +return -ECANCELED ; +} + +static void conn_update_sync_destroy (struct hci_dev *hdev,void *data,int err) +{ +hci_conn_put (data); } static int load_conn_param(struct sock *sk, struct hci_dev *hdev, void *data,
@@ -8041,9 +8063,13 @@ static int load_conn_param(struct sock *sk, struct hci_dev *hdev, void *data, (conn->le_conn_min_interval != min || conn->le_conn_max_interval != max || conn->le_conn_latency != latency || - conn->le_supv_timeout != timeout)) -hci_cmd_sync_queue (hdev, conn_update_sync, - hci_param,NULL ); + conn->le_supv_timeout != timeout)) { +hci_conn_get (conn); +if (hci_cmd_sync_queue (hdev, conn_update_sync, + conn, + conn_update_sync_destroy) <0 ) +hci_conn_put (conn); + } } }
Signature · 1 line
2.53.0