5.10.265-rc1 review
Greg Kroah-Hartman
maintainercover 5.10.265-rc1 review
This is the start of the stable review cycle for the 5.10.265 release. There are 389 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 Wed, 19 Aug 2026 13:23:44 +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/v5.x/stable-review/patch-5.10.265-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-5.10.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 5.10.265-rc1
Luiz Angelo Daros de Luca <[email protected]>
hwmon: (adt7470) Fix fans stuck in manual mode on I2C errors
Javier Carrasco <[email protected]>
hwmon: (adt7470) Add missing dependency on REGMAP_I2C
Jonas Gorski <[email protected]>
prestera: fix fallback to previous version on same major version
Bryam Vargas <[email protected]>
thunderbolt: Bound the DROM dual link port number before indexing sw->ports
Qing Ming <[email protected]>
sctp: clear new_transport when removing a peer
Yuxiang Yang <[email protected]>
sctp: fix use-after-free of cached ASCONF chunk
Baul Lee <[email protected]>
sctp: keep chunk->transport in step with the list it is queued on
Xu Rao <[email protected]>
scsi: scsi_debug: Negate wrapped memcmp() result
Chengfeng Ye <[email protected]>
bpf, sockmap: Fix sk_redir use-after-free in send verdict
Zhiling Zou <[email protected]>
ip6_tunnel: clear skb2->cb[] in ip6ip6_err()
Yuejie Shi <[email protected]>
ipv6: fix Route Information option length validation
Tengda Wu <[email protected]>
ring-buffer: Use current_context for safe per-CPU buffer swap
Jun Yang <[email protected]>
tipc: read le->link under the node lock in tipc_node_link_down()
Jun Yang <[email protected]>
vhost: reset the vring metadata cache on vring reconfiguration
Weiming Shi <[email protected]>
vsock/virtio: avoid refilling the RX queue after teardown
Baul Lee <[email protected]>
vxlan: do not arm the ageing timer on a device that is down
Yangyu Chen <[email protected]>
net: atlantic: free RX pages of consumed but not refilled buffers
Zhiling Zou <[email protected]>
netfilter: bridge: release template ct on non-IP path
Kyle Zeng <[email protected]>
ipv6: prevent in6_dev_get() from resurrecting inet6_dev
Rik van Riel <[email protected]>
fbdev: bitblit: bound-check glyph index in bit_cursor()
Eddie Lin <[email protected]>
misc: fastrpc: fix memory leak in fastrpc_channel_ctx_free
Anandu Krishnan E <[email protected]>
misc: fastrpc: fix channel ctx ref leak when session alloc fails
Mariano Baragiola <[email protected]>
staging: rtl8723bs: validate monitor transmit frame lengths
Muhammad Bilal <[email protected]>
staging: rtl8723bs: fix OOB read in rtw_get_wpa_ie()
Cunhao Lu <[email protected]>
serial: 8250_dma: Clear stale RX state on shutdown
Chengfeng Ye <[email protected]>
ipv4: fix use-after-free in fib_nhc_update_mtu()
Eric Biggers <[email protected]>
fscrypt: Replace mk_users keyring with simple list
Aaron Tomlin <[email protected]>
mips: sched: Fix CPUMASK_OFFSTACK memory corruption
Zhu Yanjun <[email protected]>
RDMA/rxe: Fix a use-after-free problem in rxe_mmap
Keno Fischer <[email protected]>
futex: Prevent robust futex exit race some more
Lincoln Wallace <[email protected]>
ima: fix out-of-bounds read in xattr_verify()
Luiz Augusto von Dentz <[email protected]>
Bluetooth: 6lowpan: Fix using chan->conn as indication to no remote netdev
Marco Elver <[email protected]>
Bluetooth: L2CAP: Fix UAF in channel timeout by holding conn ref
Dmitry Torokhov <[email protected]>
Input: evdev - fix information leak in evdev_pass_values()
Joshua Rogers <[email protected]>
vt: stabilize tty reference in kbd_keycode with tty_port_tty_get
Joshua Rogers <[email protected]>
vt: add permission check for KDSKBMETA ioctl
Chengfeng Ye <[email protected]>
netfilter: ebt_nflog: pin the NFLOG backend
Qihang Tang <[email protected]>
net: remove CAP_SYS_RAWIO zero-padding in dev_validate_header
Zhiling Zou <[email protected]>
net: openvswitch: reallocate update replies for mismatched IDs
Doruk Tan Ozturk <[email protected]>
net/packet: reset the MAC header on the packet-socket transmit path
Kyle Zeng <[email protected]>
ipvs: clear IPv4 options after rebasing tunnel ICMP errors
Julian Anastasov <[email protected]>
ipvs: properly update the overload flag on dest edit
Julian Anastasov <[email protected]>
ipvs: add totalconns for dest
Sonali Pradhan <[email protected]>
usb: gadget: f_ncm: Use unsigned int for ndp_index
Aleksandr Nogikh <[email protected]>
usb: atm: cxacru: properly kill rcv_urb on error in cxacru_cm()
Baul Lee <[email protected]>
ALSA: usb-audio: fix OOB write on Type II inbound URBs
Dmitry Torokhov <[email protected]>
Input: evdev - sanitize event type index when fetching event masks
Takashi Iwai <[email protected]>
ALSA: usb-audio: Evaluate packsize caps at the right place
Larisa Grigore <[email protected]>
spi: spi-fsl-dspi: Avoid setup_accel logic for DMA transfers
Maximilian Immanuel Brandtner <[email protected]>
tls: don't abort the connection on signal-interrupted sends
Xin Long <[email protected]>
sctp: extract sctp_v4_err_handle function from sctp_v4_err
Xin Long <[email protected]>
sctp: extract sctp_v6_err_handle function from sctp_v6_err
Xin Long <[email protected]>
sctp: remove the unessessary hold for idev in sctp_v6_err
Xin Long <[email protected]>
sctp: clear control chunk transport if it is being removed
Hongyan Xu <[email protected]>
ata: pata_sl82c105: fix bridge revision use-after-free
Łukasz Patron <[email protected]>
net: qrtr: ns: Raise lookup limit to 128
Eric Dumazet <[email protected]>
net: remove WARN_ON_ONCE() from sk_mc_loop()
Pengpeng Hou <[email protected]>
net: prestera: validate firmware header length
Vadym Kochan <[email protected]>
net: marvell: prestera: try to load previous fw version
Henry Martin <[email protected]>
net/ncsi: fix heap OOB read in NCSI_CMD_SEND_CMD payload length
Qing Luo <[email protected]>
sctp: fix addip_serial increment on ASCONF_ACK allocation failure
Michael Chan <[email protected]>
bnxt_en: Disable EOP for TPA on all chips to prevent data corruption
Michael Chan <[email protected]>
bnxt_en: Do not set EOP on RX AGG BDs on 5760X chips
Cen Zhang (Microsoft) <[email protected]>
net/openvswitch: check Ethernet header length in key_extract()
Randy Dunlap <[email protected]>
net: openvswitch: fix kernel-doc warnings in flow.c
Andrew Lunn <[email protected]>
net: openvswitch: Fix kerneldoc warnings
Toke Høiland-Jørgensen <[email protected]>
net/sched: sch_cake: drop WARN_ON(1) for malformed packets in ACK filter
Xuanqiang Luo <[email protected]>
udp: fix potential use-after-free in tunnel segmentation
Babanpreet Singh <[email protected]>
counter: microchip-tcb-capture: Fix DT channel validation
Michael Guralnik <[email protected]>
net/mlx5: fw_tracer, return NULL on create error
Leon Romanovsky <[email protected]>
net/mlx5: Remove second FW tracer check
Jiawen Liu <[email protected]>
net: hisilicon: hix5hd2_gmac: remove redundant NAPI delete
Jamal Hadi Salim <[email protected]>
net/sched: cls_route: fix fastmap use-after-free on filter
Mahanta Jambigi <[email protected]>
net/smc: fix qentry overwrite for CONFIRM_LINK and ADD_LINK_CONT in smc_llc_event_handler()
Yiyang Chen <[email protected]>
bpf: Preserve pointer state for commuted arithmetic
Xiang Mei (Microsoft) <[email protected]>
bonding: alb: re-check primary_is_promisc under RTNL in bond_alb_monitor
Yuho Choi <[email protected]>
ARM: npcm: Fix OF node refcount leaks in SMP setup
Anna Schumaker <[email protected]>
NFS: Pin the 'struct nfs_server' during a FREE_STATEID call
Scott Mayhew <[email protected]>
nfs4: take a reference on the nfs_client when running FREE_STATEID
Harald Freudenberger <[email protected]>
s390/zcrypt: Fix missing mem scrub at clear key import in cca_clr2cipherkey()
Al Viro <[email protected]>
mount: honour SB_NOUSER in the new mount API
Junjie Cao <[email protected]>
gpio: pch: use raw_spinlock_t for the register lock
Tze Yee Ng <[email protected]>
firmware: stratix10-svc: fix memory leaks and list corruption bugs
Ilya Maximets <[email protected]>
net: openvswitch: fix skb leak on flow key update failure during recirculation
Hyunwoo Kim <[email protected]>
Bluetooth: SCO: Fix use-after-free in sco_recv_frame() due to missing sock_hold
Luiz Augusto von Dentz <[email protected]>
Bluetooth: SCO: Fix UAF on sco_sock_timeout
Kiryl Shutsemau (Meta) <[email protected]>
mm/huge_memory: unlock i_mmap_rwsem before releasing after-split folios
HyeongJun An <[email protected]>
HID: logitech-dj: Fix maxfield check in DJ short report validation
Zack Rusin <[email protected]>
drm/vmwgfx: bound DMA command body size against suffix pointer
Zack Rusin <[email protected]>
drm/vmwgfx: validate DRAW_PRIMITIVES header size before division
Harkirat Gill <[email protected]>
drm/amdgpu: cap GTT size to physical RAM on APUs
Maíra Canal <[email protected]>
drm/vc4: Zero the tile state data array before each BIN job
Pengpeng Hou <[email protected]>
can: peak_usb: validate uCAN receive record lengths
Maoyi Xie <[email protected]>
can: peak_usb: peak_usb_start(): fix double free of transfer buffer on URB submit error
James Gao <[email protected]>
can: peak_usb: add bounds check for USB channel index
Pengpeng Hou <[email protected]>
can: softing: fw_parse(): validate firmware record spans
Pengpeng Hou <[email protected]>
can: kvaser_usb_leaf: kvaser_usb_leaf_wait_cmd(): validate received command extents
Abdun Nihaal <[email protected]>
can: kvaser_usb: kvaser_usb_hydra_get_busparams(): fix memory leak in kvaser_usb_hydra_get_busparams()
Oleksij Rempel <[email protected]>
can: j1939: transport: j1939_session_fresh_new(): initialize receive buffer
H. Nikolaus Schaller <[email protected]>
i2c: jz4780: Cache host clock rate at probe to prevent CCF prepare_lock deadlock
Ilya Maximets <[email protected]>
net: openvswitch: fix skb leak on flow key update failure during ct
Ilya Maximets <[email protected]>
net: openvswitch: fix potential UAF on meter attach failure
Nava kishore Manne <[email protected]>
phy: zynqmp: keep SERDES scrambler and 8b/10b enabled for USB
Nava kishore Manne <[email protected]>
phy: zynqmp: use read-modify-write for SERDES scrambler bypass
Nava kishore Manne <[email protected]>
phy: zynqmp: fix L0_TM_DISABLE_SCRAMBLE_ENCODER mask
Holger Dengler <[email protected]>
s390/zcrypt: Validate length for CCA ECC private key requests
Holger Dengler <[email protected]>
s390/zcrypt: Validate length for CCA AES cipher key requests
Jan Höppner <[email protected]>
s390/dasd: Fix potential NULL pointer dereference
Abdun Nihaal <[email protected]>
cpufreq: powernow-k8: Fix possible memory leak in powernowk8_cpu_init()
Myeonghun Pak <[email protected]>
i2c: amd-mp2: Unregister callback on adapter add failure
Asim Viladi Oglu Manizada <[email protected]>
sctp: prevent peer transport count overflow
Yuxiang Yang <[email protected]>
sctp: reject stale cookies with mismatched verification tags
Chris Gellermann <[email protected]>
selftests/clone3: fix wild pointer access of getline due to missing init
Masami Hiramatsu (Google) <[email protected]>
tracing/filters: Fix false positive match in regex_match_full()
Masami Hiramatsu (Google) <[email protected]>
tracing: Check return value of __register_event() in trace_module_add_events()
Eric Dumazet <[email protected]>
vxlan: use pskb_network_may_pull() in route_shortcircuit()
Eric Dumazet <[email protected]>
vxlan: use neigh_ha_snapshot() in route_shortcircuit()
Eric Dumazet <[email protected]>
vxlan: unclone skb head before modifying eth header in route_shortcircuit()
Eric Dumazet <[email protected]>
vxlan: re-fetch eth header after route_shortcircuit()
Michael Bommarito <[email protected]>
um: vector: fix use-after-free in vector_mmsg_rx()
Thorsten Blum <[email protected]>
powerpc/ps3: Fix map failure path in dma_ioc0_map_pages()
Zhiling Zou <[email protected]>
net: ipv6: clear suppressed fib6 rule result
Zhiling Zou <[email protected]>
net: bridge: stop fast-leave after deleting a port group
Link Lin <[email protected]>
mm/page_reporting: use system_freezable_wq to fix UAF during suspend
Christian Brauner <[email protected]>
binfmt_misc: reject a flag character as the field delimiter
Zhao Li <[email protected]>
wifi: mwifiex: use the subframe length when parsing A-MSDU TDLS frames
Zihan Xi <[email protected]>
tipc: avoid use-after-free in poll trace queue dumps
David Lee <[email protected]>
netfilter: ipset: do not update comments from kernel-side hash adds
Xuanqiang Luo <[email protected]>
net/smc: fix socket use-after-free during link group termination
Zhiling Zou <[email protected]>
ipvs: do not propagate one-packet flag to synced conns
Matt Vollrath <[email protected]>
igbvf: Fix leak in TX DMA error cleanup
Dawei Feng <[email protected]>
e1000: fix memory leak in e1000_probe()
Md Sadre Alam <[email protected]>
dmaengine: qcom: bam_dma: Fix command element mask field for BAM v1.6.0+
Sonali Pradhan <[email protected]>
ALSA: usb-audio: Clamp frame size in implicit-feedback mode
Sonali Pradhan <[email protected]>
ALSA: usb-audio: Fix DMA buffer out-of-bounds write when fill_max is set
Baul Lee <[email protected]>
ALSA: usb-audio: fix OOB write in snd_usbmidi_akai_output()
Haidar Lee <[email protected]>
ASoC: tas2562: fix broken entries in the volume lookup table
Haidar Lee <[email protected]>
ASoC: tas2562: fix DVC coefficient write order
Norbert Szetei <[email protected]>
ALSA: pcm: wake linked drain waiters on unlink
Xu Rao <[email protected]>
ALSA: lx6464es: fix period byte count for 16-bit streams
Takashi Iwai <[email protected]>
ALSA: 6fire: Fix UAF at error handling during probe
Xuanqiang Luo <[email protected]>
bpf: lwt: Fix dst reference leak on reroute failure
Sangho Lee <[email protected]>
Bluetooth: HIDP: validate numbered report payloads
Luxiao Xu <[email protected]>
audit: fix potential use-after-free in audit_del_rule()
Zhan Xusheng <[email protected]>
audit: fix potential integer overflow in audit_log_n_string()
Charles Vosburgh <[email protected]>
sctp: validate Adaptation Indication parameter length
Xiangfeng Cai <[email protected]>
mm/hugetlb: fix list corruption in allocate_file_region_entries()
Zi Yan <[email protected]>
mm/percpu-km: fix bitmap overflow and accounting in pcpu_create_chunk()
Benjamin Boortz <[email protected]>
pinctrl: bm1880: add missing select GENERIC_PINCONF
Karl Mehltretter <[email protected]>
pinctrl: devicetree: don't free uninitialized dev_name on error path
Cen Zhang (Microsoft) <[email protected]>
rhashtable: clear stale iter->p on table restart
Pengfei Zhang <[email protected]>
ipv6: fib6: fix NULL deref in fib6_walk_continue() on multi-batch dump
Denis V. Lunev <[email protected]>
qede: sync udp_tunnel ports outside qede_lock in the recovery path
Suman Ghosh <[email protected]>
octeontx2-pf: Set correct sequence for carrier off and tx queue stop
Masami Hiramatsu (Google) <[email protected]>
tracing/mmiotrace: Reset dropped_count in mmio_reset_data()
Minhong He <[email protected]>
can: isotp: check register_netdevice_notifier() error in module init
Chenguang Zhao <[email protected]>
net: sxgbe: check descriptor ring allocation failures
Chenguang Zhao <[email protected]>
net: sxgbe: free TX rings on RX allocation failure
Benjamin Block <[email protected]>
scsi: zfcp: Fix memory leak during adapter release by destroying gid_pn_req
Christian Marangi <[email protected]>
net: phylink: put link_gpio if phylink_create fails
Jiale Yao <[email protected]>
Bluetooth: L2CAP: fix UAF in l2cap_le_connect_rsp
Guenter Roeck <[email protected]>
hwmon: (pmbus) Fix return value from pmbus_update_byte_data()
Thorsten Blum <[email protected]>
powerpc/boot: Fix treeboot-akebono CPU node lookup check
Thorsten Blum <[email protected]>
powerpc/boot: Fix treeboot-currituck CPU node lookup check
Thorsten Blum <[email protected]>
powerpc/boot: Fix simpleboot CPU node lookup check
Luiz Angelo Daros de Luca <[email protected]>
hwmon: (adt7470) Fix PWM auto temp state array and bounds check
Chris Packham <[email protected]>
hwmon: (adt7470) Convert to use regmap
Chris Packham <[email protected]>
hwmon: (adt7470) Fix some style issues
Chris Packham <[email protected]>
hwmon: (adt7470) Create functions for updating readings and limits
Luiz Angelo Daros de Luca <[email protected]>
hwmon: (adt7470) Fix swapped PWM3 and PWM4 auto mode masks
Luiz Angelo Daros de Luca <[email protected]>
hwmon: (adt7470) Fix busy-loop and I2C flooding in update thread
Chenguang Zhao <[email protected]>
forcedeth: fix UAF of txrx_stats in nv_remove
Guenter Roeck <[email protected]>
hwmon: (nct6775-core) Prevent access to unsupported weight registers
Dawei Feng <[email protected]>
smb: client: fix buffer leaks in SMB1 read and write
HyeongJun An <[email protected]>
scsi: libiscsi_tcp: Bound SCSI Response data segment to the connection buffer
HyeongJun An <[email protected]>
scsi: libiscsi: Fix stale-data leak into the SCSI sense buffer
Xiang Mei <[email protected]>
rds: tcp: hold the RCU lock across ipv6_chk_addr() in rds_tcp_laddr_check()
Ilia Gavrilov <[email protected]>
rds: Fix inet6_addr_lst NULL dereference when IPv6 is disabled
Xiang Mei (Microsoft) <[email protected]>
netfilter: nft_payload: fix mask build for partial field offload
Pablo Neira Ayuso <[email protected]>
netfilter: xt_hashlimit: validate hashtable supports XT_HASHLIMIT_RATE_MATCH
Michael Bommarito <[email protected]>
assoc_array: trim the final shortcut word using the current chunk end
Michael Bommarito <[email protected]>
keys: make keyring key-chunk byte order agree with keyring_diff_objects()
Michael Bommarito <[email protected]>
keys: fix out-of-bounds read in keyring_get_key_chunk()
Xiang Mei <[email protected]>
netfilter: nf_conntrack_sip: widen NAT rewrite delta to s32 in sip_help_tcp()
Uday Khare <[email protected]>
ASoC: max98090: fix missing IS_ERR() before PTR_ERR() on mclk lookup
Uday Khare <[email protected]>
ASoC: max98095: fix missing IS_ERR() before PTR_ERR() on mclk lookup
Hongling Zeng <[email protected]>
dmaengine: sun6i-dma: Fix reclaim descriptors while terminating DMA
Sabrina Dubroca <[email protected]>
tls: separate no-async decryption request handling from async
Youssef Samir <[email protected]>
net: qrtr: ns: Raise node count limit to 512
Manivannan Sadhasivam <[email protected]>
net: qrtr: ns: Limit the maximum server registration per node
Benjamin Tissoires <[email protected]>
HID: logitech-dj: fix wrong detection of bad DJ_SHORT output report
Lee Jones <[email protected]>
HID: logitech-dj: Prevent REPORT_ID_DJ_SHORT related user initiated OOB write
Lee Jones <[email protected]>
HID: logitech-dj: Standardise hid_report_enum variable nomenclature
Ricardo Ribalda <[email protected]>
media: uvcvideo: Fix sequence number when no EOF
Isaac Scott <[email protected]>
media: uvcvideo: Implement dual stream quirk to fix loss of usb packets
Yehyeong Lee <[email protected]>
net: mpls: initialize rtm_tos in mpls_getroute()
Nikolay Aleksandrov <[email protected]>
net: bridge: vlan: fix global vlan option range dumping
Eric Dumazet <[email protected]>
raw: fix a typo in raw_icmp_error()
Eric Dumazet <[email protected]>
raw: remove unused variables from raw6_icmp_error()
Kyle Zeng <[email protected]>
openvswitch: fix GSO userspace truncation underflow
Devin Wittmayer <[email protected]>
wifi: mt76: mt7615: drop TXRX_NOTIFY on non-mmio buses
Weiming Shi <[email protected]>
tipc: fix use-after-free of the discoverer in tipc_disc_rcv()
Ce Sun <[email protected]>
drm/amdgpu: invoke pm_genpd_remove() before freeing genpd
Boyuan Zhang <[email protected]>
drm/amdgpu: fix division by zero with invalid uvd dimensions
Alex Deucher <[email protected]>
drm/amdgpu/gfx9: replace BUG_ON() with WARN_ON()
Alex Deucher <[email protected]>
drm/amdgpu/gfx8: drop unecessary BUG_ON()
Alex Deucher <[email protected]>
drm/amdgpu/gfx10: replace BUG_ON() with WARN_ON()
Daehyeon Ko <[email protected]>
tipc: clear sock->sk on the failed-insert path in tipc_sk_create()
Asim Viladi Oglu Manizada <[email protected]>
pppoe: reload header pointer after dev_hard_header()
Doruk Tan Ozturk <[email protected]>
mac802154: llsec: reject frames shorter than the authentication tag
Michael Bommarito <[email protected]>
ila: reload IPv6 header after pskb_may_pull in checksum adjust
Raphael Zimmer <[email protected]>
rbd: Reset positive result codes to zero in object map update path
Jann Horn <[email protected]>
proc: Fix broken error paths for namespace links
Fan Wu <[email protected]>
net: hip04: fix RX buffer leak on build_skb failure
David Lee <[email protected]>
net/x25: fix use-after-free in x25_kill_by_neigh()
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()
Lu Baolu <[email protected]>
iommu/vt-d: Disallow SVA if page walk is not coherent
Christian Brauner <[email protected]>
binfmt_elf_fdpic: only honour the first PT_INTERP
Douya Le <[email protected]>
libceph: remove debugfs files before client teardown
Douya Le <[email protected]>
libceph: reject zero bucket types in crush_decode
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
Bryam Vargas <[email protected]>
ceph: fix pre-auth out-of-bounds read on snaptrace in ceph_handle_caps()
Jun Yang <[email protected]>
sctp: don't free the ASCONF's own transport in DEL-IP processing
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
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()
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
Guangshuo Li <[email protected]>
intel_th: fix MSC output device reference leak
Ian Abbott <[email protected]>
comedi: comedi_parport: deal with premature interrupt
Xu Rao <[email protected]>
cdrom: fix stack out-of-bounds read in CDROMVOLCTRL
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
Fan Wu <[email protected]>
wifi: brcmfmac: make release_scratchbuffers idempotent
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
Tristan Madani <[email protected]>
wifi: ath6kl: fix OOB access from firmware ADDBA window size
Hans Verkuil <[email protected]>
media: vivid: check for vb2_is_busy() when toggling caps
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
Zile Xiong <[email protected]>
media: vb2: use ssize_t for vb2_read/vb2_write
Hungyu Lin <[email protected]>
media: tegra-video: vi: fix invalid u32 return value in format lookup
Valery Borovsky <[email protected]>
media: sun4i-csi: Return queued buffers on start_streaming() failure
Ma Ke <[email protected]>
media: saa7134: Fix a possible memory leak in saa7134_video_init1
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
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
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
Wang Jun <[email protected]>
media: cx23885: add ioremap return check and cleanup
Johan Hovold <[email protected]>
media: cx231xx: fix devres lifetime
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
Valery Borovsky <[email protected]>
media: airspy: Return queued buffers on start_streaming() failure
Ian Forbes <[email protected]>
drm/vmwgfx: Validate vmw_surface_metadata::array_size
Zhu Lingshan <[email protected]>
drm/amdgpu: fix bo->pin leaking in amdgpu_bo_create_reserved
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
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
Lee Jones <[email protected]>
can: bcm: defer rx_op deallocation to workqueue to fix thrtimer UAF
Chengfeng Ye <[email protected]>
bpf, sockmap: Fix cork use-after-free in tcp_bpf_sendmsg()
Li RongQing <[email protected]>
net: ipv6: fix dif and sdif mismatch in raw6_icmp_error
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()
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()
Sergey Shtylyov <[email protected]>
drm/rockchip: cdn-dp: add missing check in cdn_dp_config_video()
Eric Dumazet <[email protected]>
raw: use more conventional iterators
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
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]>
ipv4: icmp: fill flow parameters in icmp_route_lookup decoy lookup
Nazim Amirul <[email protected]>
net: stmmac: reset residual action in L3L4 filters on delete
Cen Zhang (Microsoft) <[email protected]>
tipc: fix u16 MTU truncation in media and bearer MTU validation
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
Nikolay Aleksandrov <[email protected]>
net: bridge: vlan: fix vlan range dumps starting with pvid
Nikolay Aleksandrov <[email protected]>
net: bridge: vlan: add support for dumping global vlan options
Nikolay Aleksandrov <[email protected]>
net: bridge: vlan: add support for global options
Shelley Yang <[email protected]>
wifi: brcmfmac: fix 802.1X-SHA256 call trace warning
Helen Koike <[email protected]>
tipc: fix infinite loop in __tipc_nl_compat_dumpit
Cen Zhang (Microsoft) <[email protected]>
sctp: validate stream count in sctp_process_strreset_inreq()
HanQuan <[email protected]>
sctp: fix auth_chunk_list capacity check in sctp_auth_ep_add_chunkid
Prashanth Kumar KR <[email protected]>
amd-xgbe: fix MAC_AUTO_SW handling in CL37 AN
Andrew Pope <[email protected]>
wifi: mac80211: recalculate TIM when a station enters power save
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
Ruoyu Wang <[email protected]>
wan: wanxl: Only reset hardware after BAR mapping
Ruoyu Wang <[email protected]>
nfp: Check resource mutex allocation
Aldo Ariel Panzardo <[email protected]>
rds: drop incoming messages that cross network namespace boundaries
David Lee <[email protected]>
net/packet: avoid fanout hook re-registration after unregister
Diego Fernando Mancera Gomez <[email protected]>
usb: atm: ueagle-atm: reject descriptors that confuse probe and disconnect
Shengjiu Wang <[email protected]>
ASoC: bt-sco: fix duplicate DAPM widget names for wideband DAI
Jiaxin Yu <[email protected]>
ASoC: bt-sco: fix bt-sco-pcm-wb dai widget don't connect to the endpoint
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
Dmitry Morgun <[email protected]>
wifi: ath11k: fix potential buffer underflow in ath11k_hal_rx_msdu_list_get()
Tzung-Bi Shih <[email protected]>
watchdog: pretimeout: Fix UAF in watchdog_unregister_governor()
Guenter Roeck <[email protected]>
hwmon: (corsair-cpro) Stop device IO before calling hid_hw_stop
Cheng Yongkang <[email protected]>
wifi: ath9k: hif_usb: don't dereference hif_dev after re-arming firmware request
Xincheng Zhang <[email protected]>
usb: xhci-pci: Limit VIA VL805 DMA addressing to 36 bits
Daniel Borkmann <[email protected]>
bpf: Fix ld_{abs,ind} failure path analysis in subprogs
Doruk Tan Ozturk <[email protected]>
crypto: rsa-pkcs1pad: Don't WARN on an empty digest
Chukun Pan <[email protected]>
USB: serial: option: add TDTECH MT5710-CN
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
Sonali Pradhan <[email protected]>
usb: gadget: f_ncm: validate datagram bounds in ncm_unwrap_ntb()
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
Huihui Huang <[email protected]>
wifi: at76c50x-usb: avoid length underflow in at76_guess_freq()
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
Emre Cecanpunar <[email protected]>
drm/i915/selftests: Fix GT PM sort comparators
Shuhao Fu <[email protected]>
can: j1939: fix lockless local-destination check
Pengpeng Hou <[email protected]>
drm/i915/gt: use correct selftest config symbol
Huiwen He <[email protected]>
smb/client: handle overlapping allocated ranges in fallocate
Rosen Penev <[email protected]>
ata: sata_dwc_460ex: fix infinite loop in NCQ tag completion bit-scanning
Colin Ian King <[email protected]>
ata: sata_dwc_460ex: remove variable num_processed
Rosen Penev <[email protected]>
ata: sata_dwc_460ex: fix clear_interrupt_bit() clearing all pending interrupts
Rosen Penev <[email protected]>
ata: sata_dwc_460ex: enable SATA interrupts only after IRQ handler is registered
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
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
Christian Hewitt <[email protected]>
ASoC: meson: aiu: fifo-spdif: soft reset the S/PDIF datapath on start/stop
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: 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
Xiang Mei <[email protected]>
wifi: p54: validate RX frame length in p54_rx_eeprom_readback()
Dawei Feng <[email protected]>
wifi: libertas: fix memory leak in helper_firmware_cb()
Bryam Vargas <[email protected]>
wifi: mac80211_hwsim: clamp virtio RX length before skb_put
Ramon Fontes <[email protected]>
mac80211_hwsim: add 6GHz channels
Abdun Nihaal <[email protected]>
wifi: ipw2100: fix potential memory leak in ipw2100_pci_init_one()
Xiang Mei (Microsoft) <[email protected]>
xfrm: policy: preallocate inexact bins before xfrm_hash_rebuild reinsert
Danila Chernetsov <[email protected]>
RDMA/hns: Fix potential integer overflow in mhop hem cleanup
Xiang Mei <[email protected]>
btrfs: reject free space cache with more entries than pages
Nikolay Borisov <[email protected]>
btrfs: remove crc_check logic from free space
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
Sean Christopherson <[email protected]>
KVM: VMX: Make vmread_error_trampoline() uncallable from C code
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()
Oliver Hartkopp <[email protected]>
can: isotp: serialize TX state transitions under so->rx_lock
Oliver Hartkopp <[email protected]>
can: isotp: fix use-after-free race with concurrent NETDEV_UNREGISTER
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
Daehyeon Ko <[email protected]>
macsec: don't read an unset MAC header in macsec_encrypt()
Bradley Morgan <[email protected]>
cpu: hotplug: Bound hotplug states sysfs output
Sagi Grimberg <[email protected]>
nvmet-tcp: Fix potential UAF when ddgst mismatch
-------------
Diffstat:
Makefile | 4 +- arch/arm/mach-npcm/platsmp.c | 2 + arch/mips/kernel/mips-mt-fpaff.c | 28 +- arch/powerpc/boot/simpleboot.c | 2 +- arch/powerpc/boot/treeboot-akebono.c | 2 +- arch/powerpc/boot/treeboot-currituck.c | 2 +- arch/powerpc/platforms/ps3/mm.c | 1 + arch/um/drivers/vector_kern.c | 3 + arch/x86/kvm/mmu/mmu.c | 2 + arch/x86/kvm/vmx/nested.c | 11 +- arch/x86/kvm/vmx/vmx_ops.h | 16 +- crypto/rsa-pkcs1pad.c | 2 +- drivers/ata/pata_sl82c105.c | 4 +- drivers/ata/sata_dwc_460ex.c | 21 +- drivers/block/rbd.c | 7 +- drivers/cdrom/cdrom.c | 1 + drivers/counter/microchip-tcb-capture.c | 4 +- drivers/cpufreq/powernow-k8.c | 1 + drivers/dma/sun6i-dma.c | 11 +- drivers/firewire/net.c | 37 +- drivers/firmware/arm_scmi/notify.c | 6 +- drivers/firmware/stratix10-svc.c | 9 +- drivers/gpio/gpio-pch.c | 28 +- drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | 2 + drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c | 45 +- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 13 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 12 + drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 8 + drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 13 +- drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 3 - drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 10 +- drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c | 4 +- drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c | 4 +- drivers/gpu/drm/amd/pm/powerplay/hwmgr/hwmgr.c | 7 +- drivers/gpu/drm/i915/gt/intel_engine_user.c | 2 +- drivers/gpu/drm/i915/gt/selftest_gt_pm.c | 8 +- drivers/gpu/drm/nouveau/nvkm/subdev/acr/base.c | 1 + drivers/gpu/drm/radeon/r100.c | 13 +- drivers/gpu/drm/rockchip/cdn-dp-reg.c | 2 + drivers/gpu/drm/vc4/vc4_validate.c | 29 +- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 14 +- drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 22 +- drivers/hid/hid-logitech-dj.c | 28 +- drivers/hwmon/Kconfig | 1 + drivers/hwmon/adt7470.c | 605 +++++++++++++-------- drivers/hwmon/corsair-cpro.c | 1 + drivers/hwmon/nct6775.c | 12 +- drivers/hwmon/pmbus/pmbus_core.c | 2 +- drivers/hwtracing/intel_th/core.c | 10 - drivers/hwtracing/intel_th/msu.c | 2 + drivers/i2c/busses/i2c-amd-mp2-plat.c | 4 +- drivers/i2c/busses/i2c-jz4780.c | 5 +- drivers/infiniband/core/mad.c | 30 + drivers/infiniband/hw/hns/hns_roce_hem.c | 2 +- drivers/infiniband/sw/rxe/rxe_mmap.c | 19 +- drivers/input/evdev.c | 27 +- drivers/input/misc/ims-pcu.c | 32 +- drivers/iommu/amd/init.c | 6 + drivers/iommu/intel/svm.c | 2 +- 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/pci/cx23885/cx23885-core.c | 14 +- drivers/media/pci/dm1105/dm1105.c | 1 + drivers/media/pci/saa7134/saa7134-video.c | 25 +- drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.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-ctrls.c | 12 + drivers/media/test-drivers/vivid/vivid-vid-cap.c | 6 + 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/usb/uvc/uvc_video.c | 78 ++- drivers/media/usb/uvc/uvcvideo.h | 4 + drivers/misc/fastrpc.c | 3 +- drivers/mtd/mtdswap.c | 5 +- drivers/mtd/nand/raw/mtk_ecc.c | 16 +- drivers/net/bonding/bond_alb.c | 10 +- drivers/net/can/softing/softing_fw.c | 46 +- drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c | 1 + drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 13 +- drivers/net/can/usb/peak_usb/pcan_usb_core.c | 1 - drivers/net/can/usb/peak_usb/pcan_usb_fd.c | 40 +- drivers/net/can/usb/peak_usb/pcan_usb_pro.c | 20 +- drivers/net/ethernet/amd/xgbe/xgbe-mdio.c | 11 +- drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 22 +- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 12 +- drivers/net/ethernet/broadcom/bnxt/bnxt.h | 1 + drivers/net/ethernet/hisilicon/hip04_eth.c | 11 +- drivers/net/ethernet/hisilicon/hix5hd2_gmac.c | 1 - drivers/net/ethernet/huawei/hinic/hinic_dev.h | 2 - drivers/net/ethernet/huawei/hinic/hinic_ethtool.c | 21 - drivers/net/ethernet/intel/e1000/e1000_main.c | 2 +- drivers/net/ethernet/intel/igbvf/netdev.c | 2 - .../net/ethernet/marvell/octeontx2/nic/otx2_pf.c | 2 +- .../net/ethernet/marvell/prestera/prestera_pci.c | 87 ++- .../ethernet/mellanox/mlx5/core/diag/fw_tracer.c | 18 +- drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 15 + .../ethernet/mellanox/mlx5/core/esw/acl/helper.c | 2 +- drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c | 7 +- .../ethernet/netronome/nfp/nfpcore/nfp_resource.c | 3 + drivers/net/ethernet/nvidia/forcedeth.c | 4 +- drivers/net/ethernet/qlogic/qede/qede_main.c | 44 +- drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c | 14 +- drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c | 1 + drivers/net/geneve.c | 3 + drivers/net/macsec.c | 2 +- drivers/net/phy/phylink.c | 29 +- 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 | 20 +- drivers/net/wan/wanxl.c | 3 +- drivers/net/wireless/ath/ath11k/dp_rx.c | 3 + drivers/net/wireless/ath/ath6kl/txrx.c | 10 +- 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 +- .../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/intersil/p54/txrx.c | 8 + drivers/net/wireless/mac80211_hwsim.c | 75 ++- drivers/net/wireless/marvell/libertas/firmware.c | 1 + .../net/wireless/marvell/mwifiex/11n_rxreorder.c | 2 +- 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 | 4 + drivers/net/wireless/microchip/wilc1000/hif.c | 5 + drivers/nvme/target/tcp.c | 4 +- drivers/phy/xilinx/phy-zynqmp.c | 37 +- drivers/pinctrl/Kconfig | 1 + drivers/pinctrl/devicetree.c | 4 + drivers/s390/block/dasd_ioctl.c | 2 +- drivers/s390/crypto/zcrypt_ccamisc.c | 26 +- drivers/s390/scsi/zfcp_aux.c | 1 + drivers/scsi/libiscsi.c | 2 +- drivers/scsi/libiscsi_tcp.c | 8 +- drivers/scsi/scsi_debug.c | 4 +- drivers/spi/spi-fsl-dspi.c | 13 +- drivers/staging/comedi/drivers/comedi_parport.c | 13 +- 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 | 3 + drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c | 4 + drivers/thunderbolt/eeprom.c | 9 +- drivers/tty/serial/8250/8250_dma.c | 12 +- drivers/tty/vt/keyboard.c | 5 +- drivers/tty/vt/vt_ioctl.c | 2 + drivers/usb/atm/cxacru.c | 2 + drivers/usb/atm/ueagle-atm.c | 17 + drivers/usb/chipidea/core.c | 1 + drivers/usb/gadget/function/f_midi.c | 1 + drivers/usb/gadget/function/f_ncm.c | 19 +- drivers/usb/gadget/function/f_printer.c | 23 +- drivers/usb/gadget/function/uvc_v4l2.c | 2 + drivers/usb/gadget/udc/dummy_hcd.c | 40 +- drivers/usb/gadget/udc/fsl_udc_core.c | 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/serial/ftdi_sio.c | 2 + drivers/usb/serial/ftdi_sio_ids.h | 5 + drivers/usb/serial/io_edgeport.c | 3 +- drivers/usb/serial/option.c | 1 + drivers/usb/storage/unusual_devs.h | 7 + drivers/vhost/vhost.c | 8 + drivers/video/fbdev/core/bitblit.c | 9 +- drivers/watchdog/watchdog_pretimeout.c | 2 + fs/binfmt_elf_fdpic.c | 4 + fs/binfmt_misc.c | 9 +- fs/btrfs/free-space-cache.c | 38 +- fs/btrfs/free-space-cache.h | 1 - fs/ceph/caps.c | 1 + fs/cifs/cifssmb.c | 12 +- fs/cifs/smb2ops.c | 25 +- fs/crypto/fscrypt_private.h | 32 +- fs/crypto/keyring.c | 212 ++++---- fs/exec.c | 2 +- fs/namespace.c | 5 + fs/nfs/nfs4proc.c | 13 + fs/proc/namespaces.c | 4 +- include/linux/dma/qcom_bam_dma.h | 21 +- include/linux/netdevice.h | 5 - include/linux/netfilter/nf_conntrack_sip.h | 2 +- include/media/videobuf2-core.h | 8 +- include/net/addrconf.h | 4 +- include/net/bluetooth/bluetooth.h | 1 + include/net/bluetooth/l2cap.h | 1 + include/net/bluetooth/rfcomm.h | 3 + include/net/ip_vs.h | 20 +- include/net/raw.h | 5 +- include/net/rawv6.h | 6 +- include/net/route.h | 2 + include/net/sctp/structs.h | 3 +- include/uapi/linux/if_bridge.h | 14 + kernel/audit.c | 11 +- kernel/auditfilter.c | 6 +- kernel/bpf/verifier.c | 31 +- kernel/cpu.c | 9 +- kernel/futex/core.c | 82 ++- kernel/trace/ring_buffer.c | 8 +- kernel/trace/trace_events.c | 4 +- kernel/trace/trace_events_filter.c | 3 + kernel/trace/trace_mmiotrace.c | 5 +- kernel/trace/trace_probe.c | 13 +- lib/assoc_array.c | 3 +- lib/rhashtable.c | 1 + mm/huge_memory.c | 16 +- mm/hugetlb.c | 2 +- mm/page_reporting.c | 6 +- mm/percpu-km.c | 2 +- net/bluetooth/6lowpan.c | 18 +- net/bluetooth/af_bluetooth.c | 22 + net/bluetooth/hidp/core.c | 5 +- net/bluetooth/l2cap_core.c | 41 +- net/bluetooth/rfcomm/core.c | 17 + net/bluetooth/rfcomm/tty.c | 7 +- net/bluetooth/sco.c | 27 +- net/bridge/br_multicast.c | 1 + net/bridge/br_netlink_tunnel.c | 3 +- net/bridge/br_private.h | 14 +- net/bridge/br_vlan.c | 64 ++- net/bridge/br_vlan_options.c | 119 +++- net/bridge/netfilter/ebt_nflog.c | 17 +- net/bridge/netfilter/nf_conntrack_bridge.c | 1 + net/can/bcm.c | 564 ++++++++++++++----- net/can/isotp.c | 295 +++++++--- net/can/j1939/transport.c | 20 +- net/ceph/auth_x.c | 9 +- net/ceph/ceph_common.c | 4 +- net/ceph/mon_client.c | 2 +- net/ceph/osdmap.c | 12 +- net/core/lwt_bpf.c | 4 +- net/core/sock.c | 1 - net/ipv4/fib_semantics.c | 34 +- net/ipv4/fib_trie.c | 2 +- net/ipv4/icmp.c | 18 +- net/ipv4/raw.c | 91 ++-- net/ipv4/raw_diag.c | 33 +- net/ipv4/route.c | 29 + net/ipv4/tcp_bpf.c | 4 +- net/ipv4/udp_offload.c | 4 +- net/ipv6/fib6_rules.c | 1 + net/ipv6/ila/ila_common.c | 12 + net/ipv6/ip6_fib.c | 17 +- net/ipv6/ip6_tunnel.c | 3 + net/ipv6/raw.c | 102 ++-- net/ipv6/route.c | 8 +- net/iucv/af_iucv.c | 21 +- net/mac80211/iface.c | 8 +- net/mac80211/rx.c | 2 + net/mac802154/llsec.c | 5 + net/mpls/af_mpls.c | 4 + net/ncsi/ncsi-netlink.c | 4 + net/netfilter/ipset/ip_set_hash_gen.h | 2 +- net/netfilter/ipvs/ip_vs_conn.c | 44 +- net/netfilter/ipvs/ip_vs_core.c | 1 + net/netfilter/ipvs/ip_vs_ctl.c | 77 ++- net/netfilter/ipvs/ip_vs_lc.c | 4 +- net/netfilter/ipvs/ip_vs_proto_sctp.c | 2 - net/netfilter/ipvs/ip_vs_proto_tcp.c | 2 - net/netfilter/ipvs/ip_vs_sync.c | 7 +- net/netfilter/nf_conntrack_sip.c | 2 +- net/netfilter/nf_nat_sip.c | 2 +- net/netfilter/nft_payload.c | 12 +- net/netfilter/xt_hashlimit.c | 16 +- net/openvswitch/actions.c | 26 +- net/openvswitch/datapath.c | 54 +- net/openvswitch/datapath.h | 2 +- net/openvswitch/flow.c | 28 +- net/openvswitch/meter.c | 33 +- net/openvswitch/vport.c | 6 +- net/packet/af_packet.c | 13 +- net/phonet/pep.c | 2 + net/qrtr/af_qrtr.c | 8 + net/qrtr/ns.c | 33 +- net/rds/ib.c | 4 + net/rds/ib_cm.c | 4 + net/rds/recv.c | 15 + net/rds/tcp.c | 14 +- net/sched/act_tunnel_key.c | 14 +- net/sched/cls_route.c | 35 +- net/sched/sch_cake.c | 1 - net/sctp/associola.c | 14 +- net/sctp/auth.c | 2 +- net/sctp/input.c | 108 ++-- net/sctp/ipv6.c | 94 ++-- net/sctp/outqueue.c | 1 + net/sctp/sm_make_chunk.c | 26 +- net/sctp/sm_statefuns.c | 8 +- net/sctp/stream.c | 6 +- net/smc/smc_core.c | 2 +- net/smc/smc_llc.c | 3 +- net/tipc/core.c | 5 + net/tipc/discover.c | 14 +- net/tipc/netlink.c | 6 +- net/tipc/netlink_compat.c | 4 + net/tipc/node.c | 15 +- net/tipc/socket.c | 3 +- net/tls/tls_sw.c | 19 +- net/vmw_vsock/virtio_transport.c | 3 +- net/wireless/nl80211.c | 4 +- net/wireless/pmsr.c | 21 +- net/wireless/scan.c | 2 +- net/x25/af_x25.c | 8 +- net/xfrm/xfrm_policy.c | 4 +- security/integrity/ima/ima_appraise.c | 9 +- security/keys/keyring.c | 14 +- sound/core/pcm_native.c | 7 + sound/pci/lx6464es/lx6464es.c | 5 +- sound/pci/lx6464es/lx_core.c | 5 +- sound/soc/codecs/bt-sco.c | 18 +- sound/soc/codecs/max98090.c | 5 +- sound/soc/codecs/max98095.c | 5 +- sound/soc/codecs/tas2562.c | 35 +- sound/soc/meson/aiu-fifo-spdif.c | 5 + sound/usb/6fire/chip.c | 4 + sound/usb/endpoint.c | 23 +- sound/usb/midi.c | 2 + sound/usb/pcm.c | 7 + tools/testing/selftests/clone3/clone3_set_tid.c | 2 +- 333 files changed, 3984 insertions(+), 1839 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/389 nvmet-tcp: Fix potential UAF when ddgst mismatch
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sagi Grimberg <[email protected]>
commit dbbd07d0a7020b80f6a7028e561908f7b83b3d5a upstream.
Shivam Kumar found via vulnerability testing:
When data digest is enabled on an NVMe/TCP connection and a digest mismatch occurs on a non-final H2C_DATA PDU during an R2T-based data transfer, the digest error handler in nvmet_tcp_try_recv_ddgst() calls nvmet_req_uninit() - which performs percpu_ref_put() on the submission queue - but does NOT mark the command as completed. It does not set cqe->status, does not modify rbytes_done, and does not clear any flag. When the subsequent fatal error triggers queue teardown, nvmet_tcp_uninit_data_in_cmds() iterates all commands, checks nvmet_tcp_need_data_in() for each one, and finds that the already-uninited command still appears to need data (because rbytes_done < transfer_len and cqe->status == 0). It therefore calls nvmet_req_uninit() a second time on the same command - a double percpu_ref_put against a single percpu_ref_get.
--- drivers/nvme/target/tcp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/nvme/target/tcp.c +3 -1
@@ -1227,8 +1227,10 @@ static int nvmet_tcp_try_recv_ddgst(struct nvmet_tcp_queue *queue) queue->idx, cmd->req.cmd->common.command_id, queue->pdu.cmd.hdr.type,le32_to_cpu (cmd->recv_ddgst), le32_to_cpu(cmd->exp_ddgst)); -if (!(cmd->flags &NVMET_TCP_F_INIT_FAILED )) +if (!(cmd->flags &NVMET_TCP_F_INIT_FAILED )) { + cmd->req.cqe->status =NVME_SC_CMD_SEQ_ERROR ;nvmet_req_uninit (&cmd->req); + }nvmet_tcp_free_cmd_buffers (cmd);nvmet_tcp_fatal_error (queue); ret = -EPROTO ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 2/389 cpu: hotplug: Bound hotplug states sysfs output
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bradley Morgan <[email protected]>
commit 86f436567f2516a0083b210bedc933544826a2c3 upstream.
states_show() adds CPU hotplug state names into a single sysfs buffer using sprintf(). With enough registered states, this can write past the end of the PAGE_SIZE buffer.
Use sysfs_emit_at() so output is bounded.
--- kernel/cpu.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
kernel/cpu.c +3 -6
@@ -2319,18 +2319,15 @@ static const struct attribute_group cpuhp_cpu_attr_group = {static ssize_t show_cpuhp_states (struct device *dev,struct device_attribute *attr,char *buf) { -ssize_t cur, res =0 ; +ssize_t res =0 ;int i;mutex_lock (&cpuhp_state_mutex);for (i =CPUHP_OFFLINE ; i <=CPUHP_ONLINE ; i++) {struct cpuhp_step *sp =cpuhp_get_step (i); -if (sp->name) { - cur =sprintf (buf,"%3d: %s\n" , i, sp->name); - buf += cur; - res += cur; - } +if (sp->name) + res +=sysfs_emit_at (buf, res,"%3d: %s\n" , i, sp->name); }mutex_unlock (&cpuhp_state_mutex);return res;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 3/389 macsec: dont read an unset MAC header in macsec_encrypt()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daehyeon Ko <[email protected]>
commit f5089008f90c0a7c5520dff3934e0af00adf322d upstream.
macsec_encrypt() reads the Ethernet header via eth_hdr(skb) (skb->head + skb->mac_header) to memmove() the 12 source/destination MAC bytes forward and make room for the SecTAG.
On the AF_PACKET SOCK_RAW + PACKET_QDISC_BYPASS transmit path the skb reaches the macsec ndo_start_xmit() with the MAC header unset, so eth_hdr(skb) resolves to skb->head + (u16)~0 and the read is out of
bounds: a 12-byte heap over-read that is also emitted on the wire as the frame's outer source/destination MAC. KASAN reports a slab-out-of-bounds read in macsec_start_xmit() on 6.0; on current mainline a CONFIG_DEBUG_NET build flags it as an unset mac header in skb_mac_header().
On the TX path the L2 header is at skb->data, so use skb_eth_hdr(), added by commit 96cc4b69581d ("macvlan: do not assume mac_header is set in macvlan_broadcast()") for exactly this purpose.
--- drivers/net/macsec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/macsec.c +1 -1
@@ -666,7 +666,7 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb, } unprotected_len = skb->len; - eth =eth_hdr (skb); + eth =skb_eth_hdr (skb); sci_present =send_sci (secy); hh =skb_push (skb,macsec_extra_len (sci_present));memmove (hh, eth,2 *ETH_ALEN );
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 4/389 KVM: nVMX: Hide shadow VMCS right after VMCLEAR
In reply to Greg Kroah-Hartman5.10-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
@@ -279,6 +279,7 @@ static void vmx_switch_vmcs(struct kvm_vstatic 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);
@@ -295,9 +296,15 @@ static void free_nested(struct kvm_vcpu vmx->nested.current_vmptr =-1ull ;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 5/389 KVM: x86/mmu: Fix use-after-free on vendor module reload
In reply to Greg Kroah-Hartman5.10-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
@@ -5814,7 +5814,9 @@ static struct shrinker mmu_shrinker = {static 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_set_mmio_spte_mask (void )
Greg Kroah-Hartman
maintainerPATCH 6/389 can: isotp: fix use-after-free race with concurrent NETDEV_UNREGISTER
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Hartkopp <[email protected]>
commit 20bab8b88baac140ca3701116e1d486c7f51e311 upstream.
isotp_release() looked up the bound network device via dev_get_by_index() using the stored ifindex. During device unregistration the device is unlisted from the ifindex hash before the NETDEV_UNREGISTER notifier chain runs, so a concurrent isotp_release() could find no device, skip can_rx_unregister() entirely, and still proceed to free the socket. Since isotp_release() had already removed itself from the isotp notifier list at that point, isotp_notify() would never get a chance to clean up either, leaving a stale CAN filter that keeps pointing at the freed socket.
Fix this the same way raw.c already does: hold a tracked reference to the bound net_device in the socket (so->dev/so->dev_tracker) from bind() onward instead of re-resolving it from the ifindex, and serialize bind()/release() with rtnl_lock() so that so->dev is always consistent with what the NETDEV_UNREGISTER notifier sees. so->dev stays valid regardless of ifindex-hash unlisting, and is only ever cleared by whichever of isotp_release()/isotp_notify() gets there first, so the filter is always removed exactly once.
isotp_bind() now rejects a (re)bind with -EAGAIN while so->[tx|rx].state isn't ISOTP_IDLE yet, so a timer left running by a prior NETDEV_UNREGISTER can't act on a newly bound so->ifindex. Both checks share the same lock_sock() section, so there is no window in which a concurrent isotp_notify() clearing so->bound could be missed.
--- net/can/isotp.c | 88 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 59 insertions(+), 29 deletions(-)
net/can/isotp.c +59 -29
@@ -137,6 +137,7 @@ struct isotp_sock {struct sock sk;int bound;int ifindex; +struct net_device *dev;canid_t txid;canid_t rxid;ktime_t tx_gap;
@@ -939,6 +940,14 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) goto err_event_drop; } +/* so->bound is only checked once above - a wakeup may have +* unbound/rebound the socket meanwhile, so re-validate it +*/ +if (!so->bound) { + err = -EADDRNOTAVAIL ; + goto err_out_drop; + } +if (!size || size >MAX_MSG_LENGTH ) { err = -EINVAL ; goto err_out_drop;
@@ -1166,28 +1175,30 @@ static int isotp_release(struct socket *sock)list_del (&so->notifier);spin_unlock (&isotp_notifier_lock); +rtnl_lock ();lock_sock (sk); -/* remove current filters & unregister */ -if (so->bound) { -if (so->ifindex) { -struct net_device *dev; - - dev =dev_get_by_index (net, so->ifindex); -if (dev) { -if (isotp_register_rxid (so)) -can_rx_unregister (net, dev, so->rxid, -SINGLE_MASK (so->rxid), - isotp_rcv, sk); - -can_rx_unregister (net, dev, so->txid, -SINGLE_MASK (so->txid), - isotp_rcv_echo, sk); -dev_put (dev); - } - } +/* remove current filters & unregister +* tracked reference so->dev is taken at bind() time with rtnl_lock +*/ +if (so->bound && so->dev) { +if (isotp_register_rxid (so)) +can_rx_unregister (net, so->dev, so->rxid, +SINGLE_MASK (so->rxid), + isotp_rcv, sk); + +can_rx_unregister (net, so->dev, so->txid, +SINGLE_MASK (so->txid), + isotp_rcv_echo, sk); +dev_put (so->dev); } + so->ifindex =0 ; + so->bound =0 ; + so->dev =NULL ; + +rtnl_unlock (); +/* Always wait for a grace period before touching the timers below. * A concurrent NETDEV_UNREGISTER may have already unregistered our * filters and cleared so->bound in isotp_notify() without waiting
@@ -1200,9 +1211,6 @@ static int isotp_release(struct socket *sock)hrtimer_cancel (&so->txtimer);hrtimer_cancel (&so->rxtimer); - so->ifindex =0 ; - so->bound =0 ; -sock_orphan (sk); sock->sk =NULL ;
@@ -1256,6 +1264,7 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len)if (!addr->can_ifindex)return -ENODEV ; +rtnl_lock ();lock_sock (sk);if (so->bound) {
@@ -1263,6 +1272,17 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len) goto out; } +/* A transmission or reception that outlived a previous binding +* (unbound by NETDEV_UNREGISTER) may still be draining; the FC/echo +* and RX watchdog timers bound how long this takes. Checked together +* with so->bound in the same lock_sock() section above, so there is +* no window in which a concurrent isotp_notify() could be missed. +*/ +if (so->tx.state !=ISOTP_IDLE || so->rx.state !=ISOTP_IDLE ) { + err = -EAGAIN ; + goto out; + } +/* ensure different CAN IDs when the rx_id is to be registered */ if (isotp_register_rxid (so) && rx_id == tx_id) { err = -EADDRNOTAVAIL ;
@@ -1275,14 +1295,12 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len) goto out; }if (dev->type !=ARPHRD_CAN ) { -dev_put (dev); err = -ENODEV ; - goto out; + goto out_put_dev; } -if (dev->mtu < so->ll.mtu) { -dev_put (dev); +if (READ_ONCE (dev->mtu) < so->ll.mtu) { err = -EINVAL ; - goto out; + goto out_put_dev; }if (!(dev->flags &IFF_UP )) notify_enetdown =1 ;
@@ -1300,16 +1318,25 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len)can_rx_register (net, dev, tx_id,SINGLE_MASK (tx_id), isotp_rcv_echo, sk,"isotpe" , sk); -dev_put (dev); -/* switch to new settings */ so->ifindex = ifindex; so->rxid = rx_id; so->txid = tx_id; so->bound =1 ; +/* bind() ok -> hold a reference for so->dev so that isotp_release() +* can safely reach the device later, even if a concurrent +* NETDEV_UNREGISTER has already unlisted it by ifindex. +*/ + so->dev = dev; +dev_hold (so->dev); + +out_put_dev: +/* remove potential reference from dev_get_by_index() */ +dev_put (dev); out:release_sock (sk); +rtnl_unlock ();if (notify_enetdown) { sk->sk_err =ENETDOWN ;
@@ -1512,7 +1539,7 @@ static void isotp_notify(struct isotp_sock *so, unsigned long msg,if (!net_eq (dev_net (dev),sock_net (sk)))return ; -if (so->ifindex != dev->ifindex) +if (so->dev != dev)return ;switch (msg) {
@@ -1528,10 +1555,12 @@ static void isotp_notify(struct isotp_sock *so, unsigned long msg,can_rx_unregister (dev_net (dev), dev, so->txid,SINGLE_MASK (so->txid), isotp_rcv_echo, sk); +dev_put (so->dev); } so->ifindex =0 ; so->bound =0 ; + so->dev =NULL ;release_sock (sk); sk->sk_err =ENODEV ;
@@ -1576,6 +1605,7 @@ static int isotp_init(struct sock *sk) so->ifindex =0 ; so->bound =0 ; + so->dev =NULL ; so->opt.flags =CAN_ISOTP_DEFAULT_FLAGS ; so->opt.ext_address =CAN_ISOTP_DEFAULT_EXT_ADDRESS ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 7/389 can: isotp: serialize TX state transitions under so->rx_lock
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Hartkopp <[email protected]>
commit cf070fe33bfbd1a4c21236078fadb35dd223a157 upstream.
The TX state machine (so->tx.state) is driven from three contexts:sendmsg() claiming and progressing a transfer, the RX path consuming Flow Control/echo frames, and two hrtimers timing out a stalled transfer. Mixing a lock-free cmpxchg() claim in sendmsg() with hrtimer_cancel() calls made under so->rx_lock elsewhere left windows where a frame or timer callback could act on a state that had already moved on, corrupting an unrelated transfer.
so->rx_lock now covers the full lifecycle of a TX claim: sendmsg() takes it to check so->tx.state is ISOTP_IDLE, switch it to ISOTP_SENDING, bump so->tx_gen and drain the previous transfer's timers - all as one critical section. isotp_rcv_fc()/isotp_rcv_cf() already run under this lock via isotp_rcv(), and isotp_rcv_echo() now takes it itself, so none of them can ever observe a transfer mid-claim. This also means a transfer can no longer be handed to sendmsg()'s cleanup paths (signal or send error) while another thread is concurrently claiming or finishing it, so those paths can cancel timers and reset the state unconditionally.
isotp_release() claims the socket the same way, so a racing sendmsg() sees a consistent ISOTP_SHUTDOWN and skips arming its timer or sending.
Only the hrtimer callbacks stay outside so->rx_lock, since they run under so->rx_lock's cancellation elsewhere and taking it themselves would deadlock. so->tx_gen lets them recognize whether the transfer they timed out is still the one currently active, so they don't report an error against a transfer that has since completed or been superseded.
--- net/can/isotp.c | 192 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 154 insertions(+), 38 deletions(-)
net/can/isotp.c +154 -38
@@ -142,7 +142,7 @@ struct isotp_sock {canid_t rxid;ktime_t tx_gap;ktime_t lastrxcf_tstamp; -struct hrtimer rxtimer, txtimer, txfrtimer; +struct hrtimer rxtimer, txtimer, txfrtimer, echotimer;struct can_isotp_options opt;struct can_isotp_fc_options rxfc, txfc;struct can_isotp_ll_options ll;
@@ -150,6 +150,7 @@ struct isotp_sock {u32 force_tx_stmin;u32 force_rx_stmin;u32 cfecho;/* consecutive frame echo tag */ +u32 tx_gen;/* generation, bumped per new tx transfer */ struct tpcon rx, tx;struct list_head notifier;wait_queue_head_t wait;
@@ -356,6 +357,15 @@ static int isotp_rcv_fc(struct isotp_sock *so, struct canfd_frame *cf, int ae)hrtimer_cancel (&so->txtimer); +/* isotp_tx_timeout() may have given up on this job while +* hrtimer_cancel() above waited for it to finish; so->rx_lock +* (held by our caller isotp_rcv()) rules out a concurrent claim, +* so a plain recheck is enough here. +*/ +if (so->tx.state !=ISOTP_WAIT_FC && + so->tx.state !=ISOTP_WAIT_FIRST_FC ) +return 1 ; +if ((cf->len < ae +FC_CONTENT_SZ ) || ((so->opt.flags &ISOTP_CHECK_PADDING ) &&check_pad (so, cf, ae +FC_CONTENT_SZ , so->opt.rxpad_content))) {
@@ -401,7 +411,7 @@ static int isotp_rcv_fc(struct isotp_sock *so, struct canfd_frame *cf, int ae) so->tx.bs =0 ; so->tx.state =ISOTP_SENDING ;/* send CF frame and enable echo timeout handling */ -hrtimer_start (&so->txtimer,ktime_set (ISOTP_ECHO_TIMEOUT ,0 ), +hrtimer_start (&so->echotimer,ktime_set (ISOTP_ECHO_TIMEOUT ,0 ),HRTIMER_MODE_REL_SOFT );isotp_send_cframe (so);break ;
@@ -544,6 +554,14 @@ static int isotp_rcv_cf(struct sock *sk, struct canfd_frame *cf, int ae,hrtimer_cancel (&so->rxtimer); +/* isotp_rx_timer_handler() may have raced us for so->rx.state +* while hrtimer_cancel() above waited for it to finish, already +* reporting ETIMEDOUT and resetting the reception; don't process +* this CF into a reassembly that has already been given up on. +*/ +if (so->rx.state !=ISOTP_WAIT_DATA ) +return 1 ; +/* CFs are never longer than the FF */ if (cf->len > so->rx.ll_dl)return 1 ;
@@ -833,20 +851,36 @@ static void isotp_rcv_echo(struct sk_buff *skb, void *data)struct canfd_frame *cf = (struct canfd_frame *)skb->data;/* only handle my own local echo CF/SF skb's (no FF!) */ -if (skb->sk != sk || so->cfecho != *(u32 *)cf->data) +if (skb->sk != sk)return ; +/* unlike isotp_rcv_fc()/isotp_rcv_cf(), not already under so->rx_lock +* (no isotp_rcv() caller here), so take it ourselves +*/ +spin_lock (&so->rx_lock); + +/* so->cfecho may since belong to a new transfer; recheck under lock */ +if (so->cfecho != *(u32 *)cf->data) + goto out_unlock; +/* cancel local echo timeout */ -hrtimer_cancel (&so->txtimer); +hrtimer_cancel (&so->echotimer);/* local echo skb with consecutive frame has been consumed */ so->cfecho =0 ; +/* claiming a transfer also takes so->rx_lock, so a plain recheck +* is enough: so->tx.state can't have flipped to ISOTP_SENDING for +* a new claim while we're still in here +*/ +if (so->tx.state !=ISOTP_SENDING ) + goto out_unlock; +if (so->tx.idx >= so->tx.len) {/* we are done */ so->tx.state =ISOTP_IDLE ;wake_up_interruptible (&so->wait); -return ; + goto out_unlock; }if (so->txfc.bs && so->tx.bs >= so->txfc.bs) {
@@ -854,53 +888,83 @@ static void isotp_rcv_echo(struct sk_buff *skb, void *data) so->tx.state =ISOTP_WAIT_FC ;hrtimer_start (&so->txtimer,ktime_set (ISOTP_FC_TIMEOUT ,0 ),HRTIMER_MODE_REL_SOFT ); -return ; + goto out_unlock; }/* no gap between data frames needed => use burst mode */ if (!so->tx_gap) {/* enable echo timeout handling */ -hrtimer_start (&so->txtimer,ktime_set (ISOTP_ECHO_TIMEOUT ,0 ), +hrtimer_start (&so->echotimer,ktime_set (ISOTP_ECHO_TIMEOUT ,0 ),HRTIMER_MODE_REL_SOFT );isotp_send_cframe (so); -return ; + goto out_unlock; }/* start timer to send next consecutive frame with correct delay */ hrtimer_start (&so->txfrtimer, so->tx_gap,HRTIMER_MODE_REL_SOFT ); + +out_unlock: +spin_unlock (&so->rx_lock); } -static enum hrtimer_restart isotp_tx_timer_handler (struct hrtimer *hrtimer) +/* shared by so->txtimer's and so->echotimer's callbacks. Both timers get +* cancelled under so->rx_lock elsewhere, so this must stay lock-free to +* avoid deadlocking with that; uses so->tx_gen instead to avoid tainting +* a new transfer with an error from the one that just timed out. +*/ +static enum hrtimer_restart isotp_tx_timeout (struct isotp_sock *so) { - struct isotp_sock *so = container_of(hrtimer, struct isotp_sock, - txtimer);struct sock *sk = &so->sk; +u32 gen =READ_ONCE (so->tx_gen); +u32 old_state =READ_ONCE (so->tx.state);/* don't handle timeouts in IDLE or SHUTDOWN state */ -if (so->tx.state ==ISOTP_IDLE || so->tx.state ==ISOTP_SHUTDOWN ) +if (old_state ==ISOTP_IDLE || old_state ==ISOTP_SHUTDOWN ) +return HRTIMER_NORESTART ; + +/* only claim the timeout if the state is still unchanged */ +if (cmpxchg (&so->tx.state, old_state,ISOTP_IDLE ) != old_state)return HRTIMER_NORESTART ;/* we did not get any flow control or echo frame in time */ -/* report 'communication error on send' */ - sk->sk_err =ECOMM ; -if (!sock_flag (sk,SOCK_DEAD )) - sk->sk_error_report (sk); +if (READ_ONCE (so->tx_gen) == gen) { +/* report 'communication error on send' */ + sk->sk_err =ECOMM ; +if (!sock_flag (sk,SOCK_DEAD )) + sk->sk_error_report (sk); + } -/* reset tx state */ - so->tx.state =ISOTP_IDLE ;wake_up_interruptible (&so->wait);return HRTIMER_NORESTART ; } +/* so->txtimer: fires when a Flow Control frame does not arrive in time */ +static enum hrtimer_restart isotp_tx_timer_handler (struct hrtimer *hrtimer) +{ + struct isotp_sock *so = container_of(hrtimer, struct isotp_sock, + txtimer); + +return isotp_tx_timeout (so); +} + +/* so->echotimer: fires when a sent CF/SF's local echo does not arrive */ +static enum hrtimer_restart isotp_echo_timer_handler (struct hrtimer *hrtimer) +{ + struct isotp_sock *so = container_of(hrtimer, struct isotp_sock, + echotimer); + +return isotp_tx_timeout (so); +} +static enum hrtimer_restart isotp_txfr_timer_handler (struct hrtimer *hrtimer) { struct isotp_sock *so = container_of(hrtimer, struct isotp_sock, txfrtimer);/* start echo timeout handling and cover below protocol error */ -hrtimer_start (&so->txtimer,ktime_set (ISOTP_ECHO_TIMEOUT ,0 ), +hrtimer_start (&so->echotimer,ktime_set (ISOTP_ECHO_TIMEOUT ,0 ),HRTIMER_MODE_REL_SOFT );/* cfecho should be consumed by isotp_rcv_echo() here */
@@ -920,13 +984,24 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)int ae = (so->opt.flags &CAN_ISOTP_EXTEND_ADDR ) ?1 :0 ;int wait_tx_done = (so->opt.flags &CAN_ISOTP_WAIT_TX_DONE ) ?1 :0 ;s64 hrtimer_sec =ISOTP_ECHO_TIMEOUT ; +struct hrtimer *tx_hrt = &so->echotimer; +u32 new_state =ISOTP_SENDING ;int off;int err;if (!so->bound || so->tx.state ==ISOTP_SHUTDOWN )return -EADDRNOTAVAIL ; -while (cmpxchg (&so->tx.state,ISOTP_IDLE ,ISOTP_SENDING ) !=ISOTP_IDLE ) { +/* claim the socket under so->rx_lock: this serializes the claim +* with the RX path and with sendmsg()'s own error paths below, so +* none of them can ever see a transfer mid-claim +*/ +for (;;) { +spin_lock_bh (&so->rx_lock); +if (READ_ONCE (so->tx.state) ==ISOTP_IDLE ) +break ; +spin_unlock_bh (&so->rx_lock); +/* we do not support multiple buffers - for now */ if (msg->msg_flags &MSG_DONTWAIT )return -EAGAIN ;
@@ -935,11 +1010,23 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)return -EADDRNOTAVAIL ;/* wait for complete transmission of current pdu */ - err =wait_event_interruptible (so->wait, so->tx.state ==ISOTP_IDLE ); + err =wait_event_interruptible (so->wait, + so->tx.state ==ISOTP_IDLE );if (err) - goto err_event_drop; +return err; } +/* new transfer: bump so->tx_gen and drain the old one's timers, +* still under the so->rx_lock we just claimed the socket with +*/ +WRITE_ONCE (so->tx.state,ISOTP_SENDING ); +WRITE_ONCE (so->tx_gen,READ_ONCE (so->tx_gen) +1 ); +hrtimer_cancel (&so->txtimer); +hrtimer_cancel (&so->echotimer); +hrtimer_cancel (&so->txfrtimer); + so->cfecho =0 ; +spin_unlock_bh (&so->rx_lock); +/* so->bound is only checked once above - a wakeup may have * unbound/rebound the socket meanwhile, so re-validate it */
@@ -1040,18 +1127,33 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) so->cfecho = *(u32 *)cf->data; }else {/* standard flow control check */ - so->tx.state =ISOTP_WAIT_FIRST_FC ; + new_state =ISOTP_WAIT_FIRST_FC ;/* start timeout for FC */ hrtimer_sec =ISOTP_FC_TIMEOUT ; + tx_hrt = &so->txtimer;/* no CF echo tag for isotp_rcv_echo() (FF-mode) */ so->cfecho =0 ; } } -hrtimer_start (&so->txtimer,ktime_set (hrtimer_sec,0 ), +spin_lock_bh (&so->rx_lock); +if (so->tx.state ==ISOTP_SHUTDOWN ) { +/* isotp_release() has since taken over and already drained +* our timers - don't send into a socket that's going away +*/ +spin_unlock_bh (&so->rx_lock); +kfree_skb (skb); +dev_put (dev); +wake_up_interruptible (&so->wait); +return -EADDRNOTAVAIL ; + } +/* WAIT_FIRST_FC for standard FF, else stays ISOTP_SENDING */ + so->tx.state = new_state; +hrtimer_start (tx_hrt,ktime_set (hrtimer_sec,0 ),HRTIMER_MODE_REL_SOFT ); +spin_unlock_bh (&so->rx_lock);/* send the first or only CAN frame */ cf->flags = so->ll.tx_flags;
@@ -1064,13 +1166,10 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)pr_notice_once ("can-isotp: %s: can_send_ret %pe\n" , __func__,ERR_PTR (err)); +spin_lock_bh (&so->rx_lock);/* no transmission -> no timeout monitoring */ -hrtimer_cancel (&so->txtimer); - -/* reset consecutive frame echo tag */ - so->cfecho =0 ; - - goto err_out_drop; +hrtimer_cancel (tx_hrt); + goto err_out_drop_locked; }if (wait_tx_done) {
@@ -1086,14 +1185,21 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)return size; +err_out_drop: +/* claimed but nothing sent yet - no timer to cancel */ +spin_lock_bh (&so->rx_lock); + goto err_out_drop_locked; err_event_drop: -/* got signal: force tx state machine to be idle */ - so->tx.state =ISOTP_IDLE ; +/* interrupted waiting on our own transfer - drain its timers */ +spin_lock_bh (&so->rx_lock);hrtimer_cancel (&so->txfrtimer);hrtimer_cancel (&so->txtimer); -err_out_drop: -/* drop this PDU and unlock a potential wait queue */ +hrtimer_cancel (&so->echotimer); +err_out_drop_locked: +/* release the claim; so->rx_lock still held from above */ + so->cfecho =0 ; so->tx.state =ISOTP_IDLE ; +spin_unlock_bh (&so->rx_lock);wake_up_interruptible (&so->wait);return err;
@@ -1157,13 +1263,20 @@ static int isotp_release(struct socket *sock) so =isotp_sk (sk); net =sock_net (sk); -/* wait for complete transmission of current pdu */ -while (wait_event_interruptible (so->wait, so->tx.state ==ISOTP_IDLE ) ==0 && -cmpxchg (&so->tx.state,ISOTP_IDLE ,ISOTP_SHUTDOWN ) !=ISOTP_IDLE ) +/* best-effort: wait for a running pdu to finish, but don't block on +* it forever - give up after the first signal +*/ +while (so->tx.state !=ISOTP_IDLE && +wait_event_interruptible (so->wait, so->tx.state ==ISOTP_IDLE ) ==0 ) ; -/* force state machines to be idle also when a signal occurred */ +/* claim the socket under so->rx_lock like sendmsg() does, so its +* claim can't race the forced ISOTP_SHUTDOWN below; force it +* unconditionally, even when a signal cut the wait above short +*/ +spin_lock_bh (&so->rx_lock); so->tx.state =ISOTP_SHUTDOWN ; +spin_unlock_bh (&so->rx_lock); so->rx.state =ISOTP_IDLE ;spin_lock (&isotp_notifier_lock);
@@ -1209,6 +1322,7 @@ static int isotp_release(struct socket *sock)hrtimer_cancel (&so->txfrtimer);hrtimer_cancel (&so->txtimer); +hrtimer_cancel (&so->echotimer);hrtimer_cancel (&so->rxtimer);sock_orphan (sk);
@@ -1631,6 +1745,8 @@ static int isotp_init(struct sock *sk) so->rxtimer.function = isotp_rx_timer_handler;hrtimer_init (&so->txtimer,CLOCK_MONOTONIC ,HRTIMER_MODE_REL_SOFT ); so->txtimer.function = isotp_tx_timer_handler; +hrtimer_init (&so->echotimer,CLOCK_MONOTONIC ,HRTIMER_MODE_REL_SOFT ); + so->echotimer.function = isotp_echo_timer_handler;hrtimer_init (&so->txfrtimer,CLOCK_MONOTONIC ,HRTIMER_MODE_REL_SOFT ); so->txfrtimer.function = isotp_txfr_timer_handler;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 8/389 Input: ims-pcu - fix heap-buffer-overflow in ims_pcu_process_data()
In reply to Greg Kroah-Hartman5.10-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 9/389 Input: ims-pcu - fix logic error in packet reset
In reply to Greg Kroah-Hartman5.10-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 10/389 KVM: VMX: Make vmread_error_trampoline() uncallable from C code
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <[email protected]>
[ Upstream commit 0b5e7a16a0a79a3742f0df9e45bca46f01b40e6a ]
Declare vmread_error_trampoline() as an opaque symbol so that it cannot be called from C code, at least not without some serious fudging. The trampoline always passes parameters on the stack so that the inline VMREAD sequence doesn't need to clobber registers. regparm(0) was originally added to document the stack behavior, but it ended up being confusing because regparm(0) is a nop for 64-bit targets.
Opportunustically wrap the trampoline and its declaration in #ifdeffery to make it even harder to invoke incorrectly, to document why it exists, and so that it's not left behind if/when CONFIG_CC_HAS_ASM_GOTO_OUTPUT is true for all supported toolchains.
No functional change intended.
[ Vivian: Adjust context. Remove check for CONFIG_CC_HAS_ASM_GOTO_OUTPUT
which does not apply for old kernel. ]
--- arch/x86/kvm/vmx/vmx_ops.h | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
arch/x86/kvm/vmx/vmx_ops.h +14 -2
@@ -13,14 +13,26 @@#define __ex (x) __kvm_handle_fault_on_reboot(x) asmlinkage void vmread_error(unsigned long field, bool fault); -__attribute__((regparm (0 )))void vmread_error_trampoline (unsigned long field, -bool fault);void vmwrite_error (unsigned long field,unsigned long value);void vmclear_error (struct vmcs *vmcs,u64 phys_addr);void vmptrld_error (struct vmcs *vmcs,u64 phys_addr);void invvpid_error (unsigned long ext,u16 vpid,gva_t gva);void invept_error (unsigned long ext,u64 eptp,gpa_t gpa); +/* +* The VMREAD error trampoline _always_ uses the stack to pass parameters, even +* for 64-bit targets. Preserving all registers allows the VMREAD inline asm +* blob to avoid clobbering GPRs, which in turn allows the compiler to better +* optimize sequences of VMREADs. +* +* Declare the trampoline as an opaque label as it's not safe to call from C +* code; there is no way to tell the compiler to pass params on the stack for +* 64-bit targets. +* +* void vmread_error_trampoline(unsigned long field, bool fault); +*/ +extern unsigned long vmread_error_trampoline; + static __always_inline void vmcs_check16(unsigned long field) { BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6001) == 0x2000,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 11/389 IB/mad: Drop unmatched RMPP responses before reassembly
In reply to Greg Kroah-Hartman5.10-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
@@ -1783,6 +1783,24 @@ void ib_mark_mad_done(struct ib_mad_send_wr_private *mad_send_wr) &mad_send_wr->mad_agent_priv->done_list); } +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) {
@@ -1801,6 +1819,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 12/389 mtd: mtdswap: remove debugfs stats file on teardown
In reply to Greg Kroah-Hartman5.10-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 {
@@ -1264,7 +1265,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 ; }
@@ -1465,6 +1467,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 13/389 mtd: nand: mtk-ecc: stop on ECC idle timeouts
In reply to Greg Kroah-Hartman5.10-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/raw/mtk_ecc.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
drivers/mtd/nand/raw/mtk_ecc.c +12 -4
@@ -116,8 +116,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;
@@ -129,6 +129,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)
@@ -302,7 +304,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) {
@@ -402,7 +408,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 14/389 btrfs: remove crc_check logic from free space
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikolay Borisov <[email protected]>
[ Upstream commit 7dbdb443a7b49f66d9c4da0d810e2c54e0727d82 ]
Following removal of the ino cache io_ctl_init will be called only on behalf of the freespace inode. In this case we always want to check CRCs so conditional code that depended on io_ctl::check_crc can be removed.
Stable-dep-of: a2d8d5647ed8 ("btrfs: reject free space cache with more entries than pages")
--- fs/btrfs/free-space-cache.c | 37 +++++-------------------------------- fs/btrfs/free-space-cache.h | 1 - 2 files changed, 5 insertions(+), 33 deletions(-)
fs/btrfs/free-space-cache.c +5 -32
@@ -304,16 +304,11 @@ static int io_ctl_init(struct btrfs_io_ctl *io_ctl, struct inode *inode, int write) {int num_pages; -int check_crcs =0 ; num_pages =DIV_ROUND_UP (i_size_read (inode),PAGE_SIZE ); -if (btrfs_ino (BTRFS_I (inode)) !=BTRFS_FREE_INO_OBJECTID ) - check_crcs =1 ; -/* Make sure we can fit our crcs and generation into the first page */ -if (write && check_crcs && - (num_pages *sizeof (u32) +sizeof (u64)) >PAGE_SIZE ) +if (write && (num_pages *sizeof (u32) +sizeof (u64)) >PAGE_SIZE )return -ENOSPC ;memset (io_ctl,0 ,sizeof (struct btrfs_io_ctl ));
@@ -324,7 +319,6 @@ static int io_ctl_init(struct btrfs_io_ctl *io_ctl, struct inode *inode, io_ctl->num_pages = num_pages; io_ctl->fs_info =btrfs_sb (inode->i_sb); - io_ctl->check_crcs = check_crcs; io_ctl->inode = inode;return 0 ;
@@ -419,13 +413,8 @@ static void io_ctl_set_generation(struct btrfs_io_ctl *io_ctl, u64 generation)* Skip the csum areas. If we don't check crcs then we just have a * 64bit chunk at the front of the first page. */ -if (io_ctl->check_crcs) { - io_ctl->cur += (sizeof (u32) * io_ctl->num_pages); - io_ctl->size -=sizeof (u64) + (sizeof (u32) * io_ctl->num_pages); - }else { - io_ctl->cur +=sizeof (u64); - io_ctl->size -=sizeof (u64) *2 ; - } + io_ctl->cur += (sizeof (u32) * io_ctl->num_pages); + io_ctl->size -=sizeof (u64) + (sizeof (u32) * io_ctl->num_pages);put_unaligned_le64 (generation, io_ctl->cur); io_ctl->cur +=sizeof (u64);
@@ -439,14 +428,8 @@ static int io_ctl_check_generation(struct btrfs_io_ctl *io_ctl, u64 generation)* Skip the crc area. If we don't check crcs then we just have a 64bit * chunk at the front of the first page. */ -if (io_ctl->check_crcs) { - io_ctl->cur +=sizeof (u32) * io_ctl->num_pages; - io_ctl->size -=sizeof (u64) + - (sizeof (u32) * io_ctl->num_pages); - }else { - io_ctl->cur +=sizeof (u64); - io_ctl->size -=sizeof (u64) *2 ; - } + io_ctl->cur +=sizeof (u32) * io_ctl->num_pages; + io_ctl->size -=sizeof (u64) + (sizeof (u32) * io_ctl->num_pages); cache_gen =get_unaligned_le64 (io_ctl->cur);if (cache_gen != generation) {
@@ -466,11 +449,6 @@ static void io_ctl_set_crc(struct btrfs_io_ctl *io_ctl, int index)u32 crc = ~(u32 )0 ;unsigned offset =0 ; -if (!io_ctl->check_crcs) { -io_ctl_unmap_page (io_ctl); -return ; - } -if (index ==0 ) offset =sizeof (u32) * io_ctl->num_pages;
@@ -488,11 +466,6 @@ static int io_ctl_check_crc(struct btrfs_io_ctl *io_ctl, int index)u32 crc = ~(u32 )0 ;unsigned offset =0 ; -if (!io_ctl->check_crcs) { -io_ctl_map_page (io_ctl,0 ); -return 0 ; - } -if (index ==0 ) offset =sizeof (u32) * io_ctl->num_pages;
fs/btrfs/free-space-cache.h +0 -1
@@ -76,7 +76,6 @@ struct btrfs_io_ctl {int num_pages;int entries;int bitmaps; - unsigned check_crcs:1; }; struct inode *lookup_free_space_inode(struct btrfs_block_group *block_group,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 15/389 btrfs: reject free space cache with more entries than pages
In reply to Greg Kroah-Hartman5.10-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
@@ -466,6 +466,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 16/389 RDMA/hns: Fix potential integer overflow in mhop hem cleanup
In reply to Greg Kroah-Hartman5.10-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
@@ -896,7 +896,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 17/389 xfrm: policy: preallocate inexact bins before xfrm_hash_rebuild reinsert
In reply to Greg Kroah-Hartman5.10-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
@@ -1292,8 +1292,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 18/389 wifi: ipw2100: fix potential memory leak in ipw2100_pci_init_one()
In reply to Greg Kroah-Hartman5.10-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
@@ -6183,6 +6183,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; }
@@ -6195,16 +6197,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 19/389 mac80211_hwsim: add 6GHz channels
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ramon Fontes <[email protected]>
[ Upstream commit 28881922abd786a1e62a4ca77394a84373dd5279 ]
Advertise 6GHz channels to mac80211.
Stable-dep-of: 10a2b430f8f0 ("wifi: mac80211_hwsim: clamp virtio RX length before skb_put")
--- drivers/net/wireless/mac80211_hwsim.c | 74 ++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-)
drivers/net/wireless/mac80211_hwsim.c +73 -1
@@ -311,6 +311,12 @@ static struct net_device *hwsim_mon; /* global monitor netdev */ .hw_value = (_freq), \ } +#define CHAN6G (_freq) { \ + .band = NL80211_BAND_6GHZ, \ + .center_freq = (_freq), \ + .hw_value = (_freq), \ +} +static const struct ieee80211_channel hwsim_channels_2ghz[] = {CHAN2G (2412 ),/* Channel 1 */ CHAN2G (2417 ),/* Channel 2 */
@@ -377,6 +383,68 @@ static const struct ieee80211_channel hwsim_channels_5ghz[] = { CHAN5G(5925), /* Channel 185 */ }; +static const struct ieee80211_channel hwsim_channels_6ghz[] = { +CHAN6G (5955 ),/* Channel 1 */ +CHAN6G (5975 ),/* Channel 5 */ +CHAN6G (5995 ),/* Channel 9 */ +CHAN6G (6015 ),/* Channel 13 */ +CHAN6G (6035 ),/* Channel 17 */ +CHAN6G (6055 ),/* Channel 21 */ +CHAN6G (6075 ),/* Channel 25 */ +CHAN6G (6095 ),/* Channel 29 */ +CHAN6G (6115 ),/* Channel 33 */ +CHAN6G (6135 ),/* Channel 37 */ +CHAN6G (6155 ),/* Channel 41 */ +CHAN6G (6175 ),/* Channel 45 */ +CHAN6G (6195 ),/* Channel 49 */ +CHAN6G (6215 ),/* Channel 53 */ +CHAN6G (6235 ),/* Channel 57 */ +CHAN6G (6255 ),/* Channel 61 */ +CHAN6G (6275 ),/* Channel 65 */ +CHAN6G (6295 ),/* Channel 69 */ +CHAN6G (6315 ),/* Channel 73 */ +CHAN6G (6335 ),/* Channel 77 */ +CHAN6G (6355 ),/* Channel 81 */ +CHAN6G (6375 ),/* Channel 85 */ +CHAN6G (6395 ),/* Channel 89 */ +CHAN6G (6415 ),/* Channel 93 */ +CHAN6G (6435 ),/* Channel 97 */ +CHAN6G (6455 ),/* Channel 181 */ +CHAN6G (6475 ),/* Channel 105 */ +CHAN6G (6495 ),/* Channel 109 */ +CHAN6G (6515 ),/* Channel 113 */ +CHAN6G (6535 ),/* Channel 117 */ +CHAN6G (6555 ),/* Channel 121 */ +CHAN6G (6575 ),/* Channel 125 */ +CHAN6G (6595 ),/* Channel 129 */ +CHAN6G (6615 ),/* Channel 133 */ +CHAN6G (6635 ),/* Channel 137 */ +CHAN6G (6655 ),/* Channel 141 */ +CHAN6G (6675 ),/* Channel 145 */ +CHAN6G (6695 ),/* Channel 149 */ +CHAN6G (6715 ),/* Channel 153 */ +CHAN6G (6735 ),/* Channel 157 */ +CHAN6G (6755 ),/* Channel 161 */ +CHAN6G (6775 ),/* Channel 165 */ +CHAN6G (6795 ),/* Channel 169 */ +CHAN6G (6815 ),/* Channel 173 */ +CHAN6G (6835 ),/* Channel 177 */ +CHAN6G (6855 ),/* Channel 181 */ +CHAN6G (6875 ),/* Channel 185 */ +CHAN6G (6895 ),/* Channel 189 */ +CHAN6G (6915 ),/* Channel 193 */ +CHAN6G (6935 ),/* Channel 197 */ +CHAN6G (6955 ),/* Channel 201 */ +CHAN6G (6975 ),/* Channel 205 */ +CHAN6G (6995 ),/* Channel 209 */ +CHAN6G (7015 ),/* Channel 213 */ +CHAN6G (7035 ),/* Channel 217 */ +CHAN6G (7055 ),/* Channel 221 */ +CHAN6G (7075 ),/* Channel 225 */ +CHAN6G (7095 ),/* Channel 229 */ +CHAN6G (7115 ),/* Channel 233 */ +}; +#define NUM_S1G_CHANS_US 51static struct ieee80211_channel hwsim_channels_s1g[NUM_S1G_CHANS_US ];
@@ -548,6 +616,7 @@ struct mac80211_hwsim_data {struct ieee80211_supported_band bands[NUM_NL80211_BANDS ];struct ieee80211_channel channels_2ghz[ARRAY_SIZE (hwsim_channels_2ghz)];struct ieee80211_channel channels_5ghz[ARRAY_SIZE (hwsim_channels_5ghz)]; +struct ieee80211_channel channels_6ghz[ARRAY_SIZE (hwsim_channels_6ghz)];struct ieee80211_channel channels_s1g[ARRAY_SIZE (hwsim_channels_s1g)];struct ieee80211_rate rates[ARRAY_SIZE (hwsim_rates)];struct ieee80211_iface_combination if_combination;
@@ -579,7 +648,8 @@ struct mac80211_hwsim_data {struct ieee80211_channel *channel;unsigned long next_start, start, end; } survey_data[ARRAY_SIZE (hwsim_channels_2ghz) + -ARRAY_SIZE (hwsim_channels_5ghz)]; +ARRAY_SIZE (hwsim_channels_5ghz) + +ARRAY_SIZE (hwsim_channels_6ghz)];struct ieee80211_channel *channel;u64 beacon_int/* beacon interval in us */ ;
@@ -3187,6 +3257,8 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, sizeof(hwsim_channels_2ghz));memcpy (data->channels_5ghz, hwsim_channels_5ghz,sizeof (hwsim_channels_5ghz)); +memcpy (data->channels_6ghz, hwsim_channels_6ghz, +sizeof (hwsim_channels_6ghz));memcpy (data->channels_s1g, hwsim_channels_s1g,sizeof (hwsim_channels_s1g));memcpy (data->rates, hwsim_rates,sizeof (hwsim_rates));
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 20/389 wifi: mac80211_hwsim: clamp virtio RX length before skb_put
In reply to Greg Kroah-Hartman5.10-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/mac80211_hwsim.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/wireless/mac80211_hwsim.c +1 -0
@@ -4335,6 +4335,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 21/389 wifi: libertas: fix memory leak in helper_firmware_cb()
In reply to Greg Kroah-Hartman5.10-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 22/389 wifi: p54: validate RX frame length in p54_rx_eeprom_readback()
In reply to Greg Kroah-Hartman5.10-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
@@ -503,11 +503,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 23/389 wifi: cfg80211: validate PMSR measurement type data
In reply to Greg Kroah-Hartman5.10-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
@@ -168,6 +168,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;
@@ -220,6 +221,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);
@@ -229,10 +238,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 24/389 wifi: cfg80211: validate PMSR FTM preamble range
In reply to Greg Kroah-Hartman5.10-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
@@ -280,7 +280,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 25/389 wifi: cfg80211: reject unsupported PMSR FTM location requests
In reply to Greg Kroah-Hartman5.10-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
@@ -116,6 +116,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 =
@@ -124,6 +125,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 26/389 wifi: mac80211: free AP_VLAN bc_buf SKBs outside IRQ lock
In reply to Greg Kroah-Hartman5.10-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
@@ -492,6 +492,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,WARN_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);
@@ -499,10 +500,15 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,if (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 27/389 wifi: brcmfmac: initialize SDIO data work before cleanup
In reply to Greg Kroah-Hartman5.10-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
@@ -4438,6 +4438,7 @@ struct brcmf_sdio *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 ;
@@ -4451,7 +4452,6 @@ struct brcmf_sdio *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 28/389 wifi: cfg80211: bound element ID read when checking non-inheritance
In reply to Greg Kroah-Hartman5.10-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
@@ -240,7 +240,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 29/389 ASoC: meson: aiu: fifo-spdif: soft reset the S/PDIF datapath on start/stop
In reply to Greg Kroah-Hartman5.10-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 30/389 ASoC: tas2562: fix deprecated shut-down GPIO always cleared after lookup
In reply to Greg Kroah-Hartman5.10-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
@@ -720,11 +720,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 31/389 firmware: arm_scmi: Rate-limit queue-full warnings in IRQ context
In reply to Greg Kroah-Hartman5.10-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
@@ -594,9 +594,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 32/389 ipv4: fib: free fib_alias with kfree_rcu() on insert error path
In reply to Greg Kroah-Hartman5.10-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
@@ -1340,7 +1340,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 33/389 net/iucv: take a reference on the socket found in afiucv_hs_rcv()
In reply to Greg Kroah-Hartman5.10-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
@@ -2083,6 +2083,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 ;
@@ -2132,6 +2134,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 34/389 ata: sata_dwc_460ex: enable SATA interrupts only after IRQ handler is registered
In reply to Greg Kroah-Hartman5.10-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
@@ -1246,9 +1246,6 @@ static int sata_dwc_probe(struct platform_device *ofdev)/* Save dev for later use in dev_xxx() routines */ hsdev->dev = &ofdev->dev; -/* Enable SATA Interrupts */ -sata_dwc_enable_interrupts (hsdev); -/* Get SATA interrupt number */ irq =irq_of_parse_and_map (np,0 );if (irq ==NO_IRQ ) {
@@ -1281,6 +1278,8 @@ static int sata_dwc_probe(struct platform_device *ofdev)if (err)dev_err (&ofdev->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 35/389 ata: sata_dwc_460ex: fix clear_interrupt_bit() clearing all pending interrupts
In reply to Greg Kroah-Hartman5.10-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
@@ -443,8 +443,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 36/389 ata: sata_dwc_460ex: remove variable num_processed
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Colin Ian King <[email protected]>
[ Upstream commit de58fd3d80f884f7f322a06bfe08465e49b47c5d ]
Variable num_processed is just being incremented and it's never used anywhere else. The variable and the increment are redundant so remove it.
Stable-dep-of: c2130f6553f4 ("ata: sata_dwc_460ex: fix infinite loop in NCQ tag completion bit-scanning")
--- drivers/ata/sata_dwc_460ex.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/ata/sata_dwc_460ex.c +1 -3
@@ -511,7 +511,7 @@ static irqreturn_t sata_dwc_isr(int irq, void *dev_instance)struct ata_queued_cmd *qc;unsigned long flags;u8 status, tag; -int handled, num_processed, port =0 ; +int handled, port =0 ;uint intpr, sactive, sactive2, tag_mask;struct sata_dwc_device_port *hsdevp; hsdev->sactive_issued =0 ;
@@ -651,9 +651,7 @@ static irqreturn_t sata_dwc_isr(int irq, void *dev_instance)dev_dbg (ap->dev,"%s ATA status register=0x%x\n" , __func__, status); tag =0 ; - num_processed =0 ;while (tag_mask) { - num_processed++;while (!(tag_mask &0x00000001 )) { tag++; tag_mask <<=1 ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 37/389 ata: sata_dwc_460ex: fix infinite loop in NCQ tag completion bit-scanning
In reply to Greg Kroah-Hartman5.10-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
@@ -650,14 +650,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);/* To be picked up by completion functions */
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 38/389 smb/client: handle overlapping allocated ranges in fallocate
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huiwen He <[email protected]>
[ Upstream commit b09ae45d85dc816987a71db9eebc54b0ae288e94 ]
smb3_simple_fallocate_range() can skip holes when an allocated range returned by the server starts before the current fallocate offset. The skipped hole is not zero-filled, but fallocate still returns success. A later write to that hole may therefore fail with ENOSPC.
The function queries allocated ranges so that it can preserve existing contents and write zeroes only into holes. However, the server may return a range that starts before the current fallocate offset.
For example, assume the fallocate request is [100, 400) and the only allocated range returned by the server is [0, 200):
Request: [100, 400)
Server range: [ 0, 200) allocated
Correct:
[100, 200) allocated data, skip
[200, 400) hole, zero-fill
Current:
[100, 300) skipped
[300, 400) zero-filled afterwardsThe current code adds the full server range length, 200, to the current offset 100 and moves to 300. As a result, the hole in [200, 300) is skipped without being zero-filled.
Fix this by advancing only over the part of the allocated range that overlaps the current fallocate offset. Ignore ranges that end before the current offset and reject ranges whose end offset overflows.
This also prevents a malformed range length from causing an out-of-bounds zero-buffer read.
--- fs/cifs/smb2ops.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-)
fs/cifs/smb2ops.c +18 -7
@@ -3553,6 +3553,7 @@ static int smb3_simple_fallocate_range(unsigned int xid,struct file_allocated_range_buffer in_data, *out_data =NULL , *tmp_data;u32 out_data_len;char *buf =NULL ; +u64 range_start, range_len, range_end;loff_t l;int rc;
@@ -3589,13 +3590,21 @@ static int smb3_simple_fallocate_range(unsigned int xid, goto out; } -if (off <le64_to_cpu (tmp_data->file_offset)) { + range_start =le64_to_cpu (tmp_data->file_offset); + range_len =le64_to_cpu (tmp_data->length); +if (check_add_overflow (range_start, range_len, &range_end) || + range_end >S64_MAX ) { + rc = -EINVAL ; + goto out; + } + +if (off < range_start) {/* * We are at a hole. Write until the end of the region * or until the next allocated data, * whichever comes next. */ - l =le64_to_cpu (tmp_data->file_offset) - off; + l = range_start - off;if (len < l) l = len; rc = smb3_simple_fallocate_write_range(xid, tcon,
@@ -3612,11 +3621,13 @@ static int smb3_simple_fallocate_range(unsigned int xid,* until the end of the data or the end of the region * we are supposed to fallocate, whichever comes first. */ - l =le64_to_cpu (tmp_data->length); -if (len < l) - l = len; - off += l; - len -= l; +if (off < range_end) { + l = range_end - off; +if (len < l) + l = len; + off += l; + len -= l; + } tmp_data = &tmp_data[1 ]; out_data_len -=sizeof (struct file_allocated_range_buffer );
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 39/389 drm/i915/gt: use correct selftest config symbol
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pengpeng Hou <[email protected]>
[ Upstream commit a82f1bb8191aec98a971a2196136016ef70c0880 ]
intel_engine_user.c checks CONFIG_DRM_I915_SELFTESTS before running the engine UABI isolation check. Kconfig defines DRM_I915_SELFTEST, without the trailing "S", and the rest of i915 uses CONFIG_DRM_I915_SELFTEST.
Because CONFIG_DRM_I915_SELFTESTS is not backed by any Kconfig symbol, the IS_ENABLED() test is always false. Use the existing selftest symbol so the debug/selftest guarded path can be reached when selftests are enabled.
This is a source-level fix. It does not claim dynamic hardware reproduction; the evidence is the Kconfig definition and the inconsistent guard in intel_engine_user.c.
--- drivers/gpu/drm/i915/gt/intel_engine_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/i915/gt/intel_engine_user.c +1 -1
@@ -232,7 +232,7 @@ void intel_engines_driver_register(struct drm_i915_private *i915) p = &prev->rb_right; } -if (IS_ENABLED (CONFIG_DRM_I915_SELFTESTS ) && +if (IS_ENABLED (CONFIG_DRM_I915_SELFTEST ) &&IS_ENABLED (CONFIG_DRM_I915_DEBUG_GEM )) {struct intel_engine_cs *engine;unsigned int isolation;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 40/389 can: j1939: fix lockless local-destination check
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shuhao Fu <[email protected]>
[ Upstream commit e4e8af62adab2fdcca230006f829407a953070cd ]
j1939_priv.ents[].nusers is documented as protected by priv->lock, and its updates already happen under that lock. j1939_can_recv() also reads it under read_lock_bh(). However, j1939_session_skb_queue() and j1939_tp_send() still read priv->ents[da].nusers without taking the lock.
Those transport-side checks decide whether to set J1939_ECU_LOCAL_DST, so they can race with j1939_local_ecu_get() and j1939_local_ecu_put() while userspace is binding or releasing sockets concurrently with TP traffic. This can misclassify TP/ETP sessions as local or remote and take the wrong transport path.
Fix both transport paths by routing the destination-locality check through a helper that reads ents[].nusers under read_lock_bh(&priv->lock).
--- net/can/j1939/transport.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
net/can/j1939/transport.c +14 -4
@@ -346,6 +346,18 @@ static void j1939_session_skb_drop_old(struct j1939_session *session) } } +static bool j1939_address_is_local (struct j1939_priv *priv,u8 addr) +{ +bool local = false; + +read_lock_bh (&priv->lock); +if (j1939_address_is_unicast (addr) && priv->ents[addr].nusers) + local = true; +read_unlock_bh (&priv->lock); + +return local; +} +void j1939_session_skb_queue (struct j1939_session *session,struct sk_buff *skb) {
@@ -354,8 +366,7 @@ void j1939_session_skb_queue(struct j1939_session *session,j1939_ac_fixup (priv, skb); -if (j1939_address_is_unicast (skcb->addr.da) && - priv->ents[skcb->addr.da].nusers) +if (j1939_address_is_local (priv, skcb->addr.da)) skcb->flags |=J1939_ECU_LOCAL_DST ; skcb->flags |=J1939_ECU_LOCAL_SRC ;
@@ -1998,8 +2009,7 @@ struct j1939_session *j1939_tp_send(struct j1939_priv *priv,return ERR_PTR (ret);/* fix DST flags, it may be used there soon */ -if (j1939_address_is_unicast (skcb->addr.da) && - priv->ents[skcb->addr.da].nusers) +if (j1939_address_is_local (priv, skcb->addr.da)) skcb->flags |=J1939_ECU_LOCAL_DST ;/* src is always local, I'm sending ... */
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 41/389 drm/i915/selftests: Fix GT PM sort comparators
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Emre Cecanpunar <[email protected]>
[ Upstream commit 612978b83f45bf7018815209db5395d759db6f26 ]
Compare the sampled clock values instead of their addresses. Comparing addresses leaves the samples unsorted, preventing the code from discarding the minimum and maximum samples.
--- drivers/gpu/drm/i915/gt/selftest_gt_pm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/gpu/drm/i915/gt/selftest_gt_pm.c +4 -4
@@ -17,9 +17,9 @@ static int cmp_u64(const void *A, const void *B) {const u64 *a =A , *b =B ; -if (a < b) +if (*a < *b)return -1 ; -else if (a > b) +else if (*a > *b)return 1 ;else return 0 ;
@@ -29,9 +29,9 @@ static int cmp_u32(const void *A, const void *B) {const u32 *a =A , *b =B ; -if (a < b) +if (*a < *b)return -1 ; -else if (a > b) +else if (*a > *b)return 1 ;else return 0 ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 42/389 net/sched: act_tunnel_key: Defer dst_release to RCU callback
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jamal Hadi Salim <[email protected]>
[ Upstream commit f1f5c8a3955f8fda3f84ed883ac8daa1847e724c ]
Fix a race-condition use-after-free in tunnel_key_release_params().
The function releases the metadata_dst of the old params synchronously via dst_release() while deferring the params struct free with kfree_rcu(). A concurrent tunnel_key_act() reader on the datapath may still hold the old params pointer (under rcu_read_lock_bh) and proceed to call dst_clone(¶ms->tcft_enc_metadata->dst) after the writer's dst_release has already pushed the dst's rcuref to RCUREF_DEAD.
[email protected] produced a poc which i (and Victor) verified that KASAN reports:
==================================================================
BUG: KASAN: slab-use-after-free in instrument_atomic_read_write include/linux/instrumented.h:112 BUG: KASAN: slab-use-after-free in atomic_sub_return_release include/linux/atomic/atomic-instrumented.h:326 BUG: KASAN: slab-use-after-free in __rcuref_put include/linux/rcuref.h:109 BUG: KASAN: slab-use-after-free in rcuref_put include/linux/rcuref.h:173 BUG: KASAN: slab-use-after-free in dst_release+0x5b/0x370 net/core/dst.c:168 Write of size 4 at addr ffff88806158de40 by task poc/9388 CPU: 0 UID: 0 PID: 9388 Comm: poc Tainted: G W 7.1.0-rc7 #7 PREEMPT(lazy) Tainted: [W]=WARN Hardware name: QEMU Ubuntu 25.10 PC v2 (i440FX + PIIX, + 10.1 machine, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 Call Trace: <TASK> __dump_stack lib/dump_stack.c:94 dump_stack_lvl+0x100/0x190 lib/dump_stack.c:120 print_address_description mm/kasan/report.c:378 print_report+0x139/0x4ad mm/kasan/report.c:482 kasan_report+0xe4/0x1d0 mm/kasan/report.c:595 check_region_inline mm/kasan/generic.c:186 kasan_check_range+0x125/0x200 mm/kasan/generic.c:200 instrument_atomic_read_write include/linux/instrumented.h:112 atomic_sub_return_release include/linux/atomic/atomic-instrumented.h:326 __rcuref_put include/linux/rcuref.h:109 rcuref_put include/linux/rcuref.h:173 dst_release+0x5b/0x370 net/core/dst.c:168 refdst_drop include/net/dst.h:272 skb_dst_drop include/net/dst.h:284 skb_release_head_state+0x293/0x400 net/core/skbuff.c:1163 skb_release_all net/core/skbuff.c:1187 [..] Allocated by task 9391: kasan_save_stack+0x30/0x50 mm/kasan/common.c:57 kasan_save_track+0x14/0x30 mm/kasan/common.c:78 poison_kmalloc_redzone mm/kasan/common.c:398 __kasan_kmalloc+0x9a/0xb0 mm/kasan/common.c:415 kasan_kmalloc include/linux/kasan.h:263 __do_kmalloc_node mm/slub.c:5296 __kmalloc_noprof+0x2f1/0x830 mm/slub.c:5308 kmalloc_noprof include/linux/slab.h:954 kzalloc_noprof include/linux/slab.h:1188 offload_action_alloc+0x2f/0x130 net/core/flow_offload.c:35 tcf_action_offload_add_ex+0x1ba/0x880 net/sched/act_api.c:258 tcf_action_offload_add net/sched/act_api.c:293 tcf_action_init+0x66e/0xa20 net/sched/act_api.c:1547 tcf_action_add+0xf6/0x5d0 net/sched/act_api.c:2101 [..] Freed by task 9391: kasan_save_stack+0x30/0x50 mm/kasan/common.c:57 kasan_save_track+0x14/0x30 mm/kasan/common.c:78 kasan_save_free_info+0x3b/0x70 mm/kasan/generic.c:584 poison_slab_object mm/kasan/common.c:253 __kasan_slab_free+0x6b/0x90 mm/kasan/common.c:285 kasan_slab_free include/linux/kasan.h:235 slab_free_hook mm/slub.c:2689 slab_free mm/slub.c:6251 kfree+0x21f/0x6b0 mm/slub.c:6566 tcf_action_offload_add_ex+0x4ad/0x880 net/sched/act_api.c:284 tcf_action_offload_add net/sched/act_api.c:293 tcf_action_init+0x66e/0xa20 net/sched/act_api.c:1547 tcf_action_add+0xf6/0x5d0 net/sched/act_api.c:2101 The buggy address belongs to the object at ffff88806158de00 which belongs to the cache kmalloc-256 of size 256
The buggy address is located 64 bytes inside of
freed 256-byte region [ffff88806158de00, ffff88806158df00)
The buggy address belongs to the physical page: page: refcount:0 mapcount:0 mapping:0000000000000000 index:0xffff88806158d600 pfn:0x6158c head: order:1 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0 flags: 0x4fff00000000240(workingset|head|node=1|zone=1|lastcpupid=0x7ff) page_type: f5(slab) raw: 04fff00000000240 ffff88801c841b40 ffffea0001856290 ffffea0001856190 raw: ffff88806158d600 0000000800100009 00000000f5000000 0000000000000000
head: 04fff00000000240 ffff88801c841b40 ffffea0001856290 ffffea0001856190
head: ffff88806158d600 0000000800100009 00000000f5000000 0000000000000000
head: 04fff00000000001 ffffffffffffff81 00000000ffffffff 00000000ffffffff
head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000002
page dumped because: kasan: bad access detected page_owner tracks the page as allocated page last allocated via order 1, migratetype Unmovable, gfp_mask 0xd2820(GFP_ATOMIC|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC), pid 9391, tgid 9378 (poc), ts 123227323196, free_ts 0 set_page_owner include/linux/page_owner.h:32 post_alloc_hook+0xfe/0x140 mm/page_alloc.c:1853 prep_new_page mm/page_alloc.c:1861 get_page_from_freelist+0x110c/0x2fc0 mm/page_alloc.c:3941 __alloc_frozen_pages_noprof+0x263/0x2bc0 mm/page_alloc.c:5221 alloc_slab_page mm/slub.c:3278 allocate_slab mm/slub.c:3467 new_slab+0xa6/0x690 mm/slub.c:3525 refill_objects+0x271/0x420 mm/slub.c:7272 refill_sheaf mm/slub.c:2816 __pcs_replace_empty_main+0x373/0x630 mm/slub.c:4652 alloc_from_pcs mm/slub.c:4750 slab_alloc_node mm/slub.c:4884 __do_kmalloc_node mm/slub.c:5295 __kmalloc_noprof+0x66d/0x830 mm/slub.c:5308 kmalloc_noprof include/linux/slab.h:954 metadata_dst_alloc+0x26/0x90 net/core/dst.c:298 tun_rx_dst include/net/dst_metadata.h:144 __ip_tun_set_dst include/net/dst_metadata.h:208 tunnel_key_init+0xb01/0x1b90 net/sched/act_tunnel_key.c:451 tcf_action_init_1+0x46b/0x6c0 net/sched/act_api.c:1428 tcf_action_init+0x448/0xa20 net/sched/act_api.c:1503 tcf_action_add+0xf6/0x5d0 net/sched/act_api.c:2101
[..]
==================================================================
Fix by moving dst_release() into a custom RCU callback that runs after the grace period, matching the lifetime of the containing params struct. Readers in the datapath therefore always find a live rcuref when calling dst_clone().
--- net/sched/act_tunnel_key.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
net/sched/act_tunnel_key.c +10 -4
@@ -343,14 +343,20 @@ static const struct nla_policy tunnel_key_policy[TCA_TUNNEL_KEY_MAX + 1] = { [TCA_TUNNEL_KEY_ENC_TTL] = { .type = NLA_U8 }, }; -static void tunnel_key_release_params (struct tcf_tunnel_key_params *p) +static void tunnel_key_release_params_rcu (struct rcu_head *head) { -if (!p) -return ; +struct tcf_tunnel_key_params *p =container_of (head,typeof (*p), rcu); +if (p->tcft_action ==TCA_TUNNEL_KEY_ACT_SET )dst_release (&p->tcft_enc_metadata->dst); +kfree (p); +} -kfree_rcu (p, rcu); +static void tunnel_key_release_params (struct tcf_tunnel_key_params *p) +{ +if (!p) +return ; +call_rcu (&p->rcu, tunnel_key_release_params_rcu); } static int tunnel_key_init(struct net *net, struct nlattr *nla,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 43/389 sctp: fix auth_hmacs array size in struct sctp_cookie
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xin Long <[email protected]>
[ Upstream commit e0b5252a59383b77d1b8dbeda00b7184dd95f4d3 ]
The auth_hmacs array in struct sctp_cookie is supposed to store a complete SCTP_AUTH_HMAC_ALGO parameter, which consists of a struct sctp_paramhdr followed by N HMAC identifiers.
However, the array size was calculated using an extra 2 bytes instead of sizeof(struct sctp_paramhdr), which is 4 bytes. When four HMAC identifiers are configured, the HMAC-ALGO parameter stored in the endpoint is larger than the auth_hmacs buffer in the cookie.
As a result, sctp_association_init() copies beyond the end of auth_hmacs when initializing the association, corrupting the adjacent auth_chunks field. This can lead to an invalid HMAC identifier being accepted and later cause an out-of-bounds read in sctp_auth_get_hmac().
Fix the array size calculation by including the full SCTP parameter header size.
--- include/net/sctp/structs.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
include/net/sctp/structs.h +2 -1
@@ -318,7 +318,8 @@ struct sctp_cookie {__u8 auth_random[sizeof (struct sctp_paramhdr ) +SCTP_AUTH_RANDOM_LENGTH ]; -__u8 auth_hmacs[SCTP_AUTH_NUM_HMACS *sizeof (__u16) +2 ]; +__u8 auth_hmacs[sizeof (struct sctp_paramhdr ) + +SCTP_AUTH_NUM_HMACS *sizeof (__u16)];__u8 auth_chunks[sizeof (struct sctp_paramhdr ) +SCTP_AUTH_MAX_CHUNKS ];/* This is a shim for my peer's INIT packet, followed by
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 44/389 mpls: fix NULL deref in mpls_valid_fib_dump_req() on CONFIG_INET=n
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weiming Shi <[email protected]>
[ Upstream commit 56d96fededd61192cd7cc8d2b0f36adfd59036c3 ]
On CONFIG_INET=n builds, mpls_valid_fib_dump_req() walks the parsed attribute table itself instead of calling ip_valid_fib_dump_req(). The RTA_OIF arm passes tb[RTA_OIF] to nla_get_u32() without checking it is present, so an RTM_GETROUTE dump for AF_MPLS with strict checking and no RTA_OIF hits a NULL dereference.
RTM_GETROUTE is RTNL_KIND_GET, which rtnetlink_rcv_msg() permits without CAP_NET_ADMIN, so an unprivileged user can trigger it.
Oops: general protection fault, probably for non-canonical address
0xdffffc0000000000: 0000 [#1] SMP KASAN NOPTI
KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
RIP: 0010:mpls_valid_fib_dump_req (net/mpls/af_mpls.c:2189)
Call Trace:
mpls_dump_routes (net/mpls/af_mpls.c:2236)
netlink_dump (net/netlink/af_netlink.c:2331)
__netlink_dump_start (net/netlink/af_netlink.c:2446)
rtnetlink_rcv_msg (net/core/rtnetlink.c:7033)
netlink_rcv_skb (net/netlink/af_netlink.c:2556)
netlink_unicast (net/netlink/af_netlink.c:1345)
netlink_sendmsg (net/netlink/af_netlink.c:1900)
__sock_sendmsg (net/socket.c:790)
____sys_sendmsg (net/socket.c:2684)
___sys_sendmsg (net/socket.c:2738)
__sys_sendmsg (net/socket.c:2770)
do_syscall_64 (arch/x86/entry/syscall_64.c:94)
entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)Skip unset attributes, as ip_valid_fib_dump_req() does.
--- net/mpls/af_mpls.c | 3 +++ 1 file changed, 3 insertions(+)
net/mpls/af_mpls.c +3 -0
@@ -2144,6 +2144,9 @@ static int mpls_valid_fib_dump_req(struct net *net, const struct nlmsghdr *nlh,int ifindex;if (i ==RTA_OIF ) { +if (!tb[i]) +continue ; + ifindex =nla_get_u32 (tb[i]); filter->dev =__dev_get_by_index (net, ifindex);if (!filter->dev)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 45/389 wifi: at76c50x-usb: avoid length underflow in at76_guess_freq()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huihui Huang <[email protected]>
commit 61a799ffd1e5a4fd3702d547828b7ff3d161468e upstream.
at76_guess_freq() checks only that the received frame is at least a bare 802.11 header (24 bytes) before subtracting the fixed management-body offset:
len -= el_off;
For both beacon and probe response frames, el_off is 36. If the frame is shorter than el_off, subtracting it causes the calculated IE length to wrap. The length is eventually passed to cfg80211_find_elem_match() as a very large unsigned value, so the element walk runs beyond the RX skb.
This path is reached from at76_rx_tasklet() while scanning. If the device delivers a truncated beacon or probe response, the oversized IE length causes an out-of-bounds read during scanning.
Skip the IE lookup if the frame does not reach the variable elements, before subtracting el_off.
--- drivers/net/wireless/atmel/at76c50x-usb.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/net/wireless/atmel/at76c50x-usb.c +5 -2
@@ -1527,13 +1527,16 @@ static inline int at76_guess_freq(structif (ieee80211_is_probe_resp (hdr->frame_control)) { el_off = offsetof(struct ieee80211_mgmt, u.probe_resp.variable); - el = ((struct ieee80211_mgmt *)hdr)->u.probe_resp.variable; }else if (ieee80211_is_beacon (hdr->frame_control)) { el_off = offsetof(struct ieee80211_mgmt, u.beacon.variable); - el = ((struct ieee80211_mgmt *)hdr)->u.beacon.variable; }else { goto exit; } + +if (len < el_off) + goto exit; + + el = priv->rx_skb->data + el_off; len -= el_off; el =cfg80211_find_ie (WLAN_EID_DS_PARAMS , el, len);
Greg Kroah-Hartman
maintainerPATCH 46/389 USB: storage: add NO_ATA_1X quirk for Longmai USB Key
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huang Wei <[email protected]>
commit 3b4ca2e01c1dd8c00b675b794732945f460a471b upstream.
The Longmai Technologies USB Key (0x04b4:0xb708) advertises itself as a SCSI/Bulk-only mass storage device but does not correctly handle ATA pass-through commands. When such a command (ATA_12 or ATA_16) is sent to the device it fails to respond and the transfer eventually times out, leaving the device unusable.
Add an unusual_devs entry for this device that sets the US_FL_NO_ATA_1X flag, so usb-storage short-circuits ATA pass-through commands and returns INVALID COMMAND OPERATION CODE (0x20 0x05 0x24 0x00) instead of forwarding them to the device.
Information about the device in /sys/kernel/debug/usb/devices:
T: Bus=02 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 12 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=06 Prot=50 MxPS=64 #Cfgs= 1 P: Vendor=04b4 ProdID=b708 Rev= 1.00 S: Manufacturer=Longmai Technologies S: Product=USB Key C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=100mA I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
--- drivers/usb/storage/unusual_devs.h | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/usb/storage/unusual_devs.h +7 -0
@@ -395,6 +395,13 @@ UNUSUAL_DEV( 0x04b3, 0x4001, 0x0110, 0x USB_SC_DEVICE, USB_PR_CB, NULL, US_FL_MAX_SECTORS_MIN), +/* Reported by Ai Chao <[email protected]> */ +UNUSUAL_DEV (0x04b4 ,0xb708 ,0x0000 ,0xffff , +"Longmai Technologies" , +"USB Key" , +USB_SC_SCSI ,USB_PR_BULK ,NULL , + US_FL_NO_ATA_1X), +/* * Reported by Simon Levitt <[email protected]> * This entry needs Sub and Proto fields
Greg Kroah-Hartman
maintainerPATCH 47/389 usb: chipidea: fix usage_count leak when autosuspend_delay is negative
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xu Yang <[email protected]>
commit fc3afb5728e297994863f8a2a01b88a920bbf53e upstream.
The probe() calls pm_runtime_use_autosuspend(), but remove() does not call pm_runtime_dont_use_autosuspend(). This can lead to a usage_count leak if autosuspend_delay is set to a negative value.
The pm_runtime_use_autosuspend() also notes that it's important to undo this with pm_runtime_dont_use_autosuspend() at driver exit time.
--- drivers/usb/chipidea/core.c | 1 + 1 file changed, 1 insertion(+)
drivers/usb/chipidea/core.c +1 -0
@@ -1238,6 +1238,7 @@ static int ci_hdrc_remove(struct platforusb_role_switch_unregister (ci->role_switch);if (ci->supports_runtime_pm) { +pm_runtime_dont_use_autosuspend (&pdev->dev);pm_runtime_get_sync (&pdev->dev);pm_runtime_disable (&pdev->dev);pm_runtime_put_noidle (&pdev->dev);
Greg Kroah-Hartman
maintainerPATCH 48/389 usb: gadget: dummy_hcd: prevent fifo_req reuse during giveback
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinchao Wang <[email protected]>
commit d5e5cd3654d2b5359a12ea6586120f05b28634ee upstream.
dummy_hcd embeds a single shared usb_request (dum->fifo_req) that the "emulated single-request FIFO" fast-path in dummy_queue() reuses for small IN transfers: it copies the caller's request into it (req->req = *_req) and queues it, treating list_empty(&fifo_req.queue) as "the slot is free".
The completion side (dummy_timer/transfer/nuke/dummy_dequeue) follows the standard pattern: list_del_init(&req->queue) unlinks the request, then the lock is dropped and usb_gadget_giveback_request() invokes req->complete(). But list_del_init() makes fifo_req.queue look empty *before* the completion callback returns, so a concurrent dummy_queue() on another CPU sees the slot as free, reuses fifo_req and runs req->req = *_req -- overwriting req->complete while dummy_timer is mid-calling it. The indirect call then jumps to a clobbered pointer, causing a general protection fault / page fault in dummy_timer (syzkaller extid faf3a6cf579fc65591ca). The clobbering write is an in-bounds memcpy on a live shared object, so KASAN cannot flag it.
Add a fifo_req_busy bit covering the shared request's whole lifetime:
set it in dummy_queue() when the FIFO fast-path takes fifo_req (making it the fast-path guard, replacing the list_empty(&fifo_req.queue) test), and clear it after the completion callback has returned, via a dummy_giveback() helper used at all four gadget-request giveback sites. The shared slot can no longer be reused until its completion callback has finished.
--- drivers/usb/gadget/udc/dummy_hcd.c | 40 ++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-)
drivers/usb/gadget/udc/dummy_hcd.c +27 -13
@@ -274,6 +274,7 @@ struct dummy { unsigned ints_enabled:1; unsigned udc_suspended:1; unsigned pullup:1; + unsigned fifo_req_busy:1;/* * HOST side support
@@ -325,6 +326,26 @@ static inline struct dummy *gadget_dev_t/* DEVICE/GADGET SIDE UTILITY ROUTINES */ +/* +* Give back a gadget request with dum->lock dropped around the callback. +* If @req is the shared fifo_req, clear fifo_req_busy afterward: the flag +* was set in dummy_queue() when the shared request was taken and must stay +* set until its completion callback has returned; list_del_init() alone +* makes the request look idle while the callback is still running. +* Caller holds dum->lock and has already done list_del_init() + status. +*/ +static void dummy_giveback (struct dummy *dum,struct usb_ep *_ep, +struct dummy_request *req) +{ +bool fifo = req == &dum->fifo_req; + +spin_unlock (&dum->lock); +usb_gadget_giveback_request (_ep, &req->req); +spin_lock (&dum->lock); +if (fifo) + dum->fifo_req_busy =0 ; +} +/* called with spinlock held */ static void nuke (struct dummy *dum,struct dummy_ep *ep) {
@@ -335,9 +356,7 @@ static void nuke(struct dummy *dum, strulist_del_init (&req->queue); req->req.status = -ESHUTDOWN ; -spin_unlock (&dum->lock); -usb_gadget_giveback_request (&ep->ep, &req->req); -spin_lock (&dum->lock); +dummy_giveback (dum, &ep->ep, req); } }
@@ -722,10 +741,11 @@ static int dummy_queue(struct usb_ep *_e/* implement an emulated single-request FIFO */ if (ep->desc && (ep->desc->bEndpointAddress &USB_DIR_IN ) && -list_empty (&dum->fifo_req.queue) && + !dum->fifo_req_busy &&list_empty (&ep->queue) && _req->length <=FIFO_SIZE ) { req = &dum->fifo_req; + dum->fifo_req_busy =1 ; req->req = *_req; req->req.buf = dum->fifo_buf;memcpy (dum->fifo_buf, _req->buf, _req->length);
@@ -779,9 +799,7 @@ static int dummy_dequeue(struct usb_ep *dev_dbg (udc_dev (dum),"dequeued req %p from %s, len %d buf %p\n" , req, _ep->name, _req->length, _req->buf); -spin_unlock (&dum->lock); -usb_gadget_giveback_request (_ep, _req); -spin_lock (&dum->lock); +dummy_giveback (dum, _ep, req); }spin_unlock_irqrestore (&dum->lock, flags);return retval;
@@ -1506,9 +1524,7 @@ top:if (req->req.status != -EINPROGRESS ) {list_del_init (&req->queue); -spin_unlock (&dum->lock); -usb_gadget_giveback_request (&ep->ep, &req->req); -spin_lock (&dum->lock); +dummy_giveback (dum, &ep->ep, req);/* requests might have been unlinked... */ rescan =1 ;
@@ -1891,9 +1907,7 @@ restart:dev_dbg (udc_dev (dum),"stale req = %p\n" , req); -spin_unlock (&dum->lock); -usb_gadget_giveback_request (&ep->ep, &req->req); -spin_lock (&dum->lock); +dummy_giveback (dum, &ep->ep, req); ep->already_seen =0 ; goto restart; }
Greg Kroah-Hartman
maintainerPATCH 49/389 usb: gadget: f_midi: cancel pending IN work before freeing the midi object
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fan Wu <[email protected]>
commit 5650c18d93a1db7e27cb5a40b394747eb4686d5b upstream.
The f_midi driver embeds a work item (midi->work) whose handler, f_midi_in_work(), dereferences the enclosing struct f_midi through container_of(). This work is armed from two sites: f_midi_complete(), on a normal IN-endpoint completion, and f_midi_in_trigger(), on an ALSA rawmidi output-stream start.
Neither f_midi_disable() nor f_midi_unbind() cancels midi->work. f_midi_disable() only disables the endpoints and drains the in_req_fifo; it does not synchronize the work item, and the sound card is released asynchronously to the final free of the midi object.
The midi object is reference-counted (midi->free_ref) and is freed in f_midi_free() only once both the usb_function reference and the rawmidi private_data reference have been dropped. In f_midi_unbind(), f_midi_disable() runs before the sound card is released, so while the USB endpoints are already disabled the rawmidi device is still usable by an open substream. A concurrent userspace write on such a substream can reach f_midi_in_trigger() and queue midi->work again after f_midi_disable() has returned. A work item armed this way may still be pending when the last reference drops and f_midi_free() proceeds to kfree(midi), letting f_midi_in_work() dereference the struct after it has been freed, a use-after-free.
For this reason cancelling midi->work in f_midi_disable() would not be
sufficient: the ALSA trigger path can rearm the work after disable() returns. Cancelling at the refcount-zero free site is the boundary after which neither arming source can survive, because by then both references that keep the midi object alive have been dropped: the USB endpoints are already disabled and the rawmidi device has been released.
Fix this by calling cancel_work_sync(&midi->work) in the refcount-zero block of f_midi_free(), before the embedded work_struct is freed along with the rest of the structure. opts->lock is a sleeping mutex, so calling cancel_work_sync() under it is permitted, and the handler takes midi->transmit_lock rather than opts->lock, so no self-deadlock can occur while it waits for a running instance of the work to finish.
This issue was found by an in-house static analysis tool.
--- drivers/usb/gadget/function/f_midi.c | 1 + 1 file changed, 1 insertion(+)
drivers/usb/gadget/function/f_midi.c +1 -0
@@ -1258,6 +1258,7 @@ static void f_midi_free(struct usb_funct opts = container_of(f->fi, struct f_midi_opts, func_inst);mutex_lock (&opts->lock);if (!--midi->free_ref) { +cancel_work_sync (&midi->work);kfree (midi->id);kfifo_free (&midi->in_req_fifo);kfree (midi);
Greg Kroah-Hartman
maintainerPATCH 50/389 usb: gadget: printer: fix infinite loop in printer_read()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Melbin K Mathew <[email protected]>
commit c2e819be6a5c7f34344926b4bd7e3dfca58cf48a upstream.
printer_read() uses the same variable for the requested copy size and the number of bytes actually copied to user space. copy_to_user() returns the number of bytes not copied, so when it fails to copy anything, the computed copied length becomes zero.
In that case len, buf, current_rx_bytes and current_rx_buf are left unchanged. If RX data is available and the user buffer remains unwritable, the read loop can repeat indefinitely.
Track the copied length separately and return -EFAULT, or the number of bytes already copied, if an iteration makes no progress.
--- drivers/usb/gadget/function/f_printer.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-)
drivers/usb/gadget/function/f_printer.c +18 -5
@@ -426,7 +426,7 @@ printer_read(struct file *fd, char __use {struct printer_dev *dev = fd->private_data;unsigned long flags; -size_t size; +size_t size, not_copied, copied;size_t bytes_copied;struct usb_request *req;/* This is a pointer to the current USB rx request. */
@@ -519,10 +519,12 @@ printer_read(struct file *fd, char __useelse size = len; - size -=copy_to_user (buf, current_rx_buf, size); - bytes_copied += size; - len -= size; - buf += size; + not_copied =copy_to_user (buf, current_rx_buf, size); + copied = size - not_copied; + + bytes_copied += copied; + len -= copied; + buf += copied;spin_lock_irqsave (&dev->lock, flags);
@@ -537,6 +539,17 @@ printer_read(struct file *fd, char __useif (dev->interface <0 ) goto out_disabled; +if (!copied) { + dev->current_rx_req = current_rx_req; + dev->current_rx_bytes = current_rx_bytes; + dev->current_rx_buf = current_rx_buf; +spin_unlock_irqrestore (&dev->lock, flags); +mutex_unlock (&dev->lock_printer_io); +return bytes_copied ? bytes_copied : -EFAULT ; + } + + size = copied; +/* If we not returning all the data left in this RX request * buffer then adjust the amount of data left in the buffer. * Othewise if we are done with this RX request buffer then
Greg Kroah-Hartman
maintainerPATCH 51/389 USB: gadget: snps-udc: fix device name leak on probe failure
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit 29a142d3e8b35ebc9e0bcc78f4bc26c9b6a9ac0b upstream.
The gadget device name is set by UDC core when registering the gadget and must not be set before to avoid leaking the name in intermediate error paths (e.g. when detecting an older chip revision).
--- drivers/usb/gadget/udc/snps_udc_core.c | 1 - 1 file changed, 1 deletion(-)
drivers/usb/gadget/udc/snps_udc_core.c +0 -1
@@ -3158,7 +3158,6 @@ int udc_probe(struct udc *dev)/* device struct setup */ dev->gadget.ops = &udc_ops; -dev_set_name (&dev->gadget.dev,"gadget" ); dev->gadget.name = name; dev->gadget.max_speed =USB_SPEED_HIGH ;
Greg Kroah-Hartman
maintainerPATCH 52/389 USB: gadget: fsl-udc: fix device name leak on probe failure
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit 6b874d00c466e73c6448a89856407fe46b2f50e4 upstream.
The gadget device name is set by UDC core when registering the gadget and must not be set before to avoid leaking the name in intermediate error paths (e.g. on dma pool creation failure).
--- drivers/usb/gadget/udc/fsl_udc_core.c | 1 - 1 file changed, 1 deletion(-)
drivers/usb/gadget/udc/fsl_udc_core.c +0 -1
@@ -2480,7 +2480,6 @@ static int fsl_udc_probe(struct platform udc_controller->gadget.name = driver_name;/* Setup gadget.dev and register with kernel */ -dev_set_name (&udc_controller->gadget.dev,"gadget" ); udc_controller->gadget.dev.of_node = pdev->dev.of_node;if (!IS_ERR_OR_NULL (udc_controller->transceiver))
Greg Kroah-Hartman
maintainerPATCH 53/389 usb: gadget: f_ncm: validate datagram bounds in ncm_unwrap_ntb()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sonali Pradhan <[email protected]>
commit 1febec7e47cdcd01f43fb0211094e3010474666e upstream.
When unpacking host-supplied NTBs, ncm_unwrap_ntb() checks datagram length against frame_max but does not verify that the datagram fits within the declared block length. Additionally, when decoding multiple NTBs from a single socket buffer, subsequent block lengths are not checked against the actual remaining buffer data.
With these checks missing, a malicious USB host can specify datagram offsets and lengths that point beyond the block, or supply secondary NTB headers declaring lengths larger than the buffer. skb_put_data() then copies adjacent kernel memory from skb_shared_info into the network skb.
Fix this by verifying that sufficient buffer space remains for the NTB header before parsing, handling zero-length block declarations, ensuring that block lengths never exceed the remaining buffer space, and verifying that each datagram payload stays strictly within the block boundary.
--- drivers/usb/gadget/function/f_ncm.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-)
drivers/usb/gadget/function/f_ncm.c +13 -4
@@ -1197,6 +1197,10 @@ static int ncm_unwrap_ntb(struct getherint to_process = skb->len; parse_ntb: +if (to_process < (int )opts->nth_size) { +INFO (port->func.config->cdev,"Packet too small for headers\n" ); + goto err; + } tmp = (__le16 *)ntb_ptr;/* dwSignature */
@@ -1217,8 +1221,12 @@ parse_ntb: tmp++;/* skip wSequence */ block_len =get_ncm (&tmp, opts->block_length); +if (block_len ==0 ) + block_len = to_process; +/* (d)wBlockLength */ -if ((block_len < opts->nth_size + opts->ndp_size) || (block_len > ntb_max)) { +if ((block_len < opts->nth_size + opts->ndp_size) || (block_len > ntb_max) || + (block_len > to_process)) {INFO (port->func.config->cdev,"Bad block length: %#X\n" , block_len); goto err; }
@@ -1281,7 +1289,7 @@ parse_ntb: index = index2;/* wDatagramIndex[0] */ if ((index < opts->nth_size) || - (index > block_len - opts->dpe_size)) { + (index > block_len)) {INFO (port->func.config->cdev,"Bad index: %#X\n" , index); goto err;
@@ -1293,7 +1301,8 @@ parse_ntb:* ethernet hdr + crc or larger than max frame size */ if ((dg_len <14 + crc_len) || - (dg_len > frame_max)) { + (dg_len > frame_max) || + (dg_len > block_len - index)) {INFO (port->func.config->cdev,"Bad dgram length: %#X\n" , dg_len); goto err;
@@ -1318,7 +1327,7 @@ parse_ntb: dg_len2 =get_ncm (&tmp, opts->dgram_item_len);/* wDatagramIndex[1] */ -if (index2 > block_len - opts->dpe_size) { +if (index2 > block_len) {INFO (port->func.config->cdev,"Bad index: %#X\n" , index2); goto err;
Greg Kroah-Hartman
maintainerPATCH 54/389 usb: gadget: uvc: clamp SEND_RESPONSE length to the response buffer
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Muhammad Bilal <[email protected]>
commit b70dc75e85ba968b7b76eebfe5d63000080b875b upstream.
uvc_send_response() builds the UVC control response from a user-supplied struct uvc_request_data:
req->length = min_t(unsigned int, uvc->event_length, data->length); ... memcpy(req->buf, data->data, req->length);
req->length is clamped to uvc->event_length, which is taken from the host control request wLength (up to UVC_MAX_REQUEST_SIZE, 64), and to data->length, which comes from the UVCIOC_SEND_RESPONSE ioctl and is only checked for being negative. The source buffer data->data is only 60 bytes, so a response with uvc->event_length and data->length both greater than 60 makes memcpy() read past the end of data->data.
Clamp req->length to sizeof(data->data) as well.
--- drivers/usb/gadget/function/uvc_v4l2.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/usb/gadget/function/uvc_v4l2.c +2 -0
@@ -39,6 +39,8 @@ uvc_send_response(struct uvc_device *uvcreturn usb_ep_set_halt (cdev->gadget->ep0); req->length = min_t(unsigned int, uvc->event_length, data->length); +if (req->length >sizeof (data->data)) + req->length =sizeof (data->data); req->zero = data->length < uvc->event_length;memcpy (req->buf, data->data, req->length);
Greg Kroah-Hartman
maintainerPATCH 55/389 USB: serial: ftdi_sio: add support for E+H FXA291
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tim Pambor <[email protected]>
commit fad0fd120e29041b3e6cdf41bb12e3184fb524a2 upstream.
The Commubox FXA291 by Endress+Hauser AG is a USB serial converter based on FT232B which is used to communicate with field devices.
It enumerates using the FTDI vendor ID and a custom PID.
usb 1-9: New USB device found, idVendor=0403, idProduct=e510, bcdDevice= 4.00 usb 1-9: New USB device strings: Mfr=1, Product=2, SerialNumber=0 usb 1-9: Product: FXA291
usb 1-9: Manufacturer: Endress+Hauser
usb 1-9: SerialNumber: 00000000ftdi_sio 1-9:1.0: FTDI USB Serial Device converter detected
usb 1-9: Detected FT232B
usb 1-9: FTDI USB Serial Device converter now attached to ttyUSB0
--- drivers/usb/serial/ftdi_sio.c | 2 ++ drivers/usb/serial/ftdi_sio_ids.h | 5 +++++ 2 files changed, 7 insertions(+)
drivers/usb/serial/ftdi_sio.c +2 -0
@@ -1053,6 +1053,8 @@ static const struct usb_device_id id_tab { USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_602E_PID, 3) },/* Abacus Electrics */ { USB_DEVICE(FTDI_VID, ABACUS_OPTICAL_PROBE_PID) }, +/* Endress+Hauser AG devices */ + { USB_DEVICE(FTDI_VID, FTDI_EH_FXA291_PID) }, { } /* Terminating entry */ };
drivers/usb/serial/ftdi_sio_ids.h +5 -0
@@ -307,6 +307,11 @@#define FTDI_ELV_UIO88_PID 0xFB5F/* USB-I/O Interface (UIO 88) */ /* +* Endress+Hauser AG product ids (FTDI_VID) +*/ +#define FTDI_EH_FXA291_PID 0xE510 + +/* * EVER Eco Pro UPS (http://www.ever.com.pl/) */
Greg Kroah-Hartman
maintainerPATCH 56/389 USB: serial: io_edgeport: cap received transmit credits
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sunho Park <[email protected]>
commit faaddd811c5099f11a5f52e68a6b31a5898cda4f upstream.
The interrupt-status packet reports transmit credits returned by the device. edge_interrupt_callback() adds the 16-bit value to txCredits without checking maxTxCredits.
edge_write() uses txCredits minus the software FIFO count as the amount of data that fits. Since the FIFO is allocated with maxTxCredits bytes, txCredits exceeding maxTxCredits can cause OOB write in ring buffer.
Cap accumulated credits at maxTxCredits. Conforming devices should never hit the cap.
--- drivers/usb/serial/io_edgeport.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/usb/serial/io_edgeport.c +2 -1
@@ -722,7 +722,8 @@ static void edge_interrupt_callback(struif (edge_port && edge_port->open) {spin_lock_irqsave (&edge_port->ep_lock, flags); - edge_port->txCredits += txCredits; + edge_port->txCredits =min (edge_port->txCredits + txCredits, + edge_port->maxTxCredits);spin_unlock_irqrestore (&edge_port->ep_lock, flags); dev_dbg(dev, "%s - txcredits for port%d = %d\n",
Greg Kroah-Hartman
maintainerPATCH 57/389 USB: serial: option: add TDTECH MT5710-CN
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chukun Pan <[email protected]>
commit 55645e4f3c6022ffb160ad3617d2b624eaa38501 upstream.
Add support for the TDTECH MT5710-CN (5G redcap) module based on the Huawei HiSilicon Balong chip.
T: Bus=01 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#= 3 Spd=480 MxCh= 0 D: Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=3466 ProdID=3301 Rev=ff.ff S: Manufacturer=TD Tech Ltd. S: Product=TDTECH MT571X S: SerialNumber=0123456789ABCDEF C:* #Ifs= 6 Cfg#= 1 Atr=c0 MxPwr= 0mA A: FirstIf#= 0 IfCount= 2 Cls=02(comm.) Sub=0d Prot=00 I:* If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=0d Prot=00 Driver=cdc_ncm E: Ad=82(I) Atr=03(Int.) MxPS= 16 Ivl=32ms I: If#= 1 Alt= 0 #EPs= 0 Cls=0a(data ) Sub=00 Prot=01 Driver=cdc_ncm I:* If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=01 Driver=cdc_ncm E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=06 Prot=13 Driver=option E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=06 Prot=12 Driver=option E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=06 Prot=1c Driver=option E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 5 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=06 Prot=14 Driver=option E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
Interface: ECM / NCM + DIAG + AT + SERIAL + GPS
--- drivers/usb/serial/option.c | 1 + 1 file changed, 1 insertion(+)
drivers/usb/serial/option.c +1 -0
@@ -2497,6 +2497,7 @@ static const struct usb_device_id option .driver_info = RSVD(5) }, { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x1003, 0xff), /* Rolling RW135R-GL (laptop MBIM) */ .driver_info = RSVD(5) }, + { USB_DEVICE_INTERFACE_CLASS(0x3466, 0x3301, 0xff) }, /* TDTECH MT5710-CN */ { USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0100, 0xff, 0xff, 0x30) }, /* NetPrisma LCUK54-WWD for Global */ { USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0100, 0xff, 0x00, 0x40) }, { USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0100, 0xff, 0xff, 0x40) },
Greg Kroah-Hartman
maintainerPATCH 58/389 crypto: rsa-pkcs1pad: Dont WARN on an empty digest
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Doruk Tan Ozturk <[email protected]>
KEYCTL_PKEY_VERIFY lets an unprivileged caller supply a zero-length digest (in_len == 0). keyctl_pkey_params_get_2() accepts the zero length and the request reaches pkcs1pad_verify(), where the empty digest is rejected but only after being passed through WARN_ON(!req->dst_len). The warning is therefore directly user-triggerable, and on kernels built with panic_on_warn=1 an unprivileged process can panic the machine -- a local denial of service. Reproduced as UID 65534 in a setuid sandbox.
Keep rejecting the invalid request with -EINVAL, but do not emit a warning for the user-controlled length.
This is the 5.10.y/5.15.y form of the fix, where the length is read directly from req->dst_len rather than cached in a digest_size local. Mainline does not contain this code path; commit 1e562deacecc ("crypto: rsassa-pkcs1 - Migrate to sig_alg backend") removed pkcs1pad_verify() in v6.13-rc1. This is a minimal fix for the affected stable branches. The 6.1.y/6.6.y/6.12.y form (WARN_ON(!digest_size)) is sent as a separate patch.
Found by 0sec automated security-research tooling (https://0sec.ai).
--- crypto/rsa-pkcs1pad.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
crypto/rsa-pkcs1pad.c +1 -1
@@ -535,7 +535,7 @@ static int pkcs1pad_verify(struct akcipher_request *req)int err;if (WARN_ON (req->dst) || -WARN_ON (!req->dst_len) || + !req->dst_len || !ctx->key_size || req->src_len != ctx->key_size)return -EINVAL ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 59/389 bpf: Fix ld_{abs,ind} failure path analysis in subprogs
In reply to Greg Kroah-Hartman5.10-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;
Dropped mark_reg_scratched(), which only affects log verbosity, introduced by 0f55f9ed21f9 ("bpf: Only print scratched registers and stack slots to verifier logs.").]
--- kernel/bpf/verifier.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
kernel/bpf/verifier.c +16 -0
@@ -8556,6 +8556,22 @@ 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; + + 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 60/389 usb: xhci-pci: Limit VIA VL805 DMA addressing to 36 bits
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xincheng Zhang <[email protected]>
commit 1fc50f1ecde39feb4fccdaf4bc71aa6c0eb25c49 upstream.
The VIA VL805/806 xHCI controller advertises AC64, but fails to handle DMA addresses at or above 0x1000000000. On systems with large amounts of RAM, this can cause USB device failures when the controller is given DMA addresses beyond its usable address width.
Do not use XHCI_NO_64BIT_SUPPORT for this controller. That quirk clears the cached AC64 capability and limits DMA to 32 bits, causing unnecessary bouncing for addresses between 4GiB and 64GiB and hiding the controller's real AC64 capability from code that may need to distinguish register access width from usable DMA address width.
Track the usable DMA address width separately from the AC64 capability. Initialize the generic xhci->dma_mask_bits field to 64 and let PCI quirks reduce it for controllers with narrower DMA support. Set VIA VL805/806 to 36 bits so the DMA API only hands it addresses in the range it can handle while keeping HCCPARAMS1.AC64 visible.
--- drivers/usb/host/xhci-pci.c | 1 + drivers/usb/host/xhci.c | 15 ++++++++++----- drivers/usb/host/xhci.h | 1 + 3 files changed, 12 insertions(+), 5 deletions(-)
drivers/usb/host/xhci-pci.c +1 -0
@@ -302,6 +302,7 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) xhci->quirks |=XHCI_LPM_SUPPORT ; xhci->quirks |=XHCI_TRB_OVERFETCH ; xhci->quirks |=XHCI_EP_CTX_BROKEN_DCS ; + xhci->dma_mask_bits =36 ; } if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
drivers/usb/host/xhci.c +10 -5
@@ -5323,6 +5323,7 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)if (xhci->hci_version >0x100 ) xhci->hcc_params2 =readl (&xhci->cap_regs->hcc_params2); + xhci->dma_mask_bits =64 ; xhci->quirks |= quirks;get_quirks (dev, xhci);
@@ -5358,12 +5359,16 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)if (xhci->quirks &XHCI_NO_64BIT_SUPPORT ) xhci->hcc_params &= ~BIT (0 ); -/* Set dma_mask and coherent_dma_mask to 64-bits, -* if xHC supports 64-bit addressing */ +/* +* Set dma_mask and coherent_dma_mask to 64-bits if xHC supports +* 64-bit addressing, unless a controller-specific quirk callback +* limits the usable address width. +*/ if (HCC_64BIT_ADDR (xhci->hcc_params) && - !dma_set_mask (dev,DMA_BIT_MASK (64 ))) { -xhci_dbg (xhci,"Enabling 64-bit DMA addresses.\n" ); -dma_set_coherent_mask (dev,DMA_BIT_MASK (64 )); + !dma_set_mask (dev,DMA_BIT_MASK (xhci->dma_mask_bits))) { +xhci_dbg (xhci,"Enabling %u-bit DMA addresses.\n" , + xhci->dma_mask_bits); +dma_set_coherent_mask (dev,DMA_BIT_MASK (xhci->dma_mask_bits)); }else {/* * This is to avoid error in cases where a 32-bit USB
drivers/usb/host/xhci.h +1 -0
@@ -1782,6 +1782,7 @@ struct xhci_hcd {int event_ring_max;/* 4KB min, 128MB max */ int page_size; +unsigned int dma_mask_bits;/* Valid values are 12 to 20, inclusive */ int page_shift;/* msi-x vectors */
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 61/389 wifi: ath9k: hif_usb: dont dereference hif_dev after re-arming firmware request
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cheng Yongkang <[email protected]>
[ Upstream commit dad9f96945d77ecd4708f730c06ef54dcd8cc057 ]
ath9k_hif_request_firmware() re-arms an asynchronous firmware load via request_firmware_nowait(), passing hif_dev as the completion context, and then still dereferences hif_dev:
dev_info(&hif_dev->udev->dev, "ath9k_htc: Firmware %s requested\n", hif_dev->fw_name);
The re-armed callback ath9k_hif_usb_firmware_cb() runs on the "events" workqueue and, when the firmware is missing, walks the retry chain into ath9k_hif_usb_firmware_fail() -> complete_all(&hif_dev->fw_done). That releases the wait_for_completion(&hif_dev->fw_done) in a concurrent ath9k_hif_usb_disconnect(), which then kfree()s hif_dev. The trailing dev_info() in the frame that re-armed the request can therefore read freed memory (hif_dev->udev, the first field of struct hif_device_usb):
BUG: KASAN: slab-use-after-free in ath9k_hif_request_firmware Read of size 8 ... by task kworker/... ath9k_hif_request_firmware ath9k_hif_usb_firmware_cb drivers/net/wireless/ath/ath9k/hif_usb.c:1247 request_firmware_work_func Allocated by ...: ath9k_hif_usb_probe drivers/net/wireless/ath/ath9k/hif_usb.c Freed by ...: ath9k_hif_usb_disconnect -> kfree drivers/net/wireless/ath/ath9k/hif_usb.c
The fw_done barrier only makes disconnect wait for the firmware chain to *terminate*; it does not protect the outer ath9k_hif_request_firmware() frame that re-armed the request and keeps touching hif_dev afterwards.
Drop the post-request dev_info(): it is the only use of hif_dev after the async request is armed, and it is purely informational (the dev_err() on the failure path runs only when request_firmware_nowait() did not arm a callback, so hif_dev is still alive there).
This was first reported by syzbot as a single, non-reproduced crash that was later auto-obsoleted, and was independently rediscovered by the reFuzz fuzzer, which produced a C reproducer (USB-gadget connect/disconnect of an ath9k_htc device whose firmware download fails). The vulnerable code is unchanged and still present in v7.1-rc6, where the slab-use-after-free reproduces under KASAN once the (sub-microsecond) race window is widened.
--- drivers/net/wireless/ath/ath9k/hif_usb.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-)
drivers/net/wireless/ath/ath9k/hif_usb.c +1 -6
@@ -1227,15 +1227,10 @@ static int ath9k_hif_request_firmware(struct hif_device_usb *hif_dev, ret =request_firmware_nowait (THIS_MODULE , true, hif_dev->fw_name, &hif_dev->udev->dev,GFP_KERNEL , hif_dev, ath9k_hif_usb_firmware_cb); -if (ret) { +if (ret)dev_err (&hif_dev->udev->dev,"ath9k_htc: Async request for firmware %s failed\n" , hif_dev->fw_name); -return ret; - } - -dev_info (&hif_dev->udev->dev,"ath9k_htc: Firmware %s requested\n" , - hif_dev->fw_name);return ret; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 62/389 hwmon: (corsair-cpro) Stop device IO before calling hid_hw_stop
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <[email protected]>
[ Upstream commit 94c87871b051d7ad758828a805215a2ec194512a ]
Calling hid_hw_stop() does not stop the device IO.
This results in a race condition between hid_input_report() and the point immediately following the execution of hid_device_io_start() within the driver probe function. If the probe operation fails after "io start" has been initiated, this race condition will result in a UAF vulnerability.
Fix the problem by calling hid_device_io_stop() before calling hid_hw_stop().
--- drivers/hwmon/corsair-cpro.c | 1 + 1 file changed, 1 insertion(+)
drivers/hwmon/corsair-cpro.c +1 -0
@@ -557,6 +557,7 @@ static int ccp_probe(struct hid_device *hdev, const struct hid_device_id *id) out_hw_close:hid_hw_close (hdev); +hid_device_io_stop (hdev); out_hw_stop:hid_hw_stop (hdev);return ret;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 63/389 watchdog: pretimeout: Fix UAF in watchdog_unregister_governor()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tzung-Bi Shih <[email protected]>
[ Upstream commit 7362ba0f9c96ac3ad6a2ca3995bd9fc9a28a8661 ]
When a watchdog governor is unregistered, it updates existing watchdog devices that were using this governor by falling back to default_gov.
If the governor being unregistered is currently set as default_gov, the default_gov is never cleared. This leads to 2 use-after-free issues:
1. New watchdog devices registered after this point will inherit the dangling default_gov.
2. Existing watchdog devices using the unregistered governor will have their wdd->gov reassigned to the dangling default_gov.
Fix the UAF by clearing default_gov if it matches the governor being unregistered.
--- drivers/watchdog/watchdog_pretimeout.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/watchdog/watchdog_pretimeout.c +2 -0
@@ -164,6 +164,8 @@ void watchdog_unregister_governor(struct watchdog_governor *gov) }spin_lock_irq (&pretimeout_lock); +if (default_gov == gov) + default_gov =NULL ;list_for_each_entry (p, &pretimeout_list, entry)if (p->wdd->gov == gov) p->wdd->gov = default_gov;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 64/389 wifi: ath11k: fix potential buffer underflow in ath11k_hal_rx_msdu_list_get()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Morgun <[email protected]>
[ Upstream commit 7f11e70629650ff6ea140984e5ce188b775b2683 ]
When the first entry in msdu_details has a zero buffer address, the code accesses msdu_details[i - 1] with i == 0, causing a buffer underflow.
Fix similarly to ath12k_wifi7_hal_rx_msdu_list_get() by adding a separate check for i == 0 before the main condition to prevent the out-of-bounds access.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/net/wireless/ath/ath11k/dp_rx.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/wireless/ath/ath11k/dp_rx.c +3 -0
@@ -4441,6 +4441,9 @@ static void ath11k_hal_rx_msdu_list_get(struct ath11k *ar, msdu_details = &msdu_link->msdu_link[0 ];for (i =0 ; i <HAL_RX_NUM_MSDU_DESC ; i++) { +if (!i &&FIELD_GET (BUFFER_ADDR_INFO0_ADDR , + msdu_details[i].buf_addr_info.info0) ==0 ) +break ;if (FIELD_GET (BUFFER_ADDR_INFO0_ADDR , msdu_details[i].buf_addr_info.info0) ==0 ) { msdu_desc_info = &msdu_details[i -1 ].rx_msdu_info;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 65/389 firewire: net: Fix fragmented datagram reassembly
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ruoyu Wang <[email protected]>
[ Upstream commit d52a13adbb8ccbab99cd3bad36804e87d8b5c052 ]
fwnet_frag_new() keeps a sorted list of received fragments for a partial datagram. When a new fragment is adjacent to an existing fragment, the code checks whether the new fragment also closes the gap to the next or previous list entry.
Those neighbor lookups currently assume that the current fragment always has a real next or previous fragment. At a list edge, the next or previous entry is the list head, not a struct fwnet_fragment_info.
The gap checks also compare against the old edge of the current fragment instead of the edge after adding the new fragment. As a result, a fragment that bridges two existing ranges may leave two adjacent ranges unmerged, so fwnet_pd_is_complete() can miss a complete datagram.
Check for the list head before looking up the neighboring fragment, and compare the neighbor against the new fragment's far edge when deciding whether to merge all three ranges.
This issue was found by a static analysis checker and confirmed by manual source review.
--- drivers/firewire/net.c | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-)
drivers/firewire/net.c +21 -18
@@ -306,31 +306,34 @@ static struct fwnet_fragment_info *fwnet_frag_new(if (fi->offset + fi->len == offset) {/* The new fragment can be tacked on to the end */ /* Did the new fragment plug a hole? */ - fi2 =list_entry (fi->fi_link.next, - struct fwnet_fragment_info, fi_link); -if (fi->offset + fi->len == fi2->offset) { -/* glue fragments together */ - fi->len += len + fi2->len; -list_del (&fi2->fi_link); -kfree (fi2); - }else { - fi->len += len; +if (!list_is_last (&fi->fi_link, &pd->fi_list)) { + fi2 =list_next_entry (fi, fi_link); +if (offset + len == fi2->offset) { +/* glue fragments together */ + fi->len += len + fi2->len; +list_del (&fi2->fi_link); +kfree (fi2); + +return fi; + } } + fi->len += len;return fi; }if (offset + len == fi->offset) {/* The new fragment can be tacked on to the beginning */ /* Did the new fragment plug a hole? */ - fi2 =list_entry (fi->fi_link.prev, - struct fwnet_fragment_info, fi_link); -if (fi2->offset + fi2->len == fi->offset) { -/* glue fragments together */ - fi2->len += fi->len + len; -list_del (&fi->fi_link); -kfree (fi); - -return fi2; +if (!list_is_first (&fi->fi_link, &pd->fi_list)) { + fi2 =list_prev_entry (fi, fi_link); +if (fi2->offset + fi2->len == offset) { +/* glue fragments together */ + fi2->len += fi->len + len; +list_del (&fi->fi_link); +kfree (fi); + +return fi2; + } } fi->offset = offset; fi->len += len;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 66/389 wifi: ath6kl: fix OOB read from firmware num_msg in TX complete handler
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tristan Madani <[email protected]>
[ Upstream commit 3a21c89215cc18f1a97c5e5bfd1da6d4f3d44495 ]
The firmware-controlled num_msg field (u8, 0-255) drives the loop in ath6kl_wmi_tx_complete_event_rx() without validation against the buffer length. This allows out-of-bounds reads of up to 1020 bytes past the WMI event buffer when the firmware sends an inflated num_msg.
Add a check that the buffer is large enough to hold the fixed struct and the num_msg variable-length entries.
--- drivers/net/wireless/ath/ath6kl/wmi.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
drivers/net/wireless/ath/ath6kl/wmi.c +12 -0
@@ -484,6 +484,18 @@ static int ath6kl_wmi_tx_complete_event_rx(u8 *datap, int len) evt = (struct wmi_tx_complete_event *) datap; +if (len <sizeof (*evt)) { +ath6kl_dbg (ATH6KL_DBG_WMI ,"tx complete: invalid len %d\n" , + len); +return -EINVAL ; + } + +if (len <sizeof (*evt) + evt->num_msg *sizeof (struct tx_complete_msg_v1 )) { +ath6kl_dbg (ATH6KL_DBG_WMI ,"tx complete: invalid len %d for %u msgs\n" , + len, evt->num_msg); +return -EINVAL ; + } +ath6kl_dbg (ATH6KL_DBG_WMI ,"comp: %d %d %d\n" , evt->num_msg, evt->msg_len, evt->msg_type);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 67/389 wifi: ath6kl: fix OOB read from firmware IE lengths in connect event
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tristan Madani <[email protected]>
[ Upstream commit 6b47b29730de3232b919d8362749f6814c5f2a33 ]
The firmware-controlled beacon_ie_len, assoc_req_len, and assoc_resp_len fields in ath6kl_wmi_connect_event_rx() are not validated against the buffer length. Their sum (up to 765) can exceed the actual WMI event data, causing out-of-bounds reads during IE parsing and state corruption of wmi->is_wmm_enabled.
Add a check that the total IE length fits within the buffer.
--- drivers/net/wireless/ath/ath6kl/wmi.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/net/wireless/ath/ath6kl/wmi.c +8 -0
@@ -874,6 +874,14 @@ static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len, ev = (struct wmi_connect_event *) datap; +if (len <sizeof (*ev) + ev->beacon_ie_len + + ev->assoc_req_len + ev->assoc_resp_len) { +ath6kl_dbg (ATH6KL_DBG_WMI , +"connect event: IE lengths %u+%u+%u exceed buffer %d\n" , + ev->beacon_ie_len, ev->assoc_req_len, + ev->assoc_resp_len, len); +return -EINVAL ; + }if (vif->nw_type ==AP_NETWORK ) {/* AP mode start/STA connected event */ struct net_device *dev = vif->ndev;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 68/389 wifi: carl9170: bound memcpy length in cmd callback to prevent OOB read
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tristan Madani <[email protected]>
[ Upstream commit 4cde55b2feff9504d1f993ab80e84e7ccb62791c ]
When the firmware sends a command response with a length mismatch, carl9170_cmd_callback() logs the mismatch and calls carl9170_restart() but then falls through to memcpy(ar->readbuf, buffer + 4, len - 4). Since len comes from the firmware and can exceed ar->readlen, this copies more data than the readbuf was allocated for.
Bound the memcpy to min(len - 4, ar->readlen) so that the response is still completed -- avoiding repeated restarts from queued garbage -- while preventing an overread past the response buffer.
--- drivers/net/wireless/ath/carl9170/rx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/wireless/ath/carl9170/rx.c +2 -1
@@ -150,7 +150,8 @@ static void carl9170_cmd_callback(struct ar9170 *ar, u32 len, void *buffer)spin_lock (&ar->cmd_lock);if (ar->readbuf) {if (len >=4 ) -memcpy (ar->readbuf, buffer +4 , len -4 ); +memcpy (ar->readbuf, buffer +4 , +min_t (u32, len -4 , ar->readlen)); ar->readbuf =NULL ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 69/389 wifi: carl9170: fix OOB read from off-by-two in TX status handler
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tristan Madani <[email protected]>
[ Upstream commit a3f42f1049ad80c65560d2b078ad426c3134f78d ]
The bounds check in carl9170_tx_process_status() usesi > ((cmd->hdr.len / 2) + 1) which is off by two, allowing 2 extra iterations past valid _tx_status entries when the firmware- controlled hdr.ext exceeds hdr.len/2. Fix by using the correct comparison i >= (cmd->hdr.len / 2).
--- drivers/net/wireless/ath/carl9170/tx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/ath/carl9170/tx.c +1 -1
@@ -692,7 +692,7 @@ void carl9170_tx_process_status(struct ar9170 *ar,unsigned int i;for (i =0 ; i < cmd->hdr.ext; i++) { -if (WARN_ON (i > ((cmd->hdr.len /2 ) +1 ))) { +if (WARN_ON (i >= (cmd->hdr.len /2 ))) {print_hex_dump_bytes ("UU:" ,DUMP_PREFIX_NONE , (void *) cmd, cmd->hdr.len +4 );break ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 70/389 wifi: carl9170: fix buffer overflow in rx_stream failover path
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tristan Madani <[email protected]>
[ Upstream commit a1a21995c2e1cc2ca6b2226cfe4f5f018370182a ]
The failover continuation in carl9170_rx_stream() copies the full tlen from the second USB transfer instead of capping at rx_failover_missing bytes. When both transfers are near maximum size, the total exceeds the 65535-byte failover SKB, triggering skb_over_panic.
Limit the copy size to the missing byte count.
--- drivers/net/wireless/ath/carl9170/rx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/wireless/ath/carl9170/rx.c +3 -1
@@ -918,7 +918,9 @@ static void carl9170_rx_stream(struct ar9170 *ar, void *buf, unsigned int len) } } -skb_put_data (ar->rx_failover, tbuf, tlen); +skb_put_data (ar->rx_failover, tbuf, + min_t(unsigned int, tlen, + ar->rx_failover_missing)); ar->rx_failover_missing -= tlen;if (ar->rx_failover_missing <=0 ) {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 71/389 ASoC: bt-sco: fix bt-sco-pcm-wb dai widget dont connect to the endpoint
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiaxin Yu <[email protected]>
[ Upstream commit 8f2b025abc31bc15d38657d1286d7470bbbd5efa ]
This patch fix the second dai driver's dai widget can't connect to the endpoint. Because "bt-sco-pcm" and "bt-sco-pcm-wb" dai driver have the same stream_name, so it will cause they have the same widget name. Therefor it will just create only one route when do snd_soc_dapm_add_route that only find the widget through the widget name.
Stable-dep-of: 0b604e886ece ("ASoC: bt-sco: fix duplicate DAPM widget names for wideband DAI")
--- sound/soc/codecs/bt-sco.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
sound/soc/codecs/bt-sco.c +6 -2
@@ -13,11 +13,15 @@static const struct snd_soc_dapm_widget bt_sco_widgets[] = {SND_SOC_DAPM_INPUT ("RX" ),SND_SOC_DAPM_OUTPUT ("TX" ), +SND_SOC_DAPM_AIF_IN ("BT_SCO_RX" ,"Playback" ,0 , +SND_SOC_NOPM ,0 ,0 ), +SND_SOC_DAPM_AIF_OUT ("BT_SCO_TX" ,"Capture" ,0 , +SND_SOC_NOPM ,0 ,0 ), };static const struct snd_soc_dapm_route bt_sco_routes[] = { - {"Capture" ,NULL ,"RX" }, - {"TX" ,NULL ,"Playback" }, + {"BT_SCO_TX" ,NULL ,"RX" }, + {"TX" ,NULL ,"BT_SCO_RX" }, };static struct snd_soc_dai_driver bt_sco_dai[] = {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 72/389 ASoC: bt-sco: fix duplicate DAPM widget names for wideband DAI
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shengjiu Wang <[email protected]>
[ Upstream commit 0b604e886ece11b71c4daaeccc512c784b89b014 ]
The bt-sco-pcm-wb DAI uses the same stream_name strings as bt-sco-pcm ("Playback" and "Capture"). This causes duplicate DAPM AIF widget names within the same component, leading to debugfs warnings:
debugfs: 'Playback' already exists in 'dapm'
debugfs: 'Capture' already exists in 'dapm'
Give the wideband DAI distinct stream names ("WB Playback" and "WB Capture") and add corresponding DAPM AIF widgets and routes for them.
--- sound/soc/codecs/bt-sco.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
sound/soc/codecs/bt-sco.c +8 -2
@@ -17,11 +17,17 @@ static const struct snd_soc_dapm_widget bt_sco_widgets[] = { SND_SOC_NOPM, 0, 0),SND_SOC_DAPM_AIF_OUT ("BT_SCO_TX" ,"Capture" ,0 ,SND_SOC_NOPM ,0 ,0 ), +SND_SOC_DAPM_AIF_IN ("BT_SCO_RX_WB" ,"WB Playback" ,0 , +SND_SOC_NOPM ,0 ,0 ), +SND_SOC_DAPM_AIF_OUT ("BT_SCO_TX_WB" ,"WB Capture" ,0 , + SND_SOC_NOPM, 0, 0), };static const struct snd_soc_dapm_route bt_sco_routes[] = { {"BT_SCO_TX" ,NULL ,"RX" }, {"TX" ,NULL ,"BT_SCO_RX" }, + {"BT_SCO_TX_WB" ,NULL ,"RX" }, + {"TX" ,NULL ,"BT_SCO_RX_WB" }, }; static struct snd_soc_dai_driver bt_sco_dai[] = {
@@ -45,14 +51,14 @@ static struct snd_soc_dai_driver bt_sco_dai[] = { { .name = "bt-sco-pcm-wb", .playback = { - .stream_name = "Playback", + .stream_name = "WB Playback", .channels_min = 1, .channels_max = 1, .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000, .formats = SNDRV_PCM_FMTBIT_S16_LE, }, .capture = { - .stream_name = "Capture", + .stream_name = "WB Capture", .channels_min = 1, .channels_max = 1, .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 73/389 usb: atm: ueagle-atm: reject descriptors that confuse probe and disconnect
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Diego Fernando Mancera Gomez <[email protected]>
[ Upstream commit 71132cedd1ecbc4032d76e9928c18a10f7e39b80 ]
uea_probe() distinguishes a pre-firmware device from a post-firmware one using the USB id (UEA_IS_PREFIRM()), and stores a different object as the interface data in each case: a 'struct completion' for a pre-firmware device (to be waited on in .disconnect()), or a 'struct usbatm_data' for a post-firmware one.
uea_disconnect() instead tells the two apart by the number of interfaces of the active configuration (a pre-firmware device exposes a single interface, ADI930 has 2 and eagle has 3), and casts the interface data accordingly.
Because the two handlers use different criteria, a crafted device that advertises a pre-firmware id together with a multi-interface descriptor (or a post-firmware id with a single interface) makes them disagree: the small 'struct completion' stored by uea_probe() is then passed to usbatm_usb_disconnect(), which casts it to 'struct usbatm_data' and takes instance->serialize, reading past the end of the allocation:
BUG: KASAN: slab-out-of-bounds in __mutex_lock+0x152a/0x1b80 Read of size 8 at addr ffff8880470e2c60 by task kworker/1:2/982 ... __mutex_lock+0x152a/0x1b80 usbatm_usb_disconnect+0x70/0x820 uea_disconnect+0x133/0x2c0 usb_unbind_interface+0x1dd/0x9e0 ... which belongs to the cache kmalloc-96 of size 96 The buggy address is located 0 bytes to the right of allocated 96-byte region [ffff8880470e2c00, ffff8880470e2c60)
Reject such inconsistent descriptors in uea_probe() so that both handlers always make the same pre/post-firmware decision.
--- drivers/usb/atm/ueagle-atm.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
drivers/usb/atm/ueagle-atm.c +17 -0
@@ -2591,6 +2591,7 @@ static struct usbatm_driver uea_usbatm_driver = {static int uea_probe (struct usb_interface *intf,const struct usb_device_id *id) {struct usb_device *usb =interface_to_usbdev (intf); +bool single_iface = usb->config->desc.bNumInterfaces ==1 ;int ret;uea_enters (usb);
@@ -2600,6 +2601,22 @@ static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id)le16_to_cpu (usb->descriptor.bcdDevice), chip_name[UEA_CHIP_VERSION(id)]); +/* +* uea_probe() decides between the pre-firmware and post-firmware case +* from the USB id and stores a different object as interface data in +* each case: a struct completion for a pre-firmware device, a struct +* usbatm_data for a post-firmware one. uea_disconnect() instead tells +* the two apart by the number of interfaces (a pre-firmware device +* exposes a single interface, ADI930 has 2 and eagle has 3). A crafted +* device advertising a pre-firmware id together with a multi-interface +* descriptor (or the other way around) makes the two disagree, so that +* usbatm_usb_disconnect() treats the small completion object as a +* struct usbatm_data and reads out of bounds. Reject such inconsistent +* descriptors so both paths make the same decision. +*/ +if (UEA_IS_PREFIRM (id) != single_iface) +return -ENODEV ; +usb_reset_device (usb);if (UEA_IS_PREFIRM (id)) {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 74/389 net/packet: avoid fanout hook re-registration after unregister
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Lee <[email protected]>
[ Upstream commit 50aff80475abd3533eef4320477037e6fcc6b56e ]
packet_set_ring() temporarily detaches a socket from packet delivery while reconfiguring its ring. It records the previous running state, clears po->num, unregisters the protocol hook when needed, drops po->bind_lock, and later restores po->num and re-registers the hook from the saved was_running value.
That unlocked window can race with NETDEV_UNREGISTER. The notifier can observe the socket as not running, skip __unregister_prot_hook(), and invalidate the per-socket binding by setting po->ifindex to -1 and clearing po->prot_hook.dev. A one-member fanout group can still retain its shared fanout hook device pointer. When packet_set_ring() resumes, re-registering solely from the stale was_running state can re-add the fanout hook after the device has been unregistered.
Treat po->ifindex == -1 as an invalidated binding after reacquiring po->bind_lock. This is distinct from ifindex 0, the normal unbound/wildcard state: ifindex -1 marks an existing device binding that was invalidated when the device was unregistered. Restore po->num as before, but do not re-register the hook if device unregister already detached the socket.
--- net/packet/af_packet.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
net/packet/af_packet.c +5 -1
@@ -4551,7 +4551,11 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,spin_lock (&po->bind_lock);WRITE_ONCE (po->num, num); -if (was_running) +/* +* NETDEV_UNREGISTER may have invalidated the binding while bind_lock +* was dropped above. Do not re-add a fanout hook to a dead device. +*/ +if (was_running &&READ_ONCE (po->ifindex) !=-1 )register_prot_hook (sk);spin_unlock (&po->bind_lock);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 75/389 rds: drop incoming messages that cross network namespace boundaries
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aldo Ariel Panzardo <[email protected]>
[ Upstream commit 5521ae71e32a8069ed4ca6e792179dc57bc43ab2 ]
rds_find_bound() looks up the destination socket using a global rhashtable keyed solely on (addr, port, scope_id). Network namespaces are not part of the key, so a sender in netns A can deliver an incoming message (inc) to a socket that lives in a different netns B.
When this happens, inc->i_conn points to an rds_connection whose c_net is netns A, but the receiving rs lives in netns B. Once the child process that created netns A exits, cleanup_net() calls rds_loop_exit_net() -> rds_loop_kill_conns() -> rds_conn_destroy(), freeing that connection. If the survivor socket in netns B still holds the inc, any subsequent dereference of inc->i_conn is a use-after-free.
There are two dangerous sites in rds_clear_recv_queue():
1. inc->i_conn->c_lcong (offset 88 of freed rds_connection, size 200) read via rds_recv_rcvbuf_delta() -- confirmed by KASAN.
2. inc->i_conn->c_trans->inc_free(inc) (function pointer at offset 80) called via rds_inc_put() when the inc refcount reaches zero -- same race window, potential call-through-freed-object primitive.
The bug is reachable from unprivileged user namespaces (CLONE_NEWUSER + CLONE_NEWNET), available since Linux 3.8.
Fix this by rejecting the delivery in rds_recv_incoming() when the socket returned by rds_find_bound() belongs to a different network namespace than the connection that carried the message. Use the existing rds_conn_net() / sock_net() helpers and net_eq() for the comparison.
--- net/rds/recv.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
net/rds/recv.c +15 -0
@@ -365,6 +365,21 @@ void rds_recv_incoming(struct rds_connection *conn, struct in6_addr *saddr, goto out; } +/* +* rds_find_bound() uses a global (netns-agnostic) hash table. +* An RDS connection created in netns A can match a socket bound +* in the init netns, delivering inc cross-netns with inc->i_conn +* pointing into netns A. When cleanup_net() then frees that conn, +* any subsequent dereference of inc->i_conn is a use-after-free. +* Drop the inc if the receiving socket lives in a different netns. +*/ +if (!net_eq (sock_net (rds_rs_to_sk (rs)),rds_conn_net (conn))) { +rds_stats_inc (s_recv_drop_no_sock); +rds_sock_put (rs); + rs =NULL ; + goto out; + } +/* Process extension headers */ rds_recv_incoming_exthdrs (inc, rs);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 76/389 nfp: Check resource mutex allocation
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ruoyu Wang <[email protected]>
[ Upstream commit a61b4db34a753bdf5c9e77a7f3d3dddd41dcfacc ]
nfp_cpp_resource_find() allocates a CPP mutex handle for the matching resource-table entry and then reports success. nfp_resource_try_acquire() immediately passes that handle to nfp_cpp_mutex_trylock().
However, nfp_cpp_mutex_alloc() returns NULL on failure. If that happens for a matching table entry, the resource lookup still returns success and the following trylock dereferences a NULL mutex pointer while opening the resource.
nfp_resource_acquire() already treats failure to allocate the table mutex as -ENOMEM. Do the same for the resource mutex and fail the lookup before publishing the rest of the resource handle.
This issue was found by a static analysis checker and confirmed by manual source review.
--- drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c +3 -0
@@ -96,6 +96,9 @@ static int nfp_cpp_resource_find(struct nfp_cpp *cpp, struct nfp_resource *res) res->mutex =nfp_cpp_mutex_alloc (cpp,NFP_RESOURCE_TBL_TARGET , addr, key); +if (!res->mutex) +return -ENOMEM ; + res->cpp_id =NFP_CPP_ID (entry.region.cpp_target, entry.region.cpp_action, entry.region.cpp_token);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 77/389 wan: wanxl: Only reset hardware after BAR mapping
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ruoyu Wang <[email protected]>
[ Upstream commit 91957b89da995607cb654b1f9a3c126ddbaee10f ]
wanxl_pci_init_one() stores the freshly allocated card in driver data before the PLX BAR is mapped. Several early probe failures then unwind through wanxl_pci_remove_one(), including failure to allocate the coherent status area or to restore the DMA mask.
wanxl_pci_remove_one() unconditionally calls wanxl_reset(), and wanxl_reset() dereferences card->plx. On those early failures card->plx is still NULL, so the error path can dereference a NULL MMIO pointer.
Only issue the hardware reset once the BAR mapping exists. The remaining cleanup in wanxl_pci_remove_one() already checks whether later resources were allocated.
This issue was found by a static analysis checker and confirmed by manual source review.
--- drivers/net/wan/wanxl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/wan/wanxl.c +2 -1
@@ -521,7 +521,8 @@ static void wanxl_pci_remove_one(struct pci_dev *pdev)if (card->irq)free_irq (card->irq, card); -wanxl_reset (card); +if (card->plx) +wanxl_reset (card);for (i =0 ; i <RX_QUEUE_LENGTH ; i++)if (card->rx_skbs[i]) {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 78/389 wifi: mwifiex: bound uAP association event IEs to the event buffer
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: HE WEI (ギカク) <[email protected]>
[ Upstream commit f0858bfc7d3cab411a447b88e3ef970e575032c9 ]
mwifiex_process_uap_event() handles EVENT_UAP_STA_ASSOC by exposing the (re)association request IEs that the firmware copies into the event:
sinfo->assoc_req_ies = &event->data[len]; len = (u8 *)sinfo->assoc_req_ies - (u8 *)&event->frame_control; sinfo->assoc_req_ies_len = le16_to_cpu(event->len) - (u16)len;
event->len is supplied by the device firmware and is never validated, and the subtraction is unchecked. assoc_req_ies points into adapter->event_body[MAX_EVENT_SIZE], a fixed-size array embedded in the kmalloc()'d struct mwifiex_adapter.
On the ap_11n_enabled path mwifiex_set_sta_ht_cap() walks these IEs with cfg80211_find_ie(), whose for_each_element() loop dereferences each element header. A firmware-reported event->len larger than the bytes actually received makes assoc_req_ies_len describe IEs that extend past event_body, so the walk reads out of the adapter slab object, a slab-out-of-bounds read (KASAN: slab-out-of-bounds in cfg80211_find_ie). An event->len smaller than the header instead makes the int subtraction negative, which wraps to a huge size_t when stored in assoc_req_ies_len. The same length is handed to cfg80211_new_sta(), so a more modest over-claim can also copy stale event_body bytes into the NL80211_CMD_NEW_STATION notification.
A malicious or malfunctioning mwifiex device (USB/SDIO/PCIe) can deliver such an event while the interface is in AP/uAP mode.
Validate event->len before use: reject a length that underflows the header or that would place the IEs outside the event_body[] buffer the event was copied into. event->len here is struct mwifiex_assoc_event.len, a payload field internal to this event, not the transport frame length, so it is validated in this handler rather than at the generic MWIFIEX_TYPE_EVENT receive path, which only sees the event cause and the transport frame length. The bound is against event_body[MAX_EVENT_SIZE] rather than the actually-received length because the transports store the event differently (USB and SDIO leave the 4-byte event header in event_skb, PCIe strips it via skb_pull), whereas event_body is the single fixed buffer all of them copy the event into. This is the event-path analogue of the receive-path bounds checks added in commit 119585281617 ("wifi: mwifiex: Fix OOB and integer underflow when rx packets").
--- .../net/wireless/marvell/mwifiex/uap_event.c | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-)
drivers/net/wireless/marvell/mwifiex/uap_event.c +22 -2
@@ -135,11 +135,31 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv) len =ETH_ALEN ;if (len !=-1 ) { +u16 evt_len =le16_to_cpu (event->len); + sinfo->assoc_req_ies = &event->data[len]; len = (u8 *)sinfo->assoc_req_ies - (u8 *)&event->frame_control; - sinfo->assoc_req_ies_len = -le16_to_cpu (event->len) - (u16 )len; + +/* +* event->len is reported by the device firmware +* and is not otherwise validated. Reject a +* length that underflows the header, or that +* would place the association request IEs +* outside the fixed-size event_body[] buffer the +* event was copied into; otherwise the IE walk +* in mwifiex_set_sta_ht_cap() reads past +* event_body and out of the adapter slab object. +*/ +if (evt_len < len || + (u8 *)&event->frame_control + evt_len > + adapter->event_body +MAX_EVENT_SIZE ) { +mwifiex_dbg (adapter,ERROR , +"invalid STA assoc event length\n" ); +kfree (sinfo); +return -1 ; + } + sinfo->assoc_req_ies_len = evt_len - (u16 )len; } } cfg80211_new_sta(priv->netdev, event->sta_addr, sinfo,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 79/389 iommu/amd: Bound the early ACPI HID map
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pengpeng Hou <[email protected]>
[ Upstream commit fb80117fddb5b477218dc99bb53911b72c3847f8 ]
The ivrs_acpihid command-line parser appends entries to a fixed four-element early_acpihid_map array. Unlike the sibling IOAPIC and HPET parsers, it does not reject a fifth entry before incrementing the map size.
Check the capacity at the common found label before parsing the HID and UID or writing the entry.
--- drivers/iommu/amd/init.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/iommu/amd/init.c +6 -0
@@ -3227,6 +3227,12 @@ static int __init parse_ivrs_acpihid(char *str)return 1 ; found: +if (early_acpihid_map_size ==EARLY_MAP_SIZE ) { +pr_err ("Early ACPI HID map overflow - ignoring ivrs_acpihid%s\n" , + str); +return 1 ; + } + p = acpiid; hid =strsep (&p,":" ); uid = p;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 80/389 wifi: mac80211: recalculate TIM when a station enters power save
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrew Pope <[email protected]>
[ Upstream commit a007a384c9eb17610f53a53e2f59944c31f1565a ]
When an AP buffers frames for a station on its per-station TXQs and the station subsequently enters power save, sta_ps_start() records the buffered TIDs in txq_buffered_tids but does not update the TIM. The station's TIM bit is only ever set when a further frame is buffered while the station is already asleep (ieee80211_tx_h_unicast_ps_buf() -> sta_info_recalc_tim()).
If no further downlink frame arrives for that station the beacon TIM never advertises the buffered traffic. A station relying on the TIM then remains in doze indefinitely on top of a non-empty queue. Its TXQs were removed from the scheduler's active list at PS entry, nothing pages it, and the flow deadlocks until an unrelated event wakes the station.
Recalculate the TIM at the end of sta_ps_start(), so traffic already buffered at PS entry is advertised immediately. sta_info_recalc_tim() already consults txq_buffered_tids, which is updated above, and is safe in this context (it is already called from equivalent paths such as the tx handlers and ieee80211_handle_filtered_frame()).
--- net/mac80211/rx.c | 2 ++ 1 file changed, 2 insertions(+)
net/mac80211/rx.c +2 -0
@@ -1585,6 +1585,8 @@ static void sta_ps_start(struct sta_info *sta)else clear_bit (tid, &sta->txq_buffered_tids); } + +sta_info_recalc_tim (sta); }static void sta_ps_end (struct sta_info *sta)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 81/389 amd-xgbe: fix MAC_AUTO_SW handling in CL37 AN
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Prashanth Kumar KR <[email protected]>
[ Upstream commit 4bf22afe53a1de4b44b04cf677fd5199089cbdff ]
MAC_AUTO_SW (VR_MII_DIG_CTRL1 bit 9) enables automatic XPCS speed mode switching after CL37 auto-negotiation and is only meaningful in SGMII MAC mode. The original code unconditionally set this bit on every call to xgbe_an37_set(), including when called from xgbe_an37_disable() with enable=false. This left MAC_AUTO_SW=1 after AN was disabled, causing the XPCS to autonomously switch speed from stale AN state during subsequent mode changes, breaking SGMII speed negotiation on 1G copper SFP modules.
Patrick: This was breaking negotiation for all 1G SFP modules, not just copper modules.
--- drivers/net/ethernet/amd/xgbe/xgbe-mdio.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
drivers/net/ethernet/amd/xgbe/xgbe-mdio.c +8 -3
@@ -364,9 +364,14 @@ static void xgbe_an37_set(struct xgbe_prv_data *pdata, bool enable,XMDIO_WRITE (pdata,MDIO_MMD_VEND2 ,MDIO_CTRL1 , reg); - reg =XMDIO_READ (pdata,MDIO_MMD_VEND2 ,MDIO_PCS_DIG_CTRL ); - reg |=XGBE_VEND2_MAC_AUTO_SW ; -XMDIO_WRITE (pdata,MDIO_MMD_VEND2 ,MDIO_PCS_DIG_CTRL , reg); +if (pdata->an_mode ==XGBE_AN_MODE_CL37_SGMII ) { + reg =XMDIO_READ (pdata,MDIO_MMD_VEND2 ,MDIO_PCS_DIG_CTRL ); +if (enable) + reg |=XGBE_VEND2_MAC_AUTO_SW ; +else + reg &= ~XGBE_VEND2_MAC_AUTO_SW ; +XMDIO_WRITE (pdata,MDIO_MMD_VEND2 ,MDIO_PCS_DIG_CTRL , reg); + } }static void xgbe_an37_restart (struct xgbe_prv_data *pdata)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 82/389 sctp: fix auth_chunk_list capacity check in sctp_auth_ep_add_chunkid
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: HanQuan <[email protected]>
[ Upstream commit ff04b26794a16a8a879eb4fd2c02c2d6b03850e9 ]
sctp_auth_ep_add_chunkid() uses SCTP_NUM_CHUNK_TYPES (20) as the capacity limit for ep->auth_chunk_list, allowing it to hold up to 20 chunk entries (param_hdr.length up to 24). However, the copy destination asoc->c.auth_chunks in struct sctp_cookie is only SCTP_AUTH_MAX_CHUNKS (16) entries (20 bytes). When more than 16 chunks are added, sctp_association_init() memcpy overflows the destination by up to 4 bytes.
Fix by using SCTP_AUTH_MAX_CHUNKS as the capacity limit, matching the destination capacity.
--- net/sctp/auth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/sctp/auth.c +1 -1
@@ -766,7 +766,7 @@ int sctp_auth_ep_add_chunkid(struct sctp_endpoint *ep, __u8 chunk_id)/* Check if we can add this chunk to the array */ param_len =ntohs (p->param_hdr.length); nchunks = param_len -sizeof (struct sctp_paramhdr ); -if (nchunks ==SCTP_NUM_CHUNK_TYPES ) +if (nchunks ==SCTP_AUTH_MAX_CHUNKS )return -EINVAL ; p->chunks[nchunks] = chunk_id;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 83/389 sctp: validate stream count in sctp_process_strreset_inreq()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cen Zhang (Microsoft) <[email protected]>
[ Upstream commit 18ae07691d43183d270de8be9dc8e027906015d9 ]
When processing a RESET_IN_REQUEST from a peer, sctp_process_strreset_inreq() derives the stream count from the parameter length but does not check whether the resulting RESET_OUT_REQUEST would exceed SCTP_MAX_CHUNK_LEN.
The OUT request header (sctp_strreset_outreq, 16 bytes) is 8 bytes larger than the IN request header (sctp_strreset_inreq, 8 bytes). Generally, the IP payload is bounded to 65535 bytes, so the stream list cannot be large enough to trigger the overflow. However, on interfaces with MTU > 65535 (e.g., loopback with IPv6 jumbograms), a stream list that fits within the incoming IN parameter can cause a __u16 overflow in sctp_make_strreset_req() when computing the OUT request size, leading to an undersized skb allocation and a kernel BUG:
net/core/skbuff.c:207 skb_panic
net/core/skbuff.c:2625 skb_put
net/sctp/sm_make_chunk.c:1535 sctp_addto_chunk net/sctp/sm_make_chunk.c:3695 sctp_make_strreset_req
net/sctp/stream.c:655 sctp_process_strreset_inreq
The local setsockopt path validates the generated reset request size. However, for an incoming-only reset, it accounts for the smaller IN request even though the peer must generate an OUT request with the same stream list. Such a request cannot be completed successfully by the peer.
Reject peer IN requests whose corresponding OUT request would exceed SCTP_MAX_CHUNK_LEN. Also tighten the local check so it does not send an IN request that would require an oversized OUT request from the peer.
--- net/sctp/stream.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
net/sctp/stream.c +5 -1
@@ -308,7 +308,8 @@ int sctp_send_reset_streams(struct sctp_association *asoc, goto out; param_len += str_nums *sizeof (__u16) + -sizeof (struct sctp_strreset_inreq ); + (out ?sizeof (struct sctp_strreset_inreq ) + :sizeof (struct sctp_strreset_outreq )); } if (param_len > SCTP_MAX_CHUNK_LEN -
@@ -639,6 +640,9 @@ struct sctp_chunk *sctp_process_strreset_inreq( nums = (ntohs (param.p->length) -sizeof (*inreq)) /sizeof (__u16); str_p = inreq->list_of_streams; +if (nums *sizeof (__u16) +sizeof (struct sctp_strreset_outreq ) > +SCTP_MAX_CHUNK_LEN -sizeof (struct sctp_reconf_chunk )) + goto out;for (i =0 ; i < nums; i++) {if (ntohs (str_p[i]) >= stream->outcnt) { result =SCTP_STRRESET_ERR_WRONG_SSN ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 84/389 tipc: fix infinite loop in __tipc_nl_compat_dumpit
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Helen Koike <[email protected]>
[ Upstream commit 22f8aa35964e8f2ab026578f45befc9605fd1b28 ]
cmd->dumpit callback can return a negative errno, causing an infinite loop due to the while(len) condition. As the loop never terminates, genl_mutex is never released, and other tasks waiting on it starve in D state.
Check dumpit's return value, propagate it and jump to err_out on error.
--- net/tipc/netlink_compat.c | 4 ++++ 1 file changed, 4 insertions(+)
net/tipc/netlink_compat.c +4 -0
@@ -223,6 +223,10 @@ static int __tipc_nl_compat_dumpit(struct tipc_nl_compat_cmd_dump *cmd,int rem; len = (*cmd->dumpit)(buf, &cb); +if (len <0 ) { + err = len; + goto err_out; + }nlmsg_for_each_msg (nlmsg,nlmsg_hdr (buf), len, rem) { err = nlmsg_parse_deprecated(nlmsg, GENL_HDRLEN,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 85/389 wifi: brcmfmac: fix 802.1X-SHA256 call trace warning
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shelley Yang <[email protected]>
[ Upstream commit 7cb34f6c4fe8a68af621d870abe63bfca2275dd6 ]
Based on wpa_auth as 1x_256 mode, need to set up "use_fwsup" with BRCMF_PROFILE_FWSUP_1X.
Or it will happen trace warning when call brcmf_cfg80211_set_pmk().
[ 4481.831101] ------------[ cut here ]------------ [ 4481.831102] WARNING: CPU: 1 PID: 2997 at drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c:7242 brcmf_cfg80211_set_pmk+0x77/0xd0 [brcmfmac] [...] [ 4481.831202] Call Trace: [ 4481.831204] <TASK> [ 4481.831205] nl80211_set_pmk+0x183/0x250 [cfg80211] [ 4481.831233] genl_family_rcv_msg_doit+0xea/0x150 [ 4481.831237] genl_rcv_msg+0x104/0x240 [ 4481.831239] ? cfg80211_probe_status+0x2c0/0x2c0 [cfg80211] [ 4481.831257] ? genl_family_rcv_msg_doit+0x150/0x150 [ 4481.831259] netlink_rcv_skb+0x4e/0x100 [ 4481.831261] genl_rcv+0x24/0x40 [ 4481.831262] netlink_unicast+0x236/0x380 [ 4481.831264] netlink_sendmsg+0x250/0x4b0 [ 4481.831266] sock_sendmsg+0x5c/0x70 [ 4481.831269] ____sys_sendmsg+0x236/0x2b0 [ 4481.831271] ? copy_msghdr_from_user+0x6d/0xa0 [ 4481.831272] ___sys_sendmsg+0x86/0xd0 [ 4481.831274] ? avc_has_perm+0x8c/0x1a0 [ 4481.831276] ? preempt_count_add+0x6a/0xa0 [ 4481.831279] ? sock_has_perm+0x82/0xa0 [ 4481.831280] __sys_sendmsg+0x57/0xa0 [ 4481.831282] do_syscall_64+0x38/0x90 [ 4481.831284] entry_SYSCALL_64_after_hwframe+0x63/0xcd [ 4481.831286] RIP: 0033:0x7fd270d369b4
--- drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +1 -1
@@ -1790,7 +1790,7 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme) sme->crypto.cipher_group);return -EINVAL ; } - }else if (val & (WPA2_AUTH_PSK |WPA2_AUTH_UNSPECIFIED )) { + }else if (val & (WPA2_AUTH_PSK |WPA2_AUTH_UNSPECIFIED |WPA2_AUTH_1X_SHA256 )) {switch (sme->crypto.akm_suites[0 ]) {case WLAN_AKM_SUITE_8021X : val =WPA2_AUTH_UNSPECIFIED ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 86/389 net: bridge: vlan: add support for global options
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikolay Aleksandrov <[email protected]>
[ Upstream commit 47ecd2dbd8ec43125ea75d7d2e73c888cda8663f ]
We can have two types of vlan options depending on context:
- per-device vlan options (split in per-bridge and per-port)
- global vlan options
The second type wasn't supported in the bridge until now, but we need them for per-vlan multicast support, per-vlan STP support and other options which require global vlan context. They are contained in the global bridge vlan context even if the vlan is not configured on the bridge device itself. This patch adds initial netlink attributes and support for setting these global vlan options, they can only be set (RTM_NEWVLAN) and the operation must use the bridge device. Since there are no such options yet it shouldn't have any functional effect.
Stable-dep-of: 43171c97e471 ("net: bridge: vlan: fix vlan range dumps starting with pvid")
--- include/uapi/linux/if_bridge.h | 13 ++++++ net/bridge/br_private.h | 4 ++ net/bridge/br_vlan.c | 16 +++++-- net/bridge/br_vlan_options.c | 85 ++++++++++++++++++++++++++++++++++ 4 files changed, 115 insertions(+), 3 deletions(-)
include/uapi/linux/if_bridge.h +13 -0
@@ -360,10 +360,15 @@ enum {* [BRIDGE_VLANDB_ENTRY_INFO] * ... * } +* [BRIDGE_VLANDB_GLOBAL_OPTIONS] = { +* [BRIDGE_VLANDB_GOPTS_ID] +* ... +* } */ enum {BRIDGE_VLANDB_UNSPEC ,BRIDGE_VLANDB_ENTRY , +BRIDGE_VLANDB_GLOBAL_OPTIONS , __BRIDGE_VLANDB_MAX, };#define BRIDGE_VLANDB_MAX (__BRIDGE_VLANDB_MAX - 1)
@@ -413,6 +418,14 @@ enum { };#define BRIDGE_VLANDB_STATS_MAX (__BRIDGE_VLANDB_STATS_MAX - 1) +enum { +BRIDGE_VLANDB_GOPTS_UNSPEC , +BRIDGE_VLANDB_GOPTS_ID , +BRIDGE_VLANDB_GOPTS_RANGE , + __BRIDGE_VLANDB_GOPTS_MAX +}; +#define BRIDGE_VLANDB_GOPTS_MAX (__BRIDGE_VLANDB_GOPTS_MAX - 1) +/* Bridge multicast database attributes * [MDBA_MDB] = { * [MDBA_MDB_ENTRY] = {
net/bridge/br_private.h +4 -0
@@ -1327,6 +1327,10 @@ int br_vlan_process_options(const struct net_bridge *br,struct net_bridge_vlan *range_end, struct nlattr **tb, struct netlink_ext_ack *extack); +int br_vlan_rtm_process_global_options (struct net_device *dev, +const struct nlattr *attr, +int cmd, +struct netlink_ext_ack *extack);/* vlan state manipulation helpers using *_ONCE to annotate lock-free access */ static inline u8 br_vlan_get_state (const struct net_bridge_vlan *v)
net/bridge/br_vlan.c +13 -3
@@ -2062,12 +2062,22 @@ static int br_vlan_rtm_process(struct sk_buff *skb, struct nlmsghdr *nlh, }nlmsg_for_each_attr (attr, nlh,sizeof (*bvm), rem) { -if (nla_type (attr) !=BRIDGE_VLANDB_ENTRY ) +switch (nla_type (attr)) { +case BRIDGE_VLANDB_ENTRY : + err =br_vlan_rtm_process_one (dev, attr, + nlh->nlmsg_type, + extack); +break ; +case BRIDGE_VLANDB_GLOBAL_OPTIONS : + err =br_vlan_rtm_process_global_options (dev, attr, + nlh->nlmsg_type, + extack); +break ; +default :continue ; + } vlans++; - err =br_vlan_rtm_process_one (dev, attr, nlh->nlmsg_type, - extack);if (err)break ; }
net/bridge/br_vlan_options.c +85 -0
88 lines not on this page · raw message
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 87/389 net: bridge: vlan: add support for dumping global vlan options
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikolay Aleksandrov <[email protected]>
[ Upstream commit 743a53d9636aad83da63a8638e8365e817ef6365 ]
Add a new vlan options dump flag which causes only global vlan options to be dumped. The dumps are done only with bridge devices, ports are ignored. They support vlan compression if the options in sequential vlans are equal (currently always true).
Stable-dep-of: 43171c97e471 ("net: bridge: vlan: fix vlan range dumps starting with pvid")
--- include/uapi/linux/if_bridge.h | 1 + net/bridge/br_private.h | 4 ++++ net/bridge/br_vlan.c | 41 +++++++++++++++++++++++++++------- net/bridge/br_vlan_options.c | 31 +++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 8 deletions(-)
include/uapi/linux/if_bridge.h +1 -0
@@ -354,6 +354,7 @@ enum {/* flags used in BRIDGE_VLANDB_DUMP_FLAGS attribute to affect dumps */ #define BRIDGE_VLANDB_DUMPF_STATS (1 << 0)/* Include stats in the dump */ +#define BRIDGE_VLANDB_DUMPF_GLOBAL (1 << 1)/* Dump global vlan options only */ /* Bridge vlan RTM attributes * [BRIDGE_VLANDB_ENTRY] = {
net/bridge/br_private.h +4 -0
@@ -1331,6 +1331,10 @@ int br_vlan_rtm_process_global_options(struct net_device *dev,const struct nlattr *attr, int cmd, struct netlink_ext_ack *extack); +bool br_vlan_global_opts_can_enter_range (const struct net_bridge_vlan *v_curr, +const struct net_bridge_vlan *r_end); +bool br_vlan_global_opts_fill (struct sk_buff *skb,u16 vid,u16 vid_range, +const struct net_bridge_vlan *v_opts);/* vlan state manipulation helpers using *_ONCE to annotate lock-free access */ static inline u8 br_vlan_get_state (const struct net_bridge_vlan *v)
net/bridge/br_vlan.c +33 -8
71 lines not on this page · raw message
net/bridge/br_vlan_options.c +31 -0
@@ -259,6 +259,37 @@ int br_vlan_process_options(const struct net_bridge *br,return err; } +bool br_vlan_global_opts_can_enter_range (const struct net_bridge_vlan *v_curr, +const struct net_bridge_vlan *r_end) +{ +return v_curr->vid - r_end->vid ==1 ; +} + +bool br_vlan_global_opts_fill (struct sk_buff *skb,u16 vid,u16 vid_range, +const struct net_bridge_vlan *v_opts) +{ +struct nlattr *nest; + + nest =nla_nest_start (skb,BRIDGE_VLANDB_GLOBAL_OPTIONS ); +if (!nest) +return false; + +if (nla_put_u16 (skb,BRIDGE_VLANDB_GOPTS_ID , vid)) + goto out_err; + +if (vid_range && vid < vid_range && +nla_put_u16 (skb,BRIDGE_VLANDB_GOPTS_RANGE , vid_range)) + goto out_err; + +nla_nest_end (skb, nest); + +return true; + +out_err: +nla_nest_cancel (skb, nest); +return false; +} + static int br_vlan_process_global_one_opts(const struct net_bridge *br, struct net_bridge_vlan_group *vg, struct net_bridge_vlan *v,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 88/389 net: bridge: vlan: fix vlan range dumps starting with pvid
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikolay Aleksandrov <[email protected]>
[ Upstream commit 43171c97e4714bf601b468401b37732244639c21 ]
There is a bug in all range dumps that rely on br_vlan_can_enter_range() when the PVID is a range starting VLAN, all following VLANs that match its flags can enter the range, but when the range is filled in only the PVID VLAN is dumped and the rest of the range is discarded because br_vlan_fill_vids() checks for the PVID flag. Since the PVID VLAN can be only one, we need to break ranges around it, the best way to do that consistently for all is to alter br_vlan_can_enter_range() to take into account the PVID and return false to break the range when it's matched.
Before the fix:
$ ip l add br0 type bridge vlan_filtering 1
$ ip l add dumdum type dummy
$ ip l set dumdum master br0
$ ip l set br0 up
$ ip l set dumdum up
$ bridge vlan add dev dumdum vid 1 pvid untagged master
$ bridge vlan add dev dumdum vid 2 untagged master
$ bridge vlan show dev dumdum # use legacy dump to show all vlans
port vlan-id
dumdum 1 PVID Egress Untagged
2 Egress Untagged$ bridge -d vlan show dev dumdum # use the new dump (RTM_GETVLAN)
port vlan-id
dumdum 1 PVID Egress Untagged
state forwarding mcast_router 1VLAN 2 is missing, and if there are more matching VLANs afterwards they'd be missing too.
After the fix:
[ same setup steps ]
$ bridge vlan show dev dumdum
port vlan-id
dumdum 1 PVID Egress Untagged
2 Egress Untagged
$ bridge -d vlan show dev dumdum # use the new dump (RTM_GETVLAN)
port vlan-id
dumdum 1 PVID Egress Untagged
state forwarding mcast_router 1
2 Egress Untagged
state forwarding mcast_router 1--- 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 +-- 4 files changed, 13 insertions(+), 9 deletions(-)
net/bridge/br_netlink_tunnel.c +2 -1
@@ -268,7 +268,8 @@ static void __vlan_tunnel_handle_range(const struct net_bridge_port *p,if (!*v_start) goto out_init; -if (v && curr_change &&br_vlan_can_enter_range (v, *v_end)) { +if (v && curr_change && +br_vlan_can_enter_range (v, *v_end,br_get_pvid (vg))) { *v_end = v;return ; }
net/bridge/br_private.h +4 -2
@@ -1093,7 +1093,8 @@ void br_vlan_notify(const struct net_bridge *br, u16 vid, u16 vid_range, int cmd);bool br_vlan_can_enter_range (const struct net_bridge_vlan *v_curr, -const struct net_bridge_vlan *range_end); +const struct net_bridge_vlan *range_end, +u16 pvid);static inline struct net_bridge_vlan_group *br_vlan_group (const struct net_bridge *br)
@@ -1309,7 +1310,8 @@ static inline void br_vlan_notify(const struct net_bridge *br, }static inline bool br_vlan_can_enter_range (const struct net_bridge_vlan *v_curr, -const struct net_bridge_vlan *range_end) +const struct net_bridge_vlan *range_end, +u16 pvid) {return true; }
net/bridge/br_vlan.c +6 -4
@@ -1764,9 +1764,11 @@ void br_vlan_notify(const struct net_bridge *br,/* check if v_curr can enter a range ending in range_end */ bool br_vlan_can_enter_range (const struct net_bridge_vlan *v_curr, -const struct net_bridge_vlan *range_end) +const struct net_bridge_vlan *range_end, +u16 pvid) { -return v_curr->vid - range_end->vid ==1 && +return v_curr->vid != pvid && range_end->vid != pvid && + v_curr->vid - range_end->vid ==1 && range_end->flags == v_curr->flags &&br_vlan_opts_eq_range (v_curr, range_end); }
@@ -1848,8 +1850,8 @@ static int br_vlan_dump_dev(const struct net_device *dev, idx += range_end->vid - range_start->vid +1 ; range_start = v; - } else if (dump_stats || v->vid == pvid || - !br_vlan_can_enter_range(v, range_end)) { + } else if (dump_stats || + !br_vlan_can_enter_range(v, range_end, pvid)) { u16 vlan_flags = br_vlan_flags(range_start, pvid); if (!br_vlan_fill_vids(skb, range_start->vid,
net/bridge/br_vlan_options.c +1 -2
@@ -234,8 +234,7 @@ int br_vlan_process_options(const struct net_bridge *br,continue ; } -if (v->vid == pvid || - !br_vlan_can_enter_range (v, curr_end)) { +if (!br_vlan_can_enter_range (v, curr_end, pvid)) {br_vlan_notify (br, p, curr_start->vid, curr_end->vid,RTM_NEWVLAN ); curr_start = v;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 89/389 sctp: auth: verify auth requirement when auth_chunk is NULL
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qing Luo <[email protected]>
[ Upstream commit 8e04823c120b376ef7dab14b60ebf6823aa16c14 ]
sctp_auth_chunk_verify() returns true unconditionally when chunk->auth_chunk is NULL, silently skipping authentication. This is incorrect when:
1. skb_clone() failed in the BH receive path, leaving auth_chunk NULL. In sctp_endpoint_bh_rcv() asoc is NULL for new connections, so the early sctp_auth_recv_cid() check cannot catch this.
2. No AUTH chunk precedes COOKIE-ECHO, so skb_clone() is never called and auth_chunk remains NULL.
Fix by checking sctp_auth_recv_cid() when auth_chunk is NULL:
if authentication is required, return false to drop the chunk; otherwise continue normally.
--- net/sctp/sm_statefuns.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/sctp/sm_statefuns.c +1 -1
@@ -632,7 +632,7 @@ static bool sctp_auth_chunk_verify(struct net *net, struct sctp_chunk *chunk,struct sctp_chunk auth;if (!chunk->auth_chunk) -return true; +return !sctp_auth_recv_cid (chunk->chunk_hdr->type, asoc);/* SCTP-AUTH: auth_chunk pointer is only set when the cookie-echo * is supposed to be authenticated and we have to do delayed
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 90/389 vmxnet3: fix BUG_ON in vmxnet3_get_hdr_len() for Geneve packets
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Harshaka Narayana <[email protected]>
[ Upstream commit 34a71f5361fc3adb5b7138da78750b0d535a8252 ]
vmxnet3_get_hdr_len() assumes gdesc->rcd.v4/v6/tcp always describe the outer header, but for a Geneve-encapsulated packet the device can set them based on the inner header instead, signalled by the VMXNET3_RCD_HDR_INNER_SHIFT bit in the completion descriptor. Since the function never skips the outer encapsulation, this mismatch triggers:
- BUG_ON(hdr.ipv4->protocol != IPPROTO_TCP), because the outer protocol is UDP (Geneve), not TCP.
- BUG_ON(hdr.eth->h_proto != ...), when the tunnel's outer and inner IP versions differ (e.g. outer IPv6/inner IPv4 or vice versa).
Check VMXNET3_RCD_HDR_INNER_SHIFT up front and bail out, since the function cannot locate the inner header it would need to parse. Also convert the remaining BUG_ON()s in this function to return 0 defensively.
--- drivers/net/vmxnet3/vmxnet3_drv.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-)
drivers/net/vmxnet3/vmxnet3_drv.c +16 -6
@@ -1313,7 +1313,11 @@ vmxnet3_get_hdr_len(struct vmxnet3_adapter *adapter, struct sk_buff *skb,struct ipv6hdr *ipv6;struct tcphdr *tcp; } hdr; -BUG_ON (gdesc->rcd.tcp ==0 ); + +/* v4/v6/tcp then describe the inner header, which we can't locate. */ +if ((le32_to_cpu (gdesc->dword[0 ]) & (1UL <<VMXNET3_RCD_HDR_INNER_SHIFT )) || + gdesc->rcd.tcp ==0 ) +return 0 ; maplen =skb_headlen (skb);if (unlikely (sizeof (struct iphdr ) +sizeof (struct tcphdr ) > maplen))
@@ -1327,15 +1331,21 @@ vmxnet3_get_hdr_len(struct vmxnet3_adapter *adapter, struct sk_buff *skb, hdr.eth =eth_hdr (skb);if (gdesc->rcd.v4) { -BUG_ON (hdr.eth->h_proto !=htons (ETH_P_IP ) && - hdr.veth->h_vlan_encapsulated_proto !=htons (ETH_P_IP )); +if (hdr.eth->h_proto !=htons (ETH_P_IP ) && + hdr.veth->h_vlan_encapsulated_proto !=htons (ETH_P_IP )) +return 0 ; + hdr.ptr += hlen; -BUG_ON (hdr.ipv4->protocol !=IPPROTO_TCP ); +if (hdr.ipv4->protocol !=IPPROTO_TCP ) +return 0 ; + hlen = hdr.ipv4->ihl <<2 ; hdr.ptr += hdr.ipv4->ihl <<2 ; }else if (gdesc->rcd.v6) { -BUG_ON (hdr.eth->h_proto !=htons (ETH_P_IPV6 ) && - hdr.veth->h_vlan_encapsulated_proto !=htons (ETH_P_IPV6 )); +if (hdr.eth->h_proto !=htons (ETH_P_IPV6 ) && + hdr.veth->h_vlan_encapsulated_proto !=htons (ETH_P_IPV6 )) +return 0 ; + hdr.ptr += hlen;/* Use an estimated value, since we also need to handle * TSO case.
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 91/389 tipc: fix u16 MTU truncation in media and bearer MTU validation
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cen Zhang (Microsoft) <[email protected]>
[ Upstream commit 9f29cd8a8e7901a2617c8064ce9f50fc67b97cb8 ]
Both TIPC_NL_MEDIA_SET and TIPC_NL_BEARER_SET accept user-supplied MTU values but only enforce a minimum bound, not a maximum. When a user sets the MTU to a value exceeding U16_MAX (65535), it passes validation but is silently truncated when assigned to u16 fields l->mtu and l->advertised_mtu in tipc_link_create(). Values like 65536 (0x10000) truncate to 0, causing a division by zero in tipc_link_set_queue_limits() which computes TIPC_MAX_PUBL / (l->mtu / ITEM_SIZE). Other overflowing values (e.g. 65537-131071) produce small incorrect MTU values, resulting in link malfunction behaviors.
Crash stack (triggered as unprivileged user via user namespace):
tipc_link_set_queue_limits net/tipc/link.c:2531 tipc_link_create net/tipc/link.c:520 tipc_node_check_dest net/tipc/node.c:1279 tipc_disc_rcv net/tipc/discover.c:252 tipc_rcv net/tipc/node.c:2129 tipc_udp_recv net/tipc/udp_media.c:392
Two independent paths lack the upper bound check:
1. tipc_udp_mtu_bad() -- called from __tipc_nl_media_set() (MEDIA_SET)
2. inline check in __tipc_nl_bearer_set() at bearer.c:1160 (BEARER_SET)
Fix both by rejecting MTU values above U16_MAX.
--- net/tipc/netlink.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
net/tipc/netlink.c +5 -1
@@ -113,12 +113,16 @@ const struct nla_policy tipc_nl_node_pol };/* Properties valid for media, bearer and link */ +static struct netlink_range_validation tipc_nl_mtu_range = { + .max =U16_MAX , +}; +const struct nla_policy tipc_nl_prop_policy[TIPC_NLA_PROP_MAX +1 ] = { [TIPC_NLA_PROP_UNSPEC ] = { .type =NLA_UNSPEC }, [TIPC_NLA_PROP_PRIO ] = { .type =NLA_U32 }, [TIPC_NLA_PROP_TOL ] = { .type =NLA_U32 }, [TIPC_NLA_PROP_WIN ] = { .type =NLA_U32 }, - [TIPC_NLA_PROP_MTU ] = { .type =NLA_U32 }, + [TIPC_NLA_PROP_MTU ] =NLA_POLICY_FULL_RANGE (NLA_U32 , &tipc_nl_mtu_range), [TIPC_NLA_PROP_BROADCAST ] = { .type =NLA_U32 }, [TIPC_NLA_PROP_BROADCAST_RATIO ] = { .type =NLA_U32 } };
Greg Kroah-Hartman
maintainerPATCH 92/389 net: stmmac: reset residual action in L3L4 filters on delete
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nazim Amirul <[email protected]>
[ Upstream commit a448f821289934b961dd9d8d0beb006cc8937ba2 ]
When deleting an L3/L4 flower filter entry, the action field is not reset. If a filter was previously configured with a drop action, that action may persist and affect subsequent filter configurations unintentionally.
Clear the action field when the filter entry is deleted.
--- drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c +1 -0
@@ -603,6 +603,7 @@ static int tc_del_flow(struct stmmac_priv *priv, entry->in_use = false; entry->cookie =0 ; entry->is_l4 = false; + entry->action =0 ;return ret; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 93/389 ipv4: icmp: fill flow parameters in icmp_route_lookup decoy lookup
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 853e164c2b321f0711361bc23505aaeb7dc432c3 ]
When Linux forwards a packet and needs to generate an ICMP error, icmp_route_lookup() performs a reverse-path relookup. For non-local destinations, it performs a decoy lookup to find the expected egress interface (rt2->dst.dev) before validating the path with ip_route_input().
Currently, the decoy flow structure (fl4_2) only sets .daddr = fl4_dec.saddr, leaving .saddr, .flowi4_dscp, .flowi4_proto, .flowi4_mark, .flowi4_oif, .fl4_sport, .fl4_dport, and .flowi4_uid zeroed out.
When policy routing rules (such as ip rule add from $SRC lookup 100, or dscp/fwmark/ipproto/port rules, or VRF bindings) are configured:
1. The decoy lookup fails to match the policy rule because saddr and other key flow selectors are missing in fl4_2.
2. It resolves a route using the default table instead, returning an incorrect egress netdev.
3. Passing the wrong netdev to ip_route_input() causes strict reverse-path filtering (rp_filter=1) to fail, logging false-positive "martian source" warnings and causing the relookup to fail.
Fix this by initializing fl4_2 from fl4_dec and:
- Swapping source/destination IP addresses.
- Swapping L4 ports for transport protocols with ports (TCP, UDP, SCTP, DCCP) so port-based policy routing matches correctly. Non-port protocols (such as ICMP or GRE) leave the flowi_uli union fields intact to prevent corruption.
- Setting .flowi4_oif = l3mdev_master_ifindex(route_lookup_dev) to ensure VRF routing tables are respected.
- Setting .flowi4_flags |= FLOWI_FLAG_ANYSRC to allow output route lookups for non-local source IP addresses.
- Using __ip_route_output_key() instead of ip_route_output_key() for fl4_2 so that raw FIB routing is used without triggering spurious XFRM policy lookups on the decoy flow (the actual XFRM lookup is performed later using fl4_dec).
--- net/ipv4/icmp.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
net/ipv4/icmp.c +15 -3
@@ -533,11 +533,23 @@ static struct rtable *icmp_route_lookup(struct net *net,if (IS_ERR (rt2)) err =PTR_ERR (rt2); }else { -struct flowi4 fl4_2 = {}; +struct flowi4 fl4_2 = fl4_dec;unsigned long orefdst; - fl4_2.daddr = fl4_dec.saddr; - rt2 =ip_route_output_key (net, &fl4_2); +swap (fl4_2.daddr, fl4_2.saddr); +switch (fl4_2.flowi4_proto) { +case IPPROTO_TCP : +case IPPROTO_UDP : +case IPPROTO_SCTP : +case IPPROTO_DCCP : +swap (fl4_2.fl4_sport, fl4_2.fl4_dport); +break ; + } + + fl4_2.flowi4_oif =l3mdev_master_ifindex (route_lookup_dev); + fl4_2.flowi4_flags |=FLOWI_FLAG_ANYSRC ; + + rt2 =__ip_route_output_key (net, &fl4_2);if (IS_ERR (rt2)) { err =PTR_ERR (rt2); goto relookup_failed;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 94/389 hinic: remove unused ethtool RSS user configuration buffers
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chenguang Zhao <[email protected]>
[ Upstream commit fe0c002928c6749b7f4a726f6f600f6dd70280ea ]
rss_indir_user and rss_hkey_user are allocated and filled in __set_rss_rxfh() when the user configures RSS via ethtool, but nothing ever reads them. hinic_get_rxfh() fetches the state from the device, and the hardware is programmed from the original indir/key arguments. These buffers only leaked on driver unload.
Drop the unused allocations, memcpys, and struct fields.
--- drivers/net/ethernet/huawei/hinic/hinic_dev.h | 2 -- .../net/ethernet/huawei/hinic/hinic_ethtool.c | 21 ------------------- 2 files changed, 23 deletions(-)
drivers/net/ethernet/huawei/hinic/hinic_dev.h +0 -2
@@ -100,8 +100,6 @@ struct hinic_dev {u16 num_rss;u16 rss_limit;struct hinic_rss_type rss_type; -u8 *rss_hkey_user; -s32 *rss_indir_user;struct hinic_intr_coal_info *rx_intr_coalesce;struct hinic_intr_coal_info *tx_intr_coalesce;struct hinic_sriov_info sriov_info;
drivers/net/ethernet/huawei/hinic/hinic_ethtool.c +0 -21
@@ -1061,17 +1061,6 @@ static int __set_rss_rxfh(struct net_device *netdev,int err;if (indir) { -if (!nic_dev->rss_indir_user) { - nic_dev->rss_indir_user = -kzalloc (sizeof (u32) *HINIC_RSS_INDIR_SIZE , -GFP_KERNEL ); -if (!nic_dev->rss_indir_user) -return -ENOMEM ; - } - -memcpy (nic_dev->rss_indir_user, indir, -sizeof (u32) *HINIC_RSS_INDIR_SIZE ); - err =hinic_rss_set_indir_tbl (nic_dev, nic_dev->rss_tmpl_idx, indir);if (err)
@@ -1079,16 +1068,6 @@ static int __set_rss_rxfh(struct net_device *netdev, }if (key) { -if (!nic_dev->rss_hkey_user) { - nic_dev->rss_hkey_user = -kzalloc (HINIC_RSS_KEY_SIZE *2 ,GFP_KERNEL ); - -if (!nic_dev->rss_hkey_user) -return -ENOMEM ; - } - -memcpy (nic_dev->rss_hkey_user, key,HINIC_RSS_KEY_SIZE ); - err =hinic_rss_set_template_tbl (nic_dev, nic_dev->rss_tmpl_idx, key);if (err)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 95/389 net: qrtr: restrict socket creation to the initial network namespace
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aldo Ariel Panzardo <[email protected]>
[ Upstream commit 3b536db8fb32da9e9c62f2bb45e2e319331f0426 ]
QRTR keeps its entire port and node state in module-global variables that are not partitioned per network namespace: qrtr_local_nid is a single global node id (always 1) and qrtr_ports is a single global xarray. qrtr_port_lookup() and qrtr_local_enqueue() operate on that global state with no network-namespace check, and qrtr_create() places no restriction on the namespace a socket is created in.
As a result an unprivileged process that creates an AF_QIPCRTR socket in a separate network namespace, e.g. via unshare(CLONE_NEWUSER | CLONE_NEWNET), can send QRTR datagrams - including control-plane messages such as QRTR_TYPE_NEW_SERVER - to QRTR sockets owned by another namespace, and vice versa. The receiving socket sees such a message as coming from node id 1, indistinguishable from a legitimate local client, breaking the isolation that network namespaces are expected to provide.
QRTR is a transport to global hardware endpoints (the modem and other remote processors) and has no per-namespace semantics; its in-kernel name service already creates its socket in init_net only. Confine the socket family to the initial network namespace, as other non-namespace-aware socket families do (see llc_ui_create() and the ieee802154 socket code).
--- net/qrtr/af_qrtr.c | 8 ++++++++ 1 file changed, 8 insertions(+)
net/qrtr/af_qrtr.c +8 -0
@@ -1257,6 +1257,14 @@ static int qrtr_create(struct net *net, struct socket *sock,if (sock->type !=SOCK_DGRAM )return -EPROTOTYPE ; +/* QRTR keeps its port and node state in module-global variables that +* are not partitioned per network namespace, and the in-kernel name +* service only operates in init_net. Confine the family to init_net so +* a socket in another namespace cannot reach the global control plane. +*/ +if (!net_eq (net, &init_net)) +return -EAFNOSUPPORT ; + sk =sk_alloc (net,AF_QIPCRTR ,GFP_KERNEL , &qrtr_proto, kern);if (!sk)return -ENOMEM ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 96/389 net/mlx5: E-Switch, fix zero num_dest in prio_tag egress vlan rule
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yael Chemla <[email protected]>
[ Upstream commit d12956d083eb70f2c6d72711aebaf8c2ce21e170 ]
esw_egress_acl_vlan_create() hardcodes num_dest=0 in its mlx5_add_flow_rules() call. When invoked from the non-bond path fwd_dest is NULL and num_dest=0 is correct. When invoked from esw_acl_egress_ofld_rules_create() during a bond event, fwd_dest is non-NULL and flow_act.action carries MLX5_FLOW_CONTEXT_ACTION_FWD_DEST, but _mlx5_add_flow_rules() rejects a non-NULL dest pointer paired with dest_num<=0 and returns -EINVAL. The error propagates as "configure slave vport egress fwd, err(-22)". The passive vport's egress ACL table ends up with its flow groups allocated but no FTEs, so prio-tagged packets are not popped and bond failover is broken on prio_tag_required devices.
Fix by passing fwd_dest ? 1 : 0 as num_dest to match the actual number of destinations supplied.
--- drivers/net/ethernet/mellanox/mlx5/core/esw/acl/helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/esw/acl/helper.c +1 -1
@@ -67,7 +67,7 @@ int esw_egress_acl_vlan_create(struct mlx5_eswitch *esw, flow_act.action = flow_action; vport->egress.allowed_vlan =mlx5_add_flow_rules (vport->egress.acl, spec, - &flow_act, fwd_dest,0 ); + &flow_act, fwd_dest, fwd_dest ?1 :0 );if (IS_ERR (vport->egress.allowed_vlan)) { err =PTR_ERR (vport->egress.allowed_vlan); esw_warn(esw->dev,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 97/389 net/mlx5e: Report zero bandwidth for non-ETS traffic classes
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexei Lazar <[email protected]>
[ Upstream commit ffb1873b2df11945b8c395e859169248675c91c5 ]
The IEEE 802.1Qaz standard defines that bandwidth allocation percentages only apply to Enhanced Transmission Selection (ETS) traffic classes. For STRICT and VENDOR transmission selection algorithms, bandwidth percentage values are not applicable.
Currently for non-ETS 100 bandwidth is being reported for all traffic classes in the get operation due to hardware limitation, regardless of their TSA type.
Fix this by reporting 0 for non-ETS traffic classes.
--- drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c +7 -0
@@ -158,6 +158,13 @@ static int mlx5e_dcbnl_ieee_getets(struct net_device *netdev, }memcpy (ets->tc_tsa, priv->dcbx.tc_tsa,sizeof (ets->tc_tsa)); +/* Report 0 for non ETS TSA */ +for (i =0 ; i < ets->ets_cap; i++) { +if (ets->tc_tx_bw[i] ==MLX5E_MAX_BW_ALLOC && + priv->dcbx.tc_tsa[i] !=IEEE_8021QAZ_TSA_ETS ) + ets->tc_tx_bw[i] =0 ; + } +return err; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 98/389 net/mlx5e: Reject unsupported CB Shaper TSA in ETS validation
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexei Lazar <[email protected]>
[ Upstream commit 9173e1d3c7c7d49a71eee813091f9e834ec7cee5 ]
Credit Based (CB) TSA is not supported by the mlx5 driver, so reject any configurations that specify it.
--- drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c +8 -0
@@ -309,6 +309,14 @@ static int mlx5e_dbcnl_validate_ets(struct net_device *netdev, } } +for (i =0 ; i <IEEE_8021QAZ_MAX_TCS ; i++) { +if (ets->tc_tsa[i] ==IEEE_8021QAZ_TSA_CB_SHAPER ) { +netdev_err (netdev, +"Failed to validate ETS: CB Shaper is not supported\n" ); +return -EOPNOTSUPP ; + } + } +/* Validate Bandwidth Sum */ for (i =0 ; i <IEEE_8021QAZ_MAX_TCS ; i++) {if (ets->tc_tsa[i] ==IEEE_8021QAZ_TSA_ETS ) {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 99/389 raw: use more conventional iterators
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit ba44f8182ec299c5d1c8a72fc0fde4ec127b5a6d ]
In order to prepare the following patch,
I change raw v4 & v6 code to use more conventional iterators.
Stable-dep-of: 440e274da4d1 ("net: ipv6: fix dif and sdif mismatch in raw6_icmp_error")
--- include/net/raw.h | 5 +- include/net/rawv6.h | 6 +-- net/ipv4/raw.c | 95 +++++++++++++++++------------------------------ net/ipv4/raw_diag.c | 33 ++++++++-------- net/ipv6/raw.c | 103 ++++++++++++++++++---------------------------------- 5 files changed, 92 insertions(+), 150 deletions(-)
include/net/raw.h +2 -3
@@ -20,9 +20,8 @@extern struct proto raw_prot;extern struct raw_hashinfo raw_v4_hashinfo; -struct sock *__raw_v4_lookup (struct net *net,struct sock *sk, -unsigned short num,__be32 raddr, -__be32 laddr,int dif,int sdif); +bool raw_v4_match (struct net *net,struct sock *sk,unsigned short num, +__be32 raddr,__be32 laddr,int dif,int sdif);int raw_abort (struct sock *sk,int err);void raw_icmp_error (struct sk_buff *,int ,u32 );
include/net/rawv6.h +3 -3
@@ -5,9 +5,9 @@#include <net/protocol.h> extern struct raw_hashinfo raw_v6_hashinfo; -struct sock *__raw_v6_lookup (struct net *net,struct sock *sk, -unsigned short num,const struct in6_addr *loc_addr, -const struct in6_addr *rmt_addr,int dif,int sdif); +bool raw_v6_match (struct net *net,struct sock *sk,unsigned short num, +const struct in6_addr *loc_addr, +const struct in6_addr *rmt_addr,int dif,int sdif);int raw_abort (struct sock *sk,int err);
net/ipv4/raw.c +34 -61
141 lines not on this page · raw message
net/ipv4/raw_diag.c +16 -17
@@ -34,31 +34,30 @@ raw_get_hashinfo(const struct inet_diag_* use helper to figure it out. */ -static struct sock *raw_lookup (struct net *net,struct sock *from, -const struct inet_diag_req_v2 *req) +static bool raw_lookup (struct net *net,struct sock *sk, +const struct inet_diag_req_v2 *req) {struct inet_diag_req_raw *r = (void *)req; -struct sock *sk =NULL ;if (r->sdiag_family ==AF_INET ) - sk =__raw_v4_lookup (net, from, r->sdiag_raw_protocol, - r->id.idiag_dst[0 ], - r->id.idiag_src[0 ], - r->id.idiag_if,0 ); +return raw_v4_match (net, sk, r->sdiag_raw_protocol, + r->id.idiag_dst[0 ], + r->id.idiag_src[0 ], + r->id.idiag_if,0 );#if IS_ENABLED (CONFIG_IPV6 ) else - sk =__raw_v6_lookup (net, from, r->sdiag_raw_protocol, - (const struct in6_addr *)r->id.idiag_src, - (const struct in6_addr *)r->id.idiag_dst, - r->id.idiag_if,0 ); + return raw_v6_match(net, sk, r->sdiag_raw_protocol, + (const struct in6_addr *)r->id.idiag_src, + (const struct in6_addr *)r->id.idiag_dst, + r->id.idiag_if,0 );#endif -return sk; +return false; }static struct sock *raw_sock_get (struct net *net,const struct inet_diag_req_v2 *r) {struct raw_hashinfo *hashinfo =raw_get_hashinfo (r); -struct sock *sk =NULL , *s; +struct sock *sk;int slot;if (IS_ERR (hashinfo))
@@ -66,9 +65,8 @@ static struct sock *raw_sock_get(structread_lock (&hashinfo->lock);for (slot =0 ; slot <RAW_HTABLE_SIZE ; slot++) { -sk_for_each (s, &hashinfo->ht[slot]) { - sk =raw_lookup (net, s, r); -if (sk) { +sk_for_each (sk, &hashinfo->ht[slot]) { +if (raw_lookup (net, sk, r)) {/* * Grab it and keep until we fill * diag meaage to be reported, so
@@ -81,10 +79,11 @@ static struct sock *raw_sock_get(struct } } } + sk =ERR_PTR (-ENOENT ); out_unlock:read_unlock (&hashinfo->lock); -return sk ? sk :ERR_PTR (-ENOENT ); +return sk; } static int raw_diag_dump_one(struct netlink_callback *cb,
net/ipv6/raw.c +37 -66
160 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 100/389 drm/rockchip: cdn-dp: add missing check in cdn_dp_config_video()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sergey Shtylyov <[email protected]>
commit 46c31e1604d121221167cb09380de8c7d53290b9 upstream.
The result of cdn_dp_reg_write() is checked everywhere (with the error being logged by the callers) except one place in cdn_dp_config_video(). Add the missing result check, bailing out early on error...
Found by Linux Verification Center (linuxtesting.org) with the Svace static analysis tool.
--- drivers/gpu/drm/rockchip/cdn-dp-reg.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/rockchip/cdn-dp-reg.c +2 -0
@@ -683,6 +683,8 @@ int cdn_dp_config_video(struct cdn_dp_de val =div_u64 (8 * (symbol +1 ), bit_per_pix) - val; val +=2 ; ret =cdn_dp_reg_write (dp,DP_VC_TABLE (15 ), val); +if (ret) + goto err_config_video;switch (video->color_depth) {case 6 :
Greg Kroah-Hartman
maintainerPATCH 101/389 drm/nouveau/acr: fix missing nvkm_done() in error path of nvkm_acr_oneinit()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <[email protected]>
commit c3027973f692077a1b66a9fb26d6a7c46c0dc72c upstream.
In nvkm_acr_oneinit(), nvkm_kmap(acr->wpr) is invoked unconditionally at line 309 to obtain a mapping reference. Additionally, when both acr->wpr_fw and acr->wpr_comp are present, a second nvkm_kmap() is called inside the conditional block. Both mappings are expected to be released by nvkm_done(acr->wpr) at line 320 before the function returns successfully.
However, when a mismatch is detected during the loop within the conditional block, the function returns -EINVAL at line 318 without calling nvkm_done(). This results in a leak of the kmap reference(s) acquired earlier.
Fix the issue by invoking nvkm_done(acr->wpr) prior to the early return to ensure proper release of the mapping references.
--- drivers/gpu/drm/nouveau/nvkm/subdev/acr/base.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/nouveau/nvkm/subdev/acr/base.c +1 -0
@@ -314,6 +314,7 @@ nvkm_acr_oneinit(struct nvkm_subdev *sub i, us, fw); } } +nvkm_done (acr->wpr);return -EINVAL ; }nvkm_done (acr->wpr);
Greg Kroah-Hartman
maintainerPATCH 102/389 drm/radeon: fix r100_copy_blit for large BOs
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pavel Ondračka <[email protected]>
commit f896e86273dbbebb5eac966b4a201b5c62a02e9a upstream.
r100_copy_blit() copies BOs as 1024-pixel-wide ARGB8888 blits, so one GPU page becomes one blit row. Large copies are split into chunks of at most 8191 rows.
The kernel register header names the packet coordinate dwords SRC_Y_X and DST_Y_X. In the BITBLT_MULTI description in R5xx_Acceleration_v1.5.pdf docs, these correspond to [SRC_X1 | SRC_Y1] and [DST_X1 | DST_Y1], which are signed 13-bit coordinates in the -8192..8191 range. The old code kept SRC/DST_PITCH_OFFSET at the BO base and used SRC_Y_X/DST_Y_X as the chunk address, so large BO moves could exceed that coordinate range.
Compute per-chunk SRC/DST_PITCH_OFFSET bases and emit zero source and destination coordinates. r100_copy_blit() already packs SRC/DST_PITCH_OFFSET as pitch plus base offset, so large chunk addresses belong there rather than in the coordinate fields.
This fixes Prison Architect corruption with 4096x4096 mipped textures after they are evicted to GTT under memory pressure on RV530.
--- drivers/gpu/drm/radeon/r100.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
drivers/gpu/drm/radeon/r100.c +9 -4
@@ -895,6 +895,7 @@ struct radeon_fence *r100_copy_blit(stru {struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX ];struct radeon_fence *fence; +uint64_t cur_src_offset, cur_dst_offset;uint32_t cur_pages;uint32_t stride_bytes =RADEON_GPU_PAGE_SIZE ;uint32_t pitch;
@@ -923,6 +924,10 @@ struct radeon_fence *r100_copy_blit(stru cur_pages =8191 ; } num_gpu_pages -= cur_pages; + cur_src_offset = src_offset + + (uint64_t )num_gpu_pages *RADEON_GPU_PAGE_SIZE ; + cur_dst_offset = dst_offset + + (uint64_t )num_gpu_pages *RADEON_GPU_PAGE_SIZE ;/* pages are in Y direction - height page width in X direction - width */
@@ -939,13 +944,13 @@ struct radeon_fence *r100_copy_blit(struRADEON_DP_SRC_SOURCE_MEMORY |RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS); -radeon_ring_write (ring, (pitch <<22 ) | (src_offset >>10 )); -radeon_ring_write (ring, (pitch <<22 ) | (dst_offset >>10 )); +radeon_ring_write (ring, (pitch <<22 ) | (cur_src_offset >>10 )); +radeon_ring_write (ring, (pitch <<22 ) | (cur_dst_offset >>10 ));radeon_ring_write (ring, (0x1fff ) | (0x1fff <<16 ));radeon_ring_write (ring,0 );radeon_ring_write (ring, (0x1fff ) | (0x1fff <<16 )); -radeon_ring_write (ring, num_gpu_pages); -radeon_ring_write (ring, num_gpu_pages); +radeon_ring_write (ring,0 ); +radeon_ring_write (ring,0 );radeon_ring_write (ring, cur_pages | (stride_pixels <<16 )); }radeon_ring_write (ring,PACKET0 (RADEON_DSTCACHE_CTLSTAT ,0 ));
Greg Kroah-Hartman
maintainerPATCH 103/389 drm/amdgpu/sdma5.2: replace BUG_ON() with WARN_ON()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit b9dd618a635d39fbb211454b6e8837b2a7f10fb0 upstream.
There's no need to crash the kernel for these cases.
--- drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c +2 -2
@@ -425,7 +425,7 @@ static void sdma_v5_2_ring_emit_fence(stamdgpu_ring_write (ring,SDMA_PKT_HEADER_OP (SDMA_OP_FENCE ) |SDMA_PKT_FENCE_HEADER_MTYPE (0x3 ));/* Ucached(UC) */ /* zero in first two bits */ -BUG_ON (addr &0x3 ); +WARN_ON (addr &0x3 );amdgpu_ring_write (ring,lower_32_bits (addr));amdgpu_ring_write (ring,upper_32_bits (addr));amdgpu_ring_write (ring,lower_32_bits (seq));
@@ -436,7 +436,7 @@ static void sdma_v5_2_ring_emit_fence(stamdgpu_ring_write (ring,SDMA_PKT_HEADER_OP (SDMA_OP_FENCE ) |SDMA_PKT_FENCE_HEADER_MTYPE (0x3 ));/* zero in first two bits */ -BUG_ON (addr &0x3 ); +WARN_ON (addr &0x3 );amdgpu_ring_write (ring,lower_32_bits (addr));amdgpu_ring_write (ring,upper_32_bits (addr));amdgpu_ring_write (ring,upper_32_bits (seq));
Greg Kroah-Hartman
maintainerPATCH 104/389 drm/amdgpu/sdma5.0: replace BUG_ON() with WARN_ON()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit 9e98ed3113943257ad6e5c1e6beddbdb482a70ad upstream.
There's no need to crash the kernel for these cases.
--- drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c +2 -2
@@ -487,7 +487,7 @@ static void sdma_v5_0_ring_emit_fence(stamdgpu_ring_write (ring,SDMA_PKT_HEADER_OP (SDMA_OP_FENCE ) |SDMA_PKT_FENCE_HEADER_MTYPE (0x3 ));/* Ucached(UC) */ /* zero in first two bits */ -BUG_ON (addr &0x3 ); +WARN_ON (addr &0x3 );amdgpu_ring_write (ring,lower_32_bits (addr));amdgpu_ring_write (ring,upper_32_bits (addr));amdgpu_ring_write (ring,lower_32_bits (seq));
@@ -498,7 +498,7 @@ static void sdma_v5_0_ring_emit_fence(stamdgpu_ring_write (ring,SDMA_PKT_HEADER_OP (SDMA_OP_FENCE ) |SDMA_PKT_FENCE_HEADER_MTYPE (0x3 ));/* zero in first two bits */ -BUG_ON (addr &0x3 ); +WARN_ON (addr &0x3 );amdgpu_ring_write (ring,lower_32_bits (addr));amdgpu_ring_write (ring,upper_32_bits (addr));amdgpu_ring_write (ring,upper_32_bits (seq));
Greg Kroah-Hartman
maintainerPATCH 105/389 net: ipv6: fix dif and sdif mismatch in raw6_icmp_error
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li RongQing <[email protected]>
[ Upstream commit 440e274da4d1b93c7df2cb0ce893c3009dd4db55 ]
In raw6_icmp_error(), raw_v6_match() is called with inet6_iif(skb) passed to both the 'dif' and 'sdif' arguments. This is a copy-paste or typo error, as the last argument should represent the secondary interface index (sdif).
This mismatch breaks ICMPv6 error handling for IPv6 raw sockets in VRF (Virtual Routing and Forwarding) environments. When a raw socket is bound to a VRF master device, raw_v6_match() fails to find a match because it is not given the correct sdif value, causing the socket to miss relevant ICMPv6 error notifications.
Fix this by properly passing inet6_sdif(skb) as the last argument to raw_v6_match().
--- net/ipv6/raw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv6/raw.c +1 -1
@@ -351,7 +351,7 @@ void raw6_icmp_error(struct sk_buff *skb, int nexthdr, daddr = &ip6h->daddr;if (!raw_v6_match (net, sk, nexthdr, &ip6h->saddr, &ip6h->daddr, -inet6_iif (skb),inet6_iif (skb))) +inet6_iif (skb),inet6_sdif (skb)))continue ;rawv6_err (sk, skb,NULL , type, code, inner_offset, info); }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 106/389 bpf, sockmap: Fix cork use-after-free in tcp_bpf_sendmsg()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengfeng Ye <[email protected]>
[ Upstream commit 2d66a033864e27ab8d5e44cb36f31d9d2413bee4 ]
tcp_bpf_sendmsg() keeps msg_tx across sk_stream_wait_memory(), which drops and reacquires the socket lock. Its error path tries to decide whether msg_tx names the local temporary message by comparing it with the current value of psock->cork.
This comparison is unsafe when two threads send on the same socket:
Thread A Thread B
msg_tx = psock->cork
sk_msg_alloc() fails sk_stream_wait_memory()
releases the socket lock acquires the socket lock
completes the cork psock->cork = NULL frees the cork
reacquires the socket lock
msg_tx != psock->cork
sk_msg_free(msg_tx)
The stale cork is therefore mistaken for the local temporary message and freed again. KASAN reported:
BUG: KASAN: slab-use-after-free in sk_msg_free+0x49/0x50 Read of size 4 at addr ffff88810c908800 by task poc/90 Call Trace: sk_msg_free+0x49/0x50 tcp_bpf_sendmsg+0x14f5/0x1cc0 __sys_sendto+0x32c/0x3a0 __x64_sys_sendto+0xdb/0x1b0 Allocated by task 89: __kasan_kmalloc+0x8f/0xa0 tcp_bpf_sendmsg+0x16b3/0x1cc0 Freed by task 91: __kasan_slab_free+0x43/0x70 kfree+0x131/0x3c0 tcp_bpf_sendmsg+0xec3/0x1cc0
msg_tx can only name the stack-local tmp or the shared cork. Check for tmp directly so a changed psock->cork cannot turn a shared message into an apparent local one.
--- net/ipv4/tcp_bpf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv4/tcp_bpf.c +1 -1
@@ -504,7 +504,7 @@ static int tcp_bpf_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) wait_for_memory: err =sk_stream_wait_memory (sk, &timeo);if (err) { -if (msg_tx && msg_tx != psock->cork) +if (msg_tx == &tmp)sk_msg_free (sk, msg_tx); goto out_err; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 107/389 can: bcm: defer rx_op deallocation to workqueue to fix thrtimer UAF
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lee Jones <[email protected]>
commit 68973f9db76144825e4f35dfdc80fb8279eb2d57 upstream.
Commit f1b4e32aca08 ("can: bcm: use call_rcu() instead of costly synchronize_rcu()") replaced synchronize_rcu() in bcm_delete_rx_op() with call_rcu() and introduced the RX_NO_AUTOTIMER flag.
However, this flag check was omitted for thrtimer in the packet rx fast-path. During BCM RX operation teardown, a concurrent RCU reader (bcm_rx_handler) can race and re-arm thrtimer via bcm_rx_update_and_send() after call_rcu() has been scheduled. Once the RCU grace period elapses, bcm_op is freed. The subsequently firing thrtimer then dereferences the deallocated op, causing a UAF.
Adding flag checks to the rx fast-path (bcm_rx_update_and_send) does not fully close the TOCTOU race and introduces latency for every CAN frame. Conversely, calling hrtimer_cancel() directly inside the RCU callback (softirq context) is fatal as hrtimer_cancel() can sleep, triggering a "scheduling while atomic" panic.
Resolve this by deferring the timer cancellation and memory free to a dedicated unbound workqueue (bcm_wq). The RCU callback now queues a work item to bcm_wq, which safely cancels both timers and deallocates memory in sleepable process context. A dedicated workqueue is used to prevent system-wide WQ saturation and is cleanly flushed/destroyed on module unload to avoid rmmod page faults.
Since the deferred work can now outlive the calling context by an unbounded amount, also take a reference on op->sk when it is assigned and drop it only once the deferred work has cancelled both timers, so a socket can no longer be freed out from under a still-armed timer whose callback (bcm_send_to_user()) dereferences op->sk.
--- net/can/bcm.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-)
net/can/bcm.c +32 -2
@@ -58,6 +58,7 @@#include <linux/can/skb.h> #include <linux/can/bcm.h> #include <linux/slab.h> +#include <linux/workqueue.h> #include <linux/spinlock.h> #include <net/sock.h> #include <net/net_namespace.h>
@@ -89,6 +90,8 @@ MODULE_ALIAS("can-proto-2");#define BCM_MIN_NAMELEN CAN_REQUIRED_SIZE(struct sockaddr_can, can_ifindex) +static struct workqueue_struct *bcm_wq; +/* * easy access to the first 64 bit of can(fd)_frame payload. cp->data is * 64 bit aligned so the offset has to be multiples of 8 which is ensured
@@ -102,6 +105,7 @@ static inline u64 get_u64(const struct canfd_frame *cp, int offset)struct bcm_op {struct list_head list;struct rcu_head rcu; +struct work_struct work;int ifindex;canid_t can_id;u32 flags;
@@ -740,9 +744,12 @@ static struct bcm_op *bcm_find_op(struct list_head *ops,return NULL ; } -static void bcm_free_op_rcu (struct rcu_head *rcu_head) +static void bcm_free_op_work (struct work_struct *work) { - struct bcm_op *op = container_of(rcu_head, struct bcm_op, rcu); + struct bcm_op *op = container_of(work, struct bcm_op, work); + +hrtimer_cancel (&op->timer); +hrtimer_cancel (&op->thrtimer);if ((op->frames) && (op->frames != &op->sframe))kfree (op->frames);
@@ -750,9 +757,23 @@ static void bcm_free_op_rcu(struct rcu_head *rcu_head)if ((op->last_frames) && (op->last_frames != &op->last_sframe))kfree (op->last_frames); +/* the last possible access to op->timer/op->thrtimer has now +* happened above via hrtimer_cancel() - op->sk is no longer +* needed by any pending timer callback, so drop our reference +*/ +sock_put (op->sk); +kfree (op); } +static void bcm_free_op_rcu (struct rcu_head *rcu_head) +{ + struct bcm_op *op = container_of(rcu_head, struct bcm_op, rcu); + +INIT_WORK (&op->work, bcm_free_op_work); +queue_work (bcm_wq, &op->work); +} +static void bcm_remove_op (struct bcm_op *op) {hrtimer_cancel (&op->timer);
@@ -1008,6 +1029,7 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,/* bcm_can_tx / bcm_tx_timeout_handler needs this */ op->sk = sk; +sock_hold (sk); op->ifindex = ifindex;/* initialize uninitialized (kzalloc) structure */
@@ -1173,6 +1195,7 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,/* bcm_can_tx / bcm_tx_timeout_handler needs this */ op->sk = sk; +sock_hold (sk); op->ifindex = ifindex;/* ifindex for timeout events w/o previous frame reception */
@@ -1830,11 +1853,16 @@ static int __init bcm_module_init(void) {int err; + bcm_wq =alloc_workqueue ("can-bcm-wq" ,WQ_UNBOUND ,0 ); +if (!bcm_wq) +return -ENOMEM ; +pr_info ("can: broadcast manager protocol\n" ); err =can_proto_register (&bcm_can_proto);if (err <0 ) {printk (KERN_ERR "can: registration of bcm protocol failed\n" ); +destroy_workqueue (bcm_wq);return err; }
@@ -1848,6 +1876,8 @@ static void __exit bcm_module_exit(void)can_proto_unregister (&bcm_can_proto);unregister_netdevice_notifier (&canbcm_notifier);unregister_pernet_subsys (&canbcm_pernet_ops); +rcu_barrier (); +destroy_workqueue (bcm_wq); }module_init (bcm_module_init);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 108/389 can: bcm: add locking when updating filter and timer values
In reply to Greg Kroah-Hartman5.10-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 | 178 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 134 insertions(+), 44 deletions(-)
net/can/bcm.c +134 -44
@@ -126,6 +126,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 {
@@ -280,21 +281,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) {
@@ -323,14 +330,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:
@@ -429,7 +442,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 */
@@ -446,7 +459,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) ?
@@ -585,6 +598,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' */
@@ -601,6 +616,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 ;
@@ -649,15 +666,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)) { -hrtimer_forward (hrtimer,ktime_get (), op->kt_ival2); -return HRTIMER_RESTART ; +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); + 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; }/*
@@ -667,7 +695,9 @@ 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; +bool rtr_frame;if (op->can_id != rxframe->can_id)return ;
@@ -686,12 +716,23 @@ 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 ; } +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);
@@ -725,6 +766,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); }/*
@@ -1068,7 +1111,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);
@@ -1082,6 +1125,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) */
@@ -1116,6 +1177,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 */ /*
@@ -1127,19 +1190,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 ;
@@ -1150,6 +1242,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);
@@ -1191,6 +1284,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 */
@@ -1218,29 +1313,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)
@@ -1250,9 +1338,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 109/389 can: bcm: fix CAN frame rx/tx statistics
In reply to Greg Kroah-Hartman5.10-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 | 67 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 45 insertions(+), 22 deletions(-)
net/can/bcm.c +45 -22
@@ -109,7 +109,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;
@@ -216,10 +216,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,
@@ -241,9 +244,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);
@@ -267,7 +270,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' );
@@ -277,6 +281,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
@@ -328,7 +350,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
@@ -473,12 +495,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 &= (BCM_CAN_FLAGS_MASK |RX_RECV );
@@ -713,25 +732,29 @@ 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 ; } -spin_lock_bh (&op->bcm_rx_update_lock); +/* 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);if (op->flags &RX_FILTER_ID ) {/* the easiest case */
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 110/389 can: bcm: extend bcm_tx_lock usage for data and timer updates
In reply to Greg Kroah-Hartman5.10-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
@@ -125,7 +125,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 */ };
@@ -440,12 +440,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;
@@ -462,25 +468,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 ); }
@@ -983,6 +1011,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 */ /*
@@ -993,11 +1023,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 )
@@ -1007,36 +1049,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 */
@@ -1113,10 +1157,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 111/389 can: bcm: validate frame length in bcm_rx_setup() for RTR replies
In reply to Greg Kroah-Hartman5.10-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
@@ -1194,22 +1194,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 ; }/*
@@ -1272,7 +1287,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);
@@ -1345,16 +1364,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 */
@@ -1456,6 +1471,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 112/389 can: bcm: add missing device refcount for CAN filter removal
In reply to Greg Kroah-Hartman5.10-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
@@ -884,6 +884,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);
@@ -914,17 +915,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,
@@ -1447,7 +1445,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
@@ -1820,16 +1826,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 113/389 can: bcm: fix stale rx/tx ops after device removal
In reply to Greg Kroah-Hartman5.10-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
@@ -1234,6 +1234,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))) {
@@ -1318,8 +1319,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 */
@@ -1389,6 +1397,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))) */
@@ -1402,7 +1411,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;
@@ -1432,7 +1441,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;
@@ -1462,18 +1474,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 ;
@@ -1689,11 +1715,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 114/389 can: bcm: fix data race on rx_stamp/rx_ifindex in bcm_rx_handler()
In reply to Greg Kroah-Hartman5.10-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
@@ -756,11 +756,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);
@@ -784,6 +779,14 @@ static void bcm_rx_handler(struct sk_buff *skb, void *data)*/ bcm_update_rx_stats (op); +/* 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 115/389 can: bcm: track a single source interface for ANYDEV timeout/throttle ops
In reply to Greg Kroah-Hartman5.10-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
@@ -114,6 +114,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;
@@ -753,6 +754,33 @@ static void bcm_rx_handler(struct sk_buff *skb, void *data)if (skb->len != op->cfsiz)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);
@@ -779,10 +807,9 @@ static void bcm_rx_handler(struct sk_buff *skb, void *data)*/ bcm_update_rx_stats (op); -/* 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;
@@ -1316,6 +1343,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);
@@ -1719,10 +1747,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 116/389 drm/amdgpu: Fix VFCT bus number matching with soft filter
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <[email protected]>
commit db7e8108809a2245f0a17ba323f027cac0941ffb upstream.
On systems where PCI bus renumbering occurs (e.g. pci=realloc, resource conflicts), the runtime bus number may differ from the BIOS POST bus number recorded in the VFCT table. This causes amdgpu_acpi_vfct_bios() to fail finding the VBIOS even though the correct device entry exists.
Introduce amdgpu_acpi_vfct_match() which treats the bus number as a soft filter: vendor/device/function identity is the hard requirement, while exact bus match is the preferred path. When bus numbers disagree but device identity matches, accept the VFCT entry and log a dev_notice for diagnostics.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c | 45 +++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 5 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c +40 -5
@@ -358,6 +358,45 @@ static bool amdgpu_read_disabled_bios(st }#ifdef CONFIG_ACPI +/** +* amdgpu_acpi_vfct_match() - Check if a VFCT entry matches the device +* @adev: AMDGPU device +* @vhdr: VFCT image header to check +* +* VFCT entries contain the PCI bus number as recorded during BIOS POST. +* On systems where the kernel renumbers PCI buses (e.g. pci=realloc or +* resource conflicts), the runtime bus number may differ from the POST +* value. Match by device identity (vendor + device + function) and use +* the bus number as a preference: exact bus match is preferred, but when +* the bus numbers disagree we accept the entry if the device identity +* matches. +* +* Returns: 0 on match, -ENODEV on no match +*/ +static int amdgpu_acpi_vfct_match (struct amdgpu_device *adev, +VFCT_IMAGE_HEADER *vhdr) +{ +/* Vendor and device IDs must always match */ +if (vhdr->VendorID != adev->pdev->vendor || + vhdr->DeviceID != adev->pdev->device) +return -ENODEV ; + +if (vhdr->PCIDevice !=PCI_SLOT (adev->pdev->devfn) || + vhdr->PCIFunction !=PCI_FUNC (adev->pdev->devfn)) +return -ENODEV ; + +/* Exact bus number match - preferred */ +if (vhdr->PCIBus == adev->pdev->bus->number) +return 0 ; + +/* Bus mismatch but device identity matches (PCI renumbering case) */ +dev_notice (adev->dev, +"VFCT bus number mismatch: table %u != runtime %u, matching by device identity (vendor 0x%04x device 0x%04x)\n" , + vhdr->PCIBus, adev->pdev->bus->number, + adev->pdev->vendor, adev->pdev->device); +return 0 ; +} +static bool amdgpu_acpi_vfct_bios (struct amdgpu_device *adev) {struct acpi_table_header *hdr;
@@ -393,11 +432,7 @@ static bool amdgpu_acpi_vfct_bios(struct }if (vhdr->ImageLength && - vhdr->PCIBus == adev->pdev->bus->number && - vhdr->PCIDevice ==PCI_SLOT (adev->pdev->devfn) && - vhdr->PCIFunction ==PCI_FUNC (adev->pdev->devfn) && - vhdr->VendorID == adev->pdev->vendor && - vhdr->DeviceID == adev->pdev->device) { + !amdgpu_acpi_vfct_match (adev, vhdr)) { adev->bios =kmemdup (&vbios->VbiosContent, vhdr->ImageLength,GFP_KERNEL );
Greg Kroah-Hartman
maintainerPATCH 117/389 drm/amd/pm/ci: Dont disable MCLK DPM on Bonaire 0x6658 (R7 260X)
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
commit 85371c5ef502d10add72eab38711e191dccea981 upstream.
The old radeon driver has a documented workaround in ci_dpm.c which claims that Bonaire 0x6658 with old memory controller firmware is unstable with MCLK DPM, so as a precaution I disabled MCLK DPM on this ASIC in amdgpu.
Note that the old MC firmware is not actually used with amdgpu, but in theory it's possible that the VBIOS sets up the ASIC with an old MC firmware that is already running when amdgpu initializes (in which case amdgpu doesn't load its own firmware).
What I expected to happen is that the GPU would simply use its maximum memory clock, and indeed this is what seemed to happen according to amdgpu_pm_info which reads the current MCLK value from the SMU.
However, some users reported a huge perf regression and upon a closer look it seems that the GPU seems to not actually use the highest MCLK value, despite the SMU reporting that it does.
Let's not disable MCLK DPM on Bonaire 0x6658 (R7 260X).
Keep MCLK DPM disabled on R9 M380 in the 2015 iMac because that still hangs if we enable it.
--- drivers/gpu/drm/amd/pm/powerplay/hwmgr/hwmgr.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
drivers/gpu/drm/amd/pm/powerplay/hwmgr/hwmgr.c +2 -5
@@ -110,11 +110,8 @@ int hwmgr_early_init(struct pp_hwmgr *hw hwmgr->od_enabled = false;switch (hwmgr->chip_id) {case CHIP_BONAIRE : -/* R9 M380 in iMac 2015: SMU hangs when enabling MCLK DPM -* R7 260X cards with old MC ucode: MCLK DPM is unstable -*/ -if (adev->pdev->subsystem_vendor ==0x106B || - adev->pdev->device ==0x6658 ) { +/* R9 M380 in iMac 2015: SMU hangs when enabling MCLK DPM */ +if (adev->pdev->subsystem_vendor ==0x106B ) {dev_info (adev->dev,"disabling MCLK DPM on quirky ASIC" ); adev->pm.pp_feature &= ~PP_MCLK_DPM_MASK ; hwmgr->feature_mask &= ~PP_MCLK_DPM_MASK ;
Greg Kroah-Hartman
maintainerPATCH 118/389 drm/amdgpu: fix bo->pin leaking in amdgpu_bo_create_reserved
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhu Lingshan <[email protected]>
commit a2f895f3c852063258d62e9f74b081de07ca95df upstream.
amdgpu_bo_create_reserved() only allocates a new BO when *bo_ptr (struct amdgpu_bo **bo_ptr as input parameter) is NULL, it simply skips creation when *bo_ptr is non-NULL. But it unconditionally reserves, pins, gart allocates and maps the BO afterwards.
When the same non-NULL BO pointer is passed in again,
for example firmware buffers that live in adev and are re-loaded on every resume / cp_resume / start
under AMDGPU_FW_LOAD_DIRECT, amdgpu_bo_pin() just increases pin_count unconditionally, however the matching teardown only unpins once, so pin_count never drops to zero, so TTM is not able to move, swap or evict a BO, causing BO leaks.
This commit fixes this issue by only pinning the bo once at creation, and repeated calls no longer take additional pin references.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +8 -5
@@ -275,10 +275,12 @@ int amdgpu_bo_create_reserved(struct amd goto error_free; } - r =amdgpu_bo_pin (*bo_ptr, domain); -if (r) { -dev_err (adev->dev,"(%d) kernel bo pin failed\n" , r); - goto error_unreserve; +if (free) { + r =amdgpu_bo_pin (*bo_ptr, domain); +if (r) { +dev_err (adev->dev,"(%d) kernel bo pin failed\n" , r); + goto error_unreserve; + } } r =amdgpu_ttm_alloc_gart (&(*bo_ptr)->tbo);
@@ -301,7 +303,8 @@ int amdgpu_bo_create_reserved(struct amdreturn 0 ; error_unpin: -amdgpu_bo_unpin (*bo_ptr); +if (free) +amdgpu_bo_unpin (*bo_ptr); error_unreserve:amdgpu_bo_unreserve (*bo_ptr);
Greg Kroah-Hartman
maintainerPATCH 119/389 drm/vmwgfx: Validate vmw_surface_metadata::array_size
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Forbes <[email protected]>
commit a4f55260f7f7d4dc4d0ee55063dfb0c457b77991 upstream.
This field comes from userspace and should be validated against specific limits depending on which Shader Model (SM) is available.
--- drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-)
drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +17 -5
@@ -101,7 +101,7 @@ static int vmw_gb_surface_unbind(structstatic int vmw_gb_surface_destroy (struct vmw_resource *res);static int vmw_gb_surface_define_internal (struct drm_device *dev, -struct drm_vmw_gb_surface_create_ext_req *req, +const struct drm_vmw_gb_surface_create_ext_req *req,struct drm_vmw_gb_surface_create_rep *rep,struct drm_file *file_priv); static int
@@ -1450,7 +1450,7 @@ int vmw_gb_surface_reference_ext_ioctl(s*/ static int vmw_gb_surface_define_internal (struct drm_device *dev, -struct drm_vmw_gb_surface_create_ext_req *req, +const struct drm_vmw_gb_surface_create_ext_req *req,struct drm_vmw_gb_surface_create_rep *rep,struct drm_file *file_priv) {
@@ -1469,9 +1469,21 @@ vmw_gb_surface_define_internal(struct dr req->base.svga3d_flags);/* array_size must be null for non-GL3 host. */ -if (req->base.array_size >0 && !has_sm4_context (dev_priv)) { -VMW_DEBUG_USER ("SM4 surface not supported.\n" ); -return -EINVAL ; +if (req->base.array_size >0 ) { +if (has_sm5_context (dev_priv)) { +if (req->base.array_size >SVGA3D_SM5_MAX_SURFACE_ARRAYSIZE ) { +VMW_DEBUG_USER ("Invalid Surface Array Size.\n" ); +return -EINVAL ; + } + }else if (has_sm4_context (dev_priv)) { +if (req->base.array_size >SVGA3D_SM4_MAX_SURFACE_ARRAYSIZE ) { +VMW_DEBUG_USER ("Invalid Surface Array Size.\n" ); +return -EINVAL ; + } + }else { +VMW_DEBUG_USER ("SM4+ surface not supported.\n" ); +return -EINVAL ; + } }if (!has_sm4_1_context (dev_priv)) {
Greg Kroah-Hartman
maintainerPATCH 120/389 media: airspy: Return queued buffers on start_streaming() failure
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Valery Borovsky <[email protected]>
commit 04344d0b4929caa94c0df72f767752aa0935ef5d upstream.
The vb2 framework hands buffers to the driver via buf_queue() before calling start_streaming(). If start_streaming() returns an error without first returning those buffers via vb2_buffer_done(), vb2_start_streaming() fires WARN_ON(owned_by_drv_count) and the queued buffers leak.
airspy_start_streaming() returned -ENODEV early when the USB device had been disconnected (s->udev == NULL) without returning any buffers that buf_queue() had already accepted. Take v4l2_lock first and jump to the existing err_clear_bit label, which already drains s->queued_bufs via vb2_buffer_done(..., VB2_BUF_STATE_QUEUED) before unlocking.
This mirrors the uvcvideo fix in commit 4cf3b6fd54eb ("media: uvcvideo:
Return queued buffers on start_streaming() failure").
--- drivers/media/usb/airspy/airspy.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/media/usb/airspy/airspy.c +5 -3
@@ -518,11 +518,13 @@ static int airspy_start_streaming(structdev_dbg (s->dev,"\n" ); -if (!s->udev) -return -ENODEV ; -mutex_lock (&s->v4l2_lock); +if (!s->udev) { + ret = -ENODEV ; + goto err_clear_bit; + } + s->sequence =0 ;set_bit (POWER_ON , &s->flags);
Greg Kroah-Hartman
maintainerPATCH 121/389 media: cec: seco: unregister adapter on IR probe failure
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Myeonghun Pak <[email protected]>
commit c3a78691be8245e52ced489f268e413f18061ac2 upstream.
If secocec_ir_probe() fails after cec_register_adapter() succeeds, probe returns an error and the driver remove callback is not called. The current unwind path unregisters the notifier and then falls through to cec_delete_adapter(), which violates the CEC adapter lifetime rules after a successful registration.
Add a registered-adapter unwind path that unregisters the notifier and the adapter instead.
--- drivers/media/cec/platform/seco/seco-cec.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/media/cec/platform/seco/seco-cec.c +5 -1
@@ -662,7 +662,7 @@ static int secocec_probe(struct platform ret =secocec_ir_probe (secocec);if (ret) - goto err_notifier; + goto err_unregister_adapter;platform_set_drvdata (pdev, secocec);
@@ -670,6 +670,10 @@ static int secocec_probe(struct platformreturn ret; +err_unregister_adapter: +cec_notifier_cec_adap_unregister (secocec->notifier, secocec->cec_adap); +cec_unregister_adapter (secocec->cec_adap); + goto err; err_notifier:cec_notifier_cec_adap_unregister (secocec->notifier, secocec->cec_adap); err_delete_adapter:
Greg Kroah-Hartman
maintainerPATCH 122/389 media: cedrus: clean up media device on probe failure
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Myeonghun Pak <[email protected]>
commit 2c869b6969f3061cbbdab587f4c0a88bd7fc3cc9 upstream.
cedrus_probe() initializes the media device before registering the video device, the media controller, and the media device. If any of those later steps fails, probe returns without calling media_device_cleanup(), so the media device internals initialized by media_device_init() are left behind.
Add a media-device cleanup label to the probe unwind path and route video registration failures through it as well.
--- drivers/staging/media/sunxi/cedrus/cedrus.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/staging/media/sunxi/cedrus/cedrus.c +3 -2
@@ -451,7 +451,7 @@ static int cedrus_probe(struct platform_ ret =video_register_device (vfd,VFL_TYPE_VIDEO ,0 );if (ret) {v4l2_err (&dev->v4l2_dev,"Failed to register video device\n" ); - goto err_m2m; + goto err_media; } v4l2_info(&dev->v4l2_dev,
@@ -477,7 +477,8 @@ err_m2m_mc:v4l2_m2m_unregister_media_controller (dev->m2m_dev); err_video:video_unregister_device (&dev->vfd); -err_m2m: +err_media: +media_device_cleanup (&dev->mdev);v4l2_m2m_release (dev->m2m_dev); err_v4l2:v4l2_device_unregister (&dev->v4l2_dev);
Greg Kroah-Hartman
maintainerPATCH 123/389 media: cedrus: Fix missing cleanup in error path
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Samuel Holland <[email protected]>
commit d99732334aaf33b9f93926b70b6a11c2cef3de39 upstream.
According to the documentation struct v4l2_fh has to be cleaned up with v4l2_fh_exit() before being freed. [1]
Currently there is no actual bug here, when v4l2_fh_exit() isn't called. v4l2_fh_exit() in this case only destroys internal mutex. But it may change in the future, when v4l2_fh_init/v4l2_fh_exit will be enhanced.
1. https://docs.kernel.org/driver-api/media/v4l2-fh.html
--- drivers/staging/media/sunxi/cedrus/cedrus.c | 1 + 1 file changed, 1 insertion(+)
drivers/staging/media/sunxi/cedrus/cedrus.c +1 -0
@@ -332,6 +332,7 @@ static int cedrus_open(struct file *file err_ctrls:v4l2_ctrl_handler_free (&ctx->hdl); err_free: +v4l2_fh_exit (&ctx->fh);kfree (ctx);mutex_unlock (&dev->dev_mutex);
Greg Kroah-Hartman
maintainerPATCH 124/389 media: cedrus: skip invalid H.264 reference list entries
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pengpeng Hou <[email protected]>
commit 10358ea986c3c85516d1c8206486464f79d36e76 upstream.
Cedrus consumes H.264 ref_pic_list0/ref_pic_list1 entries from the stateless slice control and later uses their indices to look up decode->dpb[] in _cedrus_write_ref_list().
Rejecting such controls in cedrus_try_ctrl() would break existing userspace, since stateless H.264 reference lists may legitimately carry out-of-range indices for missing references. Instead, guard the actual DPB lookup in Cedrus and skip entries whose indices do not fit the fixed V4L2_H264_NUM_DPB_ENTRIES array.
This keeps the fix local to the driver use site and avoids out-of-bounds reads from malformed or unsupported reference list entries.
--- drivers/staging/media/sunxi/cedrus/cedrus_h264.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/staging/media/sunxi/cedrus/cedrus_h264.c +3 -0
@@ -190,6 +190,9 @@ static void _cedrus_write_ref_list(strucu8 dpb_idx; dpb_idx = ref_list[i].index; +if (dpb_idx >=V4L2_H264_NUM_DPB_ENTRIES ) +continue ; + dpb = &decode->dpb[dpb_idx];if (!(dpb->flags &V4L2_H264_DPB_ENTRY_FLAG_ACTIVE ))
Greg Kroah-Hartman
maintainerPATCH 125/389 media: cx231xx: fix devres lifetime
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit 7d6358ab02866e5b7ed8d3a00805297617bbb0ec upstream.
USB drivers bind to USB interfaces and any device managed resources should have their lifetime tied to the interface rather than parent USB device. This avoids issues like memory leaks when drivers are unbound without their devices being physically disconnected (e.g. on probe deferral or configuration changes).
Fix the driver state lifetime so that it is released on driver unbind.
--- drivers/media/usb/cx231xx/cx231xx-cards.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
drivers/media/usb/cx231xx/cx231xx-cards.c +11 -5
@@ -1577,7 +1577,8 @@ static int cx231xx_init_v4l2(struct cx23 dev->video_mode.end_point_addr, dev->video_mode.num_alt); - dev->video_mode.alt_max_pkt_size =devm_kmalloc_array (&udev->dev,32 , dev->video_mode.num_alt,GFP_KERNEL ); + dev->video_mode.alt_max_pkt_size =devm_kmalloc_array (&interface->dev,32 , + dev->video_mode.num_alt,GFP_KERNEL );if (dev->video_mode.alt_max_pkt_size ==NULL )return -ENOMEM ;
@@ -1618,7 +1619,8 @@ static int cx231xx_init_v4l2(struct cx23 dev->vbi_mode.num_alt);/* compute alternate max packet sizes for vbi */ - dev->vbi_mode.alt_max_pkt_size =devm_kmalloc_array (&udev->dev,32 , dev->vbi_mode.num_alt,GFP_KERNEL ); + dev->vbi_mode.alt_max_pkt_size =devm_kmalloc_array (&interface->dev,32 , + dev->vbi_mode.num_alt,GFP_KERNEL );if (dev->vbi_mode.alt_max_pkt_size ==NULL )return -ENOMEM ;
@@ -1660,7 +1662,9 @@ static int cx231xx_init_v4l2(struct cx23"sliced CC EndPoint Addr 0x%x, Alternate settings: %i\n" , dev->sliced_cc_mode.end_point_addr, dev->sliced_cc_mode.num_alt); - dev->sliced_cc_mode.alt_max_pkt_size =devm_kmalloc_array (&udev->dev,32 , dev->sliced_cc_mode.num_alt,GFP_KERNEL ); + dev->sliced_cc_mode.alt_max_pkt_size =devm_kmalloc_array (&interface->dev,32 , + dev->sliced_cc_mode.num_alt, +GFP_KERNEL );if (dev->sliced_cc_mode.alt_max_pkt_size ==NULL )return -ENOMEM ;
@@ -1724,7 +1728,7 @@ static int cx231xx_usb_probe(struct usb_ udev =usb_get_dev (interface_to_usbdev (interface));/* allocate memory for our device state and initialize it */ - dev =devm_kzalloc (&udev->dev,sizeof (*dev),GFP_KERNEL ); + dev =devm_kzalloc (&interface->dev,sizeof (*dev),GFP_KERNEL );if (dev ==NULL ) { retval = -ENOMEM ; goto err_if;
@@ -1854,7 +1858,9 @@ static int cx231xx_usb_probe(struct usb_ dev->ts1_mode.end_point_addr, dev->ts1_mode.num_alt); - dev->ts1_mode.alt_max_pkt_size =devm_kmalloc_array (&udev->dev,32 , dev->ts1_mode.num_alt,GFP_KERNEL ); + dev->ts1_mode.alt_max_pkt_size =devm_kmalloc_array (&interface->dev,32 , + dev->ts1_mode.num_alt, +GFP_KERNEL );if (dev->ts1_mode.alt_max_pkt_size ==NULL ) { retval = -ENOMEM ; goto err_video_alt;
Greg Kroah-Hartman
maintainerPATCH 126/389 media: cx23885: add ioremap return check and cleanup
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wang Jun <[email protected]>
commit a0701e387b46e2481c05b47f1235b954bfc2af3e upstream.
Add a check for the return value of pci_ioremap_bar() in cx23885_dev_setup().
If ioremap for BAR0 fails, release the already allocated PCI memory region,
decrement the device count, and return -ENODEV.
This prevents a potential null pointer dereference and ensures proper cleanup
on memory mapping failure.
--- drivers/media/pci/cx23885/cx23885-core.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
drivers/media/pci/cx23885/cx23885-core.c +12 -2
@@ -990,8 +990,12 @@ static int cx23885_dev_setup(struct cx23 }/* PCIe stuff */ - dev->lmmio =ioremap (pci_resource_start (dev->pci,0 ), -pci_resource_len (dev->pci,0 )); + dev->lmmio =pci_ioremap_bar (dev->pci,0 ); +if (!dev->lmmio) { +dev_err (&dev->pci->dev,"CORE %s: can't ioremap MMIO memory\n" , + dev->name); + goto err_release_region; + } dev->bmmio = (u8 __iomem *)dev->lmmio;
@@ -1096,6 +1100,12 @@ static int cx23885_dev_setup(struct cx23 }return 0 ; + +err_release_region: +release_mem_region (pci_resource_start (dev->pci,0 ), +pci_resource_len (dev->pci,0 )); + cx23885_devcount--; +return -ENODEV ; }static void cx23885_dev_unregister (struct cx23885_dev *dev)
Greg Kroah-Hartman
maintainerPATCH 127/389 media: meson: vdec: Fix memory leak in error path of vdec_open
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Anand Moon <[email protected]>
commit 940f161f734b25f175a95d2684c2021f6323693a upstream.
The vdec_open() function previously jumped directly to err_m2m_release when vdec_init_ctrls() failed, skipping release of the m2m context. This caused a resource leak.
Fix it by introducing a proper err_m2m_ctx_release label that calls v4l2_m2m_ctx_release(sess->m2m_ctx) before releasing the m2m device.
This was identified via kmemleak:
unreferenced object 0xffff0000205d6878 (size 8):
comm "v4l_id", pid 5289, jiffies 4294938580
hex dump (first 8 bytes):
40 d2 49 18 00 00 ff ff @.I.....
backtrace (crc d3204599):
kmemleak_alloc+0xc8/0xf0
__kvmalloc_node_noprof+0x60c/0x850
v4l2_ctrl_handler_init_class+0x1b4/0x2e8 [videodev]
vdec_open+0x1f4/0x788 [meson_vdec]
v4l2_open+0x144/0x460 [videodev]
chrdev_open+0x1ac/0x500
do_dentry_open+0x3f0/0xfe8
vfs_open+0x68/0x320
do_open+0x2d8/0x9a8
path_openat+0x1d0/0x4f0
do_filp_open+0x190/0x380
do_sys_openat2+0xf8/0x1b0
__arm64_sys_openat+0x13c/0x1e8
invoke_syscall+0xdc/0x268
el0_svc_common.constprop.0+0x178/0x258
do_el0_svc+0x4c/0x70--- drivers/staging/media/meson/vdec/vdec.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/staging/media/meson/vdec/vdec.c +3 -1
@@ -897,7 +897,7 @@ static int vdec_open(struct file *file) ret =vdec_init_ctrls (sess);if (ret) - goto err_m2m_release; + goto err_m2m_ctx_release; sess->pixfmt_cap = formats[0 ].pixfmts_cap[0 ]; sess->fmt_out = &formats[0 ];
@@ -922,6 +922,8 @@ static int vdec_open(struct file *file)return 0 ; +err_m2m_ctx_release: +v4l2_m2m_ctx_release (sess->m2m_ctx); err_m2m_release:v4l2_m2m_release (sess->m2m_dev); err_free_sess:
Greg Kroah-Hartman
maintainerPATCH 128/389 media: msi2500: Return queued buffers on start_streaming() failure
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Valery Borovsky <[email protected]>
commit 7201c17786a498497bca57752883b90914d405ac upstream.
The vb2 framework hands buffers to the driver via buf_queue() before calling start_streaming(). If start_streaming() returns an error without first returning those buffers via vb2_buffer_done(), vb2_start_streaming() fires WARN_ON(owned_by_drv_count) and the queued buffers leak.
msi2500_start_streaming() had five error paths that all hit this trap and were further tangled by ret-overwriting between calls:
- -ENODEV when the USB device was already disconnected
- -ERESTARTSYS when mutex_lock_interruptible() was interrupted
- msi2500_set_usb_adc() failure: ret was silently overwritten by the next call (msi2500_isoc_init), so the error was lost entirely
- msi2500_isoc_init() failure: cleanup_queued_bufs was called, but the function then fell through to msi2500_ctrl_msg() and again masked the original error by overwriting ret
- msi2500_ctrl_msg(CMD_START_STREAMING) failure: no cleanup at all, leaving isoc URBs submitted with no way for the driver to consume them
Consolidate the error paths into a small goto chain. Every failure now stops the function, drains the queued-buffer list, and returns the real error code. The ctrl_msg failure path also rolls back the preceding msi2500_isoc_init() via msi2500_isoc_cleanup() before unlocking and draining.
The cleanup helper takes a vb2_buffer_state argument so that the start_streaming error paths can pass VB2_BUF_STATE_QUEUED (as expected by userspace on start_streaming failure) while stop_streaming keeps its existing VB2_BUF_STATE_ERROR semantics.
This mirrors the uvcvideo fix in commit 4cf3b6fd54eb ("media: uvcvideo:
Return queued buffers on start_streaming() failure").
--- drivers/media/usb/msi2500/msi2500.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-)
drivers/media/usb/msi2500/msi2500.c +24 -8
@@ -541,7 +541,8 @@ static int msi2500_isoc_init(struct msi2 }/* Must be called with vb_queue_lock hold */ -static void msi2500_cleanup_queued_bufs (struct msi2500_dev *dev) +static void msi2500_cleanup_queued_bufs (struct msi2500_dev *dev, +enum vb2_buffer_state state) {unsigned long flags;
@@ -554,7 +555,7 @@ static void msi2500_cleanup_queued_bufs( buf =list_entry (dev->queued_bufs.next, struct msi2500_frame_buf, list);list_del (&buf->list); -vb2_buffer_done (&buf->vb.vb2_buf,VB2_BUF_STATE_ERROR ); +vb2_buffer_done (&buf->vb.vb2_buf, state); }spin_unlock_irqrestore (&dev->queued_bufs_lock, flags); }
@@ -830,25 +831,40 @@ static int msi2500_start_streaming(strucdev_dbg (dev->dev,"\n" ); -if (!dev->udev) -return -ENODEV ; +if (!dev->udev) { + ret = -ENODEV ; + goto err_cleanup; + } -if (mutex_lock_interruptible (&dev->v4l2_lock)) -return -ERESTARTSYS ; +if (mutex_lock_interruptible (&dev->v4l2_lock)) { + ret = -ERESTARTSYS ; + goto err_cleanup; + }/* wake-up tuner */ v4l2_subdev_call (dev->v4l2_subdev, core, s_power,1 ); ret =msi2500_set_usb_adc (dev); +if (ret) + goto err_unlock_cleanup; ret =msi2500_isoc_init (dev);if (ret) -msi2500_cleanup_queued_bufs (dev); + goto err_unlock_cleanup; ret =msi2500_ctrl_msg (dev,CMD_START_STREAMING ,0 ); +if (ret) + goto err_isoc_cleanup;mutex_unlock (&dev->v4l2_lock); +return 0 ; +err_isoc_cleanup: +msi2500_isoc_cleanup (dev); +err_unlock_cleanup: +mutex_unlock (&dev->v4l2_lock); +err_cleanup: +msi2500_cleanup_queued_bufs (dev,VB2_BUF_STATE_QUEUED );return ret; }
@@ -863,7 +879,7 @@ static void msi2500_stop_streaming(strucif (dev->udev)msi2500_isoc_cleanup (dev); -msi2500_cleanup_queued_bufs (dev); +msi2500_cleanup_queued_bufs (dev,VB2_BUF_STATE_ERROR );/* according to tests, at least 700us delay is required */ msleep (20 );
Greg Kroah-Hartman
maintainerPATCH 129/389 media: pci: dm1105: Free allocated workqueue
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
commit 1a65db225b25bb8c8febf16974c060e0cc242eb9 upstream.
Destroy allocated workqueue in remove() callback to free its resources, thus fixing memory leak.
--- drivers/media/pci/dm1105/dm1105.c | 1 + 1 file changed, 1 insertion(+)
drivers/media/pci/dm1105/dm1105.c +1 -0
@@ -1195,6 +1195,7 @@ static void dm1105_remove(struct pci_devdm1105_hw_exit (dev);free_irq (pdev->irq, dev); +destroy_workqueue (dev->wq);pci_iounmap (pdev, dev->io_mem);pci_release_regions (pdev);pci_disable_device (pdev);
Greg Kroah-Hartman
maintainerPATCH 130/389 media: pwc: Drain fill_buf on start_streaming() failure
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Valery Borovsky <[email protected]>
commit 906e410dcffbbd99fb4081abab817a830033aa28 upstream.
pwc_isoc_init() submits its isochronous URBs with usb_submit_urb(.., GFP_KERNEL) in a loop. After the first URB is submitted, its completion handler pwc_isoc_handler() can run on another CPU before the loop finishes:
start_streaming()
pwc_isoc_init()
usb_submit_urb(urbs[0], GFP_KERNEL)
pwc_isoc_handler(urbs[0])
pdev->fill_buf =
pwc_get_next_fill_buf(pdev)
usb_submit_urb(urbs[i>0], ..) -> fails
pwc_isoc_cleanup(pdev) /* kills URBs */
return ret;
pwc_cleanup_queued_bufs(pdev, VB2_BUF_STATE_QUEUED)pwc_get_next_fill_buf() detaches a buffer from pdev->queued_bufs and stores it in pdev->fill_buf. The error path in start_streaming() only drains pdev->queued_bufs, so the buffer parked in pdev->fill_buf is leaked. vb2_start_streaming() then triggers WARN_ON(owned_by_drv_count).
stop_streaming() already handles this since commit 80b0963e1698 ("[media] pwc: fix WARN_ON"), which added the fill_buf drain in the teardown path but not in the start_streaming() error path. Mirror that handling on failure so start_streaming() returns with no buffer owned by the driver.
Issue identified by automated review of the INV-003 series at
https://sashiko.dev/
--- drivers/media/usb/pwc/pwc-if.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/media/usb/pwc/pwc-if.c +5 -0
@@ -727,6 +727,11 @@ static int start_streaming(struct vb2_qupwc_camera_power (pdev,0 );/* And cleanup any queued bufs!! */ pwc_cleanup_queued_bufs (pdev,VB2_BUF_STATE_QUEUED ); +if (pdev->fill_buf) { +vb2_buffer_done (&pdev->fill_buf->vb.vb2_buf, +VB2_BUF_STATE_QUEUED ); + pdev->fill_buf =NULL ; + } }mutex_unlock (&pdev->v4l2_lock);
Greg Kroah-Hartman
maintainerPATCH 131/389 media: pwc: Return queued buffers on start_streaming() failure
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Valery Borovsky <[email protected]>
commit 975b2ee20e569d47821e4f6c9761b4664d48a6a4 upstream.
The vb2 framework hands buffers to the driver via buf_queue() before calling start_streaming(). If start_streaming() returns an error without first returning those buffers via vb2_buffer_done(), vb2_start_streaming() fires WARN_ON(owned_by_drv_count) and the queued buffers leak.
pwc's start_streaming() had two early returns that hit this trap:-ENODEV when the USB device was already disconnected, and -ERESTARTSYS when mutex_lock_interruptible() was interrupted by a signal. Call the existing pwc_cleanup_queued_bufs() helper with VB2_BUF_STATE_QUEUED before returning (matching the state already used by the pwc_isoc_init() error path in the same function).
This mirrors the uvcvideo fix in commit 4cf3b6fd54eb ("media: uvcvideo:
Return queued buffers on start_streaming() failure").
--- drivers/media/usb/pwc/pwc-if.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/media/usb/pwc/pwc-if.c +6 -2
@@ -711,11 +711,15 @@ static int start_streaming(struct vb2_qustruct pwc_device *pdev =vb2_get_drv_priv (vq);int r; -if (!pdev->udev) +if (!pdev->udev) { +pwc_cleanup_queued_bufs (pdev,VB2_BUF_STATE_QUEUED );return -ENODEV ; + } -if (mutex_lock_interruptible (&pdev->v4l2_lock)) +if (mutex_lock_interruptible (&pdev->v4l2_lock)) { +pwc_cleanup_queued_bufs (pdev,VB2_BUF_STATE_QUEUED );return -ERESTARTSYS ; + }/* Turn on camera and set LEDS on */ pwc_camera_power (pdev,1 );pwc_set_leds (pdev, leds[0 ], leds[1 ]);
Greg Kroah-Hartman
maintainerPATCH 132/389 media: radio-si476x: Unregister v4l2_device on probe failure
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Myeonghun Pak <[email protected]>
commit 436a693af04ffb889aaf87cb69ec1f2b21d3569c upstream.
si476x_radio_probe() registers radio->v4l2dev before allocating the V4L2 controls and before registering the video device. If any of those later steps fails, probe returns through the exit label after freeing only the control handler.
A failed probe does not call si476x_radio_remove(), so the v4l2_device_unregister() there is not reached. This leaves the parent device reference taken by v4l2_device_register() behind on the error path.
Unregister the V4L2 device in the probe error path after freeing the controls.
--- drivers/media/radio/radio-si476x.c | 1 + 1 file changed, 1 insertion(+)
drivers/media/radio/radio-si476x.c +1 -0
@@ -1504,6 +1504,7 @@ static int si476x_radio_probe(struct plareturn 0 ; exit:v4l2_ctrl_handler_free (radio->videodev.ctrl_handler); +v4l2_device_unregister (&radio->v4l2dev);return rval; }
Greg Kroah-Hartman
maintainerPATCH 133/389 media: rtl2832: fix use-after-free in rtl2832_remove()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Deepanshu Kartikey <[email protected]>
commit 680daf40a82d483949f87f0d8f98639dc47e610c upstream.
cancel_delayed_work_sync() is called before i2c_mux_del_adapters() in rtl2832_remove(). While the cancel waits for any running instance of i2c_gate_work to finish, it does not prevent the timer from being rescheduled by a concurrent thread.
During probe, the r820t_attach() call attempts I2C transfers through the mux adapter. These transfers go through i2c_mux_master_xfer(), which calls rtl2832_deselect() after the transfer completes, rescheduling i2c_gate_work via schedule_delayed_work(). If this transfer is still in flight when rtl2832_remove() runs, rtl2832_deselect() can reschedule i2c_gate_work after it has been cancelled, causing a use-after-free when kfree(dev) is called.
Fix this by calling i2c_mux_del_adapters() before cancel_delayed_work_sync(). Once the mux adapter is unregistered, no new I2C transfers can go through it, so rtl2832_deselect() can no longer reschedule i2c_gate_work. The subsequent cancel_delayed_work_sync() is then guaranteed to be final.
--- drivers/media/dvb-frontends/rtl2832.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/media/dvb-frontends/rtl2832.c +2 -2
@@ -1115,10 +1115,10 @@ static int rtl2832_remove(struct i2c_clidev_dbg (&client->dev,"\n" ); -cancel_delayed_work_sync (&dev->i2c_gate_work); -i2c_mux_del_adapters (dev->muxc); +cancel_delayed_work_sync (&dev->i2c_gate_work); +regmap_exit (dev->regmap);kfree (dev);
Greg Kroah-Hartman
maintainerPATCH 134/389 media: rtl2832_sdr: Return queued buffers on start_streaming() failure
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Valery Borovsky <[email protected]>
commit 33ca0aab6f4bd90921fc1395478f38f72c4d19af upstream.
The vb2 framework hands buffers to the driver via buf_queue() before calling start_streaming(). If start_streaming() returns an error without first returning those buffers via vb2_buffer_done(), vb2_start_streaming() fires WARN_ON(owned_by_drv_count) and the queued buffers leak.
rtl2832_sdr_start_streaming() had multiple error paths that hit this
trap: two direct early returns (-ENODEV, -ERESTARTSYS), plus six goto err paths covering subdev s_power, tuner setup, ADC setup, stream-buffer allocation, urb allocation, and urb submission failures. None of them returned the queued buffers.
The original function had no distinct success exit and fell straight through into the err label, which previously only did mutex_unlock and "return ret". Adding queued-buffer cleanup at err must therefore be paired with an explicit success return; otherwise every successful start would also drain the buffer queue and kill streaming. Add that success return, then add rtl2832_sdr_cleanup_queued_bufs() at the err label and before each early return.
The cleanup helper takes a vb2_buffer_state argument so that the start_streaming error paths can pass VB2_BUF_STATE_QUEUED (as expected by userspace on start_streaming failure) while stop_streaming keeps its existing VB2_BUF_STATE_ERROR semantics.
This mirrors the uvcvideo fix in commit 4cf3b6fd54eb ("media: uvcvideo:
Return queued buffers on start_streaming() failure").
The err label still does not roll back power_ctrl(), frontend_ctrl(), the POWER_ON flag, or stream/URB allocations that may have happened before the failing step. Those are pre-existing leaks of a different class and are not addressed here.
--- drivers/media/dvb-frontends/rtl2832_sdr.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-)
drivers/media/dvb-frontends/rtl2832_sdr.c +14 -5
@@ -396,7 +396,8 @@ static int rtl2832_sdr_alloc_urbs(struct }/* Must be called with vb_queue_lock hold */ -static void rtl2832_sdr_cleanup_queued_bufs (struct rtl2832_sdr_dev *dev) +static void rtl2832_sdr_cleanup_queued_bufs (struct rtl2832_sdr_dev *dev, +enum vb2_buffer_state state) {struct platform_device *pdev = dev->pdev;unsigned long flags;
@@ -410,7 +411,7 @@ static void rtl2832_sdr_cleanup_queued_b buf =list_entry (dev->queued_bufs.next, struct rtl2832_sdr_frame_buf, list);list_del (&buf->list); -vb2_buffer_done (&buf->vb.vb2_buf,VB2_BUF_STATE_ERROR ); +vb2_buffer_done (&buf->vb.vb2_buf, state); }spin_unlock_irqrestore (&dev->queued_bufs_lock, flags); }
@@ -851,11 +852,15 @@ static int rtl2832_sdr_start_streaming(sdev_dbg (&pdev->dev,"\n" ); -if (!dev->udev) +if (!dev->udev) { +rtl2832_sdr_cleanup_queued_bufs (dev,VB2_BUF_STATE_QUEUED );return -ENODEV ; + } -if (mutex_lock_interruptible (&dev->v4l2_lock)) +if (mutex_lock_interruptible (&dev->v4l2_lock)) { +rtl2832_sdr_cleanup_queued_bufs (dev,VB2_BUF_STATE_QUEUED );return -ERESTARTSYS ; + }if (d->props->power_ctrl) d->props->power_ctrl (d,1 );
@@ -896,7 +901,11 @@ static int rtl2832_sdr_start_streaming(sif (ret) goto err; +mutex_unlock (&dev->v4l2_lock); +return 0 ; + err: +rtl2832_sdr_cleanup_queued_bufs (dev,VB2_BUF_STATE_QUEUED );mutex_unlock (&dev->v4l2_lock);return ret;
@@ -916,7 +925,7 @@ static void rtl2832_sdr_stop_streaming(srtl2832_sdr_kill_urbs (dev);rtl2832_sdr_free_urbs (dev);rtl2832_sdr_free_stream_bufs (dev); -rtl2832_sdr_cleanup_queued_bufs (dev); +rtl2832_sdr_cleanup_queued_bufs (dev,VB2_BUF_STATE_ERROR );rtl2832_sdr_unset_adc (dev);/* sleep tuner */
Greg Kroah-Hartman
maintainerPATCH 135/389 media: saa7134: Fix a possible memory leak in saa7134_video_init1
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Ke <[email protected]>
commit f86ed548386e3050e5f8f25b450d09dc009d9a88 upstream.
In saa7134_video_init1(), the return value of the first saa7134_pgtable_alloc() is not checked. If it fails, the function continues as if successful, leaving the driver with an invalid page table. Additionally, if vb2_queue_init() for the VBI queue fails after the video queue page table has been allocated, the allocated memory is not freed before returning. The second saa7134_pgtable_alloc() also lacks a return value check. Errors occur during device probing before the device is fully registered, the normal cleanup path in saa7134_finidev() is not executed, leading to memory leaks and potential use of uninitialized DMA resources.
Check the return value of both saa7134_pgtable_alloc() calls and propagate errors. On failure of any later step, free allocated page tables to avoid memory leaks. Ensure control handlers are also released on error to prevent further resource leakage.
Found by code review.
--- drivers/media/pci/saa7134/saa7134-video.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-)
drivers/media/pci/saa7134/saa7134-video.c +20 -5
@@ -2126,8 +2126,10 @@ int saa7134_video_init1(struct saa7134_d q->dev = &dev->pci->dev; ret =vb2_queue_init (q);if (ret) -return ret; -saa7134_pgtable_alloc (dev->pci, &dev->video_q.pt); + goto err_free_ctrl; + ret =saa7134_pgtable_alloc (dev->pci, &dev->video_q.pt); +if (ret) + goto err_free_ctrl; q = &dev->vbi_vbq; q->type =V4L2_BUF_TYPE_VBI_CAPTURE ;
@@ -2144,11 +2146,24 @@ int saa7134_video_init1(struct saa7134_d q->lock = &dev->lock; q->dev = &dev->pci->dev; ret =vb2_queue_init (q); -if (ret) -return ret; -saa7134_pgtable_alloc (dev->pci, &dev->vbi_q.pt); +if (ret) { +saa7134_pgtable_free (dev->pci, &dev->video_q.pt); + goto err_free_ctrl; + } + + ret =saa7134_pgtable_alloc (dev->pci, &dev->vbi_q.pt); +if (ret) { +saa7134_pgtable_free (dev->pci, &dev->video_q.pt); + goto err_free_ctrl; + }return 0 ; + +err_free_ctrl: +v4l2_ctrl_handler_free (&dev->ctrl_handler); +if (card_has_radio (dev)) +v4l2_ctrl_handler_free (&dev->radio_ctrl_handler); +return ret; }void saa7134_video_fini (struct saa7134_dev *dev)
Greg Kroah-Hartman
maintainerPATCH 136/389 media: sun4i-csi: Return queued buffers on start_streaming() failure
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Valery Borovsky <[email protected]>
commit bbba3e260a62810a717b4442a3bb96d0ec0f6309 upstream.
The vb2 framework hands buffers to the driver via buf_queue() before calling start_streaming(). If start_streaming() returns an error without first returning those buffers via vb2_buffer_done(), vb2_start_streaming() fires WARN_ON(owned_by_drv_count) and the queued buffers leak.
sun4i_csi_start_streaming() returned -EINVAL when no matching CSI format could be found, before any setup (scratch buffer allocation, pipeline start) had been performed. The remaining error paths already converge on the err_clear_dma_queue label, which calls return_all_buffers(..., VB2_BUF_STATE_QUEUED) under csi->qlock. Jump to that label directly: the intermediate err_disable_device / err_disable_pipeline / err_free_scratch_buffer labels are skipped, which is correct because nothing they would undo has happened yet.
This mirrors the uvcvideo fix in commit 4cf3b6fd54eb ("media: uvcvideo:
Return queued buffers on start_streaming() failure").
--- drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c +4 -2
@@ -234,8 +234,10 @@ static int sun4i_csi_start_streaming(strint ret; csi_fmt =sun4i_csi_find_format (&csi->fmt.pixelformat,NULL ); -if (!csi_fmt) -return -EINVAL ; +if (!csi_fmt) { + ret = -EINVAL ; + goto err_clear_dma_queue; + }dev_dbg (csi->dev,"Starting capture\n" );
Greg Kroah-Hartman
maintainerPATCH 137/389 media: tegra-video: vi: fix invalid u32 return value in format lookup
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hungyu Lin <[email protected]>
commit d5b50055338e131a1a99f923ebb0361974a00f36 upstream.
tegra_get_format_fourcc_by_idx() returns a u32 but uses -EINVAL to signal an out-of-bounds index. This results in a large unsigned value being returned, which may be interpreted as a valid fourcc.
Returning 0 is not a valid fourcc either. This condition should never happen, so use WARN_ON_ONCE() to catch unexpected out-of-bounds access and return a valid fallback format instead.
--- drivers/staging/media/tegra-video/vi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/staging/media/tegra-video/vi.c +2 -2
@@ -76,8 +76,8 @@ static int tegra_get_format_idx_by_code(static u32 tegra_get_format_fourcc_by_idx (struct tegra_vi *vi,unsigned int index) { -if (index >= vi->soc->nformats) -return -EINVAL ; +if (WARN_ON_ONCE (index >= vi->soc->nformats)) +return vi->soc->video_formats[0 ].fourcc;return vi->soc->video_formats[index].fourcc; }