Skip to contentSkip to conversation

5.10.261-rc1 review

PATCH In review Greg Kroah-Hartman 8 participants 713 messages Jul 21 – Jul 24 Page 1 of 6

Subsystems (4)
lore
Share & tools
lore

Greg Kroah-Hartman

author maintainer
#0 lore raw

cover 5.10.261-rc1 review

This is the start of the stable review cycle for the 5.10.261 release. There are 699 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 Thu, 23 Jul 2026 15:23:00 +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.261-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.261-rc1

Taehee Yoo <[email protected]>
mld: fix suspicious RCU usage in __ipv6_dev_mc_dec()

Eric Dumazet <[email protected]>
ipv6: mcast: remove one synchronize_net() barrier in ipv6_mc_down()

Nikita Zhandarovich <[email protected]>
ipv6: mcast: fix data-race in ipv6_mc_down / mld_ifc_work

Taehee Yoo <[email protected]>
net: mld: fix reference count leak in mld_{query | report}_work()

Eric Dumazet <[email protected]>
ipv6: fix lockdep splat in in6_dump_addrs()

Ignat Korchagin <[email protected]>
ipv6: mcast: use rcu-safe version of ipv6_get_lladdr()

Kristian Evensen <[email protected]>
net: ethernet: rmnet: Always subtract MAP header

Yue Haibing <[email protected]>

    ipv6: mcast: Delay put pmc->idev in mld_del_delrec()

Taehee Yoo <[email protected]>
mld: change lockdep annotation for ip6_sf_socklist and ipv6_mc_socklist

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

Jean-Baptiste Maneyrol <[email protected]>
iio: invensense: fix odr switching to same value

Jean-Baptiste Maneyrol <[email protected]>
iio: imu: inv_mpu6050: fix frequency setting when chip is off

Luiz Augusto von Dentz <[email protected]>
Bluetooth: L2CAP: Fix regressions caused by reusing ident

Marc Zyngier <[email protected]>
KVM: Move kvm_io_bus_get_dev() locking responsibilities to callers

Zhan Xusheng <[email protected]>
posix-cpu-timers: Use u64 multiplication in update_rlimit_cpu()

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

Ricardo Robaina <[email protected]>
audit: add audit_log_nf_skb helper function

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

Ahsan Atta <[email protected]>
crypto: qat - fix restarting state leak on allocation failure

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

Neill Kapron <[email protected]>
usb: gadget: f_fs: Tie read_buffer lifetime to ffs_epfile

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

Uwe Kleine-König <[email protected]>
crypto: atmel - Drop explicit initialization of struct i2c_device_id::driver_data to 0

Krzysztof Kozlowski <[email protected]>
crypto: atmel-sha204a - Mark OF related data as maybe unused

Tyler Baker <[email protected]>
usb: gadget: f_fs: initialize reset_work at allocation time

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

Mauricio Faria de Oliveira <[email protected]>
usb: atm: ueagle-atm: wait for pre-firmware load in .disconnect()

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

Uwe Kleine-König <[email protected]>
gpio: pca953x: Make platform teardown callback return void

Uwe Kleine-König <[email protected]>
leds: lm3601x: Improve error reporting for problems during .remove()

Uwe Kleine-König <[email protected]>
leds: lm3697: Remove duplicated error reporting in .remove()

Uwe Kleine-König <[email protected]>
drm/i2c/sil164: Drop no-op remove function

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

Oliver Neukum <[email protected]>
usb: iowarrior: remove inherent race with minor number

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

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

Andrzej Pietrasiewicz <[email protected]>
usb: gadget: function: Simplify diagnostic messaging in printer

Tristan Madani <[email protected]>
hfs/hfsplus: fix u32 overflow in check_and_correct_requested_length

Viacheslav Dubeyko <[email protected]>
hfs/hfsplus: prevent getting negative values of offset/length

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

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

Dave Chinner <[email protected]>
xfs: reflect sb features in xfs_mount

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

Ilpo Järvinen <[email protected]>

    serial: 8250_mid: Remove 8250_pci usage

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

Jann Horn <[email protected]>
proc: protect ptrace_may_access() with exec_update_lock (part 1)

Fushuai Wang <[email protected]>

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

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

Angela Czubak <[email protected]>
HID: add haptics page defines

Jann Horn <[email protected]>
proc: protect ptrace_may_access() with exec_update_lock (FD links)

Christoph Hellwig <[email protected]>
proc: rename proc_setattr to proc_nochmod_setattr

Thomas Weißschuh <[email protected]>
proc: use generic setattr() for /proc/$PID/net

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

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

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

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

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

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

Runyu Xiao <[email protected]>

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

Hyunwoo Kim <[email protected]>
Bluetooth: L2CAP: Fix deadlock in l2cap_conn_del()

Luiz Augusto von Dentz <[email protected]>
Bluetooth: L2CAP: Fix not tracking outstanding TX ident

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

Qianfeng Rong <[email protected]>
netfilter: ebtables: Use vmalloc_array() to improve code

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

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

Ilpo Järvinen <[email protected]>
PCI: Move Resizable BAR code to rebar.c

Ilpo Järvinen <[email protected]>
PCI: Add kerneldoc for pci_resize_resource()

Ilpo Järvinen <[email protected]>
PCI: Fix restoring BARs on BAR resize rollback path

Ilpo Järvinen <[email protected]>
PCI: Free saved list without holding pci_bus_sem

Ilpo Järvinen <[email protected]>
PCI: Prevent resource tree corruption when BAR resize fails

Giovanni Cabiddu <[email protected]>
crypto: qat - fix VF2PF work teardown race in adf_disable_sriov()

Fabio Aiuto <[email protected]>
staging: rtl8723bs: remove DBG_871X log argument

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

Christian Marangi <[email protected]>
PCI: mediatek: Convert bool to single quirks entry and bitmap

Jiri Slaby (SUSE) <[email protected]>
PCI: controller: Use dev_fwnode() instead of of_fwnode_handle()

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

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

Franziska Naepelt <[email protected]>
staging: rtl8723bs: Fix space issues

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

Michael Straube <[email protected]>
staging: rtl8723bs: clean up comparsions to NULL

Fabio Aiuto <[email protected]>
staging: rtl8723bs: remove commented out condition

Fabio Aiuto <[email protected]>
staging: rtl8723bs: remove 5Ghz code blocks

Fabio Aiuto <[email protected]>
staging: rtl8723bs: remove 5Ghz code related to channel plan definition

Fabio Aiuto <[email protected]>
staging: rtl8723bs: remove all 5Ghz network types

Fabio Aiuto <[email protected]>
staging: rtl8723bs: remove commented out RT_ASSERT occurrences

Fabio Aiuto <[email protected]>
staging: rtl8723bs: split too long line

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

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

Enzo Matsumiya <[email protected]>
cifs: remove unused server parameter from calc_smb_size()

Enzo Matsumiya <[email protected]>
smb2: small refactor in smb2_check_message()

Jakob Koschel <[email protected]>
cifs: remove check of list iterator against head past the loop body

Ronnie Sahlberg <[email protected]>
cifs: Create a new shared file holding smb2 pdu definitions

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

Martiros Shakhzadyan <[email protected]>
media: staging: media: atomisp: Fix alignment and line length issues

Martiros Shakhzadyan <[email protected]>
media: staging: media: atomisp: Replace if else clause with a ternary

Martiros Shakhzadyan <[email protected]>
media: staging: media: atomisp: Fix the rest of sh_css.c brace issues

Martiros Shakhzadyan <[email protected]>
media: staging: media: atomisp: Fix sh_css.c brace coding style issues

Aditya Srivastava <[email protected]>
media: atomisp: replace boolean comparison of values with bool variables

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

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

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

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

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

Luiz Augusto von Dentz <[email protected]>
Bluetooth: btintel: Check firmware version before download

Kiran K <[email protected]>
Bluetooth: btintel: Fix offset calculation boot address parameter

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

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

Alexander Lobakin <[email protected]>
bitops: make BYTES_TO_BITS() treewide-available

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

Jean-Baptiste Maneyrol <[email protected]>
iio: imu: inv_icm42600: stabilized timestamp in interrupt

Jean-Baptiste Maneyrol <[email protected]>
iio: invensense: fix timestamp glitches when switching frequency

Colin Ian King <[email protected]>
iio: invensense: remove redundant initialization of variable period

Jean-Baptiste Maneyrol <[email protected]>
iio: imu: inv_mpu6050: use the common inv_sensors timestamp module

Jean-Baptiste Maneyrol <[email protected]>
iio: make invensense timestamp module generic

Jean-Baptiste Maneyrol <[email protected]>
iio: move inv_icm42600 timestamp module in common

Jean-Baptiste Maneyrol <[email protected]>
iio: imu: inv_icm42600: make timestamp module chip independent

Zhang Lixu <[email protected]>
iio: hid-sensor-rotation: Fix stale or zero output when reading raw values

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

Rafael J. Wysocki <[email protected]>
ACPI: NFIT: core: Fix acpi_nfit_init() error cleanup

Sven Eckelmann <[email protected]>
batman-adv: clean untagged VLAN on netdev registration failure

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

Herbert Xu <[email protected]>
crypto: crypto4xx - Remove ahash-related code

Aditya Srivastava <[email protected]>
crypto: amcc - fix incorrect kernel-doc comment syntax in files

Pengpeng Hou <[email protected]>
mtd: rawnand: lpc32xx_slc: fail DMA transfer on completion timeout

Pengpeng Hou <[email protected]>
mtd: rawnand: lpc32xx_mlc: fail DMA transfers on timeout

Pengpeng Hou <[email protected]>
mtd: rawnand: fsl_ifc: return errors for failed page reads

Runyu Xiao <[email protected]>
mmc: vub300: defer reset until cmd_mutex is unlocked

Pengpeng Hou <[email protected]>
mtd: onenand: samsung: report DMA completion timeouts

Rafael Beims <[email protected]>
wifi: mwifiex: fix permanently busy scans after multiple roam iterations

Zhiling Zou <[email protected]>
wifi: mac80211: free ack status frame on TX header build failure

Junrui Luo <[email protected]>
powerpc/spufs: fix out-of-bounds access in spufs_mem_mmap_access()

Zhao Dongdong <[email protected]>
reset: sunxi: fix memory region leak on ioremap failure

Robby Cai <[email protected]>
reset: imx7: Correct polarity of MIPI CSI resets on i.MX8MQ

Julian Anastasov <[email protected]>
ipvs: fix more places with wrong ipv6 transport offsets

Maoyi Xie <[email protected]>
memstick: ms_block: reject a card that reports too many blocks

James Raphael Tiovalen <[email protected]>
macsec: fix promiscuity refcount leak in macsec_dev_open()

Xuanqiang Luo <[email protected]>
llc: fix SAP refcount leak when creating incoming sockets

Laxman Acharya Padhya <[email protected]>
Bluetooth: btrtl: validate firmware patch bounds

Abhishek Ojha <[email protected]>
regulator: ltc3676: Fix incorrect IRQSTAT bit offsets

Dawei Feng <[email protected]>

    wifi: mac80211: fix memory leak in ieee80211_register_hw()

Runyu Xiao <[email protected]>
wifi: rt2x00: avoid full teardown before work setup in probe

Farhad Alemi <[email protected]>
cgroup/cpuset: rebind mm mempolicy to effective_mems, not mems_allowed

Michael Bommarito <[email protected]>
drbd: reject data replies with an out-of-range payload size

Yizhou Zhao <[email protected]>
ipvs: reset full ip_vs_seq structs in ip_vs_conn_new

Yizhou Zhao <[email protected]>
ipvs: use parsed transport offset in SCTP state lookup

Shuangpeng Bai <[email protected]>
llc: fix SAP refcount leak in llc_ui_autobind()

Yousef Alhouseen <[email protected]>
mac802154: remove interfaces with RCU list deletion

Gerald Schaefer <[email protected]>
s390/monwriter: Reject buffer reuse with different data length

HyeongJun An <[email protected]>
hwmon: (asus_atk0110) Check package count before accessing element

Wentao Liang <[email protected]>
ata: pata_pxa: Fix DMA channel leak on probe error

Bryam Vargas <[email protected]>
orangefs: keep the readdir entry size 64-bit in fill_from_part()

Masami Hiramatsu (Google) <[email protected]>
tracing/probes: Fix double addition of offset for @+FOFFSET

Bryam Vargas <[email protected]>
net/sched: sch_multiq: Replace direct dequeue call with peek and qdisc_dequeue_peeked

Haoxiang Li <[email protected]>
fsl/fman: Free init resources on KeyGen failure in fman_init()

Haoxiang Li <[email protected]>
net: liquidio: fix BAR resource leak on PF number failure

Pengpeng Hou <[email protected]>
hwmon: (w83793) remove vrm sysfs file on probe failure

Pengpeng Hou <[email protected]>
hwmon: (w83627hf) remove VID sysfs files on error and remove

Abdun Nihaal <[email protected]>
bnx2x: fix potential memory leak in bnx2x_alloc_mem_bp()

Davidlohr Bueso <[email protected]>
locking/rtmutex: Skip remove_waiter() when waiter is not enqueued

Keenan Dong <[email protected]>
rtmutex: Use waiter::task instead of current in remove_waiter()

Sven Eckelmann <[email protected]>
batman-adv: ensure minimal ethernet header on TX

Sven Eckelmann <[email protected]>
batman-adv: retrieve ethhdr after potential skb realloc on RX

Shivam Kumar <[email protected]>
nvmet-tcp: check INIT_FAILED before nvmet_req_uninit in digest error path

Shitalkumar Gandhi <[email protected]>
ieee802154: ca8210: fix pointer truncation in kfifo on 64-bit

Shitalkumar Gandhi <[email protected]>
ieee802154: ca8210: fix cas_ctl leak on spi_async failure

Michael Bommarito <[email protected]>
ieee802154: allow legacy LLSEC ADD/DEL ops to pass strict validation

Michael Bommarito <[email protected]>
ieee802154: admin-gate legacy LLSEC dump operations

Maoyi Xie <[email protected]>
net: ip6_gre: require CAP_NET_ADMIN in the device netns for changelink

Maoyi Xie <[email protected]>
net: ip_vti: require CAP_NET_ADMIN in the device netns for changelink

Maoyi Xie <[email protected]>
net: ip6_vti: require CAP_NET_ADMIN in the device netns for changelink

Dawei Feng <[email protected]>
net: ena: clean up XDP TX queues when regular TX setup fails

Maoyi Xie <[email protected]>
net: sit: require CAP_NET_ADMIN in the device netns for changelink

Andreas Kemnade <[email protected]>
gpios: palmas: add .get_direction() op

Bradley Morgan <[email protected]>
cpu: hotplug: Preserve per instance callback errors

Dmitry Torokhov <[email protected]>
Input: ims-pcu - fix type confusion in CDC union descriptor parsing

Dmitry Torokhov <[email protected]>
Input: ims-pcu - fix potential infinite loop in CDC union descriptor parsing

Dmitry Torokhov <[email protected]>
Input: ims-pcu - fix out-of-bounds read in ims_pcu_irq() debug logging

Dmitry Torokhov <[email protected]>
Input: ims-pcu - fix DMA mapping violation in line setup

Dmitry Torokhov <[email protected]>
Input: ims-pcu - add response length checks

Dmitry Torokhov <[email protected]>
Input: ims-pcu - validate control endpoint type

Dmitry Torokhov <[email protected]>
Input: ims-pcu - release data interface on disconnect

Dmitry Torokhov <[email protected]>
Input: ims-pcu - fix use-after-free and double-free in disconnect

Bryam Vargas <[email protected]>
scsi: target: core: Fix iSCSI ISID use-after-free in REGISTER AND MOVE

Xu Rao <[email protected]>
scsi: sg: Report request-table problems when any status is set

Haoxiang Li <[email protected]>
scsi: hpsa: Fix DMA mapping leak on IOACCEL2 reset path

Mikulas Patocka <[email protected]>
dm-verity: increase sprintf buffer size

Mikulas Patocka <[email protected]>
dm_early_create: fix freeing used table on dm_resume failure

Mikulas Patocka <[email protected]>
dm-stats: fix merge accounting

Mikulas Patocka <[email protected]>
dm-stats: fix dm_jiffies_to_msec64

Benjamin Marzinski <[email protected]>
dm-log: fix a bitset_size overflow on 32bit machines

Mikulas Patocka <[email protected]>
dm-bufio: fix wrong count calculation in dm_bufio_issue_discard

Samuel Moelius <[email protected]>
dm era: fix out-of-bounds memory access for non-zero start sector

Ming-Hung Tsai <[email protected]>
dm thin metadata: fix metadata snapshot consistency on commit failure

Genjian Zhang <[email protected]>
dm thin metadata: fix superblock refcount leak on snapshot shadow failure

Oliver Hartkopp <[email protected]>
can: bcm: add missing rcu list annotations and operations

Oliver Hartkopp <[email protected]>
can: bcm: fix lockless bound/ifindex race and silent RX_SETUP failure

Oliver Hartkopp <[email protected]>
can: isotp: use unconditional synchronize_rcu() in isotp_release()

Bryam Vargas <[email protected]>
nvmet-rdma: handle inline data with a nonzero offset

Weiming Shi <[email protected]>
sctp: validate STALE_COOKIE cause length before reading staleness

Kunihiko Hayashi <[email protected]>
spi: uniphier: Fix completion initialization order before devm_request_irq()

Wang Yan <[email protected]>
time: Fix off-by-one in compat settimeofday() usec validation

Jaewon Yang <[email protected]>
tpm: Make the TPM character devices non-seekable

Thorsten Blum <[email protected]>
tpm: fix event_size output in tpm1_binary_bios_measurements_show

Maoyi Xie <[email protected]>
xfrm: xfrm_interface: require CAP_NET_ADMIN in the device netns for changelink

Sanman Pradhan <[email protected]>
xfrm: use compat translator only for u64 alignment mismatch

Wentao Liang <[email protected]>
xen/gntdev: fix error handling in ioctl

Xuanqiang Luo <[email protected]>
i2c: mlxbf: Fix use-after-free in mlxbf_i2c_init_resource()

Roman Vivchar <[email protected]>
i2c: mediatek: fix WRRD for SoCs without auto_restart option

Bhargav Joshi <[email protected]>
irqchip/crossbar: Use correct index in crossbar_domain_free()

Florian Fuchs <[email protected]>
mtd: maps: vmu-flash: fix NULL pointer dereference in initialization

Michael Bommarito <[email protected]>
ocfs2: reject non-inline dinodes with i_size and zero i_clusters

Michael Bommarito <[email protected]>
ocfs2: reject dinodes whose i_rdev disagrees with the file type

Michael Bommarito <[email protected]>
ocfs2: reject dinodes with non-canonical i_mode type

Ian Bridges <[email protected]>
ocfs2: fix NULL h_transaction deref in ocfs2_assure_trans_credits

Kyle Zeng <[email protected]>
ocfs2: avoid moving extents to occupied clusters

Arseniy Krasnov <[email protected]>
mtd: rawnand: fix condition in 'nand_select_target()'

Tristan Madani <[email protected]>
ocfs2: use kzalloc for quota recovery bitmap allocation

Martin Wilck <[email protected]>
scsi: smartpqi: Use shost_to_hba() in pqi_scan_finished()

Ruoyu Wang <[email protected]>
mtd: slram: remove failed entries from the device list

Krzysztof Wilczyński <[email protected]>
proc: only bump parent nlink when registering directories

WenTao Liang <[email protected]>
power: supply: charger-manager: fix refcount leak in is_full_charged()

Maciej W. Rozycki <[email protected]>
MIPS: DEC: Ensure 32-bit stack location for o32 prom_printf()

Johan Hovold <[email protected]>
MIPS: ip22-gio: fix device reference leak in probe

Johan Hovold <[email protected]>
MIPS: ip22-gio: fix kfree() of static object

Johan Hovold <[email protected]>
MIPS: ip22-gio: fix gio device memory leak

Chuck Lever <[email protected]>
lockd: Plug nlm_file refcount leak on cached nlm_do_fopen() failure

Chuck Lever <[email protected]>
lockd: Plug nlm_file leak when nlm_do_fopen() fails

Abdun Nihaal <[email protected]>
nvdimm/btt: Free arena sub-allocations on discover_arenas() error path

Abdun Nihaal <[email protected]>
nvdimm/btt: Free arenas on btt_init() error paths

Bartosz Golaszewski <[email protected]>
mfd: tps6586x: Fix OF node refcount

Sven Eckelmann <[email protected]>
batman-adv: tt: prevent TVLV OOB check overflow

Sven Eckelmann <[email protected]>
batman-adv: frag: fix primary_if leak on failed linearization

Sven Eckelmann <[email protected]>
batman-adv: frag: free unfragmentable packet

Sven Eckelmann <[email protected]>
batman-adv: fix VLAN priority offset

Sven Eckelmann <[email protected]>
batman-adv: tt: avoid request storms during pending request

Sven Eckelmann <[email protected]>
batman-adv: dat: fix tie-break for candidate selection

Sven Eckelmann <[email protected]>
batman-adv: dat: ensure accessible eth_hdr proto field

Sven Eckelmann <[email protected]>
batman-adv: bla: reacquire gw address after skb realloc

Sven Eckelmann <[email protected]>
batman-adv: dat: acquire ARP hw source only after skb realloc

Sven Eckelmann <[email protected]>

    batman-adv: access unicast_ttvn skb->data only after skb realloc

Sven Eckelmann <[email protected]>
batman-adv: gw: acquire ethernet header only after skb realloc

Thorsten Blum <[email protected]>
x86/boot: Reject too long acpi_rsdp= values

Thorsten Blum <[email protected]>
x86/boot: Validate console=uart8250 baud rate to fix early boot hang

Guangshuo Li <[email protected]>
mfd: sm501: Fix reference leak on failed device registration

Armin Wolf <[email protected]>
leds: uleds: Fix potential buffer overread

Wang Jun <[email protected]>
soc: fsl: qe: panic on ioremap() failure in qe_reset()

Siddharth Vadapalli <[email protected]>
soc: ti: k3-ringacc: Fix access mode for k3_ringacc_ring_pop_tail_io/proxy

Guangshuo Li <[email protected]>
gpu: host1x: Fix device reference leak in host1x_device_parse_dt() error path

Xiang Mei (Microsoft) <[email protected]>
netfilter: bridge: fix stale prevhdr pointer in br_ip6_fragment()

Wyatt Feng <[email protected]>
netfilter: xt_nat: reject unsupported target families

Yizhou Zhao <[email protected]>
netfilter: nf_conncount: fix zone comparison in tuple dedup

Xiang Mei <[email protected]>
netfilter: nf_conntrack_reasm: guard mac_header adjustment after IPv6 defrag

Florian Westphal <[email protected]>
netfilter: nf_nat_sip: reload possible stale data pointer

Wyatt Feng <[email protected]>
netfilter: xt_cluster: reject template conntracks in hash match

David Carlier <[email protected]>
netfilter: nfnl_cthelper: apply per-class values when updating policies

Muhammad Bilal <[email protected]>
netfilter: nf_conntrack_irc: fix parse_dcc() off-by-one OOB read

Abdun Nihaal <[email protected]>
fbdev: tridentfb: fix potential memory leak in trident_pci_probe()

Abdun Nihaal <[email protected]>
fbdev: nvidia: fix potential memory leak in nvidiafb_probe()

Abdun Nihaal <[email protected]>
fbdev: carminefb: fix potential memory leak in alloc_carmine_fb()

Abdun Nihaal <[email protected]>
fbdev: tdfxfb: fix potential memory leak in tdfxfb_probe()

Abdun Nihaal <[email protected]>
fbdev: uvesafb: fix potential memory leak in uvesafb_probe()

Abdun Nihaal <[email protected]>
fbdev: s3fb: fix potential memory leak in s3_pci_probe()

Abdun Nihaal <[email protected]>
fbdev: i740fb: fix potential memory leak in i740fb_probe()

Abdun Nihaal <[email protected]>
fbdev: radeon: fix potential memory leak in radeonfb_pci_register()

Li RongQing <[email protected]>
fbdev: sm712: Fix operator precedence in big_swap macro

Hyunwoo Kim <[email protected]>
KVM: arm64: vgic: Check the interrupt is still ours before migrating it

Nickolay Goppen <[email protected]>
arm64: dts: qcom: sdm630: describe adsp_mem region properly

Yong Wang <[email protected]>
net: ife: require ETH_HLEN to be pullable in ife_decode()

Zhengchuan Liang <[email protected]>
net: atm: reject out-of-range traffic classes in QoS validation

Michael Bommarito <[email protected]>
net: qrtr: fix 32-bit integer overflow in qrtr_endpoint_post()

Wentao Liang <[email protected]>
mlxsw: fix refcount leak in mlxsw_sp_vrs_lpm_tree_replace()

Guangshuo Li <[email protected]>
smb: client: fix overflow in passthrough ioctl bounds check

Li RongQing <[email protected]>
net/mlx5: Fix L3 tunnel entropy refcount leak

Timur Tabi <[email protected]>
regulator: core: regulator_lock_two() should test for EDEADLK not EDEADLOCK

Douglas Anderson <[email protected]>
regulator: core: Make regulator_lock_two() logic easier to follow

Cao Guanghui <[email protected]>
dm era: fix NULL pointer dereference in metadata_open()

Julian Anastasov <[email protected]>
ipvs: ensure inner headers in ICMP errors are in headroom

Yizhou Zhao <[email protected]>
ipvs: fix PMTU for GUE/GRE tunnel ICMP errors

Yizhou Zhao <[email protected]>
ipvs: use parsed transport offset in TCP state lookup

Yizhou Zhao <[email protected]>
ipvs: pass parsed transport offset to state handlers

Eric Dumazet <[email protected]>
ipv6: mcast: Fix potential UAF in MLD delayed work

Kuniyuki Iwashima <[email protected]>
ipv6: mcast: Replace locking comments with lockdep annotations.

Eric Dumazet <[email protected]>
ipv6: fix skb drops in igmp6_event_query() and igmp6_event_report()

Taehee Yoo <[email protected]>
mld: add mc_lock for protecting per-interface mld data

Taehee Yoo <[email protected]>
mld: add new workqueues for process mld events

Taehee Yoo <[email protected]>
mld: convert ifmcaddr6 to RCU

Taehee Yoo <[email protected]>
mld: convert ip6_sf_list to RCU

Taehee Yoo <[email protected]>

    mld: convert ipv6_mc_socklist->sflist to RCU

Taehee Yoo <[email protected]>

    mld: get rid of inet6_dev->mc_lock

Taehee Yoo <[email protected]>
mld: convert from timer to delayed work

Samuel Moelius <[email protected]>
net/sched: cake: reject overhead values that underflow length

Enrico Pozzobon <[email protected]>
net: usb: lan78xx: disable VLAN filter in promiscuous mode

Hui Wang <[email protected]>
ring-buffer: Fix event length with forced 8-byte alignment

Weiming Shi <[email protected]>

    Bluetooth: bpa10x: avoid OOB read of revision string in bpa10x_setup()

Pauli Virtanen <[email protected]>
Bluetooth: ISO: exclude RFU bits from ISO_SDU_Length

Xiang Mei <[email protected]>
net/smc: fix UAF in smc_cdc_rx_handler() by pinning the socket

Xiang Mei <[email protected]>
net: qualcomm: rmnet: validate MAP frame length before ingress parsing

Daniele Palmas <[email protected]>
net: qualcomm: rmnet: add tx packets aggregation

Sharath Chandra Vurukala <[email protected]>
net: ethernet: rmnet: Support for ingress MAPv5 checksum offload

Alex Elder <[email protected]>
net: qualcomm: rmnet: don't use C bit-fields in rmnet checksum header

Alex Elder <[email protected]>
net: qualcomm: rmnet: use masks instead of C bit-fields

Alex Elder <[email protected]>
net: qualcomm: rmnet: kill RMNET_MAP_GET_*() accessor macros

Alex Elder <[email protected]>
net: qualcomm: rmnet: simplify some byte order logic

Shigeru Yoshida <[email protected]>
qede: fix off-by-one in BD ring consumption on build_skb failure

Zhixing Chen <[email protected]>
netfilter: ip6tables: mark malformed IPv6 extension headers for hotdrop

Feng Wu <[email protected]>
netfilter: xt_rateest: fix u64 truncation in xt_rateest_mt()

Wyatt Feng <[email protected]>
netfilter: xt_u32: reject invalid shift counts

Qihang <[email protected]>
gue: validate REMCSUM private option length

Xiang Mei <[email protected]>
net: usb: net1080: validate packet_len before pad-byte access in rx_fixup

Lee Jones <[email protected]>
HID: core: Fix OOB read in hid_get_report for numbered reports

Georgiy Osokin <[email protected]>
HID: picolcd: prevent NULL pointer dereference in picolcd_send_and_wait()

Myeonghun Pak <[email protected]>
ata: sata_gemini: unwind clocks on IDE pinctrl errors

David Howells <[email protected]>
afs: Fix unchecked-length string display in debug statement

David Howells <[email protected]>
afs: Fix vllist leak

David Howells <[email protected]>
afs: Fix callback service message parsers to pass through -EAGAIN

Dan Carpenter <[email protected]>
afs: Fix error code in afs_extract_vl_addrs()

Samuel Moelius <[email protected]>
net/sched: hhf: clear heavy-hitter state on reset

Vladimir Zapolskiy <[email protected]>
gpio: timberdale: Return -ENOMEM on dynamic memory allocation in probe

Gleb Markov <[email protected]>
cxgb4: Fix decode strings dump for T6 adapters

Longjun Tang <[email protected]>
virtio_net: disable cb when NAPI is busy-polled

Masami Hiramatsu (Google) <[email protected]>
tracing/events: Fix to check the simple_tsk_fn creation

Xiang Mei <[email protected]>
usbnet: gl620a: fix out-of-bounds read in genelink_rx_fixup()

Matti Vaittinen <[email protected]>
hwmon: adm1275: Prevent reading uninitialized stack

Nuoqi Gui <[email protected]>
seg6: validate SRH length before reading fixed fields

Pengpeng Hou <[email protected]>
gpio: htc-egpio: use managed gpiochip registration

Pengpeng Hou <[email protected]>
gpio: mvebu: fail probe if gpiochip registration fails

Pengpeng Hou <[email protected]>
spi: sh-msiof: abort transfers when reset times out

Martin Kaiser <[email protected]>
tracing: probes: fix typo in a log message

Ruoyu Wang <[email protected]>
net: sungem: fix probe error cleanup

Yun Zhou <[email protected]>
net: mvneta: re-enable percpu interrupt on resume

Haoxiang Li <[email protected]>
rtc: cmos: unregister HPET IRQ handler on probe failure

Fredrik M Olsson <[email protected]>
rtc: ds1307: Fix off-by-one issue with wday for rx8130

Huiwen He <[email protected]>
smb/client: preserve errors from smb2_set_sparse()

Fernando Fernandez Mancera <[email protected]>
ipv6: fix error handling in disable_policy sysctl

Fernando Fernandez Mancera <[email protected]>
ipv6: fix error handling in forwarding sysctl

Fernando Fernandez Mancera <[email protected]>
ipv6: fix error handling in ignore_routes_with_linkdown sysctl

Fernando Fernandez Mancera <[email protected]>
ipv6: fix error handling in disable_ipv6 sysctl

Aleksandrova Alyona <[email protected]>
net: dsa: sja1105: round up PTP perout pin duration

Krzysztof Wilczyński <[email protected]>
alpha/PCI: Fix __pci_mmap_fits() overflow for zero-length BARs

Krzysztof Wilczyński <[email protected]>
alpha/PCI: Add security_locked_down() check to pci_mmap_resource()

Runyu Xiao <[email protected]>

    netfilter: nft_synproxy: stop bypassing the priv->info snapshot

Fernando Fernandez Mancera <[email protected]>
netfilter: nf_conncount: prevent connlimit drops for early confirmed ct

Kuniyuki Iwashima <[email protected]>
ipv4: fib: Don't ignore error route in local/main tables.

Xiang Mei <[email protected]>
ipv6: Fix null-ptr-deref in fib6_nh_mtu_change().

Xiang Mei <[email protected]>
drm/edid: fix OOB read in drm_parse_tiled_block()

Nuoqi Gui <[email protected]>
bpf: Fix stack slot index in nospec checks

Ronan Dalton <[email protected]>

    rtc: ds1307: handle oscillator stop flag for ds1337/ds1339/ds3231

Antoni Pokusinski <[email protected]>

    rtc: abx80x: fix the RTC_VL_CLR clearing all status flags

Sayali Patil <[email protected]>
selftests/mm: allow PUD-level entries in compound testcase of hmm tests

Sayali Patil <[email protected]>
selftests/mm: clarify alternate unmapping in compaction_test

Bhargav Joshi <[email protected]>
irqchip/crossbar: Fix parent domain resource leak

Florian Westphal <[email protected]>
netfilter: nft_meta_bridge: fix NFT_META_BRI_IIFPVID stack leak

Jozsef Kadlecsik <[email protected]>
netfilter: ipset: fix order of kfree_rcu() and rcu_assign_pointer()

Aleksandr Nogikh <[email protected]>
ieee802154: fix kernel-infoleak in dgram_recvmsg()

Ivan Abramov <[email protected]>

    ieee802154: Remove WARN_ON() in cfg802154_pernet_exit()

Andy Shevchenko <[email protected]>
ACPI: resource: Amend kernel-doc style

Ricardo Neri <[email protected]>
thermal: intel: Fix dangling resources on thermal_throttle_online() failure

Breno Leitao <[email protected]>
arm64/hw_breakpoint: reject unaligned watchpoints that would truncate BAS

Xin Long <[email protected]>
sctp: hold socket lock when dumping endpoints in sctp_diag

Jakub Kicinski <[email protected]>
net: psample: fix info leak in PSAMPLE_ATTR_DATA

Ratheesh Kannoth <[email protected]>
octeontx2-pf: Fix leak of SQ timestamp buffer on teardown

Arnaldo Carvalho de Melo <[email protected]>
perf machine: Use snprintf() for guestmount path construction

Eric Dumazet <[email protected]>
xfrm: validate selector family and prefixlen during match

Arnaldo Carvalho de Melo <[email protected]>
perf bpf: Validate func_info_rec_size and sub_id in synthesize_bpf_prog_name()

Arnaldo Carvalho de Melo <[email protected]>
perf tools: Use snprintf() for root_dir path construction

Arnaldo Carvalho de Melo <[email protected]>
perf symbols: Break infinite loop on zero-filled notes in sysfs__read_build_id()

Pengpeng Hou <[email protected]>
sparc: led: avoid trimming a newline from empty writes

John Johansen <[email protected]>
apparmor: fix label can not be immediately before a declaration

Adrian Hunter <[email protected]>
i3c: master: Prevent reuse of dynamic address on device add failure

Zygmunt Krynicki <[email protected]>
apparmor: put secmark label after secid lookup

Zygmunt Krynicki <[email protected]>
apparmor: aa_getprocattr free procattr leak on format failure

Maxime Bélair <[email protected]>
apparmor: fix potential UAF in aa_replace_profiles

Ryan Lee <[email protected]>
apparmor: grab ns lock and refresh when looking up changehat child profiles

Zygmunt Krynicki <[email protected]>
apparmor: aa_label_alloc use aa_label_free on alloc failure

Ruoyu Wang <[email protected]>
apparmor: check label build before no_new_privs test

Manivannan Sadhasivam <[email protected]>
PCI: mediatek: Use actual physical address instead of virt_to_phys()

Ryder Lee <[email protected]>
PCI: mediatek: Fix possible truncation in mtk_pcie_parse_port()

Arnaldo Carvalho de Melo <[email protected]>
perf symbols: Add bounds checks to read_build_id() note iteration in minimal build

Arnaldo Carvalho de Melo <[email protected]>
perf symbols: Add bounds checks to elf_read_build_id() note iteration

Arnaldo Carvalho de Melo <[email protected]>
perf bpf: Add NULL check for btf__type_by_id() in synthesize_bpf_prog_name()

Arnaldo Carvalho de Melo <[email protected]>
tools lib api: Fix mount_overload() snprintf truncation and toupper range

Arnaldo Carvalho de Melo <[email protected]>
tools lib api: Fix filename__write_int() writing uninitialized stack data

Arnaldo Carvalho de Melo <[email protected]>
perf symbols: Bounds-check descsz in sysfs__read_build_id() GNU fallback

Arnaldo Carvalho de Melo <[email protected]>
perf tools: Fix thread__set_comm_from_proc() on empty comm file

Arnaldo Carvalho de Melo <[email protected]>
perf symbols: Bounds-check .gnu_debuglink section data

Arnaldo Carvalho de Melo <[email protected]>
perf symbols: Fix signed overflow in sysfs__read_build_id() size check

Arnaldo Carvalho de Melo <[email protected]>
tools lib api: Fix missing null termination in filename__read_int/ull()

Arnaldo Carvalho de Melo <[email protected]>
perf pmu: Fix perf_pmu__parse_scale/unit() OOB access on empty sysfs file

Arnaldo Carvalho de Melo <[email protected]>
perf hists: Fix snprintf() in hists__scnprintf_title() UID filter path

Arnaldo Carvalho de Melo <[email protected]>
perf bpf: Use scnprintf() in snprintf_hex() and synthesize_bpf_prog_name()

Arnaldo Carvalho de Melo <[email protected]>
perf sched: Fix idle-hist callchain display using wrong rb_first variant

Lad Prabhakar <[email protected]>
PCI: rcar-host: Remove unused LIST_HEAD(res)

Arnaldo Carvalho de Melo <[email protected]>
perf tools: Use perf_env__get_cpu_topology() in machine__resolve()

Arnaldo Carvalho de Melo <[email protected]>
perf tools: Fix get_max_num() size_t underflow on empty sysfs file

Li RongQing <[email protected]>
PCI: mediatek: Fix operator precedence in PCIE_FTS_NUM_L0 macro

Mike Snitzer <[email protected]>
NFSv4/flexfiles: honor FF_FLAGS_NO_IO_THRU_MDS in pg_get_mirror_count_write

Mike Snitzer <[email protected]>
NFSv4/flexfiles: honor FF_FLAGS_NO_IO_THRU_MDS on fatal DS connect errors

Dai Ngo <[email protected]>
NFSv4/pnfs: defer return_range callbacks until after inode unlock

Sagi Grimberg <[email protected]>
pNFS/filelayout: fix cheking if a layout is striped

Phillip Varney <[email protected]>
clk: qcom: a53: Corrected frequency multiplier for 1152MHz

Nuno Sá <[email protected]>
dmaengine: Fix possible use after free

Arnaldo Carvalho de Melo <[email protected]>
perf c2c: Fix use-after-free in he__get_c2c_hists() error path

Arnaldo Carvalho de Melo <[email protected]>
perf mmap: Fix NULL deref in aio cleanup on alloc failure

Arnaldo Carvalho de Melo <[email protected]>
perf sched: Replace BUG_ON and add NULL checks in replay event helpers

Arnaldo Carvalho de Melo <[email protected]>
perf sched: Clean up idle_threads entry on init failure

Rui Qi <[email protected]>
perf: Fix off-by-one stack buffer overflow in kallsyms__parse()

Rosen Penev <[email protected]>
HID: logitech-hidpp: remove excess kernel-doc member in hidpp_scroll_counter

Sanjay Chitroda <[email protected]>

    iio: accel: mma8452: handle I2C read error(s) in mma8452_read()

Joshua Crofts <[email protected]>
iio: magnetometer: ak8975: fix potential kernel stack memory leak

Joshua Crofts <[email protected]>
iio: light: si1133: prevent race condition on timeout

Joshua Crofts <[email protected]>
iio: light: si1133: reset counter to prevent race condition

James Kim <[email protected]>
char: tlclk: fix use-after-free in tlclk_cleanup()

Seungjin Bae <[email protected]>
usb: host: max3421: Reject hub port requests for non-existent ports

Seungjin Bae <[email protected]>

    usb: host: max3421: Fix shift-out-of-bounds in max3421_hub_control()

Guangshuo Li <[email protected]>
staging: most: video: avoid double free on video register failure

Ian Rogers <[email protected]>
perf sched: Add missing mmap2 handler in timehist

Rafael J. Wysocki <[email protected]>
platform/x86: xo15-ebook: Fix wakeup source and GPE handling

Rafael J. Wysocki <[email protected]>
x86/platform/olpc: xo15: Drop wakeup source on driver removal

Yingchao Deng <[email protected]>
coresight: cti: Fix DT filter signals silently ignored

Alexandru Hossu <[email protected]>
staging: nvec: fix use-after-free in nvec_rx_completed()

Yizhou Zhao <[email protected]>

    net/9p: fix race condition on rdma->state in trans_rdma.c

Aleksandr Nogikh <[email protected]>
ocfs2: fix circular locking dependency in ocfs2_dio_end_io_write

Eric Dumazet <[email protected]>

    tcp: ipv6: clamp default adverting MSS to avoid GSO_BY_FRAGS (0xFFFF)

Eric Dumazet <[email protected]>
tipc: fix UAF in tipc_l2_send_msg()

Gui-Dong Han <[email protected]>
KEYS: Use acquire when reading state in keyring search

Aboorva Devarajan <[email protected]>
powerpc/kexec: fix double get_cpu() imbalance in kexec_prepare_cpus

Aboorva Devarajan <[email protected]>
powerpc/powernv: fix preempt count leak in pnv_kexec_wait_secondaries_down

Aboorva Devarajan <[email protected]>
powerpc/perf: fix preempt count underflow in fsl_emb_pmu_del

Yadan Fan <[email protected]>
MIPS: mm: Fix out-of-bounds write in maar_res_walk()

Sechang Lim <[email protected]>
bpf, sockmap: fix integer overflow in bpf_msg_pop_data() bounds check

Weiming Shi <[email protected]>
bpf, sockmap: reject overflowing copy + len in bpf_msg_push_data()

Florian Westphal <[email protected]>
netfilter: nf_conncount: callers must hold rcu read lock

Runyu Xiao <[email protected]>
kcm: use WRITE_ONCE() when changing lower socket callbacks

Victor Nogueira <[email protected]>
net/sched: sch_codel: Do not call qdisc_tree_reduce_backlog during peek before restoring qlen

Victor Nogueira <[email protected]>
net/sched: sch_fq_codel: Do not call qdisc_tree_reduce_backlog during peek before restoring qlen

Lars Pöschel <[email protected]>
spi: xilinx: use FIFO occupancy register to determine buffer size

Herbert Xu <[email protected]>
crypto: rng - Free default RNG on module exit

Felix Gu <[email protected]>
crypto: cavium/cpt - fix DMA cleanup using wrong loop index

Felix Gu <[email protected]>
crypto: marvell/octeontx - fix DMA cleanup using wrong loop index

Michael Bommarito <[email protected]>
tipc: prevent snt_unacked underflow on CONN_ACK

Michael Bommarito <[email protected]>
tipc: require net admin for TIPCv2 netlink mutators

Victor Nogueira <[email protected]>
net/sched: sch_hfsc: Don't make class passive twice

Xin Long <[email protected]>
sctp: validate embedded address parameter length

Kuniyuki Iwashima <[email protected]>
net: fib_rules: Don't dump dying fib_rule in fib_rules_dump().

HyeongJun An <[email protected]>
ASoC: tegra: tegra210_ahub: Validate written enum value

HyeongJun An <[email protected]>
ASoC: fsl: fsl_audmix: Validate written enum values

Maher Sanalla <[email protected]>
RDMA/mlx5: Fix undefined shift of user RQ WQE size

Maxwell Doose <[email protected]>
fs: efs: remove unneeded debug prints

Louis Scalbert <[email protected]>
bonding: 3ad: fix mux port state on oper down

longlong yan <[email protected]>
tools/virtio: check mmap return value in vringh_test

Qihang Tang <[email protected]>
vhost/vdpa: validate virtqueue index in mmap and fault paths

Jason Gunthorpe <[email protected]>
IB/mlx4: Fill in the access_flags if IB_MR_REREG_ACCESS is not specified

David Laight <[email protected]>
fbdev: sm501fb: Fix buffer errors in OF binding code

Filipe Manana <[email protected]>
btrfs: fix invalid pointer dereference in __btrfs_run_delayed_refs()

Wolfram Sang <[email protected]>
hwspinlock: qcom: avoid uninitialized struct members

Luca Leonardo Scorcia <[email protected]>
pinctrl: mediatek: mt8167: Fix Schmitt trigger register offset of pins 34-39

Luca Leonardo Scorcia <[email protected]>
pinctrl: mediatek: mt8516: Fix Schmitt trigger register offset of pins 34-39

Al Viro <[email protected]>

    configfs: fix lockless traversals of ->s_children

Dmitry Vyukov <[email protected]>
firmware_loader: Fix recursive lock in device_cache_fw_images()

Felix Gu <[email protected]>
spi: ep93xx: fix double-free of zeropage on DMA setup failure

Pengjie Zhang <[email protected]>
cpufreq: Documentation: fix conservative governor freq_step description

Yuho Choi <[email protected]>
ACPI: IPMI: Fix message kref handling on dead device

Rui Qi <[email protected]>

    riscv: stacktrace: Remove bogus -0x4 offset in non-FP walk_stackframe

Tristan Madani <[email protected]>
wifi: wcn36xx: fix OOB read from firmware count in PRINT_REG_INFO indication

Leon Hwang <[email protected]>
bpf: Update transport_header when encapsulating UDP tunnel in lwt

Pablo Neira Ayuso <[email protected]>
netfilter: conntrack: call nf_ct_gre_keymap_destroy() if master helper is pptp

Fernando Fernandez Mancera <[email protected]>
netfilter: synproxy: protect nf_ct_seqadj_init() with conntrack lock

Fernando Fernandez Mancera <[email protected]>
netfilter: nfnetlink_osf: fix mss parsing on big-endian architectures

Joseph Qi <[email protected]>
ocfs2: fix race between ocfs2_control_install_private() and ocfs2_control_release()

Zhang Cen <[email protected]>
ocfs2/dlm: require a ref for locking_state debugfs open

Zhang Cen <[email protected]>
ocfs2: reject FITRIM ranges shorter than a cluster

Dmitry Antipov <[email protected]>
ocfs2: fix buffer head management in ocfs2_read_blocks()

Zhang Cen <[email protected]>
ocfs2: rebase copied fsdlm LVB pointers in locking_state

Sandipan Das <[email protected]>
perf/x86/amd/core: Always use the NMI latency mitigation

Woojin Ji <[email protected]>
bpftool: Use libbpf error code for flow dissector query

Alexander Potapenko <[email protected]>

    lib/test_meminit: use && for bools

Sang-Heon Jeon <[email protected]>
mm/fake-numa: fix under-allocation detection in uniform split

Dan Carpenter <[email protected]>
scsi: pm8001: Fix error code in non_fatal_log_show()

Martin Wilck <[email protected]>
scsi: Revert "scsi: Fix sas_user_scan() to handle wildcard and multi-channel scans"

Yuho Choi <[email protected]>
ARM: imx31: Fix IIM mapping leak in revision check

Yuho Choi <[email protected]>
ARM: imx3: Fix CCM node reference leak

Zhang Yi <[email protected]>
ext4: fix LOGFLUSH shutdown ordering to allow ordered-mode data writeback

Renjiang Han <[email protected]>
media: qcom: venus: drop extra padding in NV12 raw size calculation

Jessica Zhang <[email protected]>
drm/msm/dp: Fix the ISR_* enum values

Jessica Zhang <[email protected]>
drm/msm/dp: fix HPD state status bit shift value

Tetsuo Handa <[email protected]>

    ocfs2: kill osb->system_file_mutex lock

ZhengYuan Huang <[email protected]>
ocfs2: don't BUG_ON an invalid journal dinode

Dan Carpenter <[email protected]>
rapidio/tsi721: prevent a bad dereference in tsi721_db_dpc()

Felix Gu <[email protected]>
drm/tegra: dc: Fix device node reference leak in tegra_dc_has_output()

Jiayuan Chen <[email protected]>
net/sched: cls_bpf: prevent unbounded recursion in offload rollback

Eric Dumazet <[email protected]>
ipv6: guard against possible NULL deref in __in6_dev_stats_get()

Breno Leitao <[email protected]>
workqueue: drop spurious '*' from print_worker_info() fn declaration

Nilay Shroff <[email protected]>
nvme-multipath: fix flex array size in struct nvme_ns_head

Miquel Raynal <[email protected]>
mtd: spi-nor: Drop duplicate Kconfig dependency

Maciej W. Rozycki <[email protected]>
MIPS: DEC: Remove do_IRQ() call indirection

Maciej W. Rozycki <[email protected]>
MIPS: Fix big-endian stack argument fetching in o32 wrapper

Jiakai Xu <[email protected]>
PM: sleep: Use complete() in device_pm_sleep_init()

Lianfa Weng <[email protected]>
RDMA/hns: Fix warning in poll cq direct mode

Guangshuo Li <[email protected]>
IB/mlx4: Fix refcount leak in add_port() error path

Samuel Holland <[email protected]>
bus: sunxi-rsb: Always check register address validity

Ronaldo Nunez <[email protected]>
pwm: imx27: Fix variable truncation in .apply()

Lifeng Zheng <[email protected]>
cpufreq: conservative: Simplify frequency limit handling

Pengjie Zhang <[email protected]>
cpufreq: Documentation: fix sampling_down_factor range

Stepan Ionichev <[email protected]>
device property: fix fwnode reference leak in fwnode_graph_get_endpoint_by_id()

Sven Püschel <[email protected]>
media: rockchip: rga: fix too small buffer size

Eric Dumazet <[email protected]>

    net/sched: sch_drr: annotate data-races around cl->deficit

Greg Kroah-Hartman <[email protected]>
sysfs: clamp show() return value in sysfs_kf_read()

Zilin Guan <[email protected]>
media: atomisp: Fix memory leak in atomisp_fixed_pattern_table()

Sara Venkatesh <[email protected]>
RDMA/srpt: fix integer overflow in immediate data length check

Prathamesh Deshpande <[email protected]>
RDMA/mlx5: Fix devx subscribe-event unwind NULL dereference

Alexander Chesnokov <[email protected]>
RDMA/hns: Fix arithmetic overflow in calc_hem_config()

Linmao Li <[email protected]>
ipv6: addrconf: bail out of dad_failure when state is no longer POSTDAD

Eric Dumazet <[email protected]>
net/sched: sch_htb: annotate data-races (I)

Sean Christopherson <[email protected]>
crypto: ccp - Treat zero-length cert chain as query for blob lengths

Eric Dumazet <[email protected]>
net/sched: sch_hfsc: annotate data-races in hfsc_dump_class_stats()

Rafael J. Wysocki <[email protected]>
thermal: hwmon: Fix critical temperature attribute removal

Cristian Marussi <[email protected]>
clk: scmi: Fix clock rate rounding

Sean Christopherson <[email protected]>
iommu/amd: Fix a stale comment about which legacy mode is user visible

Weiming Shi <[email protected]>
crypto: asymmetric_keys - fix OOB read in pefile_digest_pe_contents

Thorsten Blum <[email protected]>
crypto: ecrdsa - fix unknown OID check in ecrdsa_param_curve

Lothar Rubusch <[email protected]>
crypto: atmel-sha204a - fix blocking and non-blocking rng logic

Felix Gu <[email protected]>
pinctrl: sunxi: fix regulator leak in sunxi_pmx_request() error path

Samuel Holland <[email protected]>
media: cedrus: Fix failure to clean up hardware on probe failure

Felix Gu <[email protected]>
watchdog: sprd_wdt: Remove redundant sprd_wdt_disable() on register failure

Jihed Chaibi <[email protected]>
ARM: dts: am335x-sl50: Fix audio bitclock and frame master endpoint

Tristan Madani <[email protected]>
wifi: ath9k: fix OOB access from firmware tx status queue ID

Xingjing Deng <[email protected]>
kconfig: fix potential NULL pointer dereference in conf_askvalue

Tristan Madani <[email protected]>
wifi: rtw88: fix OOB read from firmware RX descriptor exceeding DMA buffer

Danilo Krummrich <[email protected]>

    driver core: use READ_ONCE() for dev->driver in dev_has_sync_state()

Yuho Choi <[email protected]>
drm/radeon: fix memory leak in radeon_ring_restore() on lock failure

Tomi Valkeinen <[email protected]>
drm/tidss: Drop extra drm_mode_config_reset() call

David Howells <[email protected]>
afs: Fix further netns teardown to cancel the preallocation charger

Matvey Kovalev <[email protected]>
afs: fix NULL pointer dereference in afs_get_tree()

David Howells <[email protected]>
afs: Fix netns teardown to cancel the preallocation charger

Matthias Feser <[email protected]>
serial: 8250_omap: clear rx_running on zero-length DMA completes

Stephan Gerhold <[email protected]>
serial: msm: Disable DMA for kernel console UART

Ricardo Ribalda <[email protected]>
media: uvcvideo: Fix buffer sequence in frame gaps

Ricardo Ribalda <[email protected]>
media: uvcvideo: Avoid partial metadata buffers

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

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

Muhammet Kaan KILINÇ <[email protected]>

    crypto: algif_skcipher - force synchronous processing on trees without ctx->state

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Sebastian Andrzej Siewior <[email protected]>
net: Drop the lock in skb_may_tx_timestamp()

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Michal Kosiorek <[email protected]>
xfrm: defensively unhash xfrm_state lists in __xfrm_state_delete

Fan Wu <[email protected]>
hdlc_ppp: sync per-proto timers before freeing hdlc state

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

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

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

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

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

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

Michael Bommarito <[email protected]>
NFSv4/flexfiles: reject zero filehandle version count

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

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

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

Wenjie Qi <[email protected]>
f2fs: validate orphan inode entry count

Sunmin Jeong <[email protected]>
f2fs: fix to round down start offset of fallocate for pin file

Jaegeuk Kim <[email protected]>
f2fs: adjust zone capacity when considering valid block count

Bryam Vargas <[email protected]>
apparmor: mediate the implicit connect of TCP fast open sendmsg

Maoyi Xie <[email protected]>
net: ip_gre: require CAP_NET_ADMIN in the device netns for changelink

Ruslan Valiyev <[email protected]>
apparmor: fix use-after-free in rawdata dedup loop

Yiming Qian <[email protected]>
net: skmsg: preserve sg.copy across SG transforms

Eric Dumazet <[email protected]>
skmsg: convert struct sk_msg_sg::copy to a bitmap

Xiang Mei <[email protected]>
netfilter: nf_log: validate MAC header was set before dumping it

Krishna chaitanya chundru <[email protected]>
bus: mhi: host: Add alignment check for event ring read pointer

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

Sean Christopherson <[email protected]>
KVM: Replace guest-triggerable BUG_ON() in ioeventfd datamatch with get_unaligned()

Lad Prabhakar <[email protected]>
mmc: renesas_sdhi: Add quirk entry for RZ/G2H SoC

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

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

Jiasheng Jiang <[email protected]>
clk: imx: Add check for kcalloc

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

Jeff Layton <[email protected]>
nfsd: reset write verifier on deferred writeback errors

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

Chaitanya Kulkarni <[email protected]>
nvmet-tcp: fix race between ICReq handling and queue teardown

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

Diffstat:

 Documentation/admin-guide/pm/cpufreq.rst           |    6 +-
 Documentation/crypto/userspace-if.rst              |   31 +-
 Documentation/driver-api/pci/pci.rst               |    3 +
 Makefile                                           |    4 +-
 arch/alpha/kernel/pci-sysfs.c                      |   13 +-
 arch/arm/boot/dts/am335x-sl50.dts                  |    4 +-
 arch/arm/mach-davinci/board-da850-evm.c            |   12 +-
 arch/arm/mach-imx/cpu-imx31.c                      |    9 +-
 arch/arm/mach-imx/mm-imx3.c                        |    2 +
 arch/arm64/boot/dts/qcom/sdm630.dtsi               |    9 +-
 arch/arm64/kernel/hw_breakpoint.c                  |    9 +
 arch/arm64/kvm/vgic/vgic-its.c                     |   15 +-
 arch/arm64/kvm/vgic/vgic.c                         |   11 +-
 arch/mips/dec/int-handler.S                        |    2 +-
 arch/mips/dec/prom/init.c                          |    6 +-
 arch/mips/dec/setup.c                              |    6 -
 arch/mips/fw/lib/call_o32.S                        |    2 +-
 arch/mips/include/asm/dec/prom.h                   |   15 +-
 arch/mips/mm/init.c                                |   12 +-
 arch/mips/sgi-ip22/ip22-gio.c                      |    7 +-
 arch/powerpc/kexec/core_64.c                       |    4 +-
 arch/powerpc/perf/core-fsl-emb.c                   |    3 +-
 arch/powerpc/platforms/cell/spufs/file.c           |    6 +-
 arch/powerpc/platforms/powernv/setup.c             |    3 +-
 arch/riscv/kernel/stacktrace.c                     |    2 +-
 arch/sparc/kernel/led.c                            |    2 +-
 arch/x86/boot/compressed/acpi.c                    |    7 +-
 arch/x86/boot/early_serial_console.c               |   11 +-
 arch/x86/events/amd/core.c                         |    6 +-
 arch/x86/kernel/cpu/mce/therm_throt.c              |    7 +-
 arch/x86/kvm/vmx/vmx.c                             |    3 +-
 arch/x86/mm/numa_emulation.c                       |   17 +-
 arch/x86/platform/olpc/olpc-xo15-sci.c             |    1 +
 block/partitions/aix.c                             |    9 +
 certs/common.c                                     |    2 +-
 crypto/af_alg.c                                    |   54 +-
 crypto/algif_skcipher.c                            |   49 +-
 crypto/asymmetric_keys/verify_pefile.c             |    2 +
 crypto/drbg.c                                      |    4 +-
 crypto/ecc.c                                       |   31 +-
 crypto/ecrdsa.c                                    |    2 +-
 crypto/pcrypt.c                                    |    4 +
 crypto/rng.c                                       |   11 +
 drivers/acpi/acpi_ipmi.c                           |    2 +-
 drivers/acpi/nfit/core.c                           |   15 +-
 drivers/acpi/resource.c                            |    6 +-
 drivers/android/binder.c                           |   19 +-
 drivers/ata/pata_pxa.c                             |    1 +
 drivers/ata/sata_gemini.c                          |    2 +-
 drivers/base/firmware_loader/main.c                |    3 +-
 drivers/base/power/main.c                          |    6 +-
 drivers/base/property.c                            |    4 +-
 drivers/block/drbd/drbd_receiver.c                 |    5 +
 drivers/bluetooth/bpa10x.c                         |    8 +-
 drivers/bluetooth/btintel.c                        |  105 +-
 drivers/bluetooth/btintel.h                        |    5 +-
 drivers/bluetooth/btrtl.c                          |    5 +-
 drivers/bluetooth/btusb.c                          |   44 +-
 drivers/bluetooth/hci_intel.c                      |    7 +-
 drivers/bus/mhi/host/main.c                        |    3 +-
 drivers/bus/sunxi-rsb.c                            |    3 +
 drivers/char/hw_random/virtio-rng.c                |   23 +-
 drivers/char/tlclk.c                               |    4 +
 drivers/char/tpm/eventlog/tpm1.c                   |    4 +-
 drivers/char/tpm/tpm-dev.c                         |    2 +-
 drivers/char/tpm/tpmrm-dev.c                       |    2 +-
 drivers/clk/clk-scmi.c                             |    4 +-
 drivers/clk/imx/clk.c                              |    2 +
 drivers/clk/qcom/a53-pll.c                         |    2 +-
 drivers/cpufreq/cpufreq.c                          |    2 +
 drivers/cpufreq/cpufreq_conservative.c             |   12 +-
 drivers/cpufreq/intel_pstate.c                     |    6 +-
 drivers/cpufreq/pcc-cpufreq.c                      |    2 +
 drivers/crypto/amcc/crypto4xx_alg.c                |  114 +-
 drivers/crypto/amcc/crypto4xx_core.c               |  148 +-
 drivers/crypto/amcc/crypto4xx_core.h               |   15 +-
 drivers/crypto/amcc/crypto4xx_reg_def.h            |   19 +-
 drivers/crypto/amcc/crypto4xx_sa.h                 |   18 +-
 drivers/crypto/amcc/crypto4xx_trng.h               |    2 +-
 drivers/crypto/amlogic/amlogic-gxl-core.c          |    2 +-
 drivers/crypto/atmel-ecc.c                         |    2 +-
 drivers/crypto/atmel-sha204a.c                     |   29 +-
 drivers/crypto/caam/caamalg.c                      |   12 +-
 drivers/crypto/caam/caamalg_qi.c                   |   12 +-
 drivers/crypto/caam/caamalg_qi2.c                  |   12 +-
 drivers/crypto/caam/caamhash.c                     |    4 +-
 drivers/crypto/caam/key_gen.c                      |    4 +-
 drivers/crypto/cavium/cpt/cptvf_reqmanager.c       |    4 +-
 drivers/crypto/ccp/sev-dev.c                       |    3 +-
 drivers/crypto/marvell/octeontx/otx_cptvf_reqmgr.c |    4 +-
 drivers/crypto/qat/qat_common/adf_accel_devices.h  |    2 +
 drivers/crypto/qat/qat_common/adf_aer.c            |    7 +-
 drivers/crypto/qat/qat_common/adf_common_drv.h     |    4 +
 drivers/crypto/qat/qat_common/adf_isr.c            |   18 +
 drivers/crypto/qat/qat_common/adf_pf2vf_msg.c      |   22 +
 drivers/crypto/qat/qat_common/adf_sriov.c          |   38 +-
 drivers/crypto/qat/qat_common/qat_asym_algs.c      |   10 +-
 drivers/crypto/talitos.c                           |   26 +-
 drivers/dma-buf/udmabuf.c                          |    5 +-
 drivers/dma/dmaengine.c                            |    3 +-
 drivers/gpio/gpio-eic-sprd.c                       |    8 +-
 drivers/gpio/gpio-htc-egpio.c                      |    6 +-
 drivers/gpio/gpio-mvebu.c                          |    5 +-
 drivers/gpio/gpio-palmas.c                         |   19 +
 drivers/gpio/gpio-pca953x.c                        |   11 +-
 drivers/gpio/gpio-timberdale.c                     |    2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c         |    4 +-
 drivers/gpu/drm/drm_edid.c                         |    8 +
 drivers/gpu/drm/i2c/sil164_drv.c                   |    7 -
 drivers/gpu/drm/msm/dp/dp_display.c                |    4 +-
 drivers/gpu/drm/msm/dp/dp_reg.h                    |    4 +-
 drivers/gpu/drm/radeon/radeon_ring.c               |    4 +-
 drivers/gpu/drm/tegra/dc.c                         |    4 +-
 drivers/gpu/drm/tidss/tidss_kms.c                  |    2 -
 drivers/gpu/host1x/bus.c                           |    2 +-
 drivers/hid/hid-appleir.c                          |   45 +-
 drivers/hid/hid-core.c                             |    7 +
 drivers/hid/hid-lg-g15.c                           |   16 +
 drivers/hid/hid-logitech-hidpp.c                   |    1 -
 drivers/hid/hid-multitouch.c                       |   32 +-
 drivers/hid/hid-picolcd_core.c                     |    3 +-
 drivers/hid/hid-sensor-hub.c                       |   77 +-
 drivers/hid/wacom_sys.c                            |   12 +-
 drivers/hwmon/asus_atk0110.c                       |    3 +
 drivers/hwmon/pmbus/adm1275.c                      |    2 +-
 drivers/hwmon/w83627hf.c                           |    4 +
 drivers/hwmon/w83793.c                             |    1 +
 drivers/hwspinlock/qcom_hwspinlock.c               |    5 +-
 .../hwtracing/coresight/coresight-cti-platform.c   |    1 +
 drivers/hwtracing/coresight/coresight-etb10.c      |    6 +-
 drivers/i2c/busses/i2c-mlxbf.c                     |    4 +-
 drivers/i2c/busses/i2c-mt65xx.c                    |    2 +-
 drivers/i2c/busses/i2c-stm32f7.c                   |    9 +-
 drivers/i2c/i2c-core-base.c                        |   82 +-
 drivers/i3c/master.c                               |   19 +-
 drivers/iio/accel/bmc150-accel-core.c              |    2 +
 drivers/iio/accel/kxsd9.c                          |    5 +-
 drivers/iio/accel/mma8452.c                        |    2 +
 drivers/iio/adc/lpc32xx_adc.c                      |    4 +-
 drivers/iio/adc/spear_adc.c                        |    4 +-
 drivers/iio/adc/ti-ads124s08.c                     |    3 +-
 drivers/iio/chemical/scd30_core.c                  |   19 +-
 drivers/iio/common/Kconfig                         |    1 +
 drivers/iio/common/Makefile                        |    1 +
 drivers/iio/common/inv_sensors/Kconfig             |    7 +
 drivers/iio/common/inv_sensors/Makefile            |    6 +
 .../inv_sensors/inv_sensors_timestamp.c}           |  120 +-
 drivers/iio/common/st_sensors/st_sensors_core.c    |   23 +-
 drivers/iio/gyro/bmg160_core.c                     |   16 +-
 drivers/iio/imu/adis_trigger.c                     |    2 +-
 drivers/iio/imu/bmi160/bmi160_core.c               |    3 +-
 drivers/iio/imu/inv_icm42600/Kconfig               |    1 +
 drivers/iio/imu/inv_icm42600/Makefile              |    1 -
 drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c  |   35 +-
 drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c |   61 +-
 drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h |    3 +
 drivers/iio/imu/inv_icm42600/inv_icm42600_core.c   |   24 +-
 drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c   |   35 +-
 .../iio/imu/inv_icm42600/inv_icm42600_timestamp.h  |   85 -
 drivers/iio/imu/inv_mpu6050/Kconfig                |    1 +
 drivers/iio/imu/inv_mpu6050/inv_mpu_core.c         |   30 +-
 drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h          |   18 +-
 drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c         |   85 +-
 drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c      |   11 +-
 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c       |   21 +-
 drivers/iio/industrialio-event.c                   |    5 +-
 drivers/iio/light/al3010.c                         |    2 +-
 drivers/iio/light/gp2ap002.c                       |    2 +-
 drivers/iio/light/opt3001.c                        |    6 +-
 drivers/iio/light/si1133.c                         |   14 +-
 drivers/iio/light/veml6030.c                       |    8 +-
 drivers/iio/magnetometer/ak8975.c                  |   15 +
 drivers/iio/orientation/hid-sensor-rotation.c      |   40 +-
 drivers/iio/temperature/ltc2983.c                  |    5 +-
 drivers/infiniband/hw/hns/hns_roce_hem.c           |    8 +-
 drivers/infiniband/hw/hns/hns_roce_main.c          |    2 +-
 drivers/infiniband/hw/mlx4/mlx4_ib.h               |    1 +
 drivers/infiniband/hw/mlx4/mr.c                    |    9 +-
 drivers/infiniband/hw/mlx4/sysfs.c                 |   45 +-
 drivers/infiniband/hw/mlx5/devx.c                  |   30 +-
 drivers/infiniband/hw/mlx5/qp.c                    |   11 +-
 drivers/infiniband/sw/siw/siw_qp_rx.c              |    9 +
 drivers/infiniband/ulp/srpt/ib_srpt.c              |    5 +-
 drivers/input/joystick/iforce/iforce-packets.c     |   18 +-
 drivers/input/joystick/maplecontrol.c              |    3 +-
 drivers/input/keyboard/maple_keyb.c                |    4 +-
 drivers/input/misc/ims-pcu.c                       |  115 +-
 drivers/input/mouse/elan_i2c_core.c                |   36 +-
 drivers/input/mouse/maplemouse.c                   |    9 +-
 drivers/input/rmi4/rmi_bus.c                       |    4 +-
 drivers/input/rmi4/rmi_f30.c                       |    2 +-
 drivers/input/rmi4/rmi_f3a.c                       |    2 +-
 drivers/input/touchscreen/goodix.c                 |    3 +-
 drivers/input/touchscreen/mms114.c                 |    2 +-
 drivers/input/touchscreen/touchwin.c               |   15 +-
 drivers/iommu/amd/amd_iommu_types.h                |   11 +-
 drivers/irqchip/irq-crossbar.c                     |   10 +-
 drivers/leds/leds-lm3601x.c                        |   11 +-
 drivers/leds/leds-lm3697.c                         |    4 +-
 drivers/leds/uleds.c                               |    3 +-
 drivers/md/dm-bufio.c                              |    4 +-
 drivers/md/dm-era-target.c                         |   10 +-
 drivers/md/dm-ioctl.c                              |    7 +-
 drivers/md/dm-log.c                                |    3 +
 drivers/md/dm-stats.c                              |   10 +-
 drivers/md/dm-thin-metadata.c                      |   67 +-
 drivers/md/dm-verity-target.c                      |    2 +-
 drivers/media/platform/qcom/venus/helpers.c        |    4 +-
 drivers/media/platform/rockchip/rga/rga-hw.c       |    2 +-
 drivers/media/platform/rockchip/rga/rga-hw.h       |    2 +-
 drivers/media/usb/uvc/uvc_video.c                  |   30 +-
 drivers/memstick/core/ms_block.c                   |    4 +
 drivers/mfd/cros_ec_dev.c                          |    3 +-
 drivers/mfd/sm501.c                                |    4 +-
 drivers/mfd/tps6586x.c                             |    2 +-
 drivers/mmc/host/renesas_sdhi_core.c               |    1 +
 drivers/mmc/host/vub300.c                          |   26 +-
 drivers/mtd/devices/slram.c                        |   22 +-
 drivers/mtd/maps/vmu-flash.c                       |    1 +
 drivers/mtd/nand/onenand/onenand_samsung.c         |    7 +-
 drivers/mtd/nand/raw/fsl_ifc_nand.c                |    9 +-
 drivers/mtd/nand/raw/lpc32xx_mlc.c                 |   12 +-
 drivers/mtd/nand/raw/lpc32xx_slc.c                 |   12 +-
 drivers/mtd/nand/raw/nand_base.c                   |    2 +-
 drivers/mtd/spi-nor/Kconfig                        |    1 -
 drivers/net/bonding/bond_3ad.c                     |    1 +
 drivers/net/dsa/sja1105/sja1105_ptp.c              |    2 +-
 drivers/net/ethernet/amazon/ena/ena_netdev.c       |   23 +-
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c    |    3 +-
 .../ethernet/cavium/liquidio/cn23xx_pf_device.c    |   18 +-
 drivers/net/ethernet/chelsio/cxgb4/t4_hw.c         |    8 -
 drivers/net/ethernet/freescale/fman/fman.c         |    4 +-
 drivers/net/ethernet/marvell/mvneta.c              |    3 +
 .../net/ethernet/marvell/octeontx2/nic/otx2_pf.c   |    1 +
 .../net/ethernet/mellanox/mlx5/core/lib/port_tun.c |    3 +-
 .../net/ethernet/mellanox/mlxsw/spectrum_router.c  |    1 +
 drivers/net/ethernet/qlogic/qede/qede_fp.c         |    5 +
 drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c |    5 +
 drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h |   20 +
 .../net/ethernet/qualcomm/rmnet/rmnet_handlers.c   |   53 +-
 drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h    |   22 +-
 .../ethernet/qualcomm/rmnet/rmnet_map_command.c    |   11 +-
 .../net/ethernet/qualcomm/rmnet/rmnet_map_data.c   |  334 +++-
 drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c    |    9 +-
 drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.h    |    1 +
 drivers/net/ethernet/sun/sungem.c                  |   13 +-
 drivers/net/ieee802154/ca8210.c                    |    9 +-
 drivers/net/macsec.c                               |    7 +-
 drivers/net/usb/gl620a.c                           |    6 +-
 drivers/net/usb/kalmia.c                           |    8 +
 drivers/net/usb/lan78xx.c                          |   18 +-
 drivers/net/usb/net1080.c                          |    2 +-
 drivers/net/virtio_net.c                           |    3 +
 drivers/net/wan/hdlc_ppp.c                         |   15 +-
 drivers/net/wireless/ath/ath9k/xmit.c              |    5 +
 drivers/net/wireless/ath/wcn36xx/smd.c             |    6 +
 drivers/net/wireless/marvell/mwifiex/join.c        |    1 -
 drivers/net/wireless/ralink/rt2x00/rt2x00dev.c     |   12 +-
 drivers/net/wireless/realtek/rtw88/pci.c           |    5 +
 drivers/nvdimm/btt.c                               |   14 +-
 drivers/nvme/host/core.c                           |    2 +-
 drivers/nvme/target/rdma.c                         |   18 +-
 drivers/nvme/target/tcp.c                          |   33 +-
 drivers/pci/Makefile                               |    2 +-
 drivers/pci/controller/dwc/pci-imx6.c              |    5 +-
 drivers/pci/controller/dwc/pcie-designware-host.c  |    2 +-
 .../pci/controller/mobiveil/pcie-mobiveil-host.c   |    8 +-
 drivers/pci/controller/pci-host-common.c           |    4 +
 drivers/pci/controller/pcie-altera-msi.c           |    2 +-
 drivers/pci/controller/pcie-altera.c               |   32 +-
 drivers/pci/controller/pcie-mediatek.c             |  117 +-
 drivers/pci/controller/pcie-rcar-host.c            |    1 -
 drivers/pci/controller/pcie-xilinx-nwl.c           |    2 +-
 drivers/pci/pci.c                                  |  135 --
 drivers/pci/pci.h                                  |    4 +
 drivers/pci/rebar.c                                |  217 +++
 drivers/pci/setup-bus.c                            |  100 +-
 drivers/pci/setup-res.c                            |   53 -
 drivers/pinctrl/mediatek/pinctrl-mt8167.c          |    2 +-
 drivers/pinctrl/mediatek/pinctrl-mt8516.c          |    2 +-
 drivers/pinctrl/sunxi/pinctrl-sunxi.c              |    2 +-
 drivers/platform/x86/xo15-ebook.c                  |    7 +-
 drivers/power/supply/charger-manager.c             |    6 +-
 drivers/pwm/pwm-imx27.c                            |    8 +-
 drivers/rapidio/devices/tsi721.c                   |    3 +-
 drivers/regulator/core.c                           |   29 +-
 drivers/regulator/ltc3676.c                        |   10 +-
 drivers/reset/reset-imx7.c                         |    6 +
 drivers/reset/reset-sunxi.c                        |    4 +-
 drivers/rtc/rtc-abx80x.c                           |    3 +-
 drivers/rtc/rtc-cmos.c                             |    6 +
 drivers/rtc/rtc-ds1307.c                           |   30 +-
 drivers/s390/char/monwriter.c                      |    3 +
 drivers/s390/net/qeth_l3_main.c                    |    6 +-
 drivers/scsi/hpsa.c                                |    4 +
 drivers/scsi/pm8001/pm8001_ctl.c                   |    5 +-
 drivers/scsi/scsi_scan.c                           |    2 +-
 drivers/scsi/scsi_transport_sas.c                  |   60 +-
 drivers/scsi/sg.c                                  |    7 +-
 drivers/scsi/smartpqi/smartpqi_init.c              |    2 +-
 drivers/soc/fsl/qe/qe.c                            |    3 +
 drivers/soc/ti/k3-ringacc.c                        |    4 +-
 drivers/spi/spi-ep93xx.c                           |    1 +
 drivers/spi/spi-fsl-lpspi.c                        |   18 +-
 drivers/spi/spi-sh-msiof.c                         |   10 +-
 drivers/spi/spi-uniphier.c                         |    4 +-
 drivers/spi/spi-xilinx.c                           |   11 +-
 drivers/staging/media/atomisp/pci/atomisp_cmd.c    |    6 +-
 .../media/atomisp/pci/atomisp_compat_css20.c       |    2 +-
 .../atomisp/pci/runtime/isys/src/virtual_isys.c    |   12 +-
 drivers/staging/media/atomisp/pci/sh_css.c         | 1946 +++++++++-----------
 drivers/staging/media/ipu3/ipu3-css-params.c       |    8 +-
 drivers/staging/media/sunxi/cedrus/cedrus.c        |    4 +-
 drivers/staging/most/video/video.c                 |    7 +-
 drivers/staging/nvec/nvec.c                        |    4 +-
 drivers/staging/rtl8723bs/core/rtw_ap.c            |   31 +-
 drivers/staging/rtl8723bs/core/rtw_cmd.c           |   96 +-
 drivers/staging/rtl8723bs/core/rtw_ieee80211.c     |   22 +-
 drivers/staging/rtl8723bs/core/rtw_ioctl_set.c     |    4 +-
 drivers/staging/rtl8723bs/core/rtw_mlme.c          |   16 +-
 drivers/staging/rtl8723bs/core/rtw_mlme_ext.c      |  349 ++--
 drivers/staging/rtl8723bs/core/rtw_recv.c          |    4 +-
 drivers/staging/rtl8723bs/core/rtw_security.c      |    6 +-
 drivers/staging/rtl8723bs/core/rtw_wlan_util.c     |   14 +-
 drivers/staging/rtl8723bs/hal/hal_com_phycfg.c     |   34 -
 drivers/staging/rtl8723bs/hal/odm.c                |   30 -
 drivers/staging/rtl8723bs/hal/odm.h                |    3 -
 drivers/staging/rtl8723bs/hal/odm_EdcaTurboCheck.c |    4 +-
 drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c  |    1 -
 drivers/staging/rtl8723bs/hal/sdio_halinit.c       |   10 -
 drivers/staging/rtl8723bs/include/hal_phy.h        |    3 -
 drivers/staging/rtl8723bs/include/ieee80211.h      |   22 +-
 drivers/staging/rtl8723bs/include/rtw_mlme_ext.h   |    6 +-
 drivers/staging/rtl8723bs/include/wifi.h           |    1 -
 drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c  |  118 +-
 drivers/staging/rtl8723bs/os_dep/ioctl_linux.c     |   41 +-
 drivers/staging/rtl8723bs/os_dep/os_intfs.c        |    6 +-
 drivers/target/target_core_pr.c                    |    8 +-
 drivers/thermal/thermal_hwmon.c                    |    5 +-
 drivers/tty/serial/8250/8250_mid.c                 |   31 +-
 drivers/tty/serial/8250/8250_omap.c                |    3 +-
 drivers/tty/serial/msm_serial.c                    |    3 +-
 drivers/usb/atm/ueagle-atm.c                       |   36 +-
 drivers/usb/class/cdc-acm.c                        |    3 +
 drivers/usb/common/ulpi.c                          |   23 +-
 drivers/usb/core/quirks.c                          |    6 +
 drivers/usb/gadget/composite.c                     |    5 +-
 drivers/usb/gadget/function/f_fs.c                 |    5 +-
 drivers/usb/gadget/function/f_printer.c            |   10 +-
 drivers/usb/gadget/function/rndis.c                |   20 +-
 drivers/usb/host/ehci-sched.c                      |   11 +-
 drivers/usb/host/fotg210-hcd.c                     |    6 +-
 drivers/usb/host/max3421-hcd.c                     |    8 +
 drivers/usb/host/sl811-hcd.c                       |    1 +
 drivers/usb/host/xhci.c                            |   11 +-
 drivers/usb/misc/chaoskey.c                        |    1 -
 drivers/usb/misc/idmouse.c                         |   45 +-
 drivers/usb/misc/iowarrior.c                       |   21 +-
 drivers/usb/misc/ldusb.c                           |   38 +-
 drivers/usb/misc/legousbtower.c                    |   37 +-
 drivers/usb/misc/uss720.c                          |    5 +-
 drivers/usb/mtu3/mtu3_gadget.c                     |    1 +
 drivers/usb/serial/digi_acceleport.c               |   43 +-
 drivers/usb/serial/option.c                        |   16 +
 drivers/usb/storage/ene_ub6250.c                   |    3 +-
 drivers/usb/storage/usb.c                          |    2 +-
 drivers/usb/typec/tcpm/tcpm.c                      |    7 +-
 drivers/usb/typec/ucsi/displayport.c               |    7 +-
 drivers/usb/typec/ucsi/ucsi_ccg.c                  |    2 +-
 drivers/usb/usbip/vudc.h                           |    1 -
 drivers/usb/usbip/vudc_dev.c                       |    4 +-
 drivers/vfio/pci/vfio_pci.c                        |    1 +
 drivers/vhost/vdpa.c                               |   29 +-
 drivers/video/fbdev/aty/radeon_base.c              |    1 +
 drivers/video/fbdev/carminefb.c                    |    1 +
 drivers/video/fbdev/core/fbcon.c                   |    7 +
 drivers/video/fbdev/i740fb.c                       |    1 +
 drivers/video/fbdev/nvidia/nvidia.c                |    1 +
 drivers/video/fbdev/s3fb.c                         |    1 +
 drivers/video/fbdev/sm501fb.c                      |   16 +-
 drivers/video/fbdev/sm712.h                        |    2 +-
 drivers/video/fbdev/tdfxfb.c                       |    1 +
 drivers/video/fbdev/tridentfb.c                    |    1 +
 drivers/video/fbdev/uvesafb.c                      |    4 +-
 drivers/virtio/virtio_mmio.c                       |   26 +-
 drivers/watchdog/sprd_wdt.c                        |    5 +-
 drivers/xen/gntdev.c                               |    8 +-
 fs/afs/cell.c                                      |    2 +
 fs/afs/cmservice.c                                 |    2 -
 fs/afs/rxrpc.c                                     |   11 +-
 fs/afs/super.c                                     |    3 +-
 fs/afs/vl_list.c                                   |   10 +-
 fs/btrfs/extent-tree.c                             |   17 +-
 fs/cifs/cifs_debug.c                               |    2 +-
 fs/cifs/cifsacl.c                                  |    2 +-
 fs/cifs/cifsfs.c                                   |    1 -
 fs/cifs/cifsglob.h                                 |    5 +-
 fs/cifs/cifsproto.h                                |    2 +-
 fs/cifs/connect.c                                  |   17 +-
 fs/cifs/misc.c                                     |    4 +-
 fs/cifs/netmisc.c                                  |    2 +-
 fs/cifs/readdir.c                                  |    6 +-
 fs/cifs/smb2maperror.c                             |   16 +-
 fs/cifs/smb2misc.c                                 |  123 +-
 fs/cifs/smb2ops.c                                  |  107 +-
 fs/cifs/smb2pdu.c                                  |  114 +-
 fs/cifs/smb2pdu.h                                  |  365 +---
 fs/cifs/smb2proto.h                                |    4 +-
 fs/cifs/smb2transport.c                            |   36 +-
 fs/configfs/dir.c                                  |   54 +-
 fs/efs/file.c                                      |   21 +-
 fs/exfat/dir.c                                     |   13 +-
 fs/ext4/ioctl.c                                    |   12 +-
 fs/f2fs/checkpoint.c                               |   13 +-
 fs/f2fs/data.c                                     |   29 +
 fs/f2fs/debug.c                                    |    2 +-
 fs/f2fs/f2fs.h                                     |    1 +
 fs/f2fs/file.c                                     |   15 +-
 fs/f2fs/gc.c                                       |    4 +-
 fs/f2fs/inode.c                                    |   13 +-
 fs/f2fs/segment.c                                  |   14 +-
 fs/f2fs/segment.h                                  |    8 +-
 fs/f2fs/xattr.c                                    |    4 +-
 fs/fs-writeback.c                                  |   20 +-
 fs/fuse/cuse.c                                     |    4 +-
 fs/fuse/dev.c                                      |    2 +-
 fs/hfs/bfind.c                                     |    2 +-
 fs/hfs/bnode.c                                     |   56 +-
 fs/hfs/brec.c                                      |    2 +-
 fs/hfs/btree.c                                     |    2 +-
 fs/hfs/btree.h                                     |   71 +-
 fs/hfs/hfs_fs.h                                    |   83 +-
 fs/hfs/inode.c                                     |    2 +-
 fs/hfsplus/bfind.c                                 |    2 +-
 fs/hfsplus/bnode.c                                 |   62 +-
 fs/hfsplus/brec.c                                  |    2 +-
 fs/hfsplus/btree.c                                 |    2 +-
 fs/hfsplus/hfsplus_fs.h                            |   40 +-
 fs/isofs/rock.c                                    |   11 +
 fs/lockd/svcsubs.c                                 |    4 +-
 fs/nfs/callback_proc.c                             |    9 +-
 fs/nfs/dir.c                                       |    2 +
 fs/nfs/filelayout/filelayout.c                     |    2 +
 fs/nfs/flexfilelayout/flexfilelayout.c             |   33 +
 fs/nfs/flexfilelayout/flexfilelayout.h             |   16 +
 fs/nfs/pnfs.c                                      |    4 +-
 fs/nfsd/nfs4layouts.c                              |    4 +-
 fs/nfsd/nfs4recover.c                              |  120 +-
 fs/nfsd/nfs4state.c                                |   22 +-
 fs/nfsd/vfs.c                                      |    9 +-
 fs/nilfs2/segment.c                                |   22 +
 fs/ocfs2/alloc.c                                   |    2 +-
 fs/ocfs2/aops.c                                    |   13 +-
 fs/ocfs2/buffer_head_io.c                          |    7 +-
 fs/ocfs2/dlm/dlmdebug.c                            |   16 +-
 fs/ocfs2/dlmglue.c                                 |   17 +
 fs/ocfs2/inode.c                                   |  150 +-
 fs/ocfs2/journal.c                                 |   13 +-
 fs/ocfs2/move_extents.c                            |    4 +-
 fs/ocfs2/ocfs2.h                                   |    2 -
 fs/ocfs2/quota_local.c                             |    2 +-
 fs/ocfs2/stack_user.c                              |   10 +-
 fs/ocfs2/super.c                                   |    2 -
 fs/ocfs2/sysfile.c                                 |    9 +-
 fs/orangefs/dir.c                                  |    7 +-
 fs/proc/array.c                                    |    6 +
 fs/proc/base.c                                     |  184 +-
 fs/proc/fd.c                                       |   29 +-
 fs/proc/generic.c                                  |    9 +-
 fs/proc/internal.h                                 |    4 +-
 fs/proc/namespaces.c                               |   16 +-
 fs/proc/proc_net.c                                 |    1 +
 fs/smbfs_common/smb2pdu.h                          |  318 ++++
 fs/sysfs/file.c                                    |    4 +
 fs/udf/balloc.c                                    |    5 +-
 fs/udf/super.c                                     |   11 +-
 fs/userfaultfd.c                                   |   14 +-
 fs/xfs/libxfs/xfs_format.h                         |    2 +-
 fs/xfs/libxfs/xfs_sb.c                             |   64 +
 fs/xfs/libxfs/xfs_sb.h                             |    1 +
 fs/xfs/xfs_dquot.c                                 |   16 +-
 fs/xfs/xfs_log_recover.c                           |    6 +-
 fs/xfs/xfs_mount.c                                 |    1 +
 fs/xfs/xfs_mount.h                                 |   75 +
 fs/xfs/xfs_rtalloc.c                               |    3 +
 include/crypto/drbg.h                              |   18 +-
 include/linux/audit.h                              |    8 +
 include/linux/bitops.h                             |    2 +
 include/linux/device.h                             |    5 +-
 include/linux/glob.h                               |    1 +
 include/linux/hid-sensor-hub.h                     |   25 +
 include/linux/hid.h                                |   29 +
 include/linux/if_rmnet.h                           |   70 +-
 include/linux/iio/common/inv_sensors_timestamp.h   |   94 +
 include/linux/pci.h                                |    4 +-
 include/linux/platform_data/pca953x.h              |    2 +-
 include/linux/skmsg.h                              |   22 +-
 include/net/addrconf.h                             |   12 +-
 include/net/bluetooth/hci.h                        |    5 +-
 include/net/bluetooth/l2cap.h                      |    2 +-
 include/net/fib_rules.h                            |    5 +
 include/net/gue.h                                  |    2 +-
 include/net/if_inet6.h                             |   37 +-
 include/net/ip_fib.h                               |    7 +-
 include/net/ip_vs.h                                |    3 +-
 include/net/mld.h                                  |    3 +
 include/net/ndisc.h                                |    4 +-
 include/net/rtnetlink.h                            |    2 +
 include/net/sctp/sctp.h                            |    3 +-
 include/net/sock.h                                 |    2 +-
 include/net/xfrm.h                                 |    7 +
 include/uapi/linux/if_link.h                       |    1 +
 io_uring/io-wq.c                                   |    2 +-
 kernel/audit.c                                     |   85 +-
 kernel/bpf/verifier.c                              |    3 +-
 kernel/cgroup/cpuset.c                             |    7 +-
 kernel/cpu.c                                       |    8 +-
 kernel/locking/rtmutex.c                           |   16 +-
 kernel/sched/fair.c                                |    2 +-
 kernel/sched/features.h                            |    8 +
 kernel/time/posix-cpu-timers.c                     |    3 +-
 kernel/time/time.c                                 |    2 +-
 kernel/trace/ring_buffer.c                         |    3 +-
 kernel/trace/trace_events_filter.c                 |    6 +-
 kernel/trace/trace_probe.c                         |    3 +-
 kernel/trace/trace_probe.h                         |    2 +-
 kernel/workqueue.c                                 |    2 +-
 lib/debugobjects.c                                 |   17 +
 lib/glob.c                                         |   31 +-
 lib/test_meminit.c                                 |    2 +-
 net/6lowpan/nhc.c                                  |    2 +-
 net/9p/trans_rdma.c                                |   19 +-
 net/atm/common.c                                   |    2 +
 net/batman-adv/distributed-arp-table.c             |   30 +-
 net/batman-adv/fragmentation.c                     |    8 +-
 net/batman-adv/gateway_client.c                    |    3 +-
 net/batman-adv/main.c                              |   22 +-
 net/batman-adv/multicast.c                         |    6 +-
 net/batman-adv/routing.c                           |    3 +-
 net/batman-adv/soft-interface.c                    |   11 +-
 net/batman-adv/soft-interface.h                    |    2 +
 net/batman-adv/translation-table.c                 |    5 +-
 net/batman-adv/types.h                             |    7 +
 net/bluetooth/af_bluetooth.c                       |   17 +-
 net/bluetooth/bnep/core.c                          |   27 +-
 net/bluetooth/l2cap_core.c                         |  123 +-
 net/bluetooth/l2cap_sock.c                         |    4 +-
 net/bridge/netfilter/ebtables.c                    |   22 +-
 net/bridge/netfilter/nft_meta_bridge.c             |    4 +-
 net/can/bcm.c                                      |   90 +-
 net/can/isotp.c                                    |    9 +-
 net/core/fib_rules.c                               |    6 +-
 net/core/filter.c                                  |   38 +-
 net/core/lwt_bpf.c                                 |   12 +
 net/core/rtnetlink.c                               |    8 +
 net/core/skbuff.c                                  |   23 +-
 net/core/skmsg.c                                   |    2 +
 net/ieee802154/core.c                              |    2 +-
 net/ieee802154/header_ops.c                        |    9 +-
 net/ieee802154/ieee802154.h                        |   17 +
 net/ieee802154/netlink.c                           |   36 +-
 net/ife/ife.c                                      |    2 +-
 net/ipv4/igmp.c                                    |    1 +
 net/ipv4/ip_gre.c                                  |    6 +
 net/ipv4/ip_vti.c                                  |    3 +
 net/ipv4/netfilter/nf_log_ipv4.c                   |    4 +-
 net/ipv4/sysctl_net_ipv4.c                         |   10 +-
 net/ipv4/tcp_output.c                              |    4 +-
 net/ipv6/addrconf.c                                |   38 +-
 net/ipv6/addrconf_core.c                           |    2 +-
 net/ipv6/af_inet6.c                                |    2 +-
 net/ipv6/icmp.c                                    |    4 +-
 net/ipv6/ip6_gre.c                                 |    6 +
 net/ipv6/ip6_vti.c                                 |    3 +
 net/ipv6/mcast.c                                   | 1184 +++++++-----
 net/ipv6/netfilter.c                               |    4 +-
 net/ipv6/netfilter/ip6t_ah.c                       |    5 +
 net/ipv6/netfilter/ip6t_hbh.c                      |    1 +
 net/ipv6/netfilter/ip6t_rt.c                       |    3 +-
 net/ipv6/netfilter/nf_conntrack_reasm.c            |    3 +-
 net/ipv6/netfilter/nf_log_ipv6.c                   |    4 +-
 net/ipv6/route.c                                   |    9 +-
 net/ipv6/seg6.c                                    |    3 +
 net/ipv6/sit.c                                     |    3 +
 net/kcm/kcmsock.c                                  |    8 +-
 net/key/af_key.c                                   |    1 +
 net/llc/af_llc.c                                   |    1 +
 net/llc/llc_conn.c                                 |    1 -
 net/mac80211/main.c                                |    3 +-
 net/mac80211/tx.c                                  |   17 +-
 net/mac802154/iface.c                              |    2 +-
 net/netfilter/ipset/ip_set_core.c                  |   12 +-
 net/netfilter/ipvs/ip_vs_app.c                     |   10 +-
 net/netfilter/ipvs/ip_vs_conn.c                    |    4 +-
 net/netfilter/ipvs/ip_vs_core.c                    |   36 +-
 net/netfilter/ipvs/ip_vs_proto_sctp.c              |   18 +-
 net/netfilter/ipvs/ip_vs_proto_tcp.c               |   11 +-
 net/netfilter/ipvs/ip_vs_proto_udp.c               |    3 +-
 net/netfilter/nf_conncount.c                       |   23 +-
 net/netfilter/nf_conntrack_core.c                  |   18 +-
 net/netfilter/nf_conntrack_irc.c                   |    6 +-
 net/netfilter/nf_conntrack_seqadj.c                |    2 +
 net/netfilter/nf_nat_sip.c                         |    9 +
 net/netfilter/nfnetlink_cthelper.c                 |    4 +-
 net/netfilter/nfnetlink_osf.c                      |    6 +-
 net/netfilter/nft_log.c                            |   58 +-
 net/netfilter/nft_synproxy.c                       |    9 +-
 net/netfilter/xt_AUDIT.c                           |   58 +-
 net/netfilter/xt_cluster.c                         |    2 +-
 net/netfilter/xt_nat.c                             |    9 +
 net/netfilter/xt_rateest.c                         |    2 +-
 net/netfilter/xt_u32.c                             |   12 +-
 net/openvswitch/conntrack.c                        |    2 +-
 net/psample/psample.c                              |    6 +-
 net/qrtr/af_qrtr.c                                 |    2 +-
 net/sched/cls_bpf.c                                |   10 +-
 net/sched/sch_cake.c                               |    5 +-
 net/sched/sch_codel.c                              |   48 +-
 net/sched/sch_drr.c                                |    8 +-
 net/sched/sch_fq_codel.c                           |   41 +-
 net/sched/sch_hfsc.c                               |   24 +-
 net/sched/sch_hhf.c                                |   27 +
 net/sched/sch_htb.c                                |    8 +-
 net/sched/sch_multiq.c                             |    2 +-
 net/sctp/diag.c                                    |   67 +-
 net/sctp/sm_make_chunk.c                           |   10 +-
 net/sctp/sm_statefuns.c                            |   23 +-
 net/sctp/socket.c                                  |   29 +-
 net/smc/smc_cdc.c                                  |   15 +-
 net/socket.c                                       |    2 +-
 net/tipc/bcast.c                                   |   22 +-
 net/tipc/bcast.h                                   |    2 +-
 net/tipc/bearer.c                                  |    1 +
 net/tipc/netlink.c                                 |   12 +
 net/tipc/node.c                                    |   15 +-
 net/tipc/socket.c                                  |    3 +
 net/tipc/udp_media.c                               |    2 +
 net/tls/tls_sw.c                                   |    4 +
 net/xfrm/xfrm_interface_core.c                     |    3 +
 net/xfrm/xfrm_policy.c                             |    3 +
 net/xfrm/xfrm_state.c                              |   11 +-
 net/xfrm/xfrm_user.c                               |    2 +-
 samples/trace_events/trace-events-sample.c         |    4 +
 scripts/kconfig/conf.c                             |    6 +-
 security/apparmor/domain.c                         |   58 +-
 security/apparmor/include/policy_unpack.h          |   19 +
 security/apparmor/label.c                          |    2 +-
 security/apparmor/lsm.c                            |   18 +-
 security/apparmor/net.c                            |    1 +
 security/apparmor/policy.c                         |   14 +-
 security/apparmor/procattr.c                       |    2 +
 security/keys/keyring.c                            |    2 +-
 sound/aoa/fabrics/layout.c                         |    6 +
 sound/firewire/isight.c                            |    3 +-
 sound/pci/es1938.c                                 |    2 +
 sound/soc/fsl/fsl_audmix.c                         |    6 +
 sound/soc/tegra/tegra210_ahub.c                    |    4 +-
 sound/usb/caiaq/input.c                            |    2 +-
 sound/usb/mixer_quirks.c                           |  101 +-
 sound/usb/mixer_scarlett.c                         |    4 +-
 sound/usb/mixer_us16x08.c                          |  127 +-
 tools/bpf/bpftool/net.c                            |    4 +-
 tools/include/linux/bitops.h                       |    2 +
 tools/lib/api/fs/fs.c                              |   19 +-
 tools/lib/symbol/kallsyms.c                        |    5 +-
 tools/perf/builtin-c2c.c                           |    1 +
 tools/perf/builtin-sched.c                         |   37 +-
 tools/perf/trace/beauty/fcntl.c                    |   16 +
 tools/perf/util/bpf-event.c                        |   18 +-
 tools/perf/util/cpumap.c                           |    6 +
 tools/perf/util/event.c                            |   15 +-
 tools/perf/util/hist.c                             |    7 +-
 tools/perf/util/machine.c                          |   10 +-
 tools/perf/util/mmap.c                             |   10 +-
 tools/perf/util/pmu.c                              |    4 +-
 tools/perf/util/probe-finder.c                     |    4 +-
 tools/perf/util/symbol-elf.c                       |   48 +-
 tools/perf/util/symbol-minimal.c                   |   11 +-
 tools/perf/util/symbol.c                           |    2 +-
 tools/perf/util/thread.c                           |    5 +
 tools/testing/selftests/vm/compaction_test.c       |    3 +
 tools/testing/selftests/vm/hmm-tests.c             |   32 +-
 tools/usb/usbip/libsrc/usbip_common.c              |    2 +
 tools/usb/usbip/libsrc/usbip_device_driver.c       |    4 +
 tools/usb/usbip/libsrc/vhci_driver.c               |    1 +
 tools/virtio/vringh_test.c                         |    5 +
 tools/vm/slabinfo.c                                |    4 +-
 virt/kvm/eventfd.c                                 |   12 +-
 virt/kvm/kvm_main.c                                |   16 +-
 689 files changed, 8712 insertions(+), 5883 deletions(-)
author maintainer
#1 lore raw

PATCH 1/699 nvmet-tcp: fix race between ICReq handling and queue teardown

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

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

From: Chaitanya Kulkarni <[email protected]>

commit 5293a8882c549fab4a878bc76b0b6c951f980a61 upstream.

nvmet_tcp_handle_icreq() updates queue->state after sending an Initialization Connection Response (ICResp), but it does so without serializing against target-side queue teardown.

If an NVMe/TCP host sends an Initialization Connection Request (ICReq) and immediately closes the connection, target-side teardown may start in softirq context before io_work drains the already buffered ICReq. In that case, nvmet_tcp_schedule_release_queue() sets queue->state to NVMET_TCP_Q_DISCONNECTING and drops the queue reference under state_lock.

If io_work later processes that ICReq, nvmet_tcp_handle_icreq() can still overwrite the state back to NVMET_TCP_Q_LIVE. That defeats the DISCONNECTING-state guard in nvmet_tcp_schedule_release_queue() and allows a later socket state change to re-enter teardown and issue a second kref_put() on an already released queue.

The ICResp send failure path has the same problem. If teardown has already moved the queue to DISCONNECTING, a send error can still overwrite the state with NVMET_TCP_Q_FAILED, again reopening the window for a second teardown path to drop the queue reference.

Fix this by serializing both post-send state transitions with state_lock and bailing out if teardown has already started.

Use -ESHUTDOWN as an internal sentinel for that bail-out path rather than propagating it as a transport error like -ECONNRESET. Keep nvmet_tcp_socket_error() setting rcv_state to NVMET_TCP_RECV_ERR before honoring that sentinel so receive-side parsing stays quiesced until the existing release path completes.

Fixes c46a6465bac2 ("nvmet-tcp: add NVMe over TCP target driver")

[ context diff adaptation: drop queue->state = NVMET_TCP_Q_FAILED since
the enum introduced in 6.7, 675b453e0241 ("nvmet-tcp: enable TLS handshake upcall" ]

---
 drivers/nvme/target/tcp.c | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)
drivers/nvme/target/tcp.c +28 -1
index edcc0662c3e571..4bd82e9b113ff5 100644
@@ -345,6 +345,19 @@ static void nvmet_tcp_build_pdu_iovec(struct nvmet_tcp_cmd *cmd)
 
 static void nvmet_tcp_fatal_error(struct nvmet_tcp_queue *queue)
 {
+	/*
+	 * Keep rcv_state at RECV_ERR even for the internal -ESHUTDOWN path.
+	 * nvmet_tcp_handle_icreq() can return -ESHUTDOWN after the ICReq has
+	 * already been consumed and queue teardown has started.
+	 *
+	 * If nvmet_tcp_data_ready() or nvmet_tcp_write_space() queues
+	 * nvmet_tcp_io_work() again before nvmet_tcp_release_queue_work()
+	 * cancels it, the queue must not keep that old receive state.
+	 * Otherwise the next nvmet_tcp_io_work() run can reach
+	 * nvmet_tcp_done_recv_pdu() and try to handle the same ICReq again.
+	 *
+	 * That is why queue->rcv_state needs to be updated before we return.
+	 */
 	queue->rcv_state = NVMET_TCP_RECV_ERR;
 	if (queue->nvme_sq.ctrl)
 		nvmet_ctrl_fatal_error(queue->nvme_sq.ctrl);
@@ -888,10 +901,24 @@ static int nvmet_tcp_handle_icreq(struct nvmet_tcp_queue *queue)
 	iov.iov_base = icresp;
 	iov.iov_len = sizeof(*icresp);
 	ret = kernel_sendmsg(queue->sock, &msg, &iov, 1, iov.iov_len);
-	if (ret < 0)
+	if (ret < 0) {
+		spin_lock_bh(&queue->state_lock);
+		if (queue->state == NVMET_TCP_Q_DISCONNECTING) {
+			spin_unlock_bh(&queue->state_lock);
+			return -ESHUTDOWN;
+		}
+		spin_unlock_bh(&queue->state_lock);
 		return ret; /* queue removal will cleanup */
+	}
 
+	spin_lock_bh(&queue->state_lock);
+	if (queue->state == NVMET_TCP_Q_DISCONNECTING) {
+		spin_unlock_bh(&queue->state_lock);
+		/* Tell nvmet_tcp_socket_error() teardown is in progress. */
+		return -ESHUTDOWN;
+	}
 	queue->state = NVMET_TCP_Q_LIVE;
+	spin_unlock_bh(&queue->state_lock);
 	nvmet_prepare_receive_pdu(queue);
 	return 0;
 }
Signature · 1 line
2.53.0
author maintainer
#2 lore raw

PATCH 2/699 nfsd: release layout stid on setlease failure

In reply to Greg Kroah-Hartman

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

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

From: Chris Mason <[email protected]>

commit 30d55c8aabb261bc3f427d6b9aae7ef6206063f9 upstream.

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

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

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

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

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

Fixes c5c707f96fc9 ("nfsd: implement pNFS layout recalls")
Assisted-by kres (claude-opus-4-7)
[ cel: no ls_fence_work in 5.10.y; dropped INIT_DELAYED_WORK hunk ]
---
 fs/nfsd/nfs4layouts.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)
fs/nfsd/nfs4layouts.c +1 -3
index d0fbbd34db689c..bcf16dd07d4883 100644
@@ -241,9 +241,7 @@ nfsd4_alloc_layout_stateid(struct nfsd4_compound_state *cstate,
 	BUG_ON(!ls->ls_file);
 
 	if (nfsd4_layout_setlease(ls)) {
-		nfsd_file_put(ls->ls_file);
-		put_nfs4_file(fp);
-		kmem_cache_free(nfs4_layout_stateid_cache, ls);
+		nfs4_put_stid(stp);
 		return NULL;
 	}
 
Signature · 1 line
2.53.0
author maintainer
#3 lore raw

PATCH 3/699 nfsd: reset write verifier on deferred writeback errors

In reply to Greg Kroah-Hartman

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

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

From: Jeff Layton <[email protected]>

commit 2090b05803faab8a9fa62fbff871007862cac1b7 upstream.

nfsd_vfs_write() and nfsd_commit() both call filemap_check_wb_err() to detect deferred writeback errors, but neither rotates the server's write verifier (nn->writeverf) when this check fails. Every other durable-storage-failure path in these functions calls commit_reset_write_verifier() before returning an error.

The missing rotation means clients holding UNSTABLE write data under the current verifier will COMMIT, receive the unchanged verifier back, and conclude their data is durable — silently dropping data that failed writeback. This violates the UNSTABLE+COMMIT durability contract (RFC 1813 §3.3.7, RFC 8881 §18.32).

Add commit_reset_write_verifier() calls at both filemap_check_wb_err() error sites, matching the pattern used by adjacent error paths in the same functions. The helper already filters -EAGAIN and -ESTALE internally, so the calls are unconditionally safe.

Fixes 555dbf1a9aac ("nfsd: Replace use of rwsem with errseq_t")
Assisted-by kres:claude-opus-4-6
[ cel: open-code the reset; commit_reset_write_verifier() is v6.7 ]
---
 fs/nfsd/vfs.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
fs/nfsd/vfs.c +8 -1
index 19468142486671..c8eebd03784a21 100644
@@ -1149,8 +1149,11 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf,
 	nfsd_stats_io_write_add(nn, exp, *cnt);
 	fsnotify_modify(file);
 	host_err = filemap_check_wb_err(file->f_mapping, since);
-	if (host_err < 0)
+	if (host_err < 0) {
+		nfsd_reset_write_verifier(nn);
+		trace_nfsd_writeverf_reset(nn, rqstp, host_err);
 		goto out_nfserr;
+	}
 
 	if (stable && use_wgather) {
 		host_err = wait_for_concurrent_writes(file);
@@ -1286,6 +1289,10 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf,
 			nfsd_copy_write_verifier(verf, nn);
 			err2 = filemap_check_wb_err(nf->nf_file->f_mapping,
 						    since);
+			if (err2 < 0) {
+				nfsd_reset_write_verifier(nn);
+				trace_nfsd_writeverf_reset(nn, rqstp, err2);
+			}
 			err = nfserrno(err2);
 			break;
 		case -EINVAL:
Signature · 1 line
2.53.0
#4 lore raw
In reply to Greg Kroah-Hartman
Quoted 9 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 5.10.261 release. There are 699 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 Thu, 23 Jul 2026 15:23:00 +0000. Anything received after that time might be too late.

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

Quoted 8 lines
	https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.10.261-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

perf fails to build with this error:

util/event.c: In function 'machine__resolve':
util/event.c:668:32: warning: implicit declaration of function 'perf_env__get_cpu_topology'; did you mean 'perf_env__read_cpu_topology_map'? [-Wimplicit-function-declaration]
668 | topo = perf_env__get_cpu_topology(env,

(struct perf_cpu){ al->cpu });
      |                                ^~~~~~~~~~~~~~~~~~~~~~~~~~
      |                                perf_env__read_cpu_topology_map
util/event.c:668:83: warning: excess elements in struct initializer
  668 |                         topo = perf_env__get_cpu_topology(env, 
(struct perf_cpu){ al->cpu });
      | 
                  ^~
util/event.c:668:83: note: (near initialization for '(anonymous)')
util/event.c:668:81: error: invalid use of undefined type 'struct perf_cpu'
  668 |                         topo = perf_env__get_cpu_topology(env, 
(struct perf_cpu){ al->cpu });
      | 
                ^

make[6]: *** [/local/users/fainelli/buildroot/output/arm/build/linux-custom/tools/build/Makefile.build:97: /local/users/fainelli/buildroot/output/arm/build/linux-custom/tools/perf/util/event.o] Error 1 make[6]: *** Waiting for unfinished jobs....

which is due to commit 07511f3c23cdaf1dbb44802f026fcc476351dfe2 ("perf tools: Use perf_env__get_cpu_topology() in machine__resolve()"), it looks like we need to also backport those commits:

751835c57632006232bf30405cd7201dceb0b8e0 ("perf stat: Introduce perf_env__get_cpu_topology() to guard NULL env->cpu")

6d18804b963b78dcd53851f11e9080408b3d85c2 ("perf cpumap: Give CPUs their own type")

c760174401f605cf63314d3817069a40945f0e0b ("perf cpumap: Reduce cpu size from int to int16_t")

Signature · 1 line
Florian
Tested-by on the v1 series
#5 lore raw
In reply to Greg Kroah-Hartman
Quoted 5 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 5.10.261 release. There are 699 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Quoted 10 lines

Responses should be made by Thu, 23 Jul 2026 15:23:00 +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.261-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.

Compiled OK for an i386 and runs OK on a 32-bit eeepc. No new problems noticed.

author maintainer
#7 lore raw

PATCH 4/699 userfaultfd: gate must_wait writability check on pte_present()

In reply to Greg Kroah-Hartman

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

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

From: Kiryl Shutsemau <[email protected]>

[ Upstream commit 8e80af52db652fbc41320eee45a4f73bc029faf2 ]

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

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

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

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

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

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

PATCH 5/699 clk: imx: Add check for kcalloc

In reply to Greg Kroah-Hartman

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

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

From: Jiasheng Jiang <[email protected]>

commit ed713e2bc093239ccd380c2ce8ae9e4162f5c037 upstream.

As the potential failure of the kcalloc(),
it should be better to check it in order to
avoid the dereference of the NULL pointer.

Fixes 379c9a24cc23 ("clk: imx: Fix reparenting of UARTs not associated with stdout")
---
 drivers/clk/imx/clk.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/clk/imx/clk.c +2 -0
index d4cf0c7045ab27..be0493e5b494e6 100644
@@ -173,6 +173,8 @@ void imx_register_uart_clocks(unsigned int clk_count)
 		int i;
 
 		imx_uart_clocks = kcalloc(clk_count, sizeof(struct clk *), GFP_KERNEL);
+		if (!imx_uart_clocks)
+			return;
 
 		if (!of_stdout)
 			return;
Signature · 1 line
2.53.0
author maintainer
#9 lore raw

PATCH 6/699 nfsd: move name lookup out of nfsd4_list_rec_dir()

In reply to Greg Kroah-Hartman

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

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

From: NeilBrown <[email protected]>

[ Upstream commit 89bd77cf436bf25e448817a662ebf76515f22863 ]

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

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

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

---
 fs/nfsd/nfs4recover.c | 55 ++++++++++++++++++++++---------------------
 1 file changed, 28 insertions(+), 27 deletions(-)
fs/nfsd/nfs4recover.c +28 -27
index 8ea55b2621ee41..c74c4023770694 100644
@@ -254,7 +254,7 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
 	nfs4_reset_creds(original_cred);
 }
 
-typedef int (recdir_func)(struct dentry *, struct dentry *, struct nfsd_net *);
+typedef int (recdir_func)(struct dentry *, char *, struct nfsd_net *);
 
 struct name_list {
 	char name[HEXDIR_LEN];
@@ -308,23 +308,14 @@ nfsd4_list_rec_dir(recdir_func *f, struct nfsd_net *nn)
 	}
 
 	status = iterate_dir(nn->rec_file, &ctx.ctx);
-	inode_lock_nested(d_inode(dir), I_MUTEX_PARENT);
 
 	list_for_each_entry_safe(entry, tmp, &ctx.names, list) {
-		if (!status) {
-			struct dentry *dentry;
-			dentry = lookup_one_len(entry->name, dir, HEXDIR_LEN-1);
-			if (IS_ERR(dentry)) {
-				status = PTR_ERR(dentry);
-				break;
-			}
-			status = f(dir, dentry, nn);
-			dput(dentry);
-		}
+		if (!status)
+			status = f(dir, entry->name, nn);
+
 		list_del(&entry->list);
 		kfree(entry);
 	}
-	inode_unlock(d_inode(dir));
 	nfs4_reset_creds(original_cred);
 
 	list_for_each_entry_safe(entry, tmp, &ctx.names, list) {
@@ -422,18 +413,19 @@ nfsd4_remove_clid_dir(struct nfs4_client *clp)
 }
 
 static int
-purge_old(struct dentry *parent, struct dentry *child, struct nfsd_net *nn)
+purge_old(struct dentry *parent, char *cname, struct nfsd_net *nn)
 {
 	int status;
+	struct dentry *child;
 	struct xdr_netobj name;
 
-	if (child->d_name.len != HEXDIR_LEN - 1) {
-		printk("%s: illegal name %pd in recovery directory\n",
-				__func__, child);
+	if (strlen(cname) != HEXDIR_LEN - 1) {
+		printk("%s: illegal name %s in recovery directory\n",
+				__func__, cname);
 		/* Keep trying; maybe the others are OK: */
 		return 0;
 	}
-	name.data = kmemdup_nul(child->d_name.name, child->d_name.len, GFP_KERNEL);
+	name.data = kstrdup(cname, GFP_KERNEL);
 	if (!name.data) {
 		dprintk("%s: failed to allocate memory for name.data!\n",
 			__func__);
@@ -443,10 +435,17 @@ purge_old(struct dentry *parent, struct dentry *child, struct nfsd_net *nn)
 	if (nfs4_has_reclaimed_state(name, nn))
 		goto out_free;
 
-	status = vfs_rmdir(d_inode(parent), child);
-	if (status)
-		printk("failed to remove client recovery directory %pd\n",
-				child);
+	inode_lock_nested(d_inode(parent), I_MUTEX_PARENT);
+	child = lookup_one_len(cname, parent, HEXDIR_LEN - 1);
+	if (!IS_ERR(child)) {
+		status = vfs_rmdir(d_inode(parent), child);
+		if (status)
+			printk("failed to remove client recovery directory %pd\n",
+			       child);
+		dput(child);
+	}
+	inode_unlock(d_inode(parent));
+
 out_free:
 	kfree(name.data);
 out:
@@ -477,18 +476,18 @@ nfsd4_recdir_purge_old(struct nfsd_net *nn)
 }
 
 static int
-load_recdir(struct dentry *parent, struct dentry *child, struct nfsd_net *nn)
+load_recdir(struct dentry *parent, char *cname, struct nfsd_net *nn)
 {
 	struct xdr_netobj name;
 	struct xdr_netobj princhash = { .len = 0, .data = NULL };
 
-	if (child->d_name.len != HEXDIR_LEN - 1) {
-		printk("%s: illegal name %pd in recovery directory\n",
-				__func__, child);
+	if (strlen(cname) != HEXDIR_LEN - 1) {
+		printk("%s: illegal name %s in recovery directory\n",
+				__func__, cname);
 		/* Keep trying; maybe the others are OK: */
 		return 0;
 	}
-	name.data = kmemdup_nul(child->d_name.name, child->d_name.len, GFP_KERNEL);
+	name.data = kstrdup(cname, GFP_KERNEL);
 	if (!name.data) {
 		dprintk("%s: failed to allocate memory for name.data!\n",
 			__func__);
@@ -843,11 +842,13 @@ __cld_pipe_inprogress_downcall(const struct cld_msg_v2 __user *cmsg,
 				return PTR_ERR(name.data);
 			name.len = namelen;
 		}
+#ifdef CONFIG_NFSD_V4
 		if (name.len > 5 && memcmp(name.data, "hash:", 5) == 0) {
 			name.len = name.len - 5;
 			memmove(name.data, name.data + 5, name.len);
 			cn->cn_has_legacy = true;
 		}
+#endif
 		if (!nfs4_client_to_reclaim(name, princhash, nn)) {
 			kfree(name.data);
 			kfree(princhash.data);
Signature · 1 line
2.53.0
author maintainer
#10 lore raw

PATCH 7/699 nfsd: change nfs4_client_to_reclaim() to allocate data

In reply to Greg Kroah-Hartman

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

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

From: NeilBrown <[email protected]>

[ Upstream commit 4552f4e3f2c96597914f07b060d5c5db84420ddd ]

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

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

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

---
 fs/nfsd/nfs4recover.c | 67 +++++++++++++++----------------------------
 fs/nfsd/nfs4state.c   | 22 ++++++++++++--
 2 files changed, 42 insertions(+), 47 deletions(-)
fs/nfsd/nfs4recover.c +23 -44
index c74c4023770694..8ff61f6184e24d 100644
@@ -167,24 +167,13 @@ legacy_recdir_name_error(struct nfs4_client *clp, int error)
 
 static void
 __nfsd4_create_reclaim_record_grace(struct nfs4_client *clp,
-		const char *dname, int len, struct nfsd_net *nn)
+				    char *dname, struct nfsd_net *nn)
 {
-	struct xdr_netobj name;
+	struct xdr_netobj name = { .len = strlen(dname), .data = dname };
 	struct xdr_netobj princhash = { .len = 0, .data = NULL };
 	struct nfs4_client_reclaim *crp;
 
-	name.data = kmemdup(dname, len, GFP_KERNEL);
-	if (!name.data) {
-		dprintk("%s: failed to allocate memory for name.data!\n",
-			__func__);
-		return;
-	}
-	name.len = len;
 	crp = nfs4_client_to_reclaim(name, princhash, nn);
-	if (!crp) {
-		kfree(name.data);
-		return;
-	}
 	crp->cr_clp = clp;
 }
 
@@ -240,8 +229,7 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
 	inode_unlock(d_inode(dir));
 	if (status == 0) {
 		if (nn->in_grace)
-			__nfsd4_create_reclaim_record_grace(clp, dname,
-					HEXDIR_LEN, nn);
+			__nfsd4_create_reclaim_record_grace(clp, dname, nn);
 		vfs_fsync(nn->rec_file, 0);
 	} else {
 		printk(KERN_ERR "NFSD: failed to write recovery record"
@@ -478,7 +466,7 @@ nfsd4_recdir_purge_old(struct nfsd_net *nn)
 static int
 load_recdir(struct dentry *parent, char *cname, struct nfsd_net *nn)
 {
-	struct xdr_netobj name;
+	struct xdr_netobj name = { .len = HEXDIR_LEN, .data = cname };
 	struct xdr_netobj princhash = { .len = 0, .data = NULL };
 
 	if (strlen(cname) != HEXDIR_LEN - 1) {
@@ -487,16 +475,7 @@ load_recdir(struct dentry *parent, char *cname, struct nfsd_net *nn)
 		/* Keep trying; maybe the others are OK: */
 		return 0;
 	}
-	name.data = kstrdup(cname, GFP_KERNEL);
-	if (!name.data) {
-		dprintk("%s: failed to allocate memory for name.data!\n",
-			__func__);
-		goto out;
-	}
-	name.len = HEXDIR_LEN;
-	if (!nfs4_client_to_reclaim(name, princhash, nn))
-		kfree(name.data);
-out:
+	nfs4_client_to_reclaim(name, princhash, nn);
 	return 0;
 }
 
@@ -792,6 +771,8 @@ __cld_pipe_inprogress_downcall(const struct cld_msg_v2 __user *cmsg,
 {
 	uint8_t cmd, princhashlen;
 	struct xdr_netobj name, princhash = { .len = 0, .data = NULL };
+	char *namecopy __free(kfree) = NULL;
+	char *princhashcopy __free(kfree) = NULL;
 	uint16_t namelen;
 	struct cld_net *cn = nn->cld_net;
 
@@ -810,20 +791,20 @@ __cld_pipe_inprogress_downcall(const struct cld_msg_v2 __user *cmsg,
 				dprintk("%s: namelen should not be zero", __func__);
 				return -EINVAL;
 			}
-			name.data = memdup_user(&ci->cc_name.cn_id, namelen);
-			if (IS_ERR(name.data))
-				return PTR_ERR(name.data);
+			namecopy = memdup_user(&ci->cc_name.cn_id, namelen);
+			if (IS_ERR(namecopy))
+				return PTR_ERR(namecopy);
+			name.data = namecopy;
 			name.len = namelen;
 			if (get_user(princhashlen, &ci->cc_princhash.cp_len))
 				return -EFAULT;
 			if (princhashlen > 0) {
-				princhash.data = memdup_user(
-						&ci->cc_princhash.cp_data,
-						princhashlen);
-				if (IS_ERR(princhash.data)) {
-					kfree(name.data);
-					return PTR_ERR(princhash.data);
-				}
+				princhashcopy = memdup_user(
+					&ci->cc_princhash.cp_data,
+					princhashlen);
+				if (IS_ERR(princhashcopy))
+					return PTR_ERR(princhashcopy);
+				princhash.data = princhashcopy;
 				princhash.len = princhashlen;
 			} else
 				princhash.len = 0;
@@ -837,23 +818,21 @@ __cld_pipe_inprogress_downcall(const struct cld_msg_v2 __user *cmsg,
 				dprintk("%s: namelen should not be zero", __func__);
 				return -EINVAL;
 			}
-			name.data = memdup_user(&cnm->cn_id, namelen);
-			if (IS_ERR(name.data))
-				return PTR_ERR(name.data);
+			namecopy = memdup_user(&cnm->cn_id, namelen);
+			if (IS_ERR(namecopy))
+				return PTR_ERR(namecopy);
+			name.data = namecopy;
 			name.len = namelen;
 		}
 #ifdef CONFIG_NFSD_V4
 		if (name.len > 5 && memcmp(name.data, "hash:", 5) == 0) {
 			name.len = name.len - 5;
-			memmove(name.data, name.data + 5, name.len);
+			name.data = name.data + 5;
 			cn->cn_has_legacy = true;
 		}
 #endif
-		if (!nfs4_client_to_reclaim(name, princhash, nn)) {
-			kfree(name.data);
-			kfree(princhash.data);
+		if (!nfs4_client_to_reclaim(name, princhash, nn))
 			return -EFAULT;
-		}
 		return nn->client_tracking_ops->msglen;
 	}
 	return -EFAULT;
fs/nfsd/nfs4state.c +19 -3
index 6b34bfac6194bb..c61e1a4ab620cc 100644
@@ -8037,9 +8037,6 @@ nfs4_has_reclaimed_state(struct xdr_netobj name, struct nfsd_net *nn)
 
 /*
  * failure => all reset bets are off, nfserr_no_grace...
- *
- * The caller is responsible for freeing name.data if NULL is returned (it
- * will be freed in nfs4_remove_reclaim_record in the normal case).
  */
 struct nfs4_client_reclaim *
 nfs4_client_to_reclaim(struct xdr_netobj name, struct xdr_netobj princhash,
@@ -8048,6 +8045,22 @@ nfs4_client_to_reclaim(struct xdr_netobj name, struct xdr_netobj princhash,
 	unsigned int strhashval;
 	struct nfs4_client_reclaim *crp;
 
+	name.data = kmemdup(name.data, name.len, GFP_KERNEL);
+	if (!name.data) {
+		dprintk("%s: failed to allocate memory for name.data!\n",
+			__func__);
+		return NULL;
+	}
+	if (princhash.len) {
+		princhash.data = kmemdup(princhash.data, princhash.len, GFP_KERNEL);
+		if (!princhash.data) {
+			dprintk("%s: failed to allocate memory for princhash.data!\n",
+				__func__);
+			kfree(name.data);
+			return NULL;
+		}
+	} else
+		princhash.data = NULL;
 	crp = alloc_reclaim();
 	if (crp) {
 		strhashval = clientstr_hashval(name);
@@ -8059,6 +8072,9 @@ nfs4_client_to_reclaim(struct xdr_netobj name, struct xdr_netobj princhash,
 		crp->cr_princhash.len = princhash.len;
 		crp->cr_clp = NULL;
 		nn->reclaim_str_hashtbl_size++;
+	} else {
+		kfree(name.data);
+		kfree(princhash.data);
 	}
 	return crp;
 }
Signature · 1 line
2.53.0
author maintainer
#11 lore raw

PATCH 8/699 mmc: renesas_sdhi: Add quirk entry for RZ/G2H SoC

In reply to Greg Kroah-Hartman

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

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

From: Lad Prabhakar <[email protected]>

The RZ/G2H (R8A774E1) SoC uses the same SDHI IP as the R-Car H3-N (R8A77951) and requires the sdhi_quirks_bad_taps2367 quirk.

The 5.10 stable backport of commit 77fa80a1b732 ("mmc: renesas_sdhi:
Add OF entry for RZ/G2H SoC") adds an OF match entry for RZ/G2H. However, unlike upstream, the 5.10 driver applies SoC-specific quirks through the sdhi_quirks_match table. As a result, the required quirk is not applied for RZ/G2H.

Add the missing sdhi_quirks_match entry for RZ/G2H ES3.x.

---
 drivers/mmc/host/renesas_sdhi_core.c | 1 +
 1 file changed, 1 insertion(+)
drivers/mmc/host/renesas_sdhi_core.c +1 -0
index c0acb309e3243b..f02f9ef5cfbc80 100644
@@ -903,6 +903,7 @@ static const struct renesas_sdhi_quirks sdhi_quirks_r8a77990 = {
  */
 static const struct soc_device_attribute sdhi_quirks_match[]  = {
 	{ .soc_id = "r8a774a1", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 },
+	{ .soc_id = "r8a774e1", .revision = "ES3.*", .data = &sdhi_quirks_bad_taps2367 },
 	{ .soc_id = "r8a7795", .revision = "ES1.*", .data = &sdhi_quirks_4tap_nohs400 },
 	{ .soc_id = "r8a7795", .revision = "ES2.0", .data = &sdhi_quirks_4tap },
 	{ .soc_id = "r8a7795", .revision = "ES3.*", .data = &sdhi_quirks_bad_taps2367 },
Signature · 1 line
2.53.0
author maintainer
#12 lore raw

PATCH 9/699 KVM: Replace guest-triggerable BUG_ON() in ioeventfd datamatch with get_unaligned()

In reply to Greg Kroah-Hartman

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

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

From: Sean Christopherson <[email protected]>

commit f1edbed787ba67988ed34e0132ca128b052b6ce8 upstream.

Drop a BUG_ON() that has been reachable since it was first added, way back in 2009, and instead use get_unaligned() to perform potentially-unaligned accesses.

For a given store, KVM x86's emulator tracks the entire value in the destination operand, x86_emulate_ctxt.dst. If the destination is memory, and the target splits multiple pages and/or is emulated MMIO, then KVM handles each fragment independently. E.g. on a page split starting at page offset 0xffc, KVM writes 4 bytes to the first page, then the remaining bytes to the second page, using ctxt->dst as the source for both (with appropriate offsets).

If the destination splits a page *and* hits emulated MMIO on the second page, then KVM will complete the write to the first page, then emulate the MMIO access to the second page. If there is a datamatch-enabled ioeventfd at offset 0 of the second page, then KVM will process the remainder of the store as a potential ioeventfd signal.

Putting it all together, if the guest emits a store that splits a page starting at page offset N, and the second page has a datamatch-enabled ioeventfd at offset 0, then KVM will check for datamatch using &dst.valptr[N] as the source. Due to dst (and thus dst.valptr) being 32-byte aligned, if N is not aligned to @len, the BUG_ON() fires.

E.g. with a 16-byte store at page offset 0xffc, to an ioeventfd of len 8, all initial checks in ioeventfd_in_range() will succeed, and the BUG_ON() fires due to @val being 4-byte aligned, but not 8-byte aligned.

  ------------[ cut here ]------------
  kernel BUG at arch/x86/kvm/../../../virt/kvm/eventfd.c:783!
  Oops: invalid opcode: 0000 [#1] SMP
  CPU: 0 UID: 1000 PID: 615 Comm: repro Not tainted 7.1.0-rc2-ff238429d1ea #365 PREEMPT
  Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
  RIP: 0010:ioeventfd_write+0x6c/0x70 [kvm]
  Call Trace:
   <TASK>
   __kvm_io_bus_write+0x85/0xb0 [kvm]
   kvm_io_bus_write+0x53/0x80 [kvm]
   vcpu_mmio_write+0x66/0xf0 [kvm]
   emulator_read_write_onepage+0x12a/0x540 [kvm]
   emulator_read_write+0x109/0x2b0 [kvm]
   x86_emulate_insn+0x4f8/0xfb0 [kvm]
   x86_emulate_instruction+0x181/0x790 [kvm]
   kvm_mmu_page_fault+0x313/0x630 [kvm]
   vmx_handle_exit+0x18a/0x590 [kvm_intel]
   kvm_arch_vcpu_ioctl_run+0xc81/0x1c90 [kvm]
   kvm_vcpu_ioctl+0x2d5/0x970 [kvm]
   __x64_sys_ioctl+0x8a/0xd0
   do_syscall_64+0xb7/0x890
   entry_SYSCALL_64_after_hwframe+0x4b/0x53
  RIP: 0033:0x7f19c931a9bf
   </TASK>
  Modules linked in: kvm_intel kvm irqbypass
  ---[ end trace 0000000000000000 ]---

In a perfect world, the fix would be to simply delete the BUG_ON(), as KVM x86 doesn't perform alignment checks on "normal" memory accesses at CPL0. Sadly, C99 ruins all the fun; while the x86 architecture plays nice, dereferencing an unaligned pointer directly is undefined behavior in C, e.g. triggers splats when running with CONFIG_UBSAN_ALIGNMENT=y.

Fixes d34e6b175e61 ("KVM: add ioeventfd support")

Message-ID: <[email protected]>

[ Use the old <asm/unaligned.h> header instead ]
---
 virt/kvm/eventfd.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)
virt/kvm/eventfd.c +5 -7
index 4702b71aad0831..ff0ef5f7246e93 100644
@@ -24,6 +24,7 @@
 #include <linux/slab.h>
 #include <linux/seqlock.h>
 #include <linux/irqbypass.h>
+#include <asm/unaligned.h>
 #include <trace/events/kvm.h>
 
 #include <kvm/iodev.h>
@@ -695,21 +696,18 @@ ioeventfd_in_range(struct _ioeventfd *p, gpa_t addr, int len, const void *val)
 		return true;
 
 	/* otherwise, we have to actually compare the data */
-
-	BUG_ON(!IS_ALIGNED((unsigned long)val, len));
-
 	switch (len) {
 	case 1:
-		_val = *(u8 *)val;
+		_val = get_unaligned((u8 *)val);
 		break;
 	case 2:
-		_val = *(u16 *)val;
+		_val = get_unaligned((u16 *)val);
 		break;
 	case 4:
-		_val = *(u32 *)val;
+		_val = get_unaligned((u32 *)val);
 		break;
 	case 8:
-		_val = *(u64 *)val;
+		_val = get_unaligned((u64 *)val);
 		break;
 	default:
 		return false;
Signature · 1 line
2.53.0
author maintainer
#13 lore raw

PATCH 10/699 perf trace beauty fcntl: Fix build with older kernel headers

In reply to Greg Kroah-Hartman

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

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

From: Florian Fainelli <[email protected]>

commit 7ee7f48413c42b90230de4a8e40898b757bc8e82 upstream.

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

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

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

PATCH 11/699 bus: mhi: host: Add alignment check for event ring read pointer

In reply to Greg Kroah-Hartman

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

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

From: Krishna chaitanya chundru <[email protected]>

commit eff9704f5332a13b08fbdbe0f84059c9e7051d5f upstream.

Though we do check the event ring read pointer by "is_valid_ring_ptr" to make sure it is in the buffer range, but there is another risk the pointer may be not aligned. Since we are expecting event ring elements are 128 bits(struct mhi_ring_element) aligned, an unaligned read pointer could lead to multiple issues like DoS or ring buffer memory corruption.

So add a alignment check for event ring read pointer.

---
 drivers/bus/mhi/host/main.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/bus/mhi/host/main.c +2 -1
@@ -222,7 +222,8 @@ static void mhi_del_ring_element(struct
 
 static bool is_valid_ring_ptr(struct mhi_ring *ring, dma_addr_t addr)
 {
-	return addr >= ring->iommu_base && addr < ring->iommu_base + ring->len;
+	return addr >= ring->iommu_base && addr < ring->iommu_base + ring->len &&
+			!(addr & (sizeof(struct mhi_tre) - 1));
 }
 
 int mhi_destroy_device(struct device *dev, void *data)
author maintainer
#15 lore raw

PATCH 12/699 netfilter: nf_log: validate MAC header was set before dumping it

In reply to Greg Kroah-Hartman

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

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

From: Xiang Mei <[email protected]>

commit a84b6fedbc97078788be78dbdd7517d143ad1a77 upstream.

The fallback path of dump_mac_header() guards the MAC header access only with "skb->mac_header != skb->network_header", without checking skb_mac_header_was_set(). When the MAC header is unset, mac_header is 0xffff, so the test passes and skb_mac_header(skb) returns skb->head + 0xffff, ~64 KiB past the buffer; the loop then reads dev->hard_header_len bytes out of bounds into the kernel log.

This is reachable via the netdev logger: nf_log_unknown_packet() calls dump_mac_header() unconditionally, and an skb sent through AF_PACKET with PACKET_QDISC_BYPASS reaches the egress hook with mac_header still unset (__dev_queue_xmit(), which would reset it, is bypassed).

Add the skb_mac_header_was_set() check the ARPHRD_ETHER path already uses, and replace the open-coded MAC header length test with skb_mac_header_len(). Only skbs with an unset MAC header are affected; valid ones are dumped as before.

 BUG: KASAN: slab-out-of-bounds in dump_mac_header (net/netfilter/nf_log_syslog.c:831)
 Read of size 1 at addr ffff88800ea49d3f by task exploit/148
 Call Trace:
  kasan_report (mm/kasan/report.c:595)
  dump_mac_header (net/netfilter/nf_log_syslog.c:831)
  nf_log_netdev_packet (net/netfilter/nf_log_syslog.c:938 net/netfilter/nf_log_syslog.c:963)
  nf_log_packet (net/netfilter/nf_log.c:260)
  nft_log_eval (net/netfilter/nft_log.c:60)
  nft_do_chain (net/netfilter/nf_tables_core.c:285)
  nft_do_chain_netdev (net/netfilter/nft_chain_filter.c:307)
  nf_hook_slow (net/netfilter/core.c:619)
  nf_hook_direct_egress (net/packet/af_packet.c:257)
  packet_xmit (net/packet/af_packet.c:280)
  packet_sendmsg (net/packet/af_packet.c:3114)
  __sys_sendto (net/socket.c:2265)
Fixes 7eb9282cd0ef ("netfilter: ipt_LOG/ip6t_LOG: add option to print decoded MAC header")
Assisted-by Claude:claude-opus-4-8
---
 net/ipv4/netfilter/nf_log_ipv4.c |    4 ++--
 net/ipv6/netfilter/nf_log_ipv6.c |    4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)
net/ipv4/netfilter/nf_log_ipv4.c +2 -2
@@ -296,8 +296,8 @@ static void dump_ipv4_mac_header(struct
 
 fallback:
 	nf_log_buf_add(m, "MAC=");
-	if (dev->hard_header_len &&
-	    skb->mac_header != skb->network_header) {
+	if (dev->hard_header_len && skb_mac_header_was_set(skb) &&
+	    skb_mac_header_len(skb) != 0) {
 		const unsigned char *p = skb_mac_header(skb);
 		unsigned int i;
 
net/ipv6/netfilter/nf_log_ipv6.c +2 -2
@@ -309,8 +309,8 @@ static void dump_ipv6_mac_header(struct
 
 fallback:
 	nf_log_buf_add(m, "MAC=");
-	if (dev->hard_header_len &&
-	    skb->mac_header != skb->network_header) {
+	if (dev->hard_header_len && skb_mac_header_was_set(skb) &&
+	    skb_mac_header_len(skb) != 0) {
 		const unsigned char *p = skb_mac_header(skb);
 		unsigned int len = dev->hard_header_len;
 		unsigned int i;
author maintainer
#16 lore raw

PATCH 13/699 skmsg: convert struct sk_msg_sg::copy to a bitmap

In reply to Greg Kroah-Hartman

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

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

From: Eric Dumazet <[email protected]>

[ Upstream commit 5a8fb33e530512ee67a11b30f3451a4f030f4b01 ]

We have plans for increasing MAX_SKB_FRAGS, but sk_msg_sg::copy is currently an unsigned long, limiting MAX_SKB_FRAGS to 30 on 32bit arches.

Convert it to a bitmap, as Jakub suggested.

Stable-dep-of: 406e8a651a7b ("net: skmsg: preserve sg.copy across SG transforms")

---
 include/linux/skmsg.h |   11 +++++------
 net/core/filter.c     |    4 ++--
 2 files changed, 7 insertions(+), 8 deletions(-)
include/linux/skmsg.h +5 -6
@@ -29,7 +29,7 @@ struct sk_msg_sg {
 	u32				end;
 	u32				size;
 	u32				copybreak;
-	unsigned long			copy;
+	DECLARE_BITMAP(copy, MAX_MSG_FRAGS + 2);
 	/* The extra two elements:
 	 * 1) used for chaining the front and sections when the list becomes
 	 *    partitioned (e.g. end < start). The crypto APIs require the
@@ -38,7 +38,6 @@ struct sk_msg_sg {
 	 */
 	struct scatterlist		data[MAX_MSG_FRAGS + 2];
 };
-static_assert(BITS_PER_LONG >= NR_MSG_FRAG_IDS);
 
 /* UAPI in filter.c depends on struct sk_msg_sg being first element. */
 struct sk_msg {
@@ -235,7 +234,7 @@ static inline void sk_msg_compute_data_p
 {
 	struct scatterlist *sge = sk_msg_elem(msg, msg->sg.start);
 
-	if (test_bit(msg->sg.start, &msg->sg.copy)) {
+	if (test_bit(msg->sg.start, msg->sg.copy)) {
 		msg->data = NULL;
 		msg->data_end = NULL;
 	} else {
@@ -254,7 +253,7 @@ static inline void sk_msg_page_add(struc
 	sg_set_page(sge, page, len, offset);
 	sg_unmark_end(sge);
 
-	__set_bit(msg->sg.end, &msg->sg.copy);
+	__set_bit(msg->sg.end, msg->sg.copy);
 	msg->sg.size += len;
 	sk_msg_iter_next(msg, end);
 }
@@ -263,9 +262,9 @@ static inline void sk_msg_sg_copy(struct
 {
 	do {
 		if (copy_state)
-			__set_bit(i, &msg->sg.copy);
+			__set_bit(i, msg->sg.copy);
 		else
-			__clear_bit(i, &msg->sg.copy);
+			__clear_bit(i, msg->sg.copy);
 		sk_msg_iter_var_next(i);
 		if (i == msg->sg.end)
 			break;
net/core/filter.c +2 -2
@@ -2677,7 +2677,7 @@ BPF_CALL_4(bpf_msg_pull_data, struct sk_
 	 * account for the headroom.
 	 */
 	bytes_sg_total = start - offset + bytes;
-	if (!test_bit(i, &msg->sg.copy) && bytes_sg_total <= len)
+	if (!test_bit(i, msg->sg.copy) && bytes_sg_total <= len)
 		goto out;
 
 	/* At this point we need to linearize multiple scatterlist
@@ -2900,7 +2900,7 @@ place_new:
 	/* Place newly allocated data buffer */
 	sk_mem_charge(msg->sk, len);
 	msg->sg.size += len;
-	__clear_bit(new, &msg->sg.copy);
+	__clear_bit(new, msg->sg.copy);
 	sg_set_page(&msg->sg.data[new], page, len + copy, 0);
 	if (rsge.length) {
 		get_page(sg_page(&rsge));
author maintainer
#17 lore raw

PATCH 14/699 net: skmsg: preserve sg.copy across SG transforms

In reply to Greg Kroah-Hartman

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

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

From: Yiming Qian <[email protected]>

[ Upstream commit 406e8a651a7b854c41fecd5117bb282b3a6c2c6b ]

The sk_msg sg.copy bitmap is part of the scatterlist entry ownership state. A set bit tells sk_msg_compute_data_pointers() not to expose the entry through writable BPF ctx->data. This protects entries backed by pages that are not private to the sk_msg, such as splice-backed file page-cache pages.

Several sk_msg transform paths move, copy, split, or compact msg->sg.data[] entries without moving the matching sg.copy bit. This can make an externally backed entry arrive at a new slot with a clear copy bit. A later SK_MSG verdict can then expose sg_virt(sge) as writable ctx->data and BPF stores can modify the original page cache.

Keep sg.copy synchronized with sg.data[] whenever entries are transferred, shifted, split, or copied into a new sk_msg. Clear the bit when an entry is replaced by a newly allocated private page or freed. This covers the BPF pull/push/pop helpers, sk_msg_shift_left/right(), sk_msg_xfer(), and tls_split_open_record(), including the partial tail entry created during TLS open-record splitting.

---
 include/linux/skmsg.h |   15 +++++++++++----
 net/core/filter.c     |   27 +++++++++++++++++++++++++++
 net/core/skmsg.c      |    2 ++
 net/tls/tls_sw.c      |    4 ++++
 4 files changed, 44 insertions(+), 4 deletions(-)
include/linux/skmsg.h +11 -4
@@ -4,6 +4,7 @@
 #ifndef _LINUX_SKMSG_H
 #define _LINUX_SKMSG_H
 
+#include <linux/bitops.h>
 #include <linux/bpf.h>
 #include <linux/filter.h>
 #include <linux/scatterlist.h>
@@ -187,11 +188,14 @@ static inline void sk_msg_xfer(struct sk
 			       int which, u32 size)
 {
 	dst->sg.data[which] = src->sg.data[which];
+	__assign_bit(which, dst->sg.copy, test_bit(which, src->sg.copy));
 	dst->sg.data[which].length  = size;
 	dst->sg.size		   += size;
 	src->sg.size		   -= size;
 	src->sg.data[which].length -= size;
 	src->sg.data[which].offset += size;
+	if (!src->sg.data[which].length)
+		__clear_bit(which, src->sg.copy);
 }
 
 static inline void sk_msg_xfer_full(struct sk_msg *dst, struct sk_msg *src)
@@ -261,16 +265,19 @@ static inline void sk_msg_page_add(struc
 static inline void sk_msg_sg_copy(struct sk_msg *msg, u32 i, bool copy_state)
 {
 	do {
-		if (copy_state)
-			__set_bit(i, msg->sg.copy);
-		else
-			__clear_bit(i, msg->sg.copy);
+		__assign_bit(i, msg->sg.copy, copy_state);
 		sk_msg_iter_var_next(i);
 		if (i == msg->sg.end)
 			break;
 	} while (1);
 }
 
+static inline void sk_msg_sg_copy_assign(struct sk_msg *dst, u32 dst_i,
+					 const struct sk_msg *src, u32 src_i)
+{
+	__assign_bit(dst_i, dst->sg.copy, test_bit(src_i, src->sg.copy));
+}
+
 static inline void sk_msg_sg_copy_set(struct sk_msg *msg, u32 start)
 {
 	sk_msg_sg_copy(msg, start, true);
net/core/filter.c +27 -0
@@ -2718,11 +2718,13 @@ BPF_CALL_4(bpf_msg_pull_data, struct sk_
 		poffset += len;
 		sge->length = 0;
 		put_page(sg_page(sge));
+		__clear_bit(i, msg->sg.copy);
 
 		sk_msg_iter_var_next(i);
 	} while (i != last_sge);
 
 	sg_set_page(&msg->sg.data[first_sge], page, copy, 0);
+	__clear_bit(first_sge, msg->sg.copy);
 
 	/* To repair sg ring we need to shift entries. If we only
 	 * had a single entry though we can just replace it and
@@ -2748,9 +2750,11 @@ BPF_CALL_4(bpf_msg_pull_data, struct sk_
 			break;
 
 		msg->sg.data[i] = msg->sg.data[move_from];
+		sk_msg_sg_copy_assign(msg, i, msg, move_from);
 		msg->sg.data[move_from].length = 0;
 		msg->sg.data[move_from].page_link = 0;
 		msg->sg.data[move_from].offset = 0;
+		__clear_bit(move_from, msg->sg.copy);
 		sk_msg_iter_var_next(i);
 	} while (1);
 
@@ -2779,6 +2783,7 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_
 {
 	struct scatterlist sge, nsge, nnsge, rsge = {0}, *psge;
 	u32 new, i = 0, l = 0, space, copy = 0, offset = 0;
+	bool sge_copy, nsge_copy, nnsge_copy, rsge_copy = false;
 	u8 *raw, *to, *from;
 	struct page *page;
 
@@ -2851,6 +2856,7 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_
 			sk_msg_iter_var_prev(i);
 		psge = sk_msg_elem(msg, i);
 		rsge = sk_msg_elem_cpy(msg, i);
+		rsge_copy = test_bit(i, msg->sg.copy);
 
 		psge->length = start - offset;
 		rsge.length -= psge->length;
@@ -2875,24 +2881,32 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_
 
 	/* Shift one or two slots as needed */
 	sge = sk_msg_elem_cpy(msg, new);
+	sge_copy = test_bit(new, msg->sg.copy);
 	sg_unmark_end(&sge);
 
 	nsge = sk_msg_elem_cpy(msg, i);
+	nsge_copy = test_bit(i, msg->sg.copy);
 	if (rsge.length) {
 		sk_msg_iter_var_next(i);
 		nnsge = sk_msg_elem_cpy(msg, i);
+		nnsge_copy = test_bit(i, msg->sg.copy);
 		sk_msg_iter_next(msg, end);
 	}
 
 	while (i != msg->sg.end) {
 		msg->sg.data[i] = sge;
+		__assign_bit(i, msg->sg.copy, sge_copy);
 		sge = nsge;
+		sge_copy = nsge_copy;
 		sk_msg_iter_var_next(i);
 		if (rsge.length) {
 			nsge = nnsge;
+			nsge_copy = nnsge_copy;
 			nnsge = sk_msg_elem_cpy(msg, i);
+			nnsge_copy = test_bit(i, msg->sg.copy);
 		} else {
 			nsge = sk_msg_elem_cpy(msg, i);
+			nsge_copy = test_bit(i, msg->sg.copy);
 		}
 	}
 
@@ -2906,6 +2920,7 @@ place_new:
 		get_page(sg_page(&rsge));
 		sk_msg_iter_var_next(new);
 		msg->sg.data[new] = rsge;
+		__assign_bit(new, msg->sg.copy, rsge_copy);
 	}
 
 	sk_msg_reset_curr(msg);
@@ -2933,25 +2948,33 @@ static void sk_msg_shift_left(struct sk_
 		prev = i;
 		sk_msg_iter_var_next(i);
 		msg->sg.data[prev] = msg->sg.data[i];
+		sk_msg_sg_copy_assign(msg, prev, msg, i);
 	} while (i != msg->sg.end);
 
 	sk_msg_iter_prev(msg, end);
+	__clear_bit(msg->sg.end, msg->sg.copy);
 }
 
 static void sk_msg_shift_right(struct sk_msg *msg, int i)
 {
 	struct scatterlist tmp, sge;
+	bool tmp_copy, sge_copy;
 
 	sk_msg_iter_next(msg, end);
 	sge = sk_msg_elem_cpy(msg, i);
+	sge_copy = test_bit(i, msg->sg.copy);
 	sk_msg_iter_var_next(i);
 	tmp = sk_msg_elem_cpy(msg, i);
+	tmp_copy = test_bit(i, msg->sg.copy);
 
 	while (i != msg->sg.end) {
 		msg->sg.data[i] = sge;
+		__assign_bit(i, msg->sg.copy, sge_copy);
 		sk_msg_iter_var_next(i);
 		sge = tmp;
+		sge_copy = tmp_copy;
 		tmp = sk_msg_elem_cpy(msg, i);
+		tmp_copy = test_bit(i, msg->sg.copy);
 	}
 }
 
@@ -3011,6 +3034,8 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_m
 		struct scatterlist *nsge, *sge = sk_msg_elem(msg, i);
 		int a = start - offset;
 		int b = sge->length - pop - a;
+		u32 sge_i = i;
+		bool sge_copy = test_bit(i, msg->sg.copy);
 
 		sk_msg_iter_var_next(i);
 
@@ -3023,6 +3048,7 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_m
 				sg_set_page(nsge,
 					    sg_page(sge),
 					    b, sge->offset + pop + a);
+				__assign_bit(i, msg->sg.copy, sge_copy);
 			} else {
 				struct page *page, *orig;
 				u8 *to, *from;
@@ -3039,6 +3065,7 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_m
 				memcpy(to, from, a);
 				memcpy(to + a, from + a + pop, b);
 				sg_set_page(sge, page, a + b, 0);
+				__clear_bit(sge_i, msg->sg.copy);
 				put_page(orig);
 			}
 			pop = 0;
net/core/skmsg.c +2 -0
@@ -65,6 +65,7 @@ int sk_msg_alloc(struct sock *sk, struct
 			sge = &msg->sg.data[msg->sg.end];
 			sg_unmark_end(sge);
 			sg_set_page(sge, pfrag->page, use, orig_offset);
+			__clear_bit(msg->sg.end, msg->sg.copy);
 			get_page(pfrag->page);
 			sk_msg_iter_next(msg, end);
 		}
@@ -185,6 +186,7 @@ static int sk_msg_free_elem(struct sock
 			sk_mem_uncharge(sk, len);
 		put_page(sg_page(sge));
 	}
+	__clear_bit(i, msg->sg.copy);
 	memset(sge, 0, sizeof(*sge));
 	return len;
 }
net/tls/tls_sw.c +4 -0
@@ -564,6 +564,7 @@ static int tls_split_open_record(struct
 	struct scatterlist *sge, *osge, *nsge;
 	u32 orig_size = msg_opl->sg.size;
 	struct scatterlist tmp = { };
+	u32 tmp_i = 0;
 	struct sk_msg *msg_npl;
 	struct tls_rec *new;
 	int ret;
@@ -585,6 +586,7 @@ static int tls_split_open_record(struct
 		if (sge->length > apply) {
 			u32 len = sge->length - apply;
 
+			tmp_i = i;
 			get_page(sg_page(sge));
 			sg_set_page(&tmp, sg_page(sge), len,
 				    sge->offset + apply);
@@ -616,6 +618,7 @@ static int tls_split_open_record(struct
 	nsge = sk_msg_elem(msg_npl, j);
 	if (tmp.length) {
 		memcpy(nsge, &tmp, sizeof(*nsge));
+		sk_msg_sg_copy_assign(msg_npl, j, msg_opl, tmp_i);
 		sk_msg_iter_var_next(j);
 		nsge = sk_msg_elem(msg_npl, j);
 	}
@@ -623,6 +626,7 @@ static int tls_split_open_record(struct
 	osge = sk_msg_elem(msg_opl, i);
 	while (osge->length) {
 		memcpy(nsge, osge, sizeof(*nsge));
+		sk_msg_sg_copy_assign(msg_npl, j, msg_opl, i);
 		sg_unmark_end(nsge);
 		sk_msg_iter_var_next(i);
 		sk_msg_iter_var_next(j);
author maintainer
#18 lore raw

PATCH 15/699 apparmor: fix use-after-free in rawdata dedup loop

In reply to Greg Kroah-Hartman

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

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

From: Ruslan Valiyev <[email protected]>

[ Upstream commit 6f060496d03e4dc560a40f73770bd08335cb7a27 ]

aa_replace_profiles() walks ns->rawdata_list to dedup the incoming policy blob against entries already attached to existing profiles. Per the kernel-doc on struct aa_loaddata, list membership does not hold a reference: profiles hold pcount, and when the last pcount drops, do_ploaddata_rmfs() is queued on a workqueue that takes ns->lock and removes the entry. Between dropping the last pcount and the workqueue running, an entry remains on the list with pcount == 0.

aa_get_profile_loaddata() is an unconditional kref_get() on pcount, so when the dedup loop hits such an entry, refcount hardening reports

refcount_t: addition on 0; use-after-free.

inside aa_replace_profiles(), and the poisoned counter then trips "saturated" and "underflow" warnings on the subsequent uses of the same loaddata.

Before commit a0b7091c4de4 ("apparmor: fix race on rawdata dereference") the dedup path used a get_unless_zero-style helper on a single counter, so the existing "if (tmp)" guard was meaningful. The split-refcount refactor introduced aa_get_profile_loaddata(), which has plain kref_get() semantics, and the guard quietly became a no-op.

Introduce aa_get_profile_loaddata_not0(), matching the existing _not0 convention used by aa_get_profile_not0(), and use it for the rawdata_list dedup lookup so dying entries are skipped.

Reproduced on x86_64 with v7.1-rc5 in QEMU+KVM running Ubuntu 24.04 + stress-ng 0.17.06:

  stress-ng --apparmor 1 --klog-check --timeout 60s

Without this patch the three refcount_t warnings fire within a few seconds. With it the same 60 s run is clean. Coverage is a smoke-test only; a longer soak with CONFIG_KASAN, CONFIG_KCSAN and CONFIG_PROVE_LOCKING would be welcome from anyone with the cycles.

---
 security/apparmor/include/policy_unpack.h |   19 +++++++++++++++++++
 security/apparmor/policy.c                |    8 ++++++--
 2 files changed, 25 insertions(+), 2 deletions(-)
security/apparmor/include/policy_unpack.h +19 -0
@@ -122,6 +122,25 @@ aa_get_profile_loaddata(struct aa_loadda
 	return data;
 }
 
+/**
+ * aa_get_profile_loaddata_not0 - get a profile reference count if not zero
+ * @data: reference to get a count on
+ *
+ * Like aa_get_profile_loaddata(), but safe to call on an entry that may
+ * be on a list (e.g. ns->rawdata_list) where the last pcount has already
+ * dropped and the deferred cleanup has not yet run.
+ *
+ * Returns: pointer to reference, or %NULL if @data is NULL or its
+ *          profile refcount has already reached zero.
+ */
+static inline struct aa_loaddata *
+aa_get_profile_loaddata_not0(struct aa_loaddata *data)
+{
+	if (data && kref_get_unless_zero(&data->pcount))
+		return data;
+	return NULL;
+}
+
 void __aa_loaddata_update(struct aa_loaddata *data, long revision);
 bool aa_rawdata_eq(struct aa_loaddata *l, struct aa_loaddata *r);
 void aa_loaddata_kref(struct kref *kref);
security/apparmor/policy.c +6 -2
@@ -976,8 +976,12 @@ ssize_t aa_replace_profiles(struct aa_ns
 		if (aa_rawdata_eq(rawdata_ent, udata)) {
 			struct aa_loaddata *tmp;
 
-			tmp = aa_get_profile_loaddata(rawdata_ent);
-			/* check we didn't fail the race */
+			/*
+			 * Entries remain on rawdata_list with
+			 * pcount == 0 until do_ploaddata_rmfs()
+			 * runs; only take a live profile ref.
+			 */
+			tmp = aa_get_profile_loaddata_not0(rawdata_ent);
 			if (tmp) {
 				aa_put_profile_loaddata(udata);
 				udata = tmp;
author maintainer
#19 lore raw

PATCH 16/699 net: ip_gre: require CAP_NET_ADMIN in the device netns for changelink

In reply to Greg Kroah-Hartman

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

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

From: Maoyi Xie <[email protected]>

[ Upstream commit 8165f7ff57d9667d2bb477ef6af83ede7fed4ad7 ]

A tunnel changelink() operates on at most two netns, dev_net(dev) and the tunnel link netns t->net. They differ once the device is created in or moved to a netns other than the one the request runs in. The rtnl changelink path checks CAP_NET_ADMIN only against dev_net(dev), so a caller privileged there but not in t->net can rewrite a tunnel that lives in t->net.

Add rtnl_dev_link_net_capable() next to rtnl_get_net_ns_capable() in net/core/rtnetlink.c. It requires CAP_NET_ADMIN in the link netns and is skipped when the link netns is dev_net(dev), where the rtnl path already checked it. The other patches in this series use the same helper.

Gate ipgre_changelink() and erspan_changelink() with it, at the top of the op before any attribute is parsed, because the parsers update live tunnel fields first. ipgre_netlink_parms() sets t->collect_md before ip_tunnel_changelink() runs.

Commit 8b484efd5cb4 ("ip6: vti: Use ip6_tnl.net in vti6_siocdevprivate().") added the same check on the ioctl path. This adds it on RTM_NEWLINK.

---
 include/net/rtnetlink.h |    2 ++
 net/core/rtnetlink.c    |    8 ++++++++
 net/ipv4/ip_gre.c       |    6 ++++++
 3 files changed, 16 insertions(+)
include/net/rtnetlink.h +2 -0
@@ -183,6 +183,8 @@ int rtnl_configure_link(struct net_devic
 int rtnl_nla_parse_ifinfomsg(struct nlattr **tb, const struct nlattr *nla_peer,
 			     struct netlink_ext_ack *exterr);
 struct net *rtnl_get_net_ns_capable(struct sock *sk, int netnsid);
+bool rtnl_dev_link_net_capable(const struct net_device *dev,
+			       const struct net *link_net);
 
 #define MODULE_ALIAS_RTNL_LINK(kind) MODULE_ALIAS("rtnl-link-" kind)
 
net/core/rtnetlink.c +8 -0
@@ -2024,6 +2024,14 @@ struct net *rtnl_get_net_ns_capable(stru
 }
 EXPORT_SYMBOL_GPL(rtnl_get_net_ns_capable);
 
+bool rtnl_dev_link_net_capable(const struct net_device *dev,
+			       const struct net *link_net)
+{
+	return net_eq(link_net, dev_net(dev)) ||
+	       ns_capable(link_net->user_ns, CAP_NET_ADMIN);
+}
+EXPORT_SYMBOL_GPL(rtnl_dev_link_net_capable);
+
 static int rtnl_valid_dump_ifinfo_req(const struct nlmsghdr *nlh,
 				      bool strict_check, struct nlattr **tb,
 				      struct netlink_ext_ack *extack)
net/ipv4/ip_gre.c +6 -0
@@ -1407,6 +1407,9 @@ static int ipgre_changelink(struct net_d
 	struct ip_tunnel_parm p;
 	int err;
 
+	if (!rtnl_dev_link_net_capable(dev, t->net))
+		return -EPERM;
+
 	err = ipgre_newlink_encap_setup(dev, data);
 	if (err)
 		return err;
@@ -1436,6 +1439,9 @@ static int erspan_changelink(struct net_
 	struct ip_tunnel_parm p;
 	int err;
 
+	if (!rtnl_dev_link_net_capable(dev, t->net))
+		return -EPERM;
+
 	err = ipgre_newlink_encap_setup(dev, data);
 	if (err)
 		return err;
author maintainer
#20 lore raw

PATCH 17/699 apparmor: mediate the implicit connect of TCP fast open sendmsg

In reply to Greg Kroah-Hartman

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

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

From: Bryam Vargas <[email protected]>

[ Upstream commit 4d587cd8a72155089a627130bbd4716ec0856e21 ]

sendmsg()/sendto() with MSG_FASTOPEN is a combination of connect(2) and write(2): it opens the connection in the SYN. apparmor_socket_sendmsg() only checks AA_MAY_SEND, so a profile that grants send but denies connect lets a confined task open an outbound TCP/MPTCP connection that connect(2) would have refused, bypassing connect mediation.

Mediate the implicit connect when MSG_FASTOPEN is set and a destination is supplied. Add it to apparmor_socket_sendmsg() (not the shared aa_sock_msg_perm() helper, which recvmsg also uses) and call aa_sk_perm() directly, mirroring the selinux and tomoyo fixes. sk_is_tcp() does not cover MPTCP fast open, so the SOCK_STREAM/IPPROTO_MPTCP arm is explicit.

Fixes cf60af03ca4e ("net-tcp: Fast Open client - sendmsg(MSG_FASTOPEN)")
[ inlined absent sk_is_tcp()/sk_is_inet() helpers into the equivalent family/type/protocol checks ]
---
 security/apparmor/lsm.c |   18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)
security/apparmor/lsm.c +17 -1
@@ -951,7 +951,23 @@ static int aa_sock_msg_perm(const char *
 static int apparmor_socket_sendmsg(struct socket *sock,
 				   struct msghdr *msg, int size)
 {
-	return aa_sock_msg_perm(OP_SENDMSG, AA_MAY_SEND, sock, msg, size);
+	int error = aa_sock_msg_perm(OP_SENDMSG, AA_MAY_SEND, sock, msg, size);
+
+	if (error)
+		return error;
+
+	/* TCP fast open carries connect() semantics in sendmsg(); mediate
+	 * the implicit connect so it cannot bypass the connect permission.
+	 */
+	if ((msg->msg_flags & MSG_FASTOPEN) && msg->msg_name &&
+	    (sock->sk->sk_family == AF_INET ||
+	     sock->sk->sk_family == AF_INET6) &&
+	    sock->sk->sk_type == SOCK_STREAM &&
+	    (sock->sk->sk_protocol == IPPROTO_TCP ||
+	     sock->sk->sk_protocol == IPPROTO_MPTCP))
+		error = aa_sk_perm(OP_CONNECT, AA_MAY_CONNECT, sock->sk);
+
+	return error;
 }
 
 /**
author maintainer
#21 lore raw

PATCH 18/699 f2fs: adjust zone capacity when considering valid block count

In reply to Greg Kroah-Hartman

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

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

From: Jaegeuk Kim <[email protected]>

[ Upstream commit 074b5ea2900ea8e40f8e7a3fd37e0a55ad3d5874 ]

This patch fixes counting unusable blocks set by zone capacity when checking the valid block count in a section.

Stable-dep-of: 4275b59673eb ("f2fs: fix to round down start offset of fallocate for pin file")

---
 fs/f2fs/debug.c   |    2 +-
 fs/f2fs/file.c    |    6 +++---
 fs/f2fs/gc.c      |    4 ++--
 fs/f2fs/segment.c |    7 +++----
 fs/f2fs/segment.h |    8 ++++----
 5 files changed, 13 insertions(+), 14 deletions(-)
fs/f2fs/debug.c +1 -1
@@ -39,7 +39,7 @@ void f2fs_update_sit_info(struct f2fs_sb
 
 	bimodal = 0;
 	total_vblocks = 0;
-	blks_per_sec = BLKS_PER_SEC(sbi);
+	blks_per_sec = CAP_BLKS_PER_SEC(sbi);
 	hblks_per_sec = blks_per_sec / 2;
 	for (segno = 0; segno < MAIN_SEGS(sbi); segno += sbi->segs_per_sec) {
 		vblocks = get_valid_blocks(sbi, segno, true);
fs/f2fs/file.c +3 -3
@@ -1681,7 +1681,7 @@ static int expand_inode_data(struct inod
 		return 0;
 
 	if (f2fs_is_pinned_file(inode)) {
-		block_t sec_blks = BLKS_PER_SEC(sbi);
+		block_t sec_blks = CAP_BLKS_PER_SEC(sbi);
 		block_t sec_len = roundup(map.m_len, sec_blks);
 
 		map.m_len = sec_blks;
@@ -2595,7 +2595,7 @@ do_more:
 			ret = -EAGAIN;
 		goto out;
 	}
-	range->start += BLKS_PER_SEC(sbi);
+	range->start += CAP_BLKS_PER_SEC(sbi);
 	if (range->start <= end)
 		goto do_more;
 out:
@@ -2717,7 +2717,7 @@ static int f2fs_defragment_range(struct
 		goto out;
 	}
 
-	sec_num = DIV_ROUND_UP(total, BLKS_PER_SEC(sbi));
+	sec_num = DIV_ROUND_UP(total, CAP_BLKS_PER_SEC(sbi));
 
 	/*
 	 * make sure there are enough free section for LFS allocation, this can
fs/f2fs/gc.c +2 -2
@@ -441,7 +441,7 @@ static void atgc_lookup_victim(struct f2
 	unsigned long long age, u, accu;
 	unsigned long long max_mtime = sit_i->dirty_max_mtime;
 	unsigned long long min_mtime = sit_i->dirty_min_mtime;
-	unsigned int sec_blocks = BLKS_PER_SEC(sbi);
+	unsigned int sec_blocks = CAP_BLKS_PER_SEC(sbi);
 	unsigned int vblocks;
 	unsigned int dirty_threshold = max(am->max_candidate_count,
 					am->candidate_ratio *
@@ -1421,7 +1421,7 @@ next_step:
 		 */
 		if ((gc_type == BG_GC && has_not_enough_free_secs(sbi, 0, 0)) ||
 			(!force_migrate && get_valid_blocks(sbi, segno, true) ==
-							BLKS_PER_SEC(sbi)))
+							CAP_BLKS_PER_SEC(sbi)))
 			return submitted;
 
 		if (check_valid_map(sbi, segno, off) == 0)
fs/f2fs/segment.c +3 -4
@@ -820,7 +820,7 @@ static void __locate_dirty_segment(struc
 				get_valid_blocks(sbi, segno, true);
 
 			f2fs_bug_on(sbi, unlikely(!valid_blocks ||
-					valid_blocks == BLKS_PER_SEC(sbi)));
+					valid_blocks == CAP_BLKS_PER_SEC(sbi)));
 
 			if (!IS_CURSEC(sbi, secno))
 				set_bit(secno, dirty_i->dirty_secmap);
@@ -856,7 +856,7 @@ static void __remove_dirty_segment(struc
 			unsigned int secno = GET_SEC_FROM_SEG(sbi, segno);
 
 			if (!valid_blocks ||
-					valid_blocks == BLKS_PER_SEC(sbi)) {
+					valid_blocks == CAP_BLKS_PER_SEC(sbi)) {
 				clear_bit(secno, dirty_i->dirty_secmap);
 				return;
 			}
@@ -4577,7 +4577,6 @@ static void init_dirty_segmap(struct f2f
 	struct free_segmap_info *free_i = FREE_I(sbi);
 	unsigned int segno = 0, offset = 0, secno;
 	block_t valid_blocks, usable_blks_in_seg;
-	block_t blks_per_sec = BLKS_PER_SEC(sbi);
 
 	while (1) {
 		/* find dirty segment based on free segmap */
@@ -4606,7 +4605,7 @@ static void init_dirty_segmap(struct f2f
 		valid_blocks = get_valid_blocks(sbi, segno, true);
 		secno = GET_SEC_FROM_SEG(sbi, segno);
 
-		if (!valid_blocks || valid_blocks == blks_per_sec)
+		if (!valid_blocks || valid_blocks == CAP_BLKS_PER_SEC(sbi))
 			continue;
 		if (IS_CURSEC(sbi, secno))
 			continue;
fs/f2fs/segment.h +4 -4
@@ -608,10 +608,10 @@ static inline bool has_not_enough_free_s
 					get_pages(sbi, F2FS_DIRTY_DENTS) +
 					get_pages(sbi, F2FS_DIRTY_IMETA);
 	unsigned int total_dent_blocks = get_pages(sbi, F2FS_DIRTY_DENTS);
-	unsigned int node_secs = total_node_blocks / BLKS_PER_SEC(sbi);
-	unsigned int dent_secs = total_dent_blocks / BLKS_PER_SEC(sbi);
-	unsigned int node_blocks = total_node_blocks % BLKS_PER_SEC(sbi);
-	unsigned int dent_blocks = total_dent_blocks % BLKS_PER_SEC(sbi);
+	unsigned int node_secs = total_node_blocks / CAP_BLKS_PER_SEC(sbi);
+	unsigned int dent_secs = total_dent_blocks / CAP_BLKS_PER_SEC(sbi);
+	unsigned int node_blocks = total_node_blocks % CAP_BLKS_PER_SEC(sbi);
+	unsigned int dent_blocks = total_dent_blocks % CAP_BLKS_PER_SEC(sbi);
 	unsigned int free, need_lower, need_upper;
 
 	if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING)))
author maintainer
#22 lore raw

PATCH 19/699 f2fs: fix to round down start offset of fallocate for pin file

In reply to Greg Kroah-Hartman

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

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

From: Sunmin Jeong <[email protected]>

[ Upstream commit 4275b59673eb60b02eec3997816c83f1f4b909c4 ]

Currently, the length of fallocate for pin file is section-aligned to keep allocated sections from being selected as victims of GC. However, for the case that the start offset of fallocate is not aligned in section, the allocated sections can't be fully utilized. It's because a new section is allocated by f2fs_allocate_pinning_section() after using blks_per_sec blocks regardless of the start offset. As a result, several unexpected dirty segments may be created, including blocks assigned to the pinned file.

To address this issue, let's round down the start offset of fallocate to the length of section.

The reproducing scenario is as below

chunk=$(((2<<20)+4096)) # 2MB + 4KB
touch test
f2fs_io pinfile set test
f2fs_io fallocate 0 0 $chunk test
f2fs_io fallocate 0 $chunk $chunk test
f2fs_io fallocate 0 $((chunk*2)) $chunk test
f2fs_io fiemap 0 $((chunk*3)) test

Fiemap: offset = 0 len = 12288
logical addr. physical addr. length flags

0   0000000000000000 000000068c600000 0000000000400000 00001088
1   0000000000400000 000000003d400000 0000000000001000 00001088
2   0000000000401000 00000003eb200000 0000000000200000 00001088
3   0000000000601000 00000005e4200000 0000000000001000 00001088
4   0000000000602000 0000000605400000 0000000000200000 00001089
---
 fs/f2fs/file.c |    9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
fs/f2fs/file.c +8 -1
@@ -1682,8 +1682,15 @@ static int expand_inode_data(struct inod
 
 	if (f2fs_is_pinned_file(inode)) {
 		block_t sec_blks = CAP_BLKS_PER_SEC(sbi);
-		block_t sec_len = roundup(map.m_len, sec_blks);
+		block_t sec_len;
 
+		if (map.m_lblk % sec_blks) {
+			map.m_lblk = rounddown(map.m_lblk, sec_blks);
+			map.m_len = pg_end - map.m_lblk;
+			if (off_end)
+				map.m_len++;
+		}
+		sec_len = roundup(map.m_len, sec_blks);
 		map.m_len = sec_blks;
 next_alloc:
 		if (has_not_enough_free_secs(sbi, 0,
author maintainer
#23 lore raw

PATCH 20/699 f2fs: validate orphan inode entry count

In reply to Greg Kroah-Hartman

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

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

From: Wenjie Qi <[email protected]>

[ Upstream commit 846c499a65816d13f1186e3090e825e8bb8bcb8b ]

f2fs_recover_orphan_inodes() trusts the orphan block entry_count when replaying orphan inodes from the checkpoint pack. A corrupted entry_count larger than F2FS_ORPHANS_PER_BLOCK makes the recovery loop read past the ino[] array and interpret footer or following data as inode numbers.

On a crafted image, mounting an unpatched kernel can drive orphan recovery into f2fs_bug_on() and panic the kernel. Validate entry_count before consuming entries so corrupted checkpoint data fails the mount with -EFSCORRUPTED and requests fsck instead.

Set ERROR_INCONSISTENT_ORPHAN as well, so the corruption reason can be recorded in the superblock s_errors[] field. This gives fsck a persistent hint even though mount-time orphan recovery failure may leave no chance to persist SBI_NEED_FSCK through a checkpoint.

Fixes 127e670abfa7 ("f2fs: add checkpoint operations")
[ Folio API ]
---
 fs/f2fs/checkpoint.c |   13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)
fs/f2fs/checkpoint.c +12 -1
@@ -723,6 +723,7 @@ int f2fs_recover_orphan_inodes(struct f2
 	for (i = 0; i < orphan_blocks; i++) {
 		struct page *page;
 		struct f2fs_orphan_block *orphan_blk;
+		unsigned int entry_count;
 
 		page = f2fs_get_meta_page(sbi, start_blk + i);
 		if (IS_ERR(page)) {
@@ -731,7 +732,17 @@ int f2fs_recover_orphan_inodes(struct f2
 		}
 
 		orphan_blk = (struct f2fs_orphan_block *)page_address(page);
-		for (j = 0; j < le32_to_cpu(orphan_blk->entry_count); j++) {
+		entry_count = le32_to_cpu(orphan_blk->entry_count);
+		if (entry_count > F2FS_ORPHANS_PER_BLOCK) {
+			f2fs_err(sbi, "invalid orphan inode entry count %u",
+				 entry_count);
+			set_sbi_flag(sbi, SBI_NEED_FSCK);
+			err = -EFSCORRUPTED;
+			f2fs_put_page(page, 1);
+			goto out;
+		}
+
+		for (j = 0; j < entry_count; j++) {
 			nid_t ino = le32_to_cpu(orphan_blk->ino[j]);
 			err = recover_orphan_inode(sbi, ino);
 			if (err) {
author maintainer
#24 lore raw

PATCH 21/699 f2fs: bound i_inline_xattr_size for non-inline-xattr inodes

In reply to Greg Kroah-Hartman

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

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

From: Bryam Vargas <[email protected]>

[ Upstream commit 378acf3cf19b6af6cba55e8dd1154c4e1504bae8 ]

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

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

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

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

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

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

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

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

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

Fixes 6afc662e68b5 ("f2fs: support flexible inline xattr size")
---
 fs/f2fs/inode.c |   13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)
fs/f2fs/inode.c +7 -6
@@ -254,14 +254,15 @@ static bool sanity_check_inode(struct in
 		return false;
 	}
 
-	if (f2fs_has_extra_attr(inode) &&
-		f2fs_sb_has_flexible_inline_xattr(sbi) &&
-		f2fs_has_inline_xattr(inode) &&
-		(!fi->i_inline_xattr_size ||
-		fi->i_inline_xattr_size > MAX_INLINE_XATTR_SIZE)) {
+	if (f2fs_sb_has_flexible_inline_xattr(sbi) &&
+		(fi->i_inline_xattr_size > MAX_INLINE_XATTR_SIZE ||
+		(f2fs_has_inline_xattr(inode) &&
+		fi->i_inline_xattr_size <
+			sizeof(struct f2fs_xattr_header) / sizeof(__le32)))) {
 		set_sbi_flag(sbi, SBI_NEED_FSCK);
-		f2fs_warn(sbi, "%s: inode (ino=%lx) has corrupted i_inline_xattr_size: %d, max: %zu",
+		f2fs_warn(sbi, "%s: inode (ino=%lx) has corrupted i_inline_xattr_size: %d, min: %zu, max: %zu",
 			  __func__, inode->i_ino, fi->i_inline_xattr_size,
+			  sizeof(struct f2fs_xattr_header) / sizeof(__le32),
 			  MAX_INLINE_XATTR_SIZE);
 		return false;
 	}
author maintainer
#25 lore raw

PATCH 22/699 f2fs: fix potential deadlock in f2fs_balance_fs()

In reply to Greg Kroah-Hartman

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

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

From: Ruipeng Qi <[email protected]>

[ Upstream commit dd3114870771562036fdcf5abe813956f36d224d ]

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

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

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

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

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

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

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

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

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

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

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

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

---
 fs/f2fs/data.c    |   29 +++++++++++++++++++++++++++++
 fs/f2fs/f2fs.h    |    1 +
 fs/f2fs/segment.c |    7 +++++++
 3 files changed, 37 insertions(+)
fs/f2fs/data.c +29 -0
@@ -906,6 +906,35 @@ void f2fs_submit_merged_ipu_write(struct
 	}
 }
 
+void f2fs_submit_all_merged_ipu_writes(struct f2fs_sb_info *sbi)
+{
+	struct bio_entry *be, *tmp;
+	struct f2fs_bio_info *io;
+	enum temp_type temp;
+
+	for (temp = HOT; temp < NR_TEMP_TYPE; temp++) {
+		LIST_HEAD(list);
+
+		io = sbi->write_io[DATA] + temp;
+
+		/* A lockless list_empty() check is safe here: any bios from
+		 * other kworkers that we miss will be submitted by those
+		 * kworkers accordingly.
+		 */
+		if (list_empty(&io->bio_list))
+			continue;
+
+		down_write(&io->bio_list_lock);
+		list_splice_init(&io->bio_list, &list);
+		up_write(&io->bio_list_lock);
+
+		list_for_each_entry_safe(be, tmp, &list, list) {
+			__submit_bio(sbi, be->bio, DATA);
+			del_bio_entry(be);
+		}
+	}
+}
+
 int f2fs_merge_page_bio(struct f2fs_io_info *fio)
 {
 	struct bio *bio = *fio->bio;
fs/f2fs/f2fs.h +1 -0
@@ -3475,6 +3475,7 @@ void f2fs_submit_merged_write_cond(struc
 				nid_t ino, enum page_type type);
 void f2fs_submit_merged_ipu_write(struct f2fs_sb_info *sbi,
 					struct bio **bio, struct page *page);
+void f2fs_submit_all_merged_ipu_writes(struct f2fs_sb_info *sbi);
 void f2fs_flush_merged_writes(struct f2fs_sb_info *sbi);
 int f2fs_submit_page_bio(struct f2fs_io_info *fio);
 int f2fs_merge_page_bio(struct f2fs_io_info *fio);
fs/f2fs/segment.c +7 -0
@@ -513,6 +513,13 @@ void f2fs_balance_fs(struct f2fs_sb_info
 	 * dir/node pages without enough free segments.
 	 */
 	if (has_not_enough_free_secs(sbi, 0, 0)) {
+		/*
+		 * Submit all cached OPU/IPU DATA bios before triggering
+		 * foreground GC to avoid potential deadlocks.
+		 */
+		f2fs_submit_merged_write(sbi, DATA);
+		f2fs_submit_all_merged_ipu_writes(sbi);
+
 		down_write(&sbi->gc_lock);
 		f2fs_gc(sbi, false, false, false, NULL_SEGNO);
 	}
author maintainer
#26 lore raw

PATCH 23/699 f2fs: fix listxattr handling of corrupted xattr entries

In reply to Greg Kroah-Hartman

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

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

From: Keshav Verma <[email protected]>

[ Upstream commit 5ef5bc304f23c3fe255d4936472378dcb74d0e94 ]

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

Fixes 688078e7f36c ("f2fs: fix to avoid memory leakage in f2fs_listxattr")
---
 fs/f2fs/xattr.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
fs/f2fs/xattr.c +2 -2
@@ -575,8 +575,7 @@ ssize_t f2fs_listxattr(struct dentry *de
 	last_base_addr = (void *)base_addr + XATTR_SIZE(inode);
 
 	list_for_each_xattr(entry, base_addr) {
-		const struct xattr_handler *handler =
-			f2fs_xattr_handler(entry->e_name_index);
+		const struct xattr_handler *handler;
 		const char *prefix;
 		size_t prefix_len;
 		size_t size;
@@ -590,6 +589,7 @@ ssize_t f2fs_listxattr(struct dentry *de
 			goto cleanup;
 		}
 
+		handler = f2fs_xattr_handler(entry->e_name_index);
 		if (!handler || (handler->list && !handler->list(dentry)))
 			continue;
 
author maintainer
#27 lore raw

PATCH 24/699 NFSv4/flexfiles: reject zero filehandle version count

In reply to Greg Kroah-Hartman

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

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

From: Michael Bommarito <[email protected]>

[ Upstream commit 2c6bb3c40bc24f6aa8dfbe6fe98c3ad6389203f2 ]

ff_layout_alloc_lseg() decodes the filehandle-version array count from the flexfiles layout body. The value is used as the count for kzalloc_objs(), and the current code only rejects NULL.

A zero count yields ZERO_SIZE_PTR, which can be stored in dss_info->fh_versions even though later flexfiles paths assume that at least one filehandle version exists.

Reject fh_count == 0 before the allocation, matching the existing zero version_count validation in the flexfiles GETDEVICEINFO parser.

A QEMU/KASAN run with a malformed flexfiles layout hit:

  KASAN: null-ptr-deref in range [0x0000000000000010-0x0000000000000017]
  RIP: 0010:ff_layout_encode_ff_layoutupdate.isra.0+0x15f/0x750
  ff_layout_encode_layoutreturn+0x683/0x970
  nfs4_xdr_enc_layoutreturn+0x278/0x3a0
  Kernel panic - not syncing: Fatal exception

The patched kernel rejects the malformed layout without KASAN/oops/panic, and a valid fh_count=1 regression still opens, reads, and unmounts cleanly.

Fixes d67ae825a59d ("pnfs/flexfiles: Add the FlexFile Layout Driver")
Assisted-by Claude:claude-opus-4-7
---
 fs/nfs/flexfilelayout/flexfilelayout.c |    4 ++++
 1 file changed, 4 insertions(+)
fs/nfs/flexfilelayout/flexfilelayout.c +4 -0
@@ -454,6 +454,10 @@ ff_layout_alloc_lseg(struct pnfs_layout_
 		if (!p)
 			goto out_err_free;
 		fh_count = be32_to_cpup(p);
+		if (fh_count == 0) {
+			rc = -EINVAL;
+			goto out_err_free;
+		}
 
 		fls->mirror_array[i]->fh_versions =
 			kcalloc(fh_count, sizeof(struct nfs_fh),
author maintainer
#28 lore raw

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

In reply to Greg Kroah-Hartman

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

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

From: Mingyu Wang <[email protected]>

[ Upstream commit 8fdc8c2057eea08d40ce2c8eed41ff9e451c65c2 ]

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

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

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

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

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

PATCH 26/699 i2c: core: fix irq domain leak on adapter registration failure

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

[ Upstream commit 8ce19524e4cc2462685f596a6402fbd8fb984ab2 ]

Make sure to tear down the host notify irq domain on adapter registration failure to avoid leaking it.

This issue was flagged by Sashiko when reviewing another adapter registration fix.

Fixes 4d5538f5882a ("i2c: use an IRQ to report Host Notify events, not alert")
Cc Benjamin Tissoires <[email protected]>

Stable-dep-of: ba14d7cf2fe7 ("i2c: core: fix adapter registration race")

---
 drivers/i2c/i2c-core-base.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/i2c/i2c-core-base.c +3 -1
@@ -1461,7 +1461,7 @@ static int i2c_register_adapter(struct i
 	res = device_register(&adap->dev);
 	if (res) {
 		pr_err("adapter '%s': can't register device (%d)\n", adap->name, res);
-		goto out_list;
+		goto err_remove_irq_domain;
 	}
 
 	res = of_i2c_setup_smbus_alert(adap);
@@ -1505,6 +1505,8 @@ out_reg:
 	init_completion(&adap->dev_released);
 	device_unregister(&adap->dev);
 	wait_for_completion(&adap->dev_released);
+err_remove_irq_domain:
+	i2c_host_notify_irq_teardown(adap);
 out_list:
 	mutex_lock(&core_lock);
 	idr_remove(&i2c_adapter_idr, adap->nr);
author maintainer
#30 lore raw

PATCH 27/699 i2c: core: fix hang on adapter registration failure

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

[ Upstream commit 3c7e164344e5bcf6f274bbf59a3274f5caad9bc1 ]

Clients may be registered from bus notifier callbacks when the adapter is registered. On a subsequent error during registration, the adapter references taken by such clients prevent the wait for the references to be released from ever completing.

Fix this by refactoring client deregistration and deregistering also on late adapter registration failures.

Fixes f8756c67b3de ("i2c: core: call of_i2c_setup_smbus_alert in i2c_register_adapter")
Cc Phil Reid <[email protected]>

Stable-dep-of: ba14d7cf2fe7 ("i2c: core: fix adapter registration race")

---
 drivers/i2c/i2c-core-base.c |   49 ++++++++++++++++++++++++++------------------
 1 file changed, 29 insertions(+), 20 deletions(-)
drivers/i2c/i2c-core-base.c +29 -20
@@ -61,6 +61,7 @@
 static DEFINE_MUTEX(core_lock);
 static DEFINE_IDR(i2c_adapter_idr);
 
+static void i2c_deregister_clients(struct i2c_adapter *adap);
 static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver);
 
 static DEFINE_STATIC_KEY_FALSE(i2c_trace_msg_key);
@@ -1502,6 +1503,7 @@ static int i2c_register_adapter(struct i
 	return 0;
 
 out_reg:
+	i2c_deregister_clients(adap);
 	init_completion(&adap->dev_released);
 	device_unregister(&adap->dev);
 	wait_for_completion(&adap->dev_released);
@@ -1644,29 +1646,10 @@ static int __process_removed_adapter(str
 	return 0;
 }
 
-/**
- * i2c_del_adapter - unregister I2C adapter
- * @adap: the adapter being unregistered
- * Context: can sleep
- *
- * This unregisters an I2C adapter which was previously registered
- * by @i2c_add_adapter or @i2c_add_numbered_adapter.
- */
-void i2c_del_adapter(struct i2c_adapter *adap)
+static void i2c_deregister_clients(struct i2c_adapter *adap)
 {
-	struct i2c_adapter *found;
 	struct i2c_client *client, *next;
 
-	/* First make sure that this adapter was ever added */
-	mutex_lock(&core_lock);
-	found = idr_find(&i2c_adapter_idr, adap->nr);
-	mutex_unlock(&core_lock);
-	if (found != adap) {
-		pr_debug("attempting to delete unregistered adapter [%s]\n", adap->name);
-		return;
-	}
-
-	i2c_acpi_remove_space_handler(adap);
 	/* Tell drivers about this removal */
 	mutex_lock(&core_lock);
 	bus_for_each_drv(&i2c_bus_type, NULL, adap,
@@ -1692,6 +1675,32 @@ void i2c_del_adapter(struct i2c_adapter
 	 * them up properly, so we give them a chance to do that first. */
 	device_for_each_child(&adap->dev, NULL, __unregister_client);
 	device_for_each_child(&adap->dev, NULL, __unregister_dummy);
+}
+
+/**
+ * i2c_del_adapter - unregister I2C adapter
+ * @adap: the adapter being unregistered
+ * Context: can sleep
+ *
+ * This unregisters an I2C adapter which was previously registered
+ * by @i2c_add_adapter or @i2c_add_numbered_adapter.
+ */
+void i2c_del_adapter(struct i2c_adapter *adap)
+{
+	struct i2c_adapter *found;
+
+	/* First make sure that this adapter was ever added */
+	mutex_lock(&core_lock);
+	found = idr_find(&i2c_adapter_idr, adap->nr);
+	mutex_unlock(&core_lock);
+	if (found != adap) {
+		pr_debug("attempting to delete unregistered adapter [%s]\n", adap->name);
+		return;
+	}
+
+	i2c_acpi_remove_space_handler(adap);
+
+	i2c_deregister_clients(adap);
 
 #ifdef CONFIG_I2C_COMPAT
 	class_compat_remove_link(i2c_adapter_compat_class, &adap->dev,
author maintainer
#31 lore raw

PATCH 28/699 i2c: core: fix NULL-deref on adapter registration failure

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

[ Upstream commit 2295d2bb101faa663fbc45fadbb3fec45f107441 ]

If adapter registration ever fails the release callback would trigger a NULL-pointer dereference as the completion struct has not been initialised.

Note that before the offending commit this would instead have resulted in a minor memory leak of the adapter name.

Fixes 3f8c4f5e9a57 ("i2c: core: fix reference leak in i2c_register_adapter()")
Cc Joe Hattori <[email protected]>

Stable-dep-of: ba14d7cf2fe7 ("i2c: core: fix adapter registration race")

---
 drivers/i2c/i2c-core-base.c |    8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/i2c/i2c-core-base.c +5 -3
@@ -1462,7 +1462,7 @@ static int i2c_register_adapter(struct i
 	res = device_register(&adap->dev);
 	if (res) {
 		pr_err("adapter '%s': can't register device (%d)\n", adap->name, res);
-		goto err_remove_irq_domain;
+		goto err_put_adap;
 	}
 
 	res = of_i2c_setup_smbus_alert(adap);
@@ -1504,10 +1504,12 @@ static int i2c_register_adapter(struct i
 
 out_reg:
 	i2c_deregister_clients(adap);
+	device_del(&adap->dev);
+err_put_adap:
 	init_completion(&adap->dev_released);
-	device_unregister(&adap->dev);
+	put_device(&adap->dev);
 	wait_for_completion(&adap->dev_released);
-err_remove_irq_domain:
+
 	i2c_host_notify_irq_teardown(adap);
 out_list:
 	mutex_lock(&core_lock);
author maintainer
#32 lore raw

PATCH 29/699 i2c: core: fix adapter debugfs creation

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

[ Upstream commit 07d5fb537928aad4369aaff0cbae73ba38a719af ]

Clients can be registered from bus notifier callbacks so the debugfs directory needs to be created before registering the adapter as clients use that directory as their debugfs parent.

Move debugfs creation before adapter registration to avoid having clients create their debugfs directories in the debugfs root (which is also more likely to fail due to name collisions).

Note that failure to allocate the adapter name must now be handled explicitly as debugfs_create_dir() cannot handle a NULL name (unlike device_add() which returns an error).

Fixes 73febd775bdb ("i2c: create debugfs entry per adapter")
Cc Wolfram Sang <[email protected]>

Stable-dep-of: ba14d7cf2fe7 ("i2c: core: fix adapter registration race")

---
 drivers/i2c/i2c-core-base.c |   19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)
drivers/i2c/i2c-core-base.c +12 -7
@@ -1456,10 +1456,19 @@ static int i2c_register_adapter(struct i
 		goto out_list;
 	}
 
-	dev_set_name(&adap->dev, "i2c-%d", adap->nr);
+	res = dev_set_name(&adap->dev, "i2c-%d", adap->nr);
+	if (res)
+		goto err_remove_irq_domain;
+
 	adap->dev.bus = &i2c_bus_type;
 	adap->dev.type = &i2c_adapter_type;
-	res = device_register(&adap->dev);
+	device_initialize(&adap->dev);
+
+	pm_runtime_no_callbacks(&adap->dev);
+	pm_suspend_ignore_children(&adap->dev, true);
+	pm_runtime_enable(&adap->dev);
+
+	res = device_add(&adap->dev);
 	if (res) {
 		pr_err("adapter '%s': can't register device (%d)\n", adap->name, res);
 		goto err_put_adap;
@@ -1469,10 +1478,6 @@ static int i2c_register_adapter(struct i
 	if (res)
 		goto out_reg;
 
-	pm_runtime_no_callbacks(&adap->dev);
-	pm_suspend_ignore_children(&adap->dev, true);
-	pm_runtime_enable(&adap->dev);
-
 	res = i2c_init_recovery(adap);
 	if (res == -EPROBE_DEFER)
 		goto out_reg;
@@ -1509,7 +1514,7 @@ err_put_adap:
 	init_completion(&adap->dev_released);
 	put_device(&adap->dev);
 	wait_for_completion(&adap->dev_released);
-
+err_remove_irq_domain:
 	i2c_host_notify_irq_teardown(adap);
 out_list:
 	mutex_lock(&core_lock);
author maintainer
#33 lore raw

PATCH 30/699 i2c: core: fix adapter registration race

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

[ Upstream commit ba14d7cf2fe7284610a29854bdff22b2537d3ce6 ]

Adapters can be looked up based on their id using i2c_get_adapter() which takes a reference to the embedded struct device.

Make sure that the adapter (including its struct device) has been initialised before adding it to the IDR to avoid accessing uninitialised data which could, for example, lead to NULL-pointer dereferences or use-after-free.

Note that the i2c-dev chardev, which is registered from a bus notifier, currently uses i2c_get_adapter() so the adapter needs to be added to the IDR before registration.

Fixes 6e13e6418418 ("i2c: Add i2c_add_numbered_adapter()")
Cc [email protected] # 2.6.22
---
 drivers/i2c/i2c-core-base.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/i2c/i2c-core-base.c +6 -2
@@ -1468,6 +1468,10 @@ static int i2c_register_adapter(struct i
 	pm_suspend_ignore_children(&adap->dev, true);
 	pm_runtime_enable(&adap->dev);
 
+	mutex_lock(&core_lock);
+	idr_replace(&i2c_adapter_idr, adap, adap->nr);
+	mutex_unlock(&core_lock);
+
 	res = device_add(&adap->dev);
 	if (res) {
 		pr_err("adapter '%s': can't register device (%d)\n", adap->name, res);
@@ -1535,7 +1539,7 @@ static int __i2c_add_numbered_adapter(st
 	int id;
 
 	mutex_lock(&core_lock);
-	id = idr_alloc(&i2c_adapter_idr, adap, adap->nr, adap->nr + 1, GFP_KERNEL);
+	id = idr_alloc(&i2c_adapter_idr, NULL, adap->nr, adap->nr + 1, GFP_KERNEL);
 	mutex_unlock(&core_lock);
 	if (WARN(id < 0, "couldn't get idr"))
 		return id == -ENOSPC ? -EBUSY : id;
@@ -1571,7 +1575,7 @@ int i2c_add_adapter(struct i2c_adapter *
 	}
 
 	mutex_lock(&core_lock);
-	id = idr_alloc(&i2c_adapter_idr, adapter,
+	id = idr_alloc(&i2c_adapter_idr, NULL,
 		       __i2c_first_dynamic_bus_num, 0, GFP_KERNEL);
 	mutex_unlock(&core_lock);
 	if (WARN(id < 0, "couldn't get idr"))
author maintainer
#34 lore raw

PATCH 31/699 hdlc_ppp: sync per-proto timers before freeing hdlc state

In reply to Greg Kroah-Hartman

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

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

From: Fan Wu <[email protected]>

[ Upstream commit c78a4e41ab5ead6193ad8a2dd92e8906bae659fa ]

Each PPP control protocol (LCP/IPCP/IPV6CP) embedded in struct ppp registers a timer via timer_setup(). That struct ppp is the hdlc->state allocation, which detach_hdlc_protocol() frees with kfree() in both teardown paths: unregister_hdlc_device() and the re-attach inside attach_hdlc_protocol().

The ppp proto never registered a .detach callback, so detach_hdlc_protocol() performs no timer synchronization before the kfree(). The only cancel, timer_delete(&proto->timer) in ppp_cp_event(), is partial (it does not wait for a running callback) and only runs on the ->CLOSED transition; ppp_stop()/ppp_close() do not sync either. A ppp_timer callback already executing (blocked on ppp->lock) survives the kfree and then dereferences proto->state / ppp->lock in freed memory, leading to a use-after-free.

Fix this by adding a .detach helper that calls timer_shutdown_sync() on every per-proto timer. detach_hdlc_protocol() invokes proto->detach(dev) before kfree(hdlc->state), so timer_shutdown_sync()
now runs on both free paths.
timer_shutdown_sync() is used instead of timer_delete_sync() because the keepalive path re-arms the timer through add_timer()/mod_timer() and shutdown blocks any re-activation during teardown.

Initialize the per-protocol timers in ppp_ioctl() when the protocol is attached, and remove the now-redundant timer_setup() from ppp_start(), so that the timers are initialized exactly once at attach time and ppp_timer_release() never operates on uninitialized timer_list structures. attach_hdlc_protocol() uses kmalloc() (not kzalloc), so struct ppp's protos[i].timer is uninitialized garbage until the first timer_setup(); without this init-at-attach, attaching the PPP protocol without ever bringing the device up would leave timer_shutdown_sync() operating on uninitialized memory in .detach. Moving the init out of ppp_start() (which only runs on NETDEV_UP) into the attach path makes the initialization unconditional and avoids initializing the same timer_list twice.

This bug was found by static analysis.

Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")
[ replaced timer_shutdown_sync() with del_timer_sync() since timer_shutdown_sync() is not available in 5.10 ]
---
 drivers/net/wan/hdlc_ppp.c |   15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)
drivers/net/wan/hdlc_ppp.c +13 -2
@@ -624,7 +624,6 @@ static void ppp_start(struct net_device
 	for (i = 0; i < IDX_COUNT; i++) {
 		struct proto *proto = &ppp->protos[i];
 		proto->dev = dev;
-		timer_setup(&proto->timer, ppp_timer, 0);
 		proto->state = CLOSED;
 	}
 	ppp->protos[IDX_LCP].pid = PID_LCP;
@@ -644,6 +643,15 @@ static void ppp_close(struct net_device
 	ppp_tx_flush();
 }
 
+static void ppp_timer_release(struct net_device *dev)
+{
+	struct ppp *ppp = get_ppp(dev);
+	int i;
+
+	for (i = 0; i < IDX_COUNT; i++)
+		del_timer_sync(&ppp->protos[i].timer);
+}
+
 static struct hdlc_proto proto = {
 	.start		= ppp_start,
 	.stop		= ppp_stop,
@@ -652,6 +660,7 @@ static struct hdlc_proto proto = {
 	.ioctl		= ppp_ioctl,
 	.netif_rx	= ppp_rx,
 	.module		= THIS_MODULE,
+	.detach		= ppp_timer_release,
 };
 
 static const struct header_ops ppp_header_ops = {
@@ -662,7 +671,7 @@ static int ppp_ioctl(struct net_device *
 {
 	hdlc_device *hdlc = dev_to_hdlc(dev);
 	struct ppp *ppp;
-	int result;
+	int i, result;
 
 	switch (ifr->ifr_settings.type) {
 	case IF_GET_PROTO:
@@ -689,6 +698,8 @@ static int ppp_ioctl(struct net_device *
 			return result;
 
 		ppp = get_ppp(dev);
+		for (i = 0; i < IDX_COUNT; i++)
+			timer_setup(&ppp->protos[i].timer, ppp_timer, 0);
 		spin_lock_init(&ppp->lock);
 		ppp->req_timeout = 2;
 		ppp->cr_retries = 10;
author maintainer
#35 lore raw

PATCH 32/699 xfrm: defensively unhash xfrm_state lists in __xfrm_state_delete

In reply to Greg Kroah-Hartman

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

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

From: Michal Kosiorek <[email protected]>

[ Upstream commit 14acf9652e5690de3c7486c6db5fb8dafd0a32a3 ]

KASAN reproduces a slab-use-after-free in __xfrm_state_delete()'s hlist_del_rcu calls under syzkaller load on linux-6.12.y stable (reproduced on 6.12.47, also reachable via the same code path on torvalds/master and on the ipsec tree). Nine unique signatures cluster in the xfrm_state lifecycle, the load-bearing one being:

  BUG: KASAN: slab-use-after-free in __hlist_del include/linux/list.h:990 [inline]
  BUG: KASAN: slab-use-after-free in hlist_del_rcu include/linux/rculist.h:516 [inline]
  BUG: KASAN: slab-use-after-free in __xfrm_state_delete net/xfrm/xfrm_state.c
  Write of size 8 at addr ffff8881198bcb70 by task kworker/u8:9/435

  Workqueue: netns cleanup_net
  Call Trace:
   __hlist_del / hlist_del_rcu
   __xfrm_state_delete
   xfrm_state_delete
   xfrm_state_flush
   xfrm_state_fini
   ops_exit_list
   cleanup_net

The other observed signatures hit the same slab object from __xfrm_state_lookup, xfrm_alloc_spi, __xfrm_state_insert and an OOB write variant of __xfrm_state_delete, all on the byseq/byspi hash chains.

__xfrm_state_delete() guards its byseq and byspi unhashes with value-based predicates:

	if (x->km.seq)
		hlist_del_rcu(&x->byseq);
	if (x->id.spi)
		hlist_del_rcu(&x->byspi);

while everywhere else in the file (e.g. state_cache, state_cache_input) the safer hlist_unhashed() check is used. xfrm_alloc_spi() sets x->id.spi = newspi inside xfrm_state_lock and then immediately inserts into byspi, but a path that observes x->id.spi != 0 outside of xfrm_state_lock can still skip-or-hit the byspi unhash inconsistently with whether x is actually on the list. The same holds for x->km.seq versus byseq, and the bydst/bysrc unhashes have no predicate at all, so a second __xfrm_state_delete() on the same object writes through LIST_POISON pprev.

The defensive change here:

- Use hlist_del_init_rcu() instead of hlist_del_rcu() on bydst, bysrc, byseq and byspi so a second deletion is a no-op rather than a write through LIST_POISON pprev. The byseq/byspi nodes are already initialised in xfrm_state_alloc().
- Test hlist_unhashed() rather than the value predicate for byseq/byspi, so the unhash decision tracks list state rather than mutable scalar fields.

Empirical verification: applied this patch on top of v6.12.47, rebuilt, and re-ran the same syzkaller harness for 1h16m on a previously-crashy configuration that produced ~100 hits each of slab-use-after-free Read in xfrm_alloc_spi / Read in __xfrm_state_lookup / Write in __xfrm_state_delete. After the patch, 7.1M execs across 32 VMs at ~1550 exec/sec produced zero xfrm_state UAF/OOB hits. /proc/slabinfo confirms the xfrm_state slab is actively allocated and freed during the run (~143 KiB resident), so the fuzzer is still exercising those code paths -- they just no longer crash.

Reproduction:

- Linux 6.12.47 x86_64 + KASAN_GENERIC + KASAN_INLINE + KCOV
- syzkaller @ 746545b8b1e4c3a128db8652b340d3df90ce61db
- 32 QEMU/KVM VMs x 2 vCPU on AWS c5.metal bare metal
- 9 unique signatures collected in ~9h, all within xfrm_state lifecycle

Fixes fe9f1d8779cb ("xfrm: add state hashtable keyed by seq")
Fixes 7b4dc3600e48 ("[XFRM]: Do not add a state whose SPI is zero to the SPI hash.")

[ 5.10: drop state_cache{,_input} lines from context because 81a331a ("xfrm: Add an inbound percpu state cache.") does not exist yet, drop xfrm_nat_keepalive_state_updated line from context because f531d13 ("xfrm: support sending NAT keepalives in ESP in UDP states") does not exist yet, and remove byseq since that optimization in fe9f1d8 ("xfrm:
add state hashtable keyed by seq") does not exist yet ]

---
 net/xfrm/xfrm_state.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)
net/xfrm/xfrm_state.c +5 -4
index 61a0a5b843d9e7..8c742258952b8a 100644
@@ -659,10 +659,11 @@ int __xfrm_state_delete(struct xfrm_state *x)
 		x->km.state = XFRM_STATE_DEAD;
 		spin_lock(&net->xfrm.xfrm_state_lock);
 		list_del(&x->km.all);
-		hlist_del_rcu(&x->bydst);
-		hlist_del_rcu(&x->bysrc);
-		if (x->id.spi)
-			hlist_del_rcu(&x->byspi);
+		hlist_del_init_rcu(&x->bydst);
+		hlist_del_init_rcu(&x->bysrc);
+
+		if (!hlist_unhashed(&x->byspi))
+			hlist_del_init_rcu(&x->byspi);
 		net->xfrm.state_num--;
 		spin_unlock(&net->xfrm.xfrm_state_lock);
 
Signature · 1 line
2.53.0
author maintainer
#36 lore raw

PATCH 33/699 usb: gadget: function: rndis: add length check to response query

In reply to Greg Kroah-Hartman

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

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

From: Griffin Kroah-Hartman <[email protected]>

commit 95f90eea070837f7c72207d5520f805bdefc3bc5 upstream.

Add variable representations for BufLength and BufOffset in rndis_query_response(), and perform a length check on them.

This is identical to how rndis_set_response() handles these parameters.

---
 drivers/usb/gadget/function/rndis.c |   14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)
drivers/usb/gadget/function/rndis.c +10 -4
@@ -591,6 +591,7 @@ static int rndis_init_response(struct rn
 static int rndis_query_response(struct rndis_params *params,
 				rndis_query_msg_type *buf)
 {
+	u32 BufLength, BufOffset;
 	rndis_query_cmplt_type *resp;
 	rndis_resp_t *r;
 
@@ -598,6 +599,13 @@ static int rndis_query_response(struct r
 	if (!params->dev)
 		return -ENOTSUPP;
 
+	BufLength = le32_to_cpu(buf->InformationBufferLength);
+	BufOffset = le32_to_cpu(buf->InformationBufferOffset);
+	if ((BufLength > RNDIS_MAX_TOTAL_SIZE) ||
+	    (BufOffset > RNDIS_MAX_TOTAL_SIZE) ||
+	    (BufOffset + 8 >= RNDIS_MAX_TOTAL_SIZE))
+		return -EINVAL;
+
 	/*
 	 * we need more memory:
 	 * gen_ndis_query_resp expects enough space for
@@ -614,10 +622,8 @@ static int rndis_query_response(struct r
 	resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
 
 	if (gen_ndis_query_resp(params, le32_to_cpu(buf->OID),
-			le32_to_cpu(buf->InformationBufferOffset)
-					+ 8 + (u8 *)buf,
-			le32_to_cpu(buf->InformationBufferLength),
-			r)) {
+				BufOffset + 8 + (u8 *)buf,
+				BufLength, r)) {
 		/* OID not supported */
 		resp->Status = cpu_to_le32(RNDIS_STATUS_NOT_SUPPORTED);
 		resp->MessageLength = cpu_to_le32(sizeof *resp);
author maintainer
#37 lore raw

PATCH 34/699 usb: gadget: function: rndis: add length check for header

In reply to Greg Kroah-Hartman

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

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

From: Griffin Kroah-Hartman <[email protected]>

commit 21b5bf155435008e0fb0736795289788e63d426f upstream.

Add a length check for the rndis header in rndis_rm_hdr, to ensure that MessageType, MessageLength, DataOffset, and DataLength fields are present before they are accessed.

---
 drivers/usb/gadget/function/rndis.c |    6 ++++++
 1 file changed, 6 insertions(+)
drivers/usb/gadget/function/rndis.c +6 -0
@@ -1080,6 +1080,12 @@ int rndis_rm_hdr(struct gether *port,
 	/* tmp points to a struct rndis_packet_msg_type */
 	__le32 *tmp = (void *)skb->data;
 
+	/* Need at least MessageType, MessageLength, DataOffset, DataLength */
+	if (skb->len < 16) {
+		dev_kfree_skb_any(skb);
+		return -EINVAL;
+	}
+
 	/* MessageType, MessageLength */
 	if (cpu_to_le32(RNDIS_MSG_PACKET)
 			!= get_unaligned(tmp++)) {
author maintainer
#38 lore raw

PATCH 35/699 iio: accel: bmc150: clamp the device-reported FIFO frame count

In reply to Greg Kroah-Hartman

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

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

From: Bryam Vargas <[email protected]>

commit ce0e1cae26096fe959a0da5563a6d6d5a801d5fb upstream.

__bmc150_accel_fifo_flush() copies the number of samples the device reports in its hardware FIFO into an on-stack buffer

	u16 buffer[BMC150_ACCEL_FIFO_LENGTH * 3];

which is sized for at most BMC150_ACCEL_FIFO_LENGTH (32) samples. The frame count is read from the FIFO_STATUS register and only masked to its 7 valid bits:

	count = val & 0x7F;

so it can be 0..127. The only other limit applied to it is the optional caller-supplied sample budget:

	if (samples && count > samples)
		count = samples;

which does not constrain count on the flush-all path (samples == 0), and leaves it well above 32 whenever samples is larger. count samples are then transferred into buffer[]:

	bmc150_accel_fifo_transfer(data, (u8 *)buffer, count);

bmc150_accel_fifo_transfer() reads count * 6 bytes through regmap, so a malfunctioning, malicious or counterfeit accelerometer (or an attacker tampering with the I2C/SPI bus) that reports up to 127 frames writes up to 762 bytes into the 192-byte buffer: a stack out-of-bounds write of up to 570 bytes that clobbers the stack canary, saved registers and the return address.

Clamp count to BMC150_ACCEL_FIFO_LENGTH, the number of samples buffer[] is sized for, before the transfer, mirroring the watermark clamp already done in bmc150_accel_set_watermark(). A well-formed flush reports at most BMC150_ACCEL_FIFO_LENGTH frames, so legitimate devices are unaffected.

Fixes 3bbec9773389 ("iio: bmc150_accel: add support for hardware fifo")
---
 drivers/iio/accel/bmc150-accel-core.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/iio/accel/bmc150-accel-core.c +2 -0
@@ -919,6 +919,8 @@ static int __bmc150_accel_fifo_flush(str
 	if (samples && count > samples)
 		count = samples;
 
+	count = min_t(u8, count, BMC150_ACCEL_FIFO_LENGTH);
+
 	ret = bmc150_accel_fifo_transfer(data, (u8 *)buffer, count);
 	if (ret)
 		return ret;
author maintainer
#39 lore raw

PATCH 36/699 iio: accel: kxsd9: fix runtime PM imbalance on write_raw() error

In reply to Greg Kroah-Hartman

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

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

From: Biren Pandya <[email protected]>

commit 44a5fd874bb6873bdaec59f722c1d57832fbc9df upstream.

kxsd9_write_raw() takes a runtime PM reference with pm_runtime_get_sync() but returns -EINVAL directly when a scale with a non-zero integer part is requested, skipping the matching pm_runtime_put_autosuspend(). This leaks a runtime PM usage-counter reference on every such write, after which the device can no longer autosuspend.

Set the error code and fall through to the existing put instead of returning early.

Fixes 9a9a369d6178 ("iio: accel: kxsd9: Deploy system and runtime PM")
Assisted-by Claude:claude-opus-4-8 coccinelle
---
 drivers/iio/accel/kxsd9.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/iio/accel/kxsd9.c +3 -2
@@ -146,8 +146,9 @@ static int kxsd9_write_raw(struct iio_de
 	if (mask == IIO_CHAN_INFO_SCALE) {
 		/* Check no integer component */
 		if (val)
-			return -EINVAL;
-		ret = kxsd9_write_scale(indio_dev, val2);
+			ret = -EINVAL;
+		else
+			ret = kxsd9_write_scale(indio_dev, val2);
 	}
 
 	pm_runtime_mark_last_busy(st->dev);
author maintainer
#40 lore raw

PATCH 37/699 iio: adc: lpc32xx: Initialize completion before requesting IRQ

In reply to Greg Kroah-Hartman

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

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

From: Maxwell Doose <[email protected]>

commit e561b35633f450ee607e87a6401d97f156a0cd54 upstream.

In the report from Jaeyoung Chung:

"lpc32xx_adc_probe() in drivers/iio/adc/lpc32xx_adc.c registers its interrupt handler with devm_request_irq() before it initializes st->completion with init_completion(). If an interrupt arrives after devm_request_irq() and before init_completion(), the handler calls complete() on an uninitialized completion, causing a kernel panic.

The probe path, in lpc32xx_adc_probe():

    iodev = devm_iio_device_alloc(&pdev->dev, sizeof(*st)); /* st kzalloc-zeroed */
    ...
    retval = devm_request_irq(&pdev->dev, irq, lpc32xx_adc_isr, 0,
                              LPC32XXAD_NAME, st);           /* register handler */
    ...
    init_completion(&st->completion);                       /* initialize completion */

lpc32xx_adc_isr() calls complete():

    complete(&st->completion);

If the device raises an interrupt before init_completion() runs, complete() acquires the uninitialized wait.lock and walks the zeroed task_list in swake_up_locked(). The zeroed task_list makes list_empty() return false, so swake_up_locked() dereferences a NULL list entry, triggering a KASAN wild-memory-access."

Fix the chance of a spurious IRQ causing an uninitialized pointer dereference by moving init_completion() above devm_request_irq().

---
 drivers/iio/adc/lpc32xx_adc.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/iio/adc/lpc32xx_adc.c +2 -2
@@ -176,6 +176,8 @@ static int lpc32xx_adc_probe(struct plat
 	if (irq <= 0)
 		return -ENXIO;
 
+	init_completion(&st->completion);
+
 	retval = devm_request_irq(&pdev->dev, irq, lpc32xx_adc_isr, 0,
 				  LPC32XXAD_NAME, st);
 	if (retval < 0) {
@@ -194,8 +196,6 @@ static int lpc32xx_adc_probe(struct plat
 
 	platform_set_drvdata(pdev, iodev);
 
-	init_completion(&st->completion);
-
 	iodev->name = LPC32XXAD_NAME;
 	iodev->info = &lpc32xx_adc_iio_info;
 	iodev->modes = INDIO_DIRECT_MODE;
author maintainer
#41 lore raw

PATCH 38/699 iio: adc: ti-ads124s08: Return reset GPIO lookup errors

In reply to Greg Kroah-Hartman

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

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

From: Pengpeng Hou <[email protected]>

commit 7dc4de2aa6316f1d044cde21f5acfec5f3ec6b47 upstream.

devm_gpiod_get_optional() returns NULL when the optional GPIO is absent, but returns an ERR_PTR when the GPIO provider lookup fails, including probe deferral.

Probe currently logs the ERR_PTR case as if the reset GPIO were simply absent and keeps the error pointer in reset_gpio. Later ads124s_reset() treats any non-NULL reset_gpio as a valid descriptor and passes it to gpiod_set_value_cansleep().

Return the lookup error instead of retaining the ERR_PTR.

---
 drivers/iio/adc/ti-ads124s08.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/iio/adc/ti-ads124s08.c +2 -1
@@ -323,7 +323,8 @@ static int ads124s_probe(struct spi_devi
 	ads124s_priv->reset_gpio = devm_gpiod_get_optional(&spi->dev,
 						   "reset", GPIOD_OUT_LOW);
 	if (IS_ERR(ads124s_priv->reset_gpio))
-		dev_info(&spi->dev, "Reset GPIO not defined\n");
+		return dev_err_probe(&spi->dev, PTR_ERR(ads124s_priv->reset_gpio),
+				     "Failed to get reset GPIO\n");
 
 	ads124s_priv->chip_info = &ads124s_chip_info_tbl[spi_id->driver_data];
 
author maintainer
#42 lore raw

PATCH 39/699 iio: chemical: scd30: Cleanup initializations and fix sign-extension bug

In reply to Greg Kroah-Hartman

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

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

From: Maxwell Doose <[email protected]>

commit 60d877910a43c305b5165131b258a17b1d772d57 upstream.

Include linux/bitfield.h for FIELD_GET().

Create new macros for bit manipulation in combination with manual bit manipulation being replaced with FIELD_GET().

The current variable declaration and initializations are barely readable and use comma separations across multiple lines. Refactor the initializations so that mantissa and exp have separate declarations and sign gets initialized later.

In addition (and due to the nature of the cleanup), fix a sign-extension bug where, float32 would get bitwise anded with ~BIT(31) (which is 0xFFFFFFFF7FFFFFFF) which corrupted the exponent.

---
 drivers/iio/chemical/scd30_core.c |   19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)
drivers/iio/chemical/scd30_core.c +15 -4
@@ -4,6 +4,8 @@
  *
  * Copyright (c) 2020 Tomasz Duszynski <[email protected]>
  */
+
+#include <linux/bitfield.h>
 #include <linux/bits.h>
 #include <linux/cleanup.h>
 #include <linux/completion.h>
@@ -43,6 +45,11 @@
 #define SCD30_TEMP_OFFSET_MAX 655360
 #define SCD30_EXTRA_TIMEOUT_PER_S 250
 
+/* Floating point arithmetic macros */
+#define SCD30_FLOAT_MANTISSA_MSK GENMASK(22, 0)
+#define SCD30_FLOAT_EXP_MSK GENMASK(30, 23)
+#define SCD30_FLOAT_SIGN_MSK BIT(31)
+
 enum {
 	SCD30_CONC,
 	SCD30_TEMP,
@@ -89,10 +96,14 @@ static int scd30_reset(struct scd30_stat
 /* simplified float to fixed point conversion with a scaling factor of 0.01 */
 static int scd30_float_to_fp(int float32)
 {
-	int fraction, shift,
-	    mantissa = float32 & GENMASK(22, 0),
-	    sign = (float32 & BIT(31)) ? -1 : 1,
-	    exp = (float32 & ~BIT(31)) >> 23;
+	int fraction, shift, sign;
+	int mantissa = FIELD_GET(SCD30_FLOAT_MANTISSA_MSK, float32);
+	int exp = FIELD_GET(SCD30_FLOAT_EXP_MSK, float32);
+
+	if (float32 & SCD30_FLOAT_SIGN_MSK)
+		sign = -1;
+	else
+		sign = 1;
 
 	/* special case 0 */
 	if (!exp && !mantissa)
author maintainer
#43 lore raw

PATCH 40/699 iio: event: Fix event FIFO reset race

In reply to Greg Kroah-Hartman

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

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

From: Lars-Peter Clausen <[email protected]>

commit af791d295737ea6b6ff2c8d8488462a49c14af01 upstream.

iio_event_getfd() creates the event file descriptor with anon_inode_getfd(), which allocates a new fd, creates the anonymous file and installs it in the process fd table before returning to the caller.

The IIO code resets the event FIFO after anon_inode_getfd() has returned, but before IIO_GET_EVENT_FD_IOCTL has copied the fd number to userspace. But since fd tables are shared between threads, another thread can guess the newly allocated fd number and issue a read() on it as soon as the fd has been installed.

This means the kfifo_to_user() in iio_event_chrdev_read() can run in parallel with the kfifo_reset_out() in iio_event_getfd().

The kfifo documentation says that kfifo_reset_out() is only safe when it is called from the reader thread and there is only one concurrent reader. Otherwise it is dangerous and must be handled in the same way as kfifo_reset().

If that happens, kfifo_to_user() can advance the FIFO out index based on state from before the reset, after the reset has already moved the out index to the current in index. That can leave the FIFO with an out index past the in index. A later read() can then see an underflowed FIFO length and copy more data than the event FIFO buffer contains. This can result in an out-of-bounds read and leak adjacent kernel memory to userspace.

Move the FIFO reset before anon_inode_getfd(). At that point the event fd is marked busy, but the new fd has not been installed yet, so userspace cannot access it while the FIFO is reset.

Fixes b91accafbb10 ("iio:event: Fix and cleanup locking")
Reported-by Codex:gpt-5.5
---
 drivers/iio/industrialio-event.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/iio/industrialio-event.c +2 -3
@@ -205,6 +205,8 @@ int iio_event_getfd(struct iio_dev *indi
 		goto unlock;
 	}
 
+	kfifo_reset_out(&ev_int->det_events);
+
 	iio_device_get(indio_dev);
 
 	fd = anon_inode_getfd("iio:event", &iio_event_chrdev_fileops,
@@ -212,10 +214,7 @@ int iio_event_getfd(struct iio_dev *indi
 	if (fd < 0) {
 		clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags);
 		iio_device_put(indio_dev);
-	} else {
-		kfifo_reset_out(&ev_int->det_events);
 	}
-
 unlock:
 	mutex_unlock(&indio_dev->mlock);
 	return fd;
author maintainer
#44 lore raw

PATCH 41/699 iio: gyro: bmg160: bail out when bandwidth/filter is not in table

In reply to Greg Kroah-Hartman

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

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

From: Stepan Ionichev <[email protected]>

commit 8320c77e67382d5d55d77043a5f60a867d408a2b upstream.

bmg160_get_filter() walks bmg160_samp_freq_table[] looking for the entry matching the bw_bits value read from the chip:

	for (i = 0; i < ARRAY_SIZE(bmg160_samp_freq_table); ++i) {
		if (bmg160_samp_freq_table[i].bw_bits == bw_bits)
			break;
	}
	*val = bmg160_samp_freq_table[i].filter;

If no entry matches, i ends up equal to the array size and the next line reads one slot past the end. bmg160_set_filter() has the same shape, driven by 'val' instead of bw_bits.

smatch flags both:

drivers/iio/gyro/bmg160_core.c:204 bmg160_get_filter() error:
buffer overflow 'bmg160_samp_freq_table' 7 <= 7 drivers/iio/gyro/bmg160_core.c:222 bmg160_set_filter() error:
buffer overflow 'bmg160_samp_freq_table' 7 <= 7

Return -EINVAL when no entry matches.

The set_filter() path is reachable from userspace via the sysfs in_anglvel_filter_low_pass_3db_frequency interface, so userspace can trivially trigger the out-of-bounds read with a value that is not in bmg160_samp_freq_table[].filter.

Fixes 22b46c45fb9b ("iio:gyro:bmg160 Gyro Sensor driver")
---
 drivers/iio/gyro/bmg160_core.c |    6 ++++++
 1 file changed, 6 insertions(+)
drivers/iio/gyro/bmg160_core.c +6 -0
@@ -203,6 +203,9 @@ static int bmg160_get_filter(struct bmg1
 			break;
 	}
 
+	if (i == ARRAY_SIZE(bmg160_samp_freq_table))
+		return -EINVAL;
+
 	*val = bmg160_samp_freq_table[i].filter;
 
 	return ret ? ret : IIO_VAL_INT;
@@ -220,6 +223,9 @@ static int bmg160_set_filter(struct bmg1
 			break;
 	}
 
+	if (i == ARRAY_SIZE(bmg160_samp_freq_table))
+		return -EINVAL;
+
 	ret = regmap_write(data->regmap, BMG160_REG_PMU_BW,
 			   bmg160_samp_freq_table[i].bw_bits);
 	if (ret < 0) {
author maintainer
#45 lore raw

PATCH 42/699 iio: gyro: bmg160: wait full startup time after mode change at probe

In reply to Greg Kroah-Hartman

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

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

From: Stepan Ionichev <[email protected]>

commit 088fcb9b567f8723074ad9eb1bf5cb46f8a0096b upstream.

bmg160_chip_init() calls bmg160_set_mode(BMG160_MODE_NORMAL) and then waits only 500-1000 us. Per the BMG160 datasheet (BST-BMG160-DS000-07 Rev. 1.0, May 2013), the start-up and wake-up times (tsu, twusm) are 30 ms.

The same file already waits BMG160_MAX_STARTUP_TIME_MS (80 ms) in bmg160_runtime_resume() after the same set_mode(NORMAL) operation. The 500 us value at probe was likely a unit mix-up; the old comment said "500 ms" while the code used microseconds.

Reuse the same constant via msleep() and add a code comment explaining the datasheet basis for the wait. Without this, register writes that follow the mode change can hit the chip before it is ready.

Fixes 22b46c45fb9b ("iio:gyro:bmg160 Gyro Sensor driver")
---
 drivers/iio/gyro/bmg160_core.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/iio/gyro/bmg160_core.c +8 -2
@@ -266,8 +266,14 @@ static int bmg160_chip_init(struct bmg16
 	if (ret < 0)
 		return ret;
 
-	/* Wait upto 500 ms to be ready after changing mode */
-	usleep_range(500, 1000);
+	/*
+	 * Wait for the chip to be ready after switching to normal mode.
+	 * The BMG160 datasheet (BST-BMG160-DS000-07 Rev. 1.0, May 2013)
+	 * specifies a start-up / wake-up time (tsu, twusm) of 30 ms; use
+	 * BMG160_MAX_STARTUP_TIME_MS (80 ms) as a safety margin, matching
+	 * what bmg160_runtime_resume() already does.
+	 */
+	msleep(BMG160_MAX_STARTUP_TIME_MS);
 
 	/* Set Bandwidth */
 	ret = bmg160_set_bw(data, BMG160_DEF_BW);
author maintainer
#46 lore raw

PATCH 43/699 iio: imu: bmi160: add IRQF_NO_THREAD to data-ready trigger IRQ

In reply to Greg Kroah-Hartman

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

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

From: Runyu Xiao <[email protected]>

commit cd5a6a5096b246e10600da3ac47a1274ce9573c8 upstream.

bmi160_probe_trigger() registers iio_trigger_generic_data_rdy_poll() through devm_request_irq(), but it passes only irq_type and does not add IRQF_NO_THREAD.

When the kernel is booted with forced IRQ threading, the parent IRQ can otherwise be threaded by the IRQ core and the subsequent IIO trigger child IRQ is dispatched from irq/... thread context instead of hardirq context. Because the handler immediately pushes the event into iio_trigger_poll(), this violates the hardirq-only IIO trigger helper contract and can drive downstream trigger consumers through the wrong execution context.

Add IRQF_NO_THREAD on top of irq_type when registering the BMI160 data- ready trigger handler.

Fixes 895bf81e6bbf ("iio:bmi160: add drdy interrupt support")
---
 drivers/iio/imu/bmi160/bmi160_core.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/iio/imu/bmi160/bmi160_core.c +2 -1
@@ -801,7 +801,8 @@ int bmi160_probe_trigger(struct iio_dev
 
 	ret = devm_request_irq(&indio_dev->dev, irq,
 			       &iio_trigger_generic_data_rdy_poll,
-			       irq_type, "bmi160", data->trig);
+			       irq_type | IRQF_NO_THREAD,
+			       "bmi160", data->trig);
 	if (ret)
 		return ret;
 
author maintainer
#47 lore raw

PATCH 44/699 iio: imu: st_lsm6dsx: deselect shub page before reading whoami

In reply to Greg Kroah-Hartman

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

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

From: Andreas Kempe <[email protected]>

commit aede83625ff5d9539508582036df30c809d51058 upstream.

As part of driver initialization, e.g. st_lsm6dsx_init_shub() selects the shub register page using st_lsm6dsx_set_page(). Selecting the shub register page shadows the regular register space so whoami, among other registers, is no longer accessible.

In applications where the IMU is permanently powered separately from the processor, there is a window where a reset of the CPU leaves the IMU in the shub register page. Once this occurs, any subsequent probe attempt fails because of the register shadowing.

Using the ism330dlc, the error typically looks like

    st_lsm6dsx_i2c 3-006a: unsupported whoami [10]

with the unknown whoami read from a reserved register in the shub page.

The reset register is also shadowed by the page select, preventing a reset from recovering the chip.

Unconditionally clear the shub page before the whoami readout to ensure normal register access and allow the initialization to proceed.

Place the fix in st_lsm6dsx_check_whoami() before the whoami check because hw->settings, which st_lsm6dsx_set_page() relies on, is first assigned in that function.

Placing the fix in a more logical place than the whoami check would require a bigger restructuring of the code.

Fixes c91c1c844ebd ("iio: imu: st_lsm6dsx: add i2c embedded controller support")
---
 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c |   21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +20 -1
@@ -1389,6 +1389,26 @@ static int st_lsm6dsx_check_whoami(struc
 		return -ENODEV;
 	}
 
+	hw->settings = &st_lsm6dsx_sensor_settings[i];
+
+	if (hw->settings->shub_settings.page_mux.addr) {
+		/*
+		 * If the IMU has the shub page selected on init, for example
+		 * after a CPU watchdog reset while the page is selected, the
+		 * regular register space is shadowed. While the regular
+		 * register space is shadowed, the registers needed for
+		 * initializing the IMU are not available.
+		 *
+		 * Unconditionally clear the shub page selection to ensure
+		 * normal register access.
+		 */
+		err = st_lsm6dsx_set_page(hw, false);
+		if (err < 0) {
+			dev_err(hw->dev, "failed to clear shub page\n");
+			return err;
+		}
+	}
+
 	err = regmap_read(hw->regmap, ST_LSM6DSX_REG_WHOAMI_ADDR, &data);
 	if (err < 0) {
 		dev_err(hw->dev, "failed to read whoami register\n");
@@ -1401,7 +1421,6 @@ static int st_lsm6dsx_check_whoami(struc
 	}
 
 	*name = st_lsm6dsx_sensor_settings[i].id[j].name;
-	hw->settings = &st_lsm6dsx_sensor_settings[i];
 
 	return 0;
 }
author maintainer
#48 lore raw

PATCH 45/699 iio: light: al3010: fix incorrect scale for the highest gain range

In reply to Greg Kroah-Hartman

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

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

From: Vidhu Sarwal <[email protected]>

commit aa411adc6ce40ad1a55ebc965f255a4cfc0005f8 upstream.

al3010_scales[] encodes the highest gain range as {0, 1187200}. For IIO_VAL_INT_PLUS_MICRO, the fractional part must be less than 1000000, so the scale 1.1872 should instead be represented as { 1, 187200 }.

Since write_raw() compares the value from userspace against this table, writing the advertised 1.1872 scale never matches the malformed entry and returns -EINVAL. As a result, the highest gain range cannot be selected. Reading the scale in that state also reports the malformed value.

Fixes c36b5195ab70 ("iio: light: add Dyna-Image AL3010 driver")
---
 drivers/iio/light/al3010.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/light/al3010.c +1 -1
@@ -43,7 +43,7 @@ enum al3xxxx_range {
 };
 
 static const int al3010_scales[][2] = {
-	{0, 1187200}, {0, 296800}, {0, 74200}, {0, 18600}
+	{ 1, 187200 }, { 0, 296800 }, { 0, 74200 }, { 0, 18600 },
 };
 
 struct al3010_data {
author maintainer
#49 lore raw

PATCH 46/699 iio: light: gp2ap002: fix runtime PM leak on read error

In reply to Greg Kroah-Hartman

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

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

From: Biren Pandya <[email protected]>

commit 38b72267b7e22768a1f26d9935de4e1752a1dc85 upstream.

gp2ap002_read_raw() calls pm_runtime_get_sync() before reading the lux value, but if gp2ap002_get_lux() fails, it returns directly. This skips the pm_runtime_put_autosuspend() call at the "out" label, permanently leaking a runtime PM reference and preventing the device from autosuspending.

Replace the direct return with a "goto out" to ensure the reference is properly dropped on the error path.

Fixes f6dbf83c17cb ("iio: light: gp2ap002: Take runtime PM reference on light read")
---
 drivers/iio/light/gp2ap002.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/light/gp2ap002.c +1 -1
@@ -258,7 +258,7 @@ static int gp2ap002_read_raw(struct iio_
 		case IIO_LIGHT:
 			ret = gp2ap002_get_lux(gp2ap002);
 			if (ret < 0)
-				return ret;
+				goto out;
 			*val = ret;
 			ret = IIO_VAL_INT;
 			goto out;
author maintainer
#50 lore raw

PATCH 47/699 iio: light: opt3001: fix missing state reset on timeout

In reply to Greg Kroah-Hartman

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

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

From: Joshua Crofts <[email protected]>

commit c123ca6ee26ad98f70a866ff428b08145c5a24fe upstream.

Currently in the function opt3001_get_processed(), there is a check that directly returns -ETIMEDOUT if the conversion IRQ times out, completely bypassing the err label, leaving ok_to_ignore_lock permanently true, potentially breaking the device's falling threshold interrupt detection.

Assign -ETIMEDOUT to the return variable and jump to the error label to ensure ok_to_ignore_lock is properly reset.

---
 drivers/iio/light/opt3001.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/iio/light/opt3001.c +4 -2
@@ -280,8 +280,10 @@ static int opt3001_get_lux(struct opt300
 		ret = wait_event_timeout(opt->result_ready_queue,
 				opt->result_ready,
 				msecs_to_jiffies(OPT3001_RESULT_READY_LONG));
-		if (ret == 0)
-			return -ETIMEDOUT;
+		if (ret == 0) {
+			ret = -ETIMEDOUT;
+			goto err;
+		}
 	} else {
 		/* Sleep for result ready time */
 		timeout = (opt->int_time == OPT3001_INT_TIME_SHORT) ?
author maintainer
#51 lore raw

PATCH 48/699 iio: light: veml6030: fix channel type when pushing events

In reply to Greg Kroah-Hartman

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

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

From: Javier Carrasco <[email protected]>

commit c52bb33b641ebaae3e209f97714cb1758206f7d9 upstream.

The events are registered for IIO_LIGHT and not for IIO_INTENSITY. Use the correct channel type.

When at it, fix minor checkpatch code style warning (alignment).

Fixes 7b779f573c48 ("iio: light: add driver for veml6030 ambient light sensor")
---
 drivers/iio/light/veml6030.c |    8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/iio/light/veml6030.c +5 -3
@@ -710,9 +710,11 @@ static irqreturn_t veml6030_event_handle
 	else
 		evtdir = IIO_EV_DIR_FALLING;
 
-	iio_push_event(indio_dev, IIO_UNMOD_EVENT_CODE(IIO_INTENSITY,
-					0, IIO_EV_TYPE_THRESH, evtdir),
-					iio_get_time_ns(indio_dev));
+	iio_push_event(indio_dev, IIO_UNMOD_EVENT_CODE(IIO_LIGHT,
+						       0,
+						       IIO_EV_TYPE_THRESH,
+						       evtdir),
+		       iio_get_time_ns(indio_dev));
 
 	return IRQ_HANDLED;
 }
author maintainer
#52 lore raw

PATCH 49/699 iio: magnetometer: ak8975: Add missed pm_runtime_put_autosuspend() call

In reply to Greg Kroah-Hartman

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

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

From: Andy Shevchenko <[email protected]>

commit e94944d7364d3ddb273539492f9bd9c9a622549a upstream.

On the failure in the ak8975_read_axis() the PM runtime gets unbalanced. Balance it by calling pm_runtime_put_autosuspend() on error path as well.

---
 drivers/iio/magnetometer/ak8975.c |    1 +
 1 file changed, 1 insertion(+)
drivers/iio/magnetometer/ak8975.c +1 -0
@@ -715,6 +715,7 @@ static int ak8975_read_axis(struct iio_d
 
 exit:
 	mutex_unlock(&data->lock);
+	pm_runtime_put_autosuspend(&data->client->dev);
 	dev_err(&client->dev, "Error in reading axis\n");
 	return ret;
 }
author maintainer
#53 lore raw

PATCH 50/699 iio: temperature: ltc2983: Fix reinit_completion() called after conversion start

In reply to Greg Kroah-Hartman

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

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

From: Liviu Stan <[email protected]>

commit 5cb9fdb446bfc3ae0524496f53fb68e67051701b upstream.

reinit_completion() was called after regmap_write() initiated the hardware conversion, creating a race window where the interrupt could fire and call complete() before reinit_completion() reset the completion.

Move reinit_completion() before the regmap_write() to close the race. ltc2983_eeprom_cmd() already does it in the correct order.

Fixes f110f3188e56 ("iio: temperature: Add support for LTC2983")
---
 drivers/iio/temperature/ltc2983.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/iio/temperature/ltc2983.c +1 -2
@@ -1147,12 +1147,11 @@ static int ltc2983_chan_read(struct ltc2
 	start_conversion |= LTC2983_STATUS_CHAN_SEL(sensor->chan);
 	dev_dbg(&st->spi->dev, "Start conversion on chan:%d, status:%02X\n",
 		sensor->chan, start_conversion);
+	reinit_completion(&st->completion);
 	/* start conversion */
 	ret = regmap_write(st->regmap, LTC2983_STATUS_REG, start_conversion);
 	if (ret)
 		return ret;
-
-	reinit_completion(&st->completion);
 	/*
 	 * wait for conversion to complete.
 	 * 300 ms should be more than enough to complete the conversion.
author maintainer
#54 lore raw

PATCH 51/699 ALSA: caiaq: fix out-of-bounds read in the Traktor Kontrol S4 input parser

In reply to Greg Kroah-Hartman

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

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

From: Maoyi Xie <[email protected]>

commit f7f3f9fd81e7adbaa12c2e62ee07f0e094a543fd upstream.

snd_usb_caiaq_tks4_dispatch() decodes the Traktor Kontrol S4 input stream in fixed 16-byte (TKS4_MSGBLOCK_SIZE) message blocks. On every iteration it advances buf and subtracts the block size while looping on "while (len)".

len is urb->actual_length. That value is supplied by the device and is not guaranteed to be a multiple of 16. When a final short block leaves len between 1 and 15, the loop runs once more, reads up to buf[15], and then does "len -= TKS4_MSGBLOCK_SIZE". As len is unsigned this underflows to a huge value. The loop then keeps iterating and walking buf far past the end of the 512-byte ep4_in_buf, reading out of bounds until a bogus block id happens to be hit.

Iterate only while a full message block is available. This stops the unsigned underflow and silently drops any trailing partial block, which carries no complete control value anyway.

The sibling endpoint-4 parsers are not affected. The Traktor Kontrol X1 and Maschine arms in snd_usb_caiaq_ep4_reply_dispatch() floor urb->actual_length before dispatching.

Fixes 15c5ab607045 ("ALSA: snd-usb-caiaq: Add support for Traktor Kontrol S4")
---
 sound/usb/caiaq/input.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
sound/usb/caiaq/input.c +1 -1
@@ -330,7 +330,7 @@ static void snd_usb_caiaq_tks4_dispatch(
 {
 	struct device *dev = caiaqdev_to_dev(cdev);
 
-	while (len) {
+	while (len >= TKS4_MSGBLOCK_SIZE) {
 		unsigned int i, block_id = (buf[0] << 8) | buf[1];
 
 		switch (block_id) {
author maintainer
#55 lore raw

PATCH 52/699 ALSA: es1938: check snd_ctl_new1() return value

In reply to Greg Kroah-Hartman

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

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

From: Zhao Dongdong <[email protected]>

commit 1edd1f02dddd20aeb6066ded41017615766ea42f upstream.

snd_ctl_new1() can return NULL when memory allocation fails. snd_es1938_mixer() does not check the return value before dereferencing the pointer, which can lead to a NULL pointer dereference.

Add a NULL check after snd_ctl_new1() and return -ENOMEM if it fails.

Assisted-by Opencode:DeepSeek-V4-Flash
Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")
---
 sound/pci/es1938.c |    2 ++
 1 file changed, 2 insertions(+)
sound/pci/es1938.c +2 -0
@@ -1718,6 +1718,8 @@ static int snd_es1938_mixer(struct es193
 	for (idx = 0; idx < ARRAY_SIZE(snd_es1938_controls); idx++) {
 		struct snd_kcontrol *kctl;
 		kctl = snd_ctl_new1(&snd_es1938_controls[idx], chip);
+		if (!kctl)
+			return -ENOMEM;
 		switch (idx) {
 			case 0:
 				chip->master_volume = kctl;
author maintainer
#56 lore raw

PATCH 53/699 ALSA: firewire: isight: bound the sample count to the packet payload

In reply to Greg Kroah-Hartman

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

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

From: Maoyi Xie <[email protected]>

commit 29b9667982e4df2ed7744f86b1144f8bb58eb698 upstream.

isight_packet() takes the frame count from the device iso packet and checks it only against the device claimed iso length.

	count = be32_to_cpu(payload->sample_count);
	if (likely(count <= (length - 16) / 4))
		isight_samples(isight, payload->samples, count);

length is the iso header data_length. It can be up to 0xffff. So the gate allows a count up to about 16379. isight_samples() then copies count frames out of payload->samples into the PCM DMA buffer.

payload->samples holds only 2 * MAX_FRAMES_PER_PACKET values. The device multiplexes two samples per frame. A count past MAX_FRAMES_PER_PACKET reads past the payload. A count past the buffer size writes past runtime->dma_area. The smallest PCM buffer is larger than MAX_FRAMES_PER_PACKET. Bounding the count to MAX_FRAMES_PER_PACKET keeps both the read and the write in range.

A malicious or faulty Apple iSight on the FireWire bus reaches this during a normal capture.

Add the MAX_FRAMES_PER_PACKET bound to the gate.

---
 sound/firewire/isight.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
sound/firewire/isight.c +2 -1
@@ -179,7 +179,8 @@ static void isight_packet(struct fw_iso_
 	if (likely(length >= 16 &&
 		   payload->signature == cpu_to_be32(0x73676874/*"sght"*/))) {
 		count = be32_to_cpu(payload->sample_count);
-		if (likely(count <= (length - 16) / 4)) {
+		if (likely(count <= (length - 16) / 4 &&
+			   count <= MAX_FRAMES_PER_PACKET)) {
 			total = be32_to_cpu(payload->sample_total);
 			if (unlikely(total != isight->total_samples)) {
 				if (!isight->first_packet)
author maintainer
#57 lore raw

PATCH 54/699 ALSA: usb-audio: avoid kobject path lookup in DualSense match

In reply to Greg Kroah-Hartman

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

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

From: Darvell Long <[email protected]>

commit 7693c0cc415f3a16a7a3355f245474a5e661be4e upstream.

The DualSense jack-detection input handler verifies that a matching input device belongs to the same physical controller by building kobject path strings for both the input device and the USB audio device, then comparing the path prefix.

This was observed when a weak physical connection caused the controller to rapidly disconnect and reconnect. During that repeated hotplug, snd_dualsense_ih_match() can run while the controller's USB device is being disconnected. kobject_get_path() walks ancestor kobjects and dereferences their names; if the USB device kobject name is no longer valid, this can fault in strlen():

  RIP: 0010:strlen+0x10/0x30
  Call Trace:
   kobject_get_path+0x34/0x150
   snd_dualsense_ih_match+0x49/0xd0 [snd_usb_audio]
   input_register_device+0x566/0x6a0
   ps_probe+0xb89/0x1590 [hid_playstation]

The same ownership check can be done without building kobject path strings. The input device is parented below the HID device, USB interface and USB device, so walking the input device parent chain and comparing against the mixer USB device preserves the check without dereferencing kobject names during disconnect.

Fixes 79d561c4ec04 ("ALSA: usb-audio: Add mixer quirk for Sony DualSense PS5")
Assisted-by Cute:gpt-5.5
---
 sound/usb/mixer_quirks.c |   40 ++++++++++++----------------------------
 1 file changed, 12 insertions(+), 28 deletions(-)
sound/usb/mixer_quirks.c +12 -28
@@ -573,46 +573,30 @@ static bool snd_dualsense_ih_match(struc
 {
 	struct dualsense_mixer_elem_info *mei;
 	struct usb_device *snd_dev;
-	char *input_dev_path, *usb_dev_path;
-	size_t usb_dev_path_len;
-	bool match = false;
+	struct device *parent;
 
 	mei = container_of(handler, struct dualsense_mixer_elem_info, ih);
 	snd_dev = mei->info.head.mixer->chip->dev;
 
-	input_dev_path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
-	if (!input_dev_path) {
-		dev_warn(&snd_dev->dev, "Failed to get input dev path\n");
-		return false;
-	}
-
-	usb_dev_path = kobject_get_path(&snd_dev->dev.kobj, GFP_KERNEL);
-	if (!usb_dev_path) {
-		dev_warn(&snd_dev->dev, "Failed to get USB dev path\n");
-		goto free_paths;
-	}
-
 	/*
 	 * Ensure the VID:PID matched input device supposedly owned by the
 	 * hid-playstation driver belongs to the actual hardware handled by
-	 * the current USB audio device, which implies input_dev_path being
-	 * a subpath of usb_dev_path.
+	 * the current USB audio device.
 	 *
 	 * This verification is necessary when there is more than one identical
 	 * controller attached to the host system.
+	 *
+	 * The input device is registered below the HID device, USB interface and
+	 * USB device, so compare the parent chain directly instead of building
+	 * kobject path strings. This avoids dereferencing kobject names while the
+	 * USB device hierarchy is being torn down during disconnect.
 	 */
-	usb_dev_path_len = strlen(usb_dev_path);
-	if (usb_dev_path_len >= strlen(input_dev_path))
-		goto free_paths;
-
-	usb_dev_path[usb_dev_path_len] = '/';
-	match = !memcmp(input_dev_path, usb_dev_path, usb_dev_path_len + 1);
-
-free_paths:
-	kfree(input_dev_path);
-	kfree(usb_dev_path);
+	for (parent = dev->dev.parent; parent; parent = parent->parent) {
+		if (parent == &snd_dev->dev)
+			return true;
+	}
 
-	return match;
+	return false;
 }
 
 static int snd_dualsense_ih_connect(struct input_handler *handler,
author maintainer
#58 lore raw

PATCH 55/699 ALSA: usb-audio: Propagate errors in scarlett_ctl_enum_put()

In reply to Greg Kroah-Hartman

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

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

From: Cássio Gabriel <[email protected]>

commit 0f25cf1f02e3dba626791d949c759a48c0a44996 upstream.

scarlett_ctl_enum_put() ignores the return value from snd_usb_set_cur_mix_value() and reports success whenever the requested enum value differs from the current one.

If the SET_CUR request fails, the callback still returns success even though neither the hardware state nor the cached mixer value changed.

Fixes 76b188c4b370 ("ALSA: usb-audio: Scarlett mixer interface for 6i6, 18i6, 18i8 and 18i20")
---
 sound/usb/mixer_scarlett.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
sound/usb/mixer_scarlett.c +3 -1
@@ -438,7 +438,9 @@ static int scarlett_ctl_enum_put(struct
 	val = ucontrol->value.integer.value[0];
 	val = val + opt->start;
 	if (val != oval) {
-		snd_usb_set_cur_mix_value(elem, 0, 0, val);
+		err = snd_usb_set_cur_mix_value(elem, 0, 0, val);
+		if (err < 0)
+			return err;
 		return 1;
 	}
 	return 0;
author maintainer
#59 lore raw

PATCH 56/699 ALSA: usb-audio: Propagate US-16x08 write errors in route/mix EQ-switch put callbacks

In reply to Greg Kroah-Hartman

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

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

From: Cássio Gabriel <[email protected]>

commit 3c06aec8abda6ba068b58a8b7119cdb2a48456b1 upstream.

Several US-16x08 mixer put callbacks log failed control URBs but still return success to userspace. That hides device write failures even though the requested value was not applied.

Return the negative write error instead in the route, master, bus, channel, and EQ switch put callbacks.

Fixes d2bb390a2081 ("ALSA: usb-audio: Tascam US-16x08 DSP mixer quirk")
---
 sound/usb/mixer_us16x08.c |   49 ++++++++++++++++++++++------------------------
 1 file changed, 24 insertions(+), 25 deletions(-)
sound/usb/mixer_us16x08.c +24 -25
@@ -225,14 +225,14 @@ static int snd_us16x08_route_put(struct
 
 	err = snd_us16x08_send_urb(chip, buf, sizeof(route_msg));
 
-	if (err > 0) {
-		elem->cached |= 1 << index;
-		elem->cache_val[index] = val;
-	} else {
+	if (err < 0) {
 		usb_audio_dbg(chip, "Failed to set routing, err:%d\n", err);
+		return err;
 	}
 
-	return err > 0 ? 1 : 0;
+	elem->cached |= 1 << index;
+	elem->cache_val[index] = val;
+	return 1;
 }
 
 static int snd_us16x08_master_info(struct snd_kcontrol *kcontrol,
@@ -284,14 +284,14 @@ static int snd_us16x08_master_put(struct
 	buf[5] = index + 1;
 	err = snd_us16x08_send_urb(chip, buf, sizeof(mix_msg_out));
 
-	if (err > 0) {
-		elem->cached |= 1 << index;
-		elem->cache_val[index] = val;
-	} else {
+	if (err < 0) {
 		usb_audio_dbg(chip, "Failed to set master, err:%d\n", err);
+		return err;
 	}
 
-	return err > 0 ? 1 : 0;
+	elem->cached |= 1 << index;
+	elem->cache_val[index] = val;
+	return 1;
 }
 
 static int snd_us16x08_bus_put(struct snd_kcontrol *kcontrol,
@@ -325,14 +325,14 @@ static int snd_us16x08_bus_put(struct sn
 		break;
 	}
 
-	if (err > 0) {
-		elem->cached |= 1;
-		elem->cache_val[0] = val;
-	} else {
+	if (err < 0) {
 		usb_audio_dbg(chip, "Failed to set bus parameter, err:%d\n", err);
+		return err;
 	}
 
-	return err > 0 ? 1 : 0;
+	elem->cached |= 1;
+	elem->cache_val[0] = val;
+	return 1;
 }
 
 static int snd_us16x08_bus_get(struct snd_kcontrol *kcontrol,
@@ -393,14 +393,14 @@ static int snd_us16x08_channel_put(struc
 
 	err = snd_us16x08_send_urb(chip, buf, sizeof(mix_msg_in));
 
-	if (err > 0) {
-		elem->cached |= 1 << index;
-		elem->cache_val[index] = val;
-	} else {
+	if (err < 0) {
 		usb_audio_dbg(chip, "Failed to set channel, err:%d\n", err);
+		return err;
 	}
 
-	return err > 0 ? 1 : 0;
+	elem->cached |= 1 << index;
+	elem->cache_val[index] = val;
+	return 1;
 }
 
 static int snd_us16x08_mix_info(struct snd_kcontrol *kcontrol,
@@ -530,13 +530,13 @@ static int snd_us16x08_eqswitch_put(stru
 		msleep(15);
 	}
 
-	if (err > 0) {
-		elem->cached |= 1 << index;
-		elem->cache_val[index] = val;
-	} else {
+	if (err < 0) {
 		usb_audio_dbg(chip, "Failed to set eq switch, err:%d\n", err);
+		return err;
 	}
 
+	elem->cached |= 1 << index;
+	elem->cache_val[index] = val;
 	return 1;
 }
 
@@ -1419,4 +1419,3 @@ int snd_us16x08_controls_create(struct u
 
 	return 0;
 }
-
author maintainer
#60 lore raw

PATCH 57/699 ALSA: usb-audio: Roll back quirk control caches on write errors

In reply to Greg Kroah-Hartman

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

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

From: Cássio Gabriel <[email protected]>

commit 6380957fa24251856a532e48a46a4dc3d1ae26b6 upstream.

Several mixer quirk callbacks cache the requested
control value in kcontrol->private_value before
issuing a single vendor or class write.

Their paired get and resume paths consume that cache directly, so a failed write currently leaves software state changed even though the update did not succeed. That can make later reads report a value the device never accepted and can replay the stale cache on resume.

Restore the previous cached value on failure in
the Audigy2NX LED, Emu0204 channel switch,
Xonar U1 output switch, Native Instruments controls,
FTU effect program switch, and Sound Blaster E1 input source switch.

Fixes 9cf3689bfe07 ("ALSA: usb-audio: Add audigy2nx resume support")
Fixes 5f503ee9e270 ("ALSA: usb-audio: Add Emu0204 channel switch resume support")
Fixes 2bfb14c3b8fb ("ALSA: usb-audio: Add Xonar U1 resume support")
Fixes da6d276957ea ("ALSA: usb-audio: Add resume support for Native Instruments controls")
Fixes 0b4e9cfcef05 ("ALSA: usb-audio: Add resume support for FTU controls")
Fixes 388fdb8f882a ("ALSA: usb-audio: Support changing input on Sound Blaster E1")
---
 sound/usb/mixer_quirks.c |   45 +++++++++++++++++++++++++++++++++++++--------
 1 file changed, 37 insertions(+), 8 deletions(-)
sound/usb/mixer_quirks.c +37 -8
@@ -335,6 +335,7 @@ static int snd_audigy2nx_led_put(struct
 	int index = kcontrol->private_value & 0xff;
 	unsigned int value = ucontrol->value.integer.value[0];
 	int old_value = kcontrol->private_value >> 8;
+	unsigned long old_pval = kcontrol->private_value;
 	int err;
 
 	if (value > 1)
@@ -343,7 +344,11 @@ static int snd_audigy2nx_led_put(struct
 		return 0;
 	kcontrol->private_value = (value << 8) | index;
 	err = snd_audigy2nx_led_update(mixer, value, index);
-	return err < 0 ? err : 1;
+	if (err < 0) {
+		kcontrol->private_value = old_pval;
+		return err;
+	}
+	return 1;
 }
 
 static int snd_audigy2nx_led_resume(struct usb_mixer_elem_list *list)
@@ -493,6 +498,7 @@ static int snd_emu0204_ch_switch_put(str
 	struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
 	struct usb_mixer_interface *mixer = list->mixer;
 	unsigned int value = ucontrol->value.enumerated.item[0];
+	unsigned long old_pval = kcontrol->private_value;
 	int err;
 
 	if (value > 1)
@@ -503,7 +509,11 @@ static int snd_emu0204_ch_switch_put(str
 
 	kcontrol->private_value = value;
 	err = snd_emu0204_ch_switch_update(mixer, value);
-	return err < 0 ? err : 1;
+	if (err < 0) {
+		kcontrol->private_value = old_pval;
+		return err;
+	}
+	return 1;
 }
 
 static int snd_emu0204_ch_switch_resume(struct usb_mixer_elem_list *list)
@@ -814,7 +824,11 @@ static int snd_xonar_u1_switch_put(struc
 
 	kcontrol->private_value = new_status;
 	err = snd_xonar_u1_switch_update(list->mixer, new_status);
-	return err < 0 ? err : 1;
+	if (err < 0) {
+		kcontrol->private_value = old_status;
+		return err;
+	}
+	return 1;
 }
 
 static int snd_xonar_u1_switch_resume(struct usb_mixer_elem_list *list)
@@ -1022,7 +1036,8 @@ static int snd_nativeinstruments_control
 					     struct snd_ctl_elem_value *ucontrol)
 {
 	struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
-	u8 oldval = (kcontrol->private_value >> 24) & 0xff;
+	unsigned long old_pval = kcontrol->private_value;
+	u8 oldval = (old_pval >> 24) & 0xff;
 	u8 newval = ucontrol->value.integer.value[0];
 	int err;
 
@@ -1032,7 +1047,11 @@ static int snd_nativeinstruments_control
 	kcontrol->private_value &= ~(0xff << 24);
 	kcontrol->private_value |= (unsigned int)newval << 24;
 	err = snd_ni_update_cur_val(list);
-	return err < 0 ? err : 1;
+	if (err < 0) {
+		kcontrol->private_value = old_pval;
+		return err;
+	}
+	return 1;
 }
 
 static const struct snd_kcontrol_new snd_nativeinstruments_ta6_mixers[] = {
@@ -1190,7 +1209,8 @@ static int snd_ftu_eff_switch_put(struct
 					struct snd_ctl_elem_value *ucontrol)
 {
 	struct usb_mixer_elem_list *list = snd_kcontrol_chip(kctl);
-	unsigned int pval = list->kctl->private_value;
+	unsigned long old_pval = list->kctl->private_value;
+	unsigned int pval = old_pval;
 	int cur_val, err, new_val;
 
 	cur_val = pval >> 24;
@@ -1201,7 +1221,11 @@ static int snd_ftu_eff_switch_put(struct
 	kctl->private_value &= ~(0xff << 24);
 	kctl->private_value |= new_val << 24;
 	err = snd_ftu_eff_switch_update(list);
-	return err < 0 ? err : 1;
+	if (err < 0) {
+		kctl->private_value = old_pval;
+		return err;
+	}
+	return 1;
 }
 
 static int snd_ftu_create_effect_switch(struct usb_mixer_interface *mixer,
@@ -1999,13 +2023,18 @@ static int snd_soundblaster_e1_switch_pu
 {
 	struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
 	unsigned char value = !!ucontrol->value.integer.value[0];
+	unsigned long old_pval = kcontrol->private_value;
 	int err;
 
 	if (kcontrol->private_value == value)
 		return 0;
 	kcontrol->private_value = value;
 	err = snd_soundblaster_e1_switch_update(list->mixer, value);
-	return err < 0 ? err : 1;
+	if (err < 0) {
+		kcontrol->private_value = old_pval;
+		return err;
+	}
+	return 1;
 }
 
 static int snd_soundblaster_e1_switch_resume(struct usb_mixer_elem_list *list)
author maintainer
#61 lore raw

PATCH 58/699 ALSA: usb-audio: Update Babyface Pro control caches only after successful writes

In reply to Greg Kroah-Hartman

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

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

From: Cássio Gabriel <[email protected]>

commit d8f802ccf1fdbeb89d62748d6a0d0fbd442c8127 upstream.

snd_bbfpro_ctl_put() and snd_bbfpro_vol_put() cache the requested packed control state in kcontrol->private_value before issuing the USB write.

Their get and resume paths use that cached value directly, so a failed write can leave the driver reporting and later replaying a setting the hardware never accepted.

Update the cached state only after a successful USB write.

---
 sound/usb/mixer_quirks.c |   16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)
sound/usb/mixer_quirks.c +10 -6
@@ -2791,12 +2791,14 @@ static int snd_bbfpro_ctl_put(struct snd
 	if (val == old_value)
 		return 0;
 
+	err = snd_bbfpro_ctl_update(mixer, reg, idx, val);
+	if (err < 0)
+		return err;
+
 	kcontrol->private_value = reg
 		| ((idx & SND_BBFPRO_CTL_IDX_MASK) << SND_BBFPRO_CTL_IDX_SHIFT)
 		| ((val & SND_BBFPRO_CTL_VAL_MASK) << SND_BBFPRO_CTL_VAL_SHIFT);
-
-	err = snd_bbfpro_ctl_update(mixer, reg, idx, val);
-	return err < 0 ? err : 1;
+	return 1;
 }
 
 static int snd_bbfpro_ctl_resume(struct usb_mixer_elem_list *list)
@@ -2881,11 +2883,13 @@ static int snd_bbfpro_vol_put(struct snd
 
 	new_val = uvalue & SND_BBFPRO_MIXER_VAL_MASK;
 
+	err = snd_bbfpro_vol_update(mixer, idx, new_val);
+	if (err < 0)
+		return err;
+
 	kcontrol->private_value = idx
 		| (new_val << SND_BBFPRO_MIXER_VAL_SHIFT);
-
-	err = snd_bbfpro_vol_update(mixer, idx, new_val);
-	return err < 0 ? err : 1;
+	return 1;
 }
 
 static int snd_bbfpro_vol_resume(struct usb_mixer_elem_list *list)
author maintainer
#62 lore raw

PATCH 59/699 ALSA: usb-audio: Update US-16x08 EQ/comp shadow state after successful writes

In reply to Greg Kroah-Hartman

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

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

From: Cássio Gabriel <[email protected]>

commit a440c17869ecd71da0f295b62868fc742d09a8ba upstream.

snd_us16x08_comp_put() and snd_us16x08_eq_put() update their software stores before sending the USB write. If the transfer fails, later get callbacks report a value the hardware never accepted.

Build the outgoing message from the current store plus the pending value, then commit the store only after a successful write.

Fixes d2bb390a2081 ("ALSA: usb-audio: Tascam US-16x08 DSP mixer quirk")
---
 sound/usb/mixer_us16x08.c |   78 ++++++++++++++++++++++++++++++----------------
 1 file changed, 52 insertions(+), 26 deletions(-)
sound/usb/mixer_us16x08.c +52 -26
@@ -436,6 +436,7 @@ static int snd_us16x08_comp_put(struct s
 	int index = ucontrol->id.index;
 	char buf[sizeof(comp_msg)];
 	int val_idx, val;
+	int threshold, ratio, attack, release, gain, switch_on;
 	int err;
 
 	val = ucontrol->value.integer.value[0];
@@ -448,36 +449,61 @@ static int snd_us16x08_comp_put(struct s
 	/* new control value incl. bias*/
 	val_idx = elem->head.id - SND_US16X08_ID_COMP_BASE;
 
-	store->val[val_idx][index] = ucontrol->value.integer.value[0];
+	threshold = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_THRESHOLD)]
+		[index];
+	ratio = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RATIO)][index];
+	attack = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_ATTACK)][index];
+	release = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RELEASE)]
+		[index];
+	gain = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_GAIN)][index];
+	switch_on = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH)]
+		[index];
+
+	switch (val_idx) {
+	case COMP_STORE_IDX(SND_US16X08_ID_COMP_THRESHOLD):
+		threshold = val;
+		break;
+	case COMP_STORE_IDX(SND_US16X08_ID_COMP_RATIO):
+		ratio = val;
+		break;
+	case COMP_STORE_IDX(SND_US16X08_ID_COMP_ATTACK):
+		attack = val;
+		break;
+	case COMP_STORE_IDX(SND_US16X08_ID_COMP_RELEASE):
+		release = val;
+		break;
+	case COMP_STORE_IDX(SND_US16X08_ID_COMP_GAIN):
+		gain = val;
+		break;
+	case COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH):
+		switch_on = val;
+		break;
+	}
 
 	/* prepare compressor URB message from template  */
 	memcpy(buf, comp_msg, sizeof(comp_msg));
 
 	/* place comp values in message buffer watch bias! */
-	buf[8] = store->val[
-		COMP_STORE_IDX(SND_US16X08_ID_COMP_THRESHOLD)][index]
-		- SND_US16X08_COMP_THRESHOLD_BIAS;
-	buf[11] = ratio_map[store->val[
-		COMP_STORE_IDX(SND_US16X08_ID_COMP_RATIO)][index]];
-	buf[14] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_ATTACK)][index]
-		+ SND_US16X08_COMP_ATTACK_BIAS;
-	buf[17] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RELEASE)][index]
-		+ SND_US16X08_COMP_RELEASE_BIAS;
-	buf[20] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_GAIN)][index];
-	buf[26] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH)][index];
+	buf[8] = threshold - SND_US16X08_COMP_THRESHOLD_BIAS;
+	buf[11] = ratio_map[ratio];
+	buf[14] = attack + SND_US16X08_COMP_ATTACK_BIAS;
+	buf[17] = release + SND_US16X08_COMP_RELEASE_BIAS;
+	buf[20] = gain;
+	buf[26] = switch_on;
 
 	/* place channel selector in message buffer */
 	buf[5] = index + 1;
 
 	err = snd_us16x08_send_urb(chip, buf, sizeof(comp_msg));
 
-	if (err > 0) {
-		elem->cached |= 1 << index;
-		elem->cache_val[index] = val;
-	} else {
+	if (err < 0) {
 		usb_audio_dbg(chip, "Failed to set compressor, err:%d\n", err);
+		return err;
 	}
 
+	store->val[val_idx][index] = val;
+	elem->cached |= 1 << index;
+	elem->cache_val[index] = val;
 	return 1;
 }
 
@@ -579,11 +605,10 @@ static int snd_us16x08_eq_put(struct snd
 	/* copy URB buffer from EQ template */
 	memcpy(buf, eqs_msq, sizeof(eqs_msq));
 
-	store->val[b_idx][p_idx][index] = val;
-	buf[20] = store->val[b_idx][3][index];
-	buf[17] = store->val[b_idx][2][index];
-	buf[14] = store->val[b_idx][1][index];
-	buf[11] = store->val[b_idx][0][index];
+	buf[20] = p_idx == 3 ? val : store->val[b_idx][3][index];
+	buf[17] = p_idx == 2 ? val : store->val[b_idx][2][index];
+	buf[14] = p_idx == 1 ? val : store->val[b_idx][1][index];
+	buf[11] = p_idx == 0 ? val : store->val[b_idx][0][index];
 
 	/* place channel index in URB buffer */
 	buf[5] = index + 1;
@@ -593,14 +618,15 @@ static int snd_us16x08_eq_put(struct snd
 
 	err = snd_us16x08_send_urb(chip, buf, sizeof(eqs_msq));
 
-	if (err > 0) {
-		/* store new value in EQ band cache */
-		elem->cached |= 1 << index;
-		elem->cache_val[index] = val;
-	} else {
+	if (err < 0) {
 		usb_audio_dbg(chip, "Failed to set eq param, err:%d\n", err);
+		return err;
 	}
 
+	store->val[b_idx][p_idx][index] = val;
+	/* store new value in EQ band cache */
+	elem->cached |= 1 << index;
+	elem->cache_val[index] = val;
 	return 1;
 }
 
author maintainer
#63 lore raw

PATCH 60/699 Bluetooth: btusb: fix use-after-free on registration failure

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

commit eedc6867ebad73edbfaf9a0a65fbef7115cc4753 upstream.

Make sure to release the sibling interfaces in case controller registration fails to avoid use-after-free and double-free when they are eventually disconnected.

This issue was reported by Sashiko while reviewing a fix for a wakeup source leak in the btusb probe errors paths.

Fixes 9bfa35fe422c ("[Bluetooth] Add SCO support to btusb driver")
Fixes 9d08f50401ac ("Bluetooth: btusb: Add support for Broadcom LM_DIAG interface")
Cc [email protected] # 2.6.27
---
 drivers/bluetooth/btusb.c |   11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)
drivers/bluetooth/btusb.c +10 -1
@@ -4369,12 +4369,21 @@ static int btusb_probe(struct usb_interf
 
 	err = hci_register_dev(hdev);
 	if (err < 0)
-		goto out_free_dev;
+		goto err_release_siblings;
 
 	usb_set_intfdata(intf, data);
 
 	return 0;
 
+err_release_siblings:
+	if (data->diag) {
+		usb_set_intfdata(data->diag, NULL);
+		usb_driver_release_interface(&btusb_driver, data->diag);
+	}
+	if (data->isoc) {
+		usb_set_intfdata(data->isoc, NULL);
+		usb_driver_release_interface(&btusb_driver, data->isoc);
+	}
 out_free_dev:
 	if (data->reset_gpio)
 		gpiod_put(data->reset_gpio);
author maintainer
#64 lore raw

PATCH 61/699 binder: fix UAF in binder_thread_release()

In reply to Greg Kroah-Hartman

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

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

From: Carlos Llamas <[email protected]>

commit 114a116aaa5f0295376cdf12da743c5bce3b20ce upstream.

When a thread exits, binder_thread_release() walks its transaction stack to clear the t->from and t->to_proc that correspond with the exiting thread. However, a process dying in parallel might attempt to kfree some of these transactions. And if one of them has no associated t->to_proc, the t->to_proc->inner_lock will not be acquired.

This means that transaction accesses in binder_thread_release() after t->to_proc has been cleared might race with binder_free_transaction() and cause a use-after-free error as reported by KASAN:

==================================================================

  BUG: KASAN: slab-use-after-free in binder_thread_release+0x5d0/0x798
  Write of size 8 at addr ffff000016627500 by task X/715

  CPU: 17 UID: 0 PID: 715 Comm: X Not tainted 7.1.0-rc5-00149-g8fde5d1d47f6 #30 PREEMPT
  Hardware name: linux,dummy-virt (DT)
  Call trace:
   binder_thread_release+0x5d0/0x798
   binder_ioctl+0x12c0/0x299c
   [...]

  Allocated by task 717 on cpu 18 at 67.267803s:
   __kasan_kmalloc+0xa0/0xbc
   __kmalloc_cache_noprof+0x174/0x444
   binder_transaction+0x554/0x8150
   binder_thread_write+0xa30/0x4354
   binder_ioctl+0x20f0/0x299c
   [...]

  Freed by task 202 on cpu 18 at 90.416221s:
   __kasan_slab_free+0x58/0x80
   kfree+0x1a0/0x4a4
   binder_free_transaction+0x150/0x294
   binder_send_failed_reply+0x398/0x6d8
   binder_release_work+0x3e4/0x4ec
   binder_deferred_func+0xbd8/0x104c
   [...]
  ==================================================================

In order to avoid this, make sure that binder_free_transaction() reads the t->to_proc under the transaction lock. This will serialize the transaction release with the accesses in binder_thread_release(). Plus, it matches the documented locking rules for @to_proc.

Cc stable <[email protected]>
Fixes 7a4408c6bd3e ("binder: make sure accesses to proc/thread are safe")
---
 drivers/android/binder.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/android/binder.c +5 -1
@@ -1909,7 +1909,11 @@ static void binder_free_txn_fixups(struc
 
 static void binder_free_transaction(struct binder_transaction *t)
 {
-	struct binder_proc *target_proc = t->to_proc;
+	struct binder_proc *target_proc;
+
+	spin_lock(&t->lock);
+	target_proc = t->to_proc;
+	spin_unlock(&t->lock);
 
 	if (target_proc) {
 		binder_inner_proc_lock(target_proc);
author maintainer
#65 lore raw

PATCH 62/699 usb: xhci: Fix sleep in atomic context in xhci_free_streams()

In reply to Greg Kroah-Hartman

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

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

From: 胡连勤 <[email protected]>

commit 42c37c4b75d38b51d84f31a8e29427f5e06a7c2a upstream.

When a USB device with active stream endpoints is disconnected, xhci_free_streams() is called from the hub_event workqueue to free the stream resources. It calls xhci_free_stream_info() while holding xhci->lock with irqs disabled.

xhci_free_stream_info() invokes xhci_free_stream_ctx(), which calls dma_free_coherent() for large stream context arrays.

dma_free_coherent() can sleep (e.g. via vunmap), triggering a BUG when called from atomic context.

Call trace:
 dma_free_attrs+0x174/0x220
 xhci_free_stream_info+0xd0/0x11c
 xhci_free_streams+0x278/0x37c
 usb_free_streams+0x98/0xc0
 usb_unbind_interface+0x1b8/0x2f8
 device_release_driver_internal+0x1d4/0x2cc
 device_release_driver+0x18/0x28
 bus_remove_device+0x160/0x1a4
 device_del+0x1ec/0x350
 usb_disable_device+0x98/0x214
 usb_disconnect+0xf0/0x35c
 hub_event+0xab4/0x19ec
 process_one_work+0x278/0x63c

Fix this by saving the stream_info pointers and clearing the ep references under the lock, then calling xhci_free_stream_info() outside the lock where sleeping is allowed.

Fixes 8df75f42f8e6 ("USB: xhci: Add memory allocation for USB3 bulk streams.")
Cc stable <[email protected]>
---
 drivers/usb/host/xhci.c |   11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)
drivers/usb/host/xhci.c +10 -1
@@ -3636,6 +3636,7 @@ static int xhci_free_streams(struct usb_
 	struct xhci_virt_device *vdev;
 	struct xhci_command *command;
 	struct xhci_input_control_ctx *ctrl_ctx;
+	struct xhci_stream_info *stream_info[EP_CTX_PER_DEV];
 	unsigned int ep_index;
 	unsigned long flags;
 	u32 changed_ep_bitmask;
@@ -3696,10 +3697,15 @@ static int xhci_free_streams(struct usb_
 	if (ret < 0)
 		return ret;
 
+	/*
+	 * dma_free_coherent() called by xhci_free_stream_info() may sleep,
+	 * so save stream_info pointers and clear references under lock,
+	 * then free the memory outside lock.
+	 */
 	spin_lock_irqsave(&xhci->lock, flags);
 	for (i = 0; i < num_eps; i++) {
 		ep_index = xhci_get_endpoint_index(&eps[i]->desc);
-		xhci_free_stream_info(xhci, vdev->eps[ep_index].stream_info);
+		stream_info[i] = vdev->eps[ep_index].stream_info;
 		vdev->eps[ep_index].stream_info = NULL;
 		/* FIXME Unset maxPstreams in endpoint context and
 		 * update deq ptr to point to normal string ring.
@@ -3709,6 +3715,9 @@ static int xhci_free_streams(struct usb_
 	}
 	spin_unlock_irqrestore(&xhci->lock, flags);
 
+	for (i = 0; i < num_eps; i++)
+		xhci_free_stream_info(xhci, stream_info[i]);
+
 	return 0;
 }
 
author maintainer
#66 lore raw

PATCH 63/699 PCI: altera: Do not dispose parent IRQ mapping

In reply to Greg Kroah-Hartman

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

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

From: Mahesh Vaidya <[email protected]>

commit 5ef4bac02189bee0b7c170e352d7a38e13fe9678 upstream.

altera_pcie_irq_teardown() calls irq_dispose_mapping() on pcie->irq. However, pcie->irq is the parent IRQ returned by platform_get_irq(), not the mapping created by Altera INTx irq_domain.

The Altera driver only sets the chained handler on the parent IRQ. It should detach that handler during teardown, but it should not dispose the parent IRQ mapping, which belongs to the parent interrupt controller's irq_domain.

Drop irq_dispose_mapping(pcie->irq) from the teardown path.

Note that during irqchip remove(), the child IRQs should've disposed. But since the chained handler itself is removed, there is no way the stale child IRQs (if exists) could fire. So it is safe here.

Fixes ec15c4d0d5d2 ("PCI: altera: Allow building as module")
[mani: added a note about IRQ disposal]
---
 drivers/pci/controller/pcie-altera.c |    1 -
 1 file changed, 1 deletion(-)
drivers/pci/controller/pcie-altera.c +0 -1
@@ -689,7 +689,6 @@ static void altera_pcie_irq_teardown(str
 {
 	irq_set_chained_handler_and_data(pcie->irq, NULL, NULL);
 	irq_domain_remove(pcie->irq_domain);
-	irq_dispose_mapping(pcie->irq);
 }
 
 static int altera_pcie_parse_dt(struct altera_pcie *pcie)
author maintainer
#67 lore raw

PATCH 64/699 PCI: host-common: Request bus reassignment when not probe-only

In reply to Greg Kroah-Hartman

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

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

From: Ratheesh Kannoth <[email protected]>

commit fda8749ba73638f5bbca3ffb39bc6861eb3b23fa upstream.

pci_host_common_init() is used by several generic ECAM host drivers. After PCI core changes around pci_flags and preserve_config, these hosts no longer opted into full bus number reassignment the way they did before, which broke enumeration of devices on a Marvell CN106XX board.

When PCI_PROBE_ONLY is not set, add PCI_REASSIGN_ALL_BUS so pci_scan_bridge_extend() takes the reassignment path: bus numbers can be assigned from firmware EA data (e.g. pci_ea_fixed_busnrs()). Skip the flag in probe-only mode so existing assignments are not overridden.

Fixes 7246a4520b4b ("PCI: Use preserve_config in place of pci_flags")
[mani: added stable tag]
[bhelgaas: add problem report link]
Cc Vidya Sagar <[email protected]>
---
 drivers/pci/controller/pci-host-common.c |    4 ++++
 1 file changed, 4 insertions(+)
drivers/pci/controller/pci-host-common.c +4 -0
@@ -75,6 +75,10 @@ int pci_host_common_probe(struct platfor
 	if (!pci_has_flag(PCI_PROBE_ONLY))
 		pci_add_flags(PCI_REASSIGN_ALL_BUS);
 
+	/* Do not reassign bus numbers if probe only */
+	if (!pci_has_flag(PCI_PROBE_ONLY))
+		pci_add_flags(PCI_REASSIGN_ALL_BUS);
+
 	bridge->sysdata = cfg;
 	bridge->ops = (struct pci_ops *)&ops->pci_ops;
 
author maintainer
#68 lore raw

PATCH 65/699 netfilter: ipset: fix race between dump and ip_set_list resize

In reply to Greg Kroah-Hartman

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

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

From: Xiang Mei <[email protected]>

commit 7cd9103283b26b917360ec99d7d2f2d761bcf1ab upstream.

The release path of ip_set_dump_do() and ip_set_dump_done() read inst->ip_set_list via ip_set_ref_netlink(), a plain rcu_dereference_raw() of the array pointer. These run from netlink_recvmsg() without the nfnl mutex and without an RCU read-side critical section.

A concurrent ip_set_create() can grow the array: it publishes the new array, calls synchronize_net() and then kvfree()s the old one. Since the dump paths read the array outside any RCU reader, synchronize_net() does not wait for them and the old array can be freed while they still index into it, causing a use-after-free.

The dumped set itself stays pinned via set->ref_netlink, so only the array load needs protecting. Take rcu_read_lock() around it, matching ip_set_get_byname() and __ip_set_put_byindex().

  BUG: KASAN: slab-use-after-free in ip_set_dump_do (net/netfilter/ipset/ip_set_core.c:1697)
  Read of size 8 at addr ffff88800b5c4018 by task exploit/150
  Call Trace:
   ...
   kasan_report (mm/kasan/report.c:595)
   ip_set_dump_do (net/netfilter/ipset/ip_set_core.c:1697)
   netlink_dump (net/netlink/af_netlink.c:2325)
   netlink_recvmsg (net/netlink/af_netlink.c:1976)
   sock_recvmsg (net/socket.c:1159)
   __sys_recvfrom (net/socket.c:2315)
   ...
  Oops: general protection fault, probably for non-canonical address ... KASAN NOPTI
  KASAN: maybe wild-memory-access in range [0x02d6...d0-0x02d6...d7]
  RIP: 0010:ip_set_dump_do (net/netfilter/ipset/ip_set_core.c:1698)
  Kernel panic - not syncing: Fatal exception
Fixes 8a02bdd50b2e ("netfilter: ipset: Fix calling ip_set() macro at dumping")
Assisted-by Claude:claude-opus-4-8
---
 net/netfilter/ipset/ip_set_core.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
net/netfilter/ipset/ip_set_core.c +7 -1
@@ -1490,7 +1490,11 @@ ip_set_dump_done(struct netlink_callback
 		struct ip_set_net *inst =
 			(struct ip_set_net *)cb->args[IPSET_CB_NET];
 		ip_set_id_t index = (ip_set_id_t)cb->args[IPSET_CB_INDEX];
-		struct ip_set *set = ip_set_ref_netlink(inst, index);
+		struct ip_set *set;
+
+		rcu_read_lock();
+		set = ip_set_ref_netlink(inst, index);
+		rcu_read_unlock();
 
 		if (set->variant->uref)
 			set->variant->uref(set, cb, false);
@@ -1695,7 +1699,9 @@ next_set:
 release_refcount:
 	/* If there was an error or set is done, release set */
 	if (ret || !cb->args[IPSET_CB_ARG0]) {
+		rcu_read_lock();
 		set = ip_set_ref_netlink(inst, index);
+		rcu_read_unlock();
 		if (set->variant->uref)
 			set->variant->uref(set, cb, false);
 		pr_debug("release set %s\n", set->name);
author maintainer
#69 lore raw

PATCH 66/699 virtio-mmio: fix device release warning on module unload

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

commit c687bc35694698ec4c7f92bf929c3d659f0cecb8 upstream.

Driver core expects devices to be allocated dynamically and complains loudly when a device that lacks a release function is freed.

Use __root_device_register() to allocate and register the root device instead of open coding using a static device.

Note that root_device_register(), which also creates a link to the module, cannot be used as the device is registered when parsing the module parameters which happens before the module kobject has been set up.

Fixes 81a054ce0b46 ("virtio-mmio: Devices parameter parsing")
Cc Pawel Moll <[email protected]>

Message-ID: <[email protected]>

---
 drivers/virtio/virtio_mmio.c |   26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)
drivers/virtio/virtio_mmio.c +13 -13
@@ -675,9 +675,7 @@ static int virtio_mmio_remove(struct pla
 
 #if defined(CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES)
 
-static struct device vm_cmdline_parent = {
-	.init_name = "virtio-mmio-cmdline",
-};
+static struct device *vm_cmdline_parent;
 
 static int vm_cmdline_parent_registered;
 static int vm_cmdline_id;
@@ -685,7 +683,6 @@ static int vm_cmdline_id;
 static int vm_cmdline_set(const char *device,
 		const struct kernel_param *kp)
 {
-	int err;
 	struct resource resources[2] = {};
 	char *str;
 	long long int base, size;
@@ -717,11 +714,10 @@ static int vm_cmdline_set(const char *de
 	resources[1].start = resources[1].end = irq;
 
 	if (!vm_cmdline_parent_registered) {
-		err = device_register(&vm_cmdline_parent);
-		if (err) {
-			put_device(&vm_cmdline_parent);
+		vm_cmdline_parent = __root_device_register("virtio-mmio-cmdline", NULL);
+		if (IS_ERR(vm_cmdline_parent)) {
 			pr_err("Failed to register parent device!\n");
-			return err;
+			return PTR_ERR(vm_cmdline_parent);
 		}
 		vm_cmdline_parent_registered = 1;
 	}
@@ -732,7 +728,7 @@ static int vm_cmdline_set(const char *de
 		       (unsigned long long)resources[0].end,
 		       (int)resources[1].start);
 
-	pdev = platform_device_register_resndata(&vm_cmdline_parent,
+	pdev = platform_device_register_resndata(vm_cmdline_parent,
 			"virtio-mmio", vm_cmdline_id++,
 			resources, ARRAY_SIZE(resources), NULL, 0);
 
@@ -756,8 +752,12 @@ static int vm_cmdline_get_device(struct
 static int vm_cmdline_get(char *buffer, const struct kernel_param *kp)
 {
 	buffer[0] = '\0';
-	device_for_each_child(&vm_cmdline_parent, buffer,
-			vm_cmdline_get_device);
+
+	if (vm_cmdline_parent_registered) {
+		device_for_each_child(vm_cmdline_parent, buffer,
+				vm_cmdline_get_device);
+	}
+
 	return strlen(buffer) + 1;
 }
 
@@ -779,9 +779,9 @@ static int vm_unregister_cmdline_device(
 static void vm_unregister_cmdline_devices(void)
 {
 	if (vm_cmdline_parent_registered) {
-		device_for_each_child(&vm_cmdline_parent, NULL,
+		device_for_each_child(vm_cmdline_parent, NULL,
 				vm_unregister_cmdline_device);
-		device_unregister(&vm_cmdline_parent);
+		root_device_unregister(vm_cmdline_parent);
 		vm_cmdline_parent_registered = 0;
 	}
 }
author maintainer
#70 lore raw

PATCH 67/699 hwrng: virtio: clamp device-reported used.len at copy_data()

In reply to Greg Kroah-Hartman

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

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

From: Michael Bommarito <[email protected]>

commit e3046eeada299f917a8ad883af4434bfb86556b1 upstream.

random_recv_done() stores the device-reported used.len directly into vi->data_avail. copy_data() then indexes vi->data[] using vi->data_idx (advanced by previous copy_data() calls) and issues a memcpy() without re-validating either value against the posted buffer size sizeof(vi->data) (SMP_CACHE_BYTES bytes, typically 32 or 64).

A malicious or buggy virtio-rng backend can set used.len beyond sizeof(vi->data), steering the memcpy() past the end of the inline array into adjacent kmalloc-1k slab bytes. hwrng_fillfn() mixes those bytes into the guest RNG, and guest root can also observe them directly via /dev/hwrng.

Concrete impact is inside the guest:

- Memory-safety / hardening: any virtio-rng backend that over-reports used.len causes the driver to read past vi->data into unrelated slab contents. hwrng_fillfn() is a kernel thread that runs as soon as the device is probed; no guest userspace interaction is required to first-trigger the OOB.

- Cross-boundary leak (confidential-compute threat model): a malicious hypervisor cooperating with a malicious or compromised guest root userspace can use /dev/hwrng as a leak channel for guest-kernel heap data. The host sets a large used.len, guest root reads /dev/hwrng, and the returned bytes contain guest kernel slab contents that were adjacent to vi->data. In practice, confidential-compute guests (SEV-SNP, TDX) usually disable virtio-rng entirely, so this path is narrow, but the fix is still worth carrying because the underlying memory-safety bug contaminates the guest RNG on any host.

KASAN confirms the OOB on a 7.1-rc4 guest whose virtio-rng backend has been patched to report used.len = 0x10000:

  BUG: KASAN: slab-out-of-bounds in virtio_read+0x394/0x5d0
  Read of size 64 at addr ffff88800ae0ba20 by task hwrng/52
  Call Trace:
   __asan_memcpy+0x23/0x60
   virtio_read+0x394/0x5d0
   hwrng_fillfn+0xb2/0x470
   kthread+0x2cc/0x3a0
  Allocated by task 1:
   probe_common+0xa5/0x660
   virtio_dev_probe+0x549/0xbc0
  The buggy address belongs to the object at ffff88800ae0b800
   which belongs to the cache kmalloc-1k of size 1024
  The buggy address is located 0 bytes to the right of
   allocated 544-byte region [ffff88800ae0b800, ffff88800ae0ba20)

Same class of bug as commit c04db81cd028 ("net/9p: Fix buffer overflow in USB transport layer"), which hardened usb9pfs_rx_complete() against unchecked device-reported length in the USB 9p transport.

With the clamp at point of use and array_index_nospec() in place, the same harness boots cleanly: copy_data() returns zero for the bogus report, the device-supplied bytes after data_idx are discarded, and the driver issues a fresh request.

Fixes f7f510ec1957 ("virtio: An entropy device, as suggested by hpa.")
Assisted-by Claude:claude-opus-4-8

Message-ID: <[email protected]>

---
 drivers/char/hw_random/virtio-rng.c |   23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)
drivers/char/hw_random/virtio-rng.c +21 -2
@@ -7,6 +7,7 @@
 #include <asm/barrier.h>
 #include <linux/err.h>
 #include <linux/hw_random.h>
+#include <linux/nospec.h>
 #include <linux/scatterlist.h>
 #include <linux/spinlock.h>
 #include <linux/virtio.h>
@@ -66,8 +67,26 @@ static void request_entropy(struct virtr
 static unsigned int copy_data(struct virtrng_info *vi, void *buf,
 			      unsigned int size)
 {
-	size = min_t(unsigned int, size, vi->data_avail);
-	memcpy(buf, vi->data + vi->data_idx, size);
+	unsigned int idx, avail;
+
+	/*
+	 * vi->data_avail was set from the device-reported used.len and
+	 * vi->data_idx was advanced by previous copy_data() calls.  A
+	 * malicious or buggy virtio-rng backend can drive either past
+	 * sizeof(vi->data).  Clamp at point of use and harden the index
+	 * with array_index_nospec() so the memcpy() below cannot be
+	 * steered into adjacent slab memory, including under
+	 * speculation.
+	 */
+	avail = min_t(unsigned int, vi->data_avail, sizeof(vi->data));
+	if (vi->data_idx >= avail) {
+		vi->data_avail = 0;
+		request_entropy(vi);
+		return 0;
+	}
+	size = min_t(unsigned int, size, avail - vi->data_idx);
+	idx = array_index_nospec(vi->data_idx, sizeof(vi->data));
+	memcpy(buf, vi->data + idx, size);
 	vi->data_idx += size;
 	vi->data_avail -= size;
 	if (vi->data_avail == 0)
author maintainer
#71 lore raw

PATCH 68/699 USB: chaoskey: Fix slab-use-after-free in chaoskey_release()

In reply to Greg Kroah-Hartman

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

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

From: Alan Stern <[email protected]>

commit abf76d3239dee97b66e7241ad04811f1ce562e28 upstream.

The chaoskey driver has a use-after-free bug in its release routine. If the user closes the device file after the USB device has been unplugged, a debugging log statement will try to access the usb_interface structure after it has been deallocated:

	BUG: KASAN: slab-use-after-free in dev_driver_string (drivers/base/core.c:2406)
	Read of size 8 at addr ffff888168e8a0b8 by task chaoskey_raw_re/10106

	Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
	Call Trace:
	 <TASK>
	 dump_stack_lvl (lib/dump_stack.c:94 lib/dump_stack.c:120)
	 print_report (mm/kasan/report.c:378 mm/kasan/report.c:482)
	 kasan_report (mm/kasan/report.c:595)
	 dev_driver_string (drivers/base/core.c:2406)
	 __dynamic_dev_dbg (lib/dynamic_debug.c:906)
	 chaoskey_release (drivers/usb/misc/chaoskey.c:323)
	 __fput (fs/file_table.c:510)
	 fput_close_sync (fs/file_table.c:615)
	 __x64_sys_close (fs/open.c:1507 fs/open.c:1492 fs/open.c:1492)
	 do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94)
	 entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)

The driver's last reference to the interface structure is dropped in the chaoskey_free() routine, so the code must not use the interface -- even in a debugging statement -- after that routine returns. (Exception: If we know that another reference is held by someone else, such as the device core while the disconnect routine runs, there's no problem. Thanks to Johan Hovold for pointing this out.)

Since the bad access is part of an unimportant debugging statement, we can fix the problem simply by removing the whole statement.

---
 drivers/usb/misc/chaoskey.c |    1 -
 1 file changed, 1 deletion(-)
drivers/usb/misc/chaoskey.c +0 -1
@@ -321,7 +321,6 @@ bail:
 	mutex_unlock(&dev->lock);
 destruction:
 	mutex_unlock(&chaoskey_list_lock);
-	usb_dbg(interface, "release success");
 	return rv;
 }
 
author maintainer
#72 lore raw

PATCH 69/699 6lowpan: fix NHC entry use-after-free on error path

In reply to Greg Kroah-Hartman

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

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

From: Yizhou Zhao <[email protected]>

commit 1720db928e5a58ca7d75ac1d514c3b73fd7061a7 upstream.

lowpan_nhc_do_uncompression() looks up an NHC descriptor while holding lowpan_nhc_lock. If the descriptor has no uncompress callback, the error path drops the lock before printing nhc->name.

lowpan_nhc_del() removes descriptors under the same lock and then relies on synchronize_net() before the owning module can be unloaded. That only waits for net RX RCU readers. lowpan_header_decompress() is also exported and can be reached from callers that are not necessarily covered by the net core RX critical section, for example the Bluetooth 6LoWPAN L2CAP receive path.

This leaves a race where one task drops lowpan_nhc_lock in the error path, another task unregisters and frees the matching descriptor after synchronize_net() returns, and the first task then dereferences nhc->name for the warning.

With the post-unlock window widened, KASAN reports:

  BUG: KASAN: slab-use-after-free in lowpan_nhc_do_uncompression+0x1f4/0x220
  Read of size 8
  lowpan_nhc_do_uncompression
  lowpan_header_decompress

Fix this by printing the warning before dropping lowpan_nhc_lock, so the descriptor name is read while unregister is still excluded. The malformed packet is still rejected with -ENOTSUPP.

---
 net/6lowpan/nhc.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/6lowpan/nhc.c +1 -1
@@ -168,9 +168,9 @@ int lowpan_nhc_do_uncompression(struct s
 				return ret;
 			}
 		} else {
-			spin_unlock_bh(&lowpan_nhc_lock);
 			netdev_warn(dev, "received nhc id for %s which is not implemented.\n",
 				    nhc->name);
+			spin_unlock_bh(&lowpan_nhc_lock);
 			return -ENOTSUPP;
 		}
 	} else {
author maintainer
#73 lore raw

PATCH 70/699 tipc: fix out-of-bounds read in broadcast Gap ACK blocks

In reply to Greg Kroah-Hartman

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

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

From: Samuel Page <[email protected]>

commit 2b66974a1b6134a4bbc3bfed181f7418f688eb54 upstream.

A broadcast PROTOCOL/STATE_MSG can carry a Gap ACK blocks record in its data area. tipc_get_gap_ack_blks() only verifies that the record's len field is self-consistent with its ugack_cnt/bgack_cnt counts (sz == struct_size(p, gacks, ugack_cnt + bgack_cnt)); it does not check that the record actually fits in the message data area, msg_data_sz().

The unicast caller tipc_link_proto_rcv() bounds it ("if (glen > dlen) break;"), but the broadcast caller tipc_bcast_sync_rcv() discards the returned size, so tipc_link_advance_transmq() copies the record off the receive skb with an attacker-controlled count:

	this_ga = kmemdup(ga, struct_size(ga, gacks, ga->bgack_cnt),
			  GFP_ATOMIC);

A TIPC neighbour that negotiated TIPC_GAP_ACK_BLOCK triggers it with one ordinary broadcast STATE_MSG (msg_bc_ack_invalid() clear), sized so its data area is short, carrying a Gap ACK record with len = 0x400, bgack_cnt = 0xff and ugack_cnt = 0. len then equals struct_size(p, gacks, 255), so the consistency check passes and ga is non-NULL; kmemdup() reads struct_size(ga, gacks, 255) = 1024 bytes out of the much smaller skb:

  BUG: KASAN: slab-out-of-bounds in kmemdup_noprof+0x48/0x60
  Read of size 1024 at addr ffff0000c7030d38 by task poc864/69
  Call trace:
   kmemdup_noprof+0x48/0x60
   tipc_link_advance_transmq+0x86c/0xb80
   tipc_link_bc_ack_rcv+0x19c/0x1e0
   tipc_bcast_sync_rcv+0x1c4/0x2c4
   tipc_rcv+0x85c/0x1340
   tipc_l2_rcv_msg+0xac/0x104
  The buggy address belongs to the object at ffff0000c7030d00
   which belongs to the cache skbuff_small_head of size 704
  The buggy address is located 56 bytes inside of
   allocated 704-byte region [ffff0000c7030d00, ffff0000c7030fc0)

The copied-out bytes are subsequently consumed as gap/ack values, but the read is already out of bounds at the kmemdup() regardless of how they are used.

The unicast STATE path drops such a message: "if (glen > dlen) break;" skips the rest of STATE_MSG handling and the skb is freed. Make the broadcast path drop it too. tipc_bcast_sync_rcv() now bounds the record against msg_data_sz() and, when it does not fit, reports it back through tipc_node_bc_sync_rcv() to tipc_rcv() so the skb is discarded rather than processed. ga is not cleared on this path: ga == NULL already means "legacy peer without Selective ACK", a distinct legitimate state.

---
 net/tipc/bcast.c |   22 ++++++++++++++--------
 net/tipc/bcast.h |    2 +-
 net/tipc/node.c  |   15 ++++++++++++---
 3 files changed, 27 insertions(+), 12 deletions(-)
net/tipc/bcast.c +14 -8
@@ -497,12 +497,13 @@ void tipc_bcast_ack_rcv(struct net *net,
  */
 int tipc_bcast_sync_rcv(struct net *net, struct tipc_link *l,
 			struct tipc_msg *hdr,
-			struct sk_buff_head *retrq)
+			struct sk_buff_head *retrq, bool *valid)
 {
 	struct sk_buff_head *inputq = &tipc_bc_base(net)->inputq;
 	struct tipc_gap_ack_blks *ga;
 	struct sk_buff_head xmitq;
 	int rc = 0;
+	u16 glen;
 
 	__skb_queue_head_init(&xmitq);
 
@@ -510,13 +511,18 @@ int tipc_bcast_sync_rcv(struct net *net,
 	if (msg_type(hdr) != STATE_MSG) {
 		tipc_link_bc_init_rcv(l, hdr);
 	} else if (!msg_bc_ack_invalid(hdr)) {
-		tipc_get_gap_ack_blks(&ga, l, hdr, false);
-		if (!sysctl_tipc_bc_retruni)
-			retrq = &xmitq;
-		rc = tipc_link_bc_ack_rcv(l, msg_bcast_ack(hdr),
-					  msg_bc_gap(hdr), ga, &xmitq,
-					  retrq);
-		rc |= tipc_link_bc_sync_rcv(l, hdr, &xmitq);
+		glen = tipc_get_gap_ack_blks(&ga, l, hdr, false);
+		if (glen > msg_data_sz(hdr)) {
+			/* Malformed Gap ACK blocks; caller drops the msg */
+			*valid = false;
+		} else {
+			if (!sysctl_tipc_bc_retruni)
+				retrq = &xmitq;
+			rc = tipc_link_bc_ack_rcv(l, msg_bcast_ack(hdr),
+						  msg_bc_gap(hdr), ga, &xmitq,
+						  retrq);
+			rc |= tipc_link_bc_sync_rcv(l, hdr, &xmitq);
+		}
 	}
 	tipc_bcast_unlock(net);
 
net/tipc/bcast.h +1 -1
@@ -97,7 +97,7 @@ void tipc_bcast_ack_rcv(struct net *net,
 			struct tipc_msg *hdr);
 int tipc_bcast_sync_rcv(struct net *net, struct tipc_link *l,
 			struct tipc_msg *hdr,
-			struct sk_buff_head *retrq);
+			struct sk_buff_head *retrq, bool *valid);
 int tipc_nl_add_bc_link(struct net *net, struct tipc_nl_msg *msg,
 			struct tipc_link *bcl);
 int tipc_nl_bc_link_set(struct net *net, struct nlattr *attrs[]);
net/tipc/node.c +12 -3
@@ -1804,12 +1804,15 @@ static void tipc_node_mcast_rcv(struct t
 }
 
 static void tipc_node_bc_sync_rcv(struct tipc_node *n, struct tipc_msg *hdr,
-				  int bearer_id, struct sk_buff_head *xmitq)
+				  int bearer_id, struct sk_buff_head *xmitq,
+				  bool *valid)
 {
 	struct tipc_link *ucl;
 	int rc;
 
-	rc = tipc_bcast_sync_rcv(n->net, n->bc_entry.link, hdr, xmitq);
+	rc = tipc_bcast_sync_rcv(n->net, n->bc_entry.link, hdr, xmitq, valid);
+	if (!*valid)
+		return;
 
 	if (rc & TIPC_LINK_DOWN_EVT) {
 		tipc_node_reset_links(n);
@@ -2111,12 +2114,18 @@ rcv:
 
 	/* Ensure broadcast reception is in synch with peer's send state */
 	if (unlikely(usr == LINK_PROTOCOL)) {
+		bool valid = true;
+
 		if (unlikely(skb_linearize(skb))) {
 			tipc_node_put(n);
 			goto discard;
 		}
 		hdr = buf_msg(skb);
-		tipc_node_bc_sync_rcv(n, hdr, bearer_id, &xmitq);
+		tipc_node_bc_sync_rcv(n, hdr, bearer_id, &xmitq, &valid);
+		if (!valid) {
+			tipc_node_put(n);
+			goto discard;
+		}
 	} else if (unlikely(tipc_link_acked(n->bc_entry.link) != bc_ack)) {
 		tipc_bcast_ack_rcv(net, n->bc_entry.link, hdr);
 	}
author maintainer
#74 lore raw

PATCH 71/699 media: staging: ipu3-imgu: Add range check for imgu_css_cfg_acc_stripe

In reply to Greg Kroah-Hartman

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

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

From: Ricardo Ribalda <[email protected]>

commit c32fe4c4918c9aa49f61359e3b42619c4d8686de upstream.

If the driver's stripe information is invalid it can result in an integer underflow. Add a range check to avoid this kind of error.

This patch fixes the following smatch error:
drivers/staging/media/ipu3/ipu3-css-params.c:1792 imgu_css_cfg_acc_stripe() warn: 'acc->stripe.bds_out_stripes[0]->width - 2 * f' 4294967168 can't fit into 65535 'acc->stripe.bds_out_stripes[1]->offset'

Fixes e11110a5b744 ("media: staging/intel-ipu3: css: Compute and program ccs")
---
 drivers/staging/media/ipu3/ipu3-css-params.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/staging/media/ipu3/ipu3-css-params.c +6 -2
@@ -1773,6 +1773,8 @@ static int imgu_css_cfg_acc_stripe(struc
 		acc->stripe.bds_out_stripes[0].width =
 			ALIGN(css_pipe->rect[IPU3_CSS_RECT_BDS].width, f);
 	} else {
+		u32 offset;
+
 		/* Image processing is divided into two stripes */
 		acc->stripe.bds_out_stripes[0].width =
 			acc->stripe.bds_out_stripes[1].width =
@@ -1791,8 +1793,10 @@ static int imgu_css_cfg_acc_stripe(struc
 			acc->stripe.bds_out_stripes[1].width += f;
 		}
 		/* Overlap between stripes is IPU3_UAPI_ISP_VEC_ELEMS * 4 */
-		acc->stripe.bds_out_stripes[1].offset =
-			acc->stripe.bds_out_stripes[0].width - 2 * f;
+		offset = acc->stripe.bds_out_stripes[0].width - 2 * f;
+		if (offset > 65535)
+			return -EINVAL;
+		acc->stripe.bds_out_stripes[1].offset = offset;
 	}
 
 	acc->stripe.effective_stripes[0].height =
author maintainer
#75 lore raw

PATCH 72/699 crypto: amlogic - avoid double cleanup in meson_crypto_probe()

In reply to Greg Kroah-Hartman

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

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

From: Dawei Feng <[email protected]>

commit 6d827ade51a24e18d81afb9f32756d339520a14c upstream.

When meson_allocate_chanlist() fails after a partial allocation, it already unwinds the allocated chanlist state through its local error path. meson_crypto_probe() then jump to error_flow and calls meson_free_chanlist() again, causing the same per-flow resources to be torn down twice. In the reproduced failure path, the second teardown re-entered crypto_engine_exit() on an already destroyed worker and KASAN reported a slab-use-after-free in kthread_destroy_worker().

Prevent double-free by handling partial allocation failures locally within meson_allocate_chanlist() and skipping the outer cleanup path.

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.

The bug was reproduced in a QEMU x86_64 guest booted with KASAN on v7.1, using the reproducer under tools/testing/meson_crypto_probe. The reproducer forces the second dma_alloc_attrs() call in the gxl-crypto probe path to return NULL, making meson_allocate_chanlist() fail after partial initialization. On the unpatched kernel this reliably triggered a slab-use-after-free. With this fix applied, the same reproducer no longer emits any KASAN report and the probe fails cleanly with -ENOMEM.

    ==================================================================
    BUG: KASAN: slab-use-after-free in kthread_destroy_worker+0xb2/0xd0
    Read of size 8 at addr ff1100010c057a68 by task insmod/265

    CPU: 1 UID: 0 PID: 265 Comm: insmod Tainted: G           O        7.1.0-rc2-00376-g810af9adc907-dirty #10 PREEMPT(lazy)
    Tainted: [O]=OOT_MODULE
    Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.15.0-1 04/01/2014
    Call Trace:
     <TASK>
     dump_stack_lvl+0x68/0xa0
     print_report+0xcb/0x5e0
     ? __virt_addr_valid+0x21d/0x3f0
     ? kthread_destroy_worker+0xb2/0xd0
     ? kthread_destroy_worker+0xb2/0xd0
     kasan_report+0xca/0x100
     ? kthread_destroy_worker+0xb2/0xd0
     kthread_destroy_worker+0xb2/0xd0
     meson_crypto_probe+0x4d0/0xc10 [amlogic_gxl_crypto]
     platform_probe+0x99/0x140
     really_probe+0x1c6/0x6a0
     ? __pfx___device_attach_driver+0x10/0x10
     __driver_probe_device+0x248/0x310
     ? acpi_driver_match_device+0xb0/0x100
     driver_probe_device+0x48/0x210
     ? __pfx___device_attach_driver+0x10/0x10
     __device_attach_driver+0x160/0x320
     bus_for_each_drv+0x104/0x190
     ? __pfx_bus_for_each_drv+0x10/0x10
     ? _raw_spin_unlock_irqrestore+0x2c/0x50
     __device_attach+0x19d/0x3b0
     ? __pfx___device_attach+0x10/0x10
     ? do_raw_spin_unlock+0x53/0x220
     device_initial_probe+0x78/0xa0
     bus_probe_device+0x5b/0x130
     device_add+0xcfd/0x1430
     ? __pfx_device_add+0x10/0x10
     ? insert_resource+0x34/0x50
     ? lock_release+0xc9/0x290
     platform_device_add+0x24e/0x590
     ? __pfx_meson_crypto_probe_repro_init+0x10/0x10 [meson_crypto_probe_repro]
     meson_crypto_probe_repro_init+0x330/0xff0 [meson_crypto_probe_repro]
     do_one_initcall+0xc0/0x450
     ? __pfx_do_one_initcall+0x10/0x10
     ? _raw_spin_unlock_irqrestore+0x2c/0x50
     ? __create_object+0x59/0x80
     ? kasan_unpoison+0x27/0x60
     do_init_module+0x27b/0x7d0
     ? __pfx_do_init_module+0x10/0x10
     ? kasan_quarantine_put+0x84/0x1d0
     ? kfree+0x32c/0x510
     ? load_module+0x561e/0x5ff0
     load_module+0x54fe/0x5ff0
     ? __pfx_load_module+0x10/0x10
     ? security_file_permission+0x20/0x40
     ? kernel_read_file+0x23d/0x6e0
     ? mmap_region+0x235/0x4a0
     ? __pfx_kernel_read_file+0x10/0x10
     ? __file_has_perm+0x2c0/0x3e0
     init_module_from_file+0x158/0x180
     ? __pfx_init_module_from_file+0x10/0x10
     ? __lock_acquire+0x45a/0x1ba0
     ? idempotent_init_module+0x315/0x610
     ? lock_release+0xc9/0x290
     ? lockdep_init_map_type+0x4b/0x220
     ? do_raw_spin_unlock+0x53/0x220
     idempotent_init_module+0x330/0x610
     ? __pfx_idempotent_init_module+0x10/0x10
     ? __pfx_cred_has_capability.isra.0+0x10/0x10
     ? ksys_mmap_pgoff+0x385/0x520
     __x64_sys_finit_module+0xbe/0x120
     do_syscall_64+0x115/0x690
     entry_SYSCALL_64_after_hwframe+0x77/0x7f
    RIP: 0033:0x7f7d6d31690d
    Code: 5b 41 5c c3 66 0f 1f 84 00 00 00 00 00 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d f3 b4 0f 00 f7 d8 >
    RSP: 002b:00007fffc027ac68 EFLAGS: 00000246 ORIG_RAX: 0000000000000139
    RAX: ffffffffffffffda RBX: 000055f7b81967c0 RCX: 00007f7d6d31690d
    RDX: 0000000000000000 RSI: 000055f79a0d6cd2 RDI: 0000000000000003
    RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000
    R10: 0000000000000003 R11: 0000000000000246 R12: 000055f79a0d6cd2
    R13: 000055f7b8196790 R14: 000055f79a0d5888 R15: 000055f7b81968e0
     </TASK>
Fixes 48fe583fe541 ("crypto: amlogic - Add crypto accelerator for amlogic GXL")
---
 drivers/crypto/amlogic/amlogic-gxl-core.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/crypto/amlogic/amlogic-gxl-core.c +1 -1
@@ -275,8 +275,8 @@ static int meson_crypto_probe(struct pla
 	return 0;
 error_alg:
 	meson_unregister_algs(mc);
-error_flow:
 	meson_free_chanlist(mc, MAXFLOW - 1);
+error_flow:
 	clk_disable_unprepare(mc->busclk);
 	return err;
 }
author maintainer
#76 lore raw

PATCH 73/699 net: af_key: initialize alg_key_len for IPComp states

In reply to Greg Kroah-Hartman

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

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

From: Zijing Yin <[email protected]>

commit d129c3177d7b1138fd5066fcc63a698b3ba415b0 upstream.

pfkey_msg2xfrm_state() handles the IPComp (SADB_X_SATYPE_IPCOMP) case by allocating x->calg and copying only the algorithm name:

	x->calg = kmalloc_obj(*x->calg);
	if (!x->calg) {
		err = -ENOMEM;
		goto out;
	}
	strcpy(x->calg->alg_name, a->name);
	x->props.calgo = sa->sadb_sa_encrypt;

Unlike the authentication (x->aalg) and encryption (x->ealg) branches of the same function, the compression branch never initializes calg->alg_key_len. IPComp carries no key and the allocation only reserves sizeof(struct xfrm_algo) (i.e. no room for a key), so the field is left containing uninitialized slab data.

calg->alg_key_len is later used as a length by xfrm_algo_clone() when an IPComp state is cloned during XFRM_MSG_MIGRATE:

	xfrm_state_migrate()
	  xfrm_state_clone_and_setup()
	    x->calg = xfrm_algo_clone(orig->calg);
	      kmemdup(orig, xfrm_alg_len(orig));

where xfrm_alg_len() returns sizeof(*alg) + (alg_key_len + 7) / 8. With a non-zero garbage alg_key_len, kmemdup() reads past the end of the 68-byte calg object. Adding an IPComp SA via PF_KEY and then migrating it triggers (net-next, KASAN, init_on_alloc=0):

  BUG: KASAN: slab-out-of-bounds in kmemdup_noprof+0x44/0x60
  Read of size 4164 at addr ff11000025a74980 by task diag2/9287
  CPU: 3 UID: 0 PID: 9287 Comm: diag2 7.1.0-rc6-g903db046d557 #1
  Call Trace:
   <TASK>
   dump_stack_lvl+0x10e/0x1f0
   print_report+0xf7/0x600
   kasan_report+0xe4/0x120
   kasan_check_range+0x105/0x1b0
   __asan_memcpy+0x23/0x60
   kmemdup_noprof+0x44/0x60
   xfrm_state_migrate+0x70a/0x1da0
   xfrm_migrate+0x753/0x18a0
   xfrm_do_migrate+0xb47/0xf10
   xfrm_user_rcv_msg+0x411/0xb50
   netlink_rcv_skb+0x158/0x420
   xfrm_netlink_rcv+0x71/0x90
   netlink_unicast+0x584/0x850
   netlink_sendmsg+0x8b0/0xdc0
   ____sys_sendmsg+0x9f7/0xb90
   ___sys_sendmsg+0x134/0x1d0
   __sys_sendmsg+0x16d/0x220
   do_syscall_64+0x116/0x7d0
   entry_SYSCALL_64_after_hwframe+0x77/0x7f
   </TASK>

  Allocated by task 9287:
   kasan_save_stack+0x33/0x60
   kasan_save_track+0x14/0x30
   __kasan_kmalloc+0xaa/0xb0
   pfkey_add+0x2652/0x2ea0
   pfkey_process+0x6d0/0x830
   pfkey_sendmsg+0x42c/0x850
   __sys_sendto+0x461/0x4b0
   __x64_sys_sendto+0xe0/0x1c0
   do_syscall_64+0x116/0x7d0
   entry_SYSCALL_64_after_hwframe+0x77/0x7f

  The buggy address belongs to the object at ff11000025a74980
   which belongs to the cache kmalloc-96 of size 96
  The buggy address is located 0 bytes inside of
   allocated 68-byte region [ff11000025a74980, ff11000025a749c4)

Depending on the uninitialized value the same field can instead request an oversized kmemdup() allocation and make the migration clone fail.

The XFRM netlink path is not affected: verify_one_alg() rejects an XFRMA_ALG_COMP attribute shorter than xfrm_alg_len(), so a calg added via XFRM_MSG_NEWSA is always self-consistent.

Initialize calg->alg_key_len to 0, matching the aalg/ealg branches.

Fixes 80c9abaabf42 ("[XFRM]: Extension for dynamic update of endpoint address(es)")
---
 net/key/af_key.c |    1 +
 1 file changed, 1 insertion(+)
net/key/af_key.c +1 -0
@@ -1206,6 +1206,7 @@ static struct xfrm_state * pfkey_msg2xfr
 				goto out;
 			}
 			strcpy(x->calg->alg_name, a->name);
+			x->calg->alg_key_len = 0;
 			x->props.calgo = sa->sadb_sa_encrypt;
 		} else {
 			int keysize = 0;
author maintainer
#77 lore raw

PATCH 74/699 audit: Fix data races of skb_queue_len() readers on audit_queue

In reply to Greg Kroah-Hartman

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

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

From: Chi Wang <[email protected]>

commit c9a71daaecb2fb1d8c704545cc0b1c920b9bf5d7 upstream.

Multiple readers access audit_queue.qlen via skb_queue_len() without holding the queue lock or using READ_ONCE(), while kauditd writes to this field via the skb_dequeue() → __skb_unlink() path with WRITE_ONCE() protected by a spinlock. This constitutes data races.

All affected skb_queue_len(&audit_queue) call sites:
- kauditd_thread() wait_event_freezable() condition
- audit_receive_msg() AUDIT_GET handler (s.backlog assignment)
- audit_receive() backlog check
- audit_log_start() backlog check and pr_warn()

KCSAN reports the following conflicting access pattern (one example):
==================================================================

BUG: KCSAN: data-race in audit_log_start / skb_dequeue

write (marked) to 0xffffffff8512ee20 of 4 bytes by task 661 on cpu 57:

 skb_dequeue+0x70/0xf0
 kauditd_send_queue+0x71/0x220
 kauditd_thread+0x1cb/0x430
 kthread+0x1c2/0x210
 ret_from_fork+0x162/0x1a0
 ret_from_fork_asm+0x1a/0x30

read to 0xffffffff8512ee20 of 4 bytes by task 36586 on cpu 1:

 audit_log_start+0x2a0/0x6b0
 audit_core_dumps+0x64/0xa0
 do_coredump+0x14b/0x1260
 get_signal+0xeb2/0xf70
 arch_do_signal_or_restart+0x41/0x170
 exit_to_user_mode_loop+0xa2/0x1c0
 do_syscall_64+0x1a3/0x1c0
 entry_SYSCALL_64_after_hwframe+0x76/0xe0

value changed: 0x00000001 -> 0x00000000
==================================================================

Resolve the race by switching to lockless helper skb_queue_len_lockless(), which internally uses READ_ONCE() and properly pairs with the WRITE_ONCE() write accesses already present on the writer side.

Fixes 3197542482df ("audit: rework audit_log_start()")
[PM: line length tweak]
---
 kernel/audit.c |   10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
kernel/audit.c +5 -5
@@ -912,7 +912,7 @@ main_queue:
 		 *       do the multicast send and rotate records from the
 		 *       main queue to the retry/hold queues */
 		wait_event_freezable(kauditd_wait,
-				     (skb_queue_len(&audit_queue) ? 1 : 0));
+				(skb_queue_len_lockless(&audit_queue) ? 1 : 0));
 	}
 
 	return 0;
@@ -1247,7 +1247,7 @@ static int audit_receive_msg(struct sk_b
 		s.rate_limit		   = audit_rate_limit;
 		s.backlog_limit		   = audit_backlog_limit;
 		s.lost			   = atomic_read(&audit_lost);
-		s.backlog		   = skb_queue_len(&audit_queue);
+		s.backlog		   = skb_queue_len_lockless(&audit_queue);
 		s.feature_bitmap	   = AUDIT_FEATURE_BITMAP_ALL;
 		s.backlog_wait_time	   = audit_backlog_wait_time;
 		s.backlog_wait_time_actual = atomic_read(&audit_backlog_wait_time_actual);
@@ -1588,7 +1588,7 @@ static void audit_receive(struct sk_buff
 
 	/* can't block with the ctrl lock, so penalize the sender now */
 	if (audit_backlog_limit &&
-	    (skb_queue_len(&audit_queue) > audit_backlog_limit)) {
+	    (skb_queue_len_lockless(&audit_queue) > audit_backlog_limit)) {
 		DECLARE_WAITQUEUE(wait, current);
 
 		/* wake kauditd to try and flush the queue */
@@ -1890,7 +1890,7 @@ struct audit_buffer *audit_log_start(str
 		long stime = audit_backlog_wait_time;
 
 		while (audit_backlog_limit &&
-		       (skb_queue_len(&audit_queue) > audit_backlog_limit)) {
+			(skb_queue_len_lockless(&audit_queue) > audit_backlog_limit)) {
 			/* wake kauditd to try and flush the queue */
 			wake_up_interruptible(&kauditd_wait);
 
@@ -1910,7 +1910,7 @@ struct audit_buffer *audit_log_start(str
 			} else {
 				if (audit_rate_check() && printk_ratelimit())
 					pr_warn("audit_backlog=%d > audit_backlog_limit=%d\n",
-						skb_queue_len(&audit_queue),
+						skb_queue_len_lockless(&audit_queue),
 						audit_backlog_limit);
 				audit_log_lost("backlog limit exceeded");
 				return NULL;
author maintainer
#78 lore raw

PATCH 75/699 debugobjects: Plug race against a concurrent OOM disable

In reply to Greg Kroah-Hartman

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

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

From: Thomas Gleixner <[email protected]>

commit b81dde13cc163450dcb402dcc915ef13ba241e01 upstream.

syzbot reported a puzzling splat:

   WARNING: kernel/time/hrtimer.c:443 at stub_timer+0xa/0x20

stub_timer() is installed as timer callback function in hrtimer_fixup_assert_init(), which is invoked when debug_object_assert_init() can't find a shadow object. In that case debug objects emits a warning about it before invoking the fixup.

Though the provided console log lacks this warning and instead has the following a few seconds before the splat:

ODEBUG: Out of memory. ODEBUG disabled

So the object was looked up in debug_object_assert_init() and the lookup failed due a concurrent out of memory situation which disabled debug objects and freed the shadow objects:

debug_object_assert_init()

        if (!debug_objects_enabled)
        	return;                         obj = alloc();
                				if (!obj) {
							// Out of memory
                                                	debug_objects_enabled = false;
                                                        free_objects();
        obj = lookup_or_alloc();

        // The lookup failed because the other side
        // removed the objects, so this returns
        // an error code as the object in question
        // is not statically initialized

	if (!IS_ERR_OR_NULL(obj))
        	return;
        if (!obj) {
        	debug_oom();
                return;
        }

        print(...)
           if (!debug_objects_enabled)
                return;

        fixup(...)

The debug object splat is skipped because debug_objects_enabled is false, but the fixup callback is invoked unconditionally, which makes the timer disfunctional.

This is only a problem in debug_object_assert_init() and debug_object_activate() as both have to handle statically initialized objects and therefore must handle the error pointer return case gracefully. All other places only handle the found/not found case and the NULL pointer return is a signal for OOM. Otherwise they get a valid shadow object.

Plug the hole by checking whether debug objects are still enabled before invoking the print and fixup function in those two places.

Fixes b84d435cc228 ("debugobjects: Extend to assert that an object is initialized")
Reported-by [email protected]
---
 lib/debugobjects.c |   17 +++++++++++++++++
 1 file changed, 17 insertions(+)
lib/debugobjects.c +17 -0
@@ -722,6 +722,14 @@ int debug_object_activate(void *addr, co
 	}
 
 	raw_spin_unlock_irqrestore(&db->lock, flags);
+
+	/*
+	 * lookup_object_or_alloc() might have raced with a concurrent
+	 * allocation failure which disabled debug objects.
+	 */
+	if (!debug_objects_enabled)
+		return 0;
+
 	debug_print_object(&o, "activate");
 
 	switch (o.state) {
@@ -899,6 +907,15 @@ void debug_object_assert_init(void *addr
 		return;
 	}
 
+	/*
+	 * lookup_object_or_alloc() might have raced with a concurrent
+	 * allocation failure which disabled debug objects. Don't run the fixup
+	 * as it might turn a valid object useless. See for example
+	 * hrtimer_fixup_assert_init().
+	 */
+	if (!debug_objects_enabled)
+		return;
+
 	/* Object is neither tracked nor static. It's not initialized. */
 	debug_print_object(&o, "assert_init");
 	debug_object_fixup(descr->fixup_assert_init, addr, ODEBUG_STATE_NOTAVAILABLE);
author maintainer
#79 lore raw

PATCH 76/699 gpio: eic-sprd: use raw_spinlock_t in the irq startup path

In reply to Greg Kroah-Hartman

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

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

From: Runyu Xiao <[email protected]>

commit 90f0109019e6817eb40a486671b7722d1544ae29 upstream.

sprd_eic_irq_unmask() enables the GPIO IRQ and then updates controller state through sprd_eic_update(), which takes sprd_eic->lock with spin_lock_irqsave(). The callback can be reached from irq_startup() while setting up a requested IRQ. That path is not sleepable, but on PREEMPT_RT a regular spinlock_t becomes a sleeping lock.

This issue was found by our static analysis tool and then manually reviewed against the current tree.

The grounded PoC kept the request_threaded_irq() -> __setup_irq() -> irq_startup() -> sprd_eic_irq_unmask() -> sprd_eic_update() carrier and used the original spin_lock_irqsave(&sprd_eic->lock) edge. Lockdep reported:

  BUG: sleeping function called from invalid context
  hardirqs last disabled at ... __setup_irq.constprop.0 ... [vuln_msv]
  sprd_rt_spin_lock_irqsave+0x1c/0x30 [vuln_msv]
  sprd_eic_update.constprop.0+0x48/0x90 [vuln_msv]
  sprd_eic_irq_unmask.constprop.0+0x35/0x50 [vuln_msv]
  __setup_irq.constprop.0+0xd/0x30 [vuln_msv]

Convert the Spreadtrum EIC controller lock to raw_spinlock_t. The locked section only serializes MMIO register updates and does not contain sleepable operations, so keeping it non-sleeping is appropriate for the irqchip callbacks.

---
 drivers/gpio/gpio-eic-sprd.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/gpio/gpio-eic-sprd.c +4 -4
@@ -94,7 +94,7 @@ struct sprd_eic {
 	struct irq_chip intc;
 	void __iomem *base[SPRD_EIC_MAX_BANK];
 	enum sprd_eic_type type;
-	spinlock_t lock;
+	raw_spinlock_t lock;
 	int irq;
 };
 
@@ -146,7 +146,7 @@ static void sprd_eic_update(struct gpio_
 	unsigned long flags;
 	u32 tmp;
 
-	spin_lock_irqsave(&sprd_eic->lock, flags);
+	raw_spin_lock_irqsave(&sprd_eic->lock, flags);
 	tmp = readl_relaxed(base + reg);
 
 	if (val)
@@ -155,7 +155,7 @@ static void sprd_eic_update(struct gpio_
 		tmp &= ~BIT(SPRD_EIC_BIT(offset));
 
 	writel_relaxed(tmp, base + reg);
-	spin_unlock_irqrestore(&sprd_eic->lock, flags);
+	raw_spin_unlock_irqrestore(&sprd_eic->lock, flags);
 }
 
 static int sprd_eic_read(struct gpio_chip *chip, unsigned int offset, u16 reg)
@@ -606,7 +606,7 @@ static int sprd_eic_probe(struct platfor
 	if (!sprd_eic)
 		return -ENOMEM;
 
-	spin_lock_init(&sprd_eic->lock);
+	raw_spin_lock_init(&sprd_eic->lock);
 	sprd_eic->type = pdata->type;
 
 	sprd_eic->irq = platform_get_irq(pdev, 0);
author maintainer
#80 lore raw

PATCH 77/699 io_uring/io-wq: re-check IO_WQ_BIT_EXIT for each linked work item

In reply to Greg Kroah-Hartman

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

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

From: Runyu Xiao <[email protected]>

commit 29bef9934b2521f787bb15dd1985d4c0d12ae02a upstream.

commit 10dc95939817 ("io_uring/io-wq: check IO_WQ_BIT_EXIT inside work run loop") fixed the obvious case where io_worker_handle_work() took one exit-bit snapshot before draining pending work, but the fix stops one level too early.

io_worker_handle_work() now re-checks IO_WQ_BIT_EXIT in its outer work run loop, yet it still snapshots that bit once before processing a whole dependent linked-work chain. If io_wq_exit_start() sets IO_WQ_BIT_EXIT after the first linked item has started, the remaining linked items can still reuse stale do_kill = false, skip IO_WQ_WORK_CANCEL, and continue running after exit has begun.

Move the check further inside, so it covers linked items too. Note: this is a syzbot special as it loves setting up tons of slow linked work on weird devices like msr that take forever to read, and immediately close the ring. Exit then takes a long time.

Fixes 10dc95939817 ("io_uring/io-wq: check IO_WQ_BIT_EXIT inside work run loop")
---
 io_uring/io-wq.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
io_uring/io-wq.c +1 -1
@@ -556,7 +556,6 @@ static void io_worker_handle_work(struct
 	struct io_wq *wq = wqe->wq;
 
 	do {
-		bool do_kill = test_bit(IO_WQ_BIT_EXIT, &wq->state);
 		struct io_wq_work *work;
 get_next:
 		/*
@@ -578,6 +577,7 @@ get_next:
 
 		/* handle a whole dependent link */
 		do {
+			bool do_kill = test_bit(IO_WQ_BIT_EXIT, &wq->state);
 			struct io_wq_work *next_hashed, *linked;
 			unsigned int hash = io_get_work_hash(work);
 
author maintainer
#81 lore raw

PATCH 78/699 ipv4: igmp: remove multicast group from hash table on device destruction

In reply to Greg Kroah-Hartman

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

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

From: Yuyang Huang <[email protected]>

commit 7993211bde166471dffac074dc965489f86531f8 upstream.

When a device is destroyed under RTNL, ip_mc_destroy_dev() iterates through the multicast list and calls ip_ma_put() on each membership, scheduling them for RCU reclamation. However, they are not unlinked from the device's multicast hash table (mc_hash).

Since the device remains published in dev->ip_ptr until after ip_mc_destroy_dev() completes, concurrent RCU readers traversing mc_hash can still locate and access the multicast group after its refcount is decremented. If the RCU callback runs and frees the group while a reader is accessing it, a use-after-free occurs.

Fix this by unlinking the multicast group from mc_hash using ip_mc_hash_remove() before scheduling it for reclamation.

BUG: KASAN: slab-use-after-free in ip_check_mc_rcu+0x149/0x3f0
Read of size 4 at addr ffff888009bf1408 by task mausezahn/2276

Call Trace:
 <IRQ>
 dump_stack_lvl+0x67/0x90
 print_report+0x175/0x7c0
 kasan_report+0x147/0x180
 ip_check_mc_rcu+0x149/0x3f0
 udp_v4_early_demux+0x36d/0x12d0
 ip_rcv_finish_core+0xb8b/0x1390
 ip_rcv_finish+0x54/0x120
 NF_HOOK+0x213/0x2b0
 __netif_receive_skb+0x126/0x340
 process_backlog+0x4f2/0xf00
 __napi_poll+0x92/0x2c0
 net_rx_action+0x583/0xc60
 handle_softirqs+0x236/0x7f0
 do_softirq+0x57/0x80
 </IRQ>

Allocated by task 2239:
 kasan_save_track+0x3e/0x80
 __kasan_kmalloc+0x72/0x90
 ____ip_mc_inc_group+0x31a/0xa40
 __ip_mc_join_group+0x334/0x3f0
 do_ip_setsockopt+0x16fa/0x2010
 ip_setsockopt+0x3f/0x90
 do_sock_setsockopt+0x1ad/0x300

Freed by task 0:
 kasan_save_track+0x3e/0x80
 kasan_save_free_info+0x40/0x50
 __kasan_slab_free+0x3a/0x60
 __rcu_free_sheaf_prepare+0xd4/0x220
 rcu_free_sheaf+0x36/0x190
 rcu_core+0x8d9/0x12f0
 handle_softirqs+0x236/0x7f0
---
 net/ipv4/igmp.c |    1 +
 1 file changed, 1 insertion(+)
net/ipv4/igmp.c +1 -0
@@ -1816,6 +1816,7 @@ void ip_mc_destroy_dev(struct in_device
 #endif
 
 	while ((i = rtnl_dereference(in_dev->mc_list)) != NULL) {
+		ip_mc_hash_remove(in_dev, i);
 		in_dev->mc_list = i->next_rcu;
 		in_dev->mc_count--;
 		ip_mc_clear_src(i);
author maintainer
#82 lore raw

PATCH 79/699 net: ipv4: bound TCP reordering sysctl writes and MTU probe sizes

In reply to Greg Kroah-Hartman

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

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

From: Wyatt Feng <[email protected]>

commit efb8763d7bbb40cff4cc55a6b62c3095a038149c upstream.

Reject invalid net.ipv4.tcp_reordering values before they reach TCP socket state. The sysctl is stored as an int but copied into the u32 tp->reordering field for new sockets, so negative writes wrap to large values.

With tcp_mtu_probing=2, the wrapped value can overflow the tcp_mtu_probe() size calculation and drive the MTU probing path into an out-of-bounds read. Route tcp_reordering writes through proc_dointvec_minmax() and require it to be at least 1. Also require tcp_max_reordering to be at least 1 so the configured maximum cannot become negative either.

When registering the table for a non-init network namespace, relocate extra2 pointers that refer into init_net.ipv4 so the tcp_reordering upper bound follows that namespace's tcp_max_reordering.

Harden tcp_mtu_probe() itself by computing size_needed as u64. This keeps the send queue and window checks from being bypassed through signed integer overflow.

---
 net/ipv4/sysctl_net_ipv4.c |   10 ++++++++--
 net/ipv4/tcp_output.c      |    4 ++--
 2 files changed, 10 insertions(+), 4 deletions(-)
net/ipv4/sysctl_net_ipv4.c +8 -2
@@ -892,7 +892,9 @@ static struct ctl_table ipv4_net_table[]
 		.data		= &init_net.ipv4.sysctl_tcp_reordering,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= SYSCTL_ONE,
+		.extra2		= &init_net.ipv4.sysctl_tcp_max_reordering,
 	},
 	{
 		.procname	= "tcp_retries1",
@@ -1109,7 +1111,8 @@ static struct ctl_table ipv4_net_table[]
 		.data		= &init_net.ipv4.sysctl_tcp_max_reordering,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= SYSCTL_ONE,
 	},
 	{
 		.procname	= "tcp_dsack",
@@ -1336,6 +1339,9 @@ static __net_init int ipv4_sysctl_init_n
 				 */
 				table[i].mode &= ~0222;
 			}
+			if (table[i].extra2 >= (void *)&init_net.ipv4 &&
+			    table[i].extra2 < (void *)(&init_net.ipv4 + 1))
+				table[i].extra2 += (void *)net - (void *)&init_net;
 		}
 	}
 
net/ipv4/tcp_output.c +2 -2
@@ -2343,7 +2343,7 @@ static int tcp_mtu_probe(struct sock *sk
 	struct sk_buff *skb, *nskb, *next;
 	struct net *net = sock_net(sk);
 	int probe_size;
-	int size_needed;
+	u64 size_needed;
 	int copy, len;
 	int mss_now;
 	int interval;
@@ -2367,7 +2367,7 @@ static int tcp_mtu_probe(struct sock *sk
 	mss_now = tcp_current_mss(sk);
 	probe_size = tcp_mtu_to_mss(sk, (icsk->icsk_mtup.search_high +
 				    icsk->icsk_mtup.search_low) >> 1);
-	size_needed = probe_size + (tp->reordering + 1) * tp->mss_cache;
+	size_needed = probe_size + (tp->reordering + 1) * (u64)tp->mss_cache;
 	interval = icsk->icsk_mtup.search_high - icsk->icsk_mtup.search_low;
 	/* When misfortune happens, we are reprobing actively,
 	 * and then reprobe timer has expired. We stick with current
author maintainer
#83 lore raw

PATCH 80/699 mfd: cros_ec: Delay dev_set_drvdata() until probe success

In reply to Greg Kroah-Hartman

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

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

From: Andrei Kuchynski <[email protected]>

commit 8b2c1d41bc36c100b38ce5ee6def246c527eaf8a upstream.

If ec_device_probe() fails, cros_ec_class_release releases memory for the cros_ec_dev structure. However, because the drvdata was already set, sub-drivers like cros_ec_typec can still retrieve the stale pointer via the platform device. This leads to a use-after-free when cros_ec_typec attempts to access &typec->ec->ec->dev on a device that has already been released. Move dev_set_drvdata() to ensure that the pointer is only made available once all initialization steps have succeeded.

sysfs: cannot create duplicate filename '/class/chromeos/cros_ec'

 Call trace:
  sysfs_do_create_link_sd+0x94/0xdc
  sysfs_create_link+0x30/0x44
  device_add_class_symlinks+0x90/0x13c
  device_add+0xf0/0x50c
  ec_device_probe+0x150/0x4f0
  platform_probe+0xa0/0xe0
 ...
 BUG: KASAN: invalid-access in __memcpy+0x44/0x230
 Write at addr f5ffff809e2d33ac by task kworker/u32:5/125
 Pointer tag: [f5], memory tag: [fe]
 Tainted : [W]=WARN, [O]=OOT_MODULE
 Hardware name: Google Navi unprovisioned 0x7FFFFFFF/sku0 board/sku3
 Workqueue: events_unbound deferred_probe_work_func
 Call trace:
  __memcpy+0x44/0x230
  cros_ec_check_features+0x60/0xcc [cros_ec_proto]
  cros_typec_probe+0xe8/0x6e0 [cros_ec_typec]
  platform_probe+0xa0/0xe0
---
 drivers/mfd/cros_ec_dev.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/mfd/cros_ec_dev.c +2 -1
@@ -137,7 +137,6 @@ static int ec_device_probe(struct platfo
 	if (!ec)
 		return retval;
 
-	dev_set_drvdata(dev, ec);
 	ec->ec_dev = dev_get_drvdata(dev->parent);
 	ec->dev = dev;
 	ec->cmd_offset = ec_platform->cmd_offset;
@@ -179,6 +178,8 @@ static int ec_device_probe(struct platfo
 	if (retval)
 		goto failed;
 
+	dev_set_drvdata(dev, ec);
+
 	/* check whether this EC is a sensor hub. */
 	if (cros_ec_get_sensor_count(ec) > 0) {
 		retval = mfd_add_hotplug_devices(ec->dev,
author maintainer
#84 lore raw

PATCH 81/699 netfilter: ebtables: module names must be null-terminated

In reply to Greg Kroah-Hartman

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

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

From: Florian Westphal <[email protected]>

commit 084d23f818321390509e9738a0b08bbf46df6425 upstream.

We need to explicitly check the length, else we may pass non-null terminated string to request_module().

Fixes bcf493428840 ("netfilter: ebtables: Fix extension lookup with identical name")
---
 net/bridge/netfilter/ebtables.c |    3 +++
 1 file changed, 3 insertions(+)
net/bridge/netfilter/ebtables.c +3 -0
@@ -363,6 +363,9 @@ ebt_check_match(struct ebt_entry_match *
 	    left - sizeof(struct ebt_entry_match) < m->match_size)
 		return -EINVAL;
 
+	if (strnlen(m->u.name, XT_EXTENSION_MAXNAMELEN) == XT_EXTENSION_MAXNAMELEN)
+		return -EINVAL;
+
 	match = xt_find_match(NFPROTO_BRIDGE, m->u.name, m->u.revision);
 	if (IS_ERR(match) || match->family != NFPROTO_BRIDGE) {
 		if (!IS_ERR(match))
author maintainer
#85 lore raw

PATCH 82/699 netfilter: ebtables: terminate table name before find_table_lock()

In reply to Greg Kroah-Hartman

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

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

From: Xiang Mei <[email protected]>

commit a622d2e9608c9dff47fc2e5759ac7aa3a836b45d upstream.

update_counters() and compat_update_counters() forward a user-supplied 32-byte table name to find_table_lock() without NUL-terminating it. On a lookup miss, find_inlist_lock() calls try_then_request_module(..., "%s%s", "ebtable_", name), and vsnprintf() reads past the name field and the stack object until it hits a zero byte.

  BUG: KASAN: stack-out-of-bounds in string (lib/vsprintf.c:648 lib/vsprintf.c:730)
  Read of size 1 at addr ffff8880119dfb20 by task exploit/147
  Call Trace:
  ...
   string (lib/vsprintf.c:648 lib/vsprintf.c:730)
   vsnprintf (lib/vsprintf.c:2945)
   __request_module (kernel/module/kmod.c:150)
   do_update_counters.isra.0 (net/bridge/netfilter/ebtables.c:371 net/bridge/netfilter/ebtables.c:380)
   update_counters (net/bridge/netfilter/ebtables.c:1440)
   do_ebt_set_ctl (net/bridge/netfilter/ebtables.c:2573)
   nf_setsockopt (net/netfilter/nf_sockopt.c:101)
   ip_setsockopt (net/ipv4/ip_sockglue.c:1424)
   raw_setsockopt (net/ipv4/raw.c:847)
   __sys_setsockopt (net/socket.c:2393)
  ...

compat_do_replace() shares the same unterminated name via compat_copy_ebt_replace_from_user(); terminate it there too so all find_table_lock() callers behave alike. The other callers already terminate the name after the copy.

Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")
Fixes 81e675c227ec ("netfilter: ebtables: add CONFIG_COMPAT support")
Assisted-by Claude:claude-opus-4-8
---
 net/bridge/netfilter/ebtables.c |    6 ++++++
 1 file changed, 6 insertions(+)
net/bridge/netfilter/ebtables.c +6 -0
@@ -1319,6 +1319,8 @@ static int update_counters(struct net *n
 	if (copy_from_sockptr(&hlp, arg, sizeof(hlp)))
 		return -EFAULT;
 
+	hlp.name[sizeof(hlp.name) - 1] = '\0';
+
 	if (len != sizeof(hlp) + hlp.num_counters * sizeof(struct ebt_counter))
 		return -EINVAL;
 
@@ -2158,6 +2160,8 @@ static int compat_copy_ebt_replace_from_
 
 	memcpy(repl, &tmp, offsetof(struct ebt_replace, hook_entry));
 
+	repl->name[sizeof(repl->name) - 1] = '\0';
+
 	/* starting with hook_entry, 32 vs. 64 bit structures are different */
 	for (i = 0; i < NF_BR_NUMHOOKS; i++)
 		repl->hook_entry[i] = compat_ptr(tmp.hook_entry[i]);
@@ -2280,6 +2284,8 @@ static int compat_update_counters(struct
 	if (copy_from_sockptr(&hlp, arg, sizeof(hlp)))
 		return -EFAULT;
 
+	hlp.name[sizeof(hlp.name) - 1] = '\0';
+
 	/* try real handler in case userland supplied needed padding */
 	if (len != sizeof(hlp) + hlp.num_counters * sizeof(struct ebt_counter))
 		return update_counters(net, arg, len);
author maintainer
#86 lore raw

PATCH 83/699 Bluetooth: bnep: pin L2CAP connection during netdev registration

In reply to Greg Kroah-Hartman

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

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

From: Yousef Alhouseen <[email protected]>

commit bb067a99a0356196c0b89a95721985485ebce5a5 upstream.

bnep_add_connection() reads the L2CAP connection without holding the channel lock, then passes its HCI device to register_netdev(). Controller teardown can clear and release that connection concurrently, leaving the network device registration path to dereference a freed parent device.

Take a reference to the L2CAP connection while holding the channel lock. Retain it until register_netdev() has taken the parent device reference.

Fixes 65f53e9802db ("Bluetooth: Access BNEP session addresses through L2CAP channel")
Reported-by [email protected]
---
 net/bluetooth/bnep/core.c |   27 +++++++++++++++++++++------
 1 file changed, 21 insertions(+), 6 deletions(-)
net/bluetooth/bnep/core.c +21 -6
@@ -540,14 +540,18 @@ static int bnep_session(void *arg)
 	return 0;
 }
 
-static struct device *bnep_get_device(struct bnep_session *session)
+static struct l2cap_conn *bnep_get_conn(struct bnep_session *session)
 {
-	struct l2cap_conn *conn = l2cap_pi(session->sock->sk)->chan->conn;
+	struct l2cap_chan *chan = l2cap_pi(session->sock->sk)->chan;
+	struct l2cap_conn *conn;
 
-	if (!conn || !conn->hcon)
-		return NULL;
+	l2cap_chan_lock(chan);
+	conn = chan->conn;
+	if (conn)
+		l2cap_conn_get(conn);
+	l2cap_chan_unlock(chan);
 
-	return &conn->hcon->dev;
+	return conn;
 }
 
 static struct device_type bnep_type = {
@@ -559,6 +563,7 @@ int bnep_add_connection(struct bnep_conn
 	u32 valid_flags = BIT(BNEP_SETUP_RESPONSE);
 	struct net_device *dev;
 	struct bnep_session *s, *ss;
+	struct l2cap_conn *conn = NULL;
 	u8 dst[ETH_ALEN], src[ETH_ALEN];
 	int err;
 
@@ -618,10 +623,18 @@ int bnep_add_connection(struct bnep_conn
 	bnep_set_default_proto_filter(s);
 #endif
 
-	SET_NETDEV_DEV(dev, bnep_get_device(s));
+	conn = bnep_get_conn(s);
+	if (!conn) {
+		err = -ENOTCONN;
+		goto failed;
+	}
+
+	SET_NETDEV_DEV(dev, &conn->hcon->dev);
 	SET_NETDEV_DEVTYPE(dev, &bnep_type);
 
 	err = register_netdev(dev);
+	l2cap_conn_put(conn);
+	conn = NULL;
 	if (err)
 		goto failed;
 
@@ -643,6 +656,8 @@ int bnep_add_connection(struct bnep_conn
 	return 0;
 
 failed:
+	if (conn)
+		l2cap_conn_put(conn);
 	up_write(&bnep_session_sem);
 	free_netdev(dev);
 	return err;
author maintainer
#87 lore raw

PATCH 84/699 Bluetooth: fix UAF in bt_accept_dequeue()

In reply to Greg Kroah-Hartman

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

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

From: Yousef Alhouseen <[email protected]>

commit 4bd0b274054f2679f28b70222b607bb0afc3ab9a upstream.

bt_accept_get() takes a temporary reference before dropping the accept queue lock. bt_accept_dequeue() currently drops that reference before bt_accept_unlink(), leaving only the queue reference.

bt_accept_unlink() drops the queue reference. The subsequent sock_hold() therefore accesses freed memory if it was the final reference, as observed by KASAN during listening L2CAP socket cleanup.

Retain the temporary queue-walk reference through unlink and hand it to the caller on success. Drop it explicitly on the closed and not-yet-connected paths.

Fixes ab1513597c6c ("Bluetooth: fix UAF in l2cap_sock_cleanup_listen() vs l2cap_conn_del()")
Reported-by [email protected]
---
 net/bluetooth/af_bluetooth.c |   17 +++--------------
 net/bluetooth/l2cap_sock.c   |    4 ++--
 2 files changed, 5 insertions(+), 16 deletions(-)
net/bluetooth/af_bluetooth.c +3 -14
@@ -281,7 +281,7 @@ struct sock *bt_accept_dequeue(struct so
 
 restart:
 	for (sk = bt_accept_get(parent, NULL); sk; sk = next) {
-		/* Prevent early freeing of sk due to unlink and sock_kill */
+		/* The reference from bt_accept_get() keeps sk alive. */
 		lock_sock(sk);
 
 		/* Check sk has not already been unlinked via
@@ -297,13 +297,11 @@ restart:
 
 		next = bt_accept_get(parent, sk);
 
-		/* sk is safely in the parent list so reduce reference count */
-		sock_put(sk);
-
 		/* FIXME: Is this check still needed */
 		if (sk->sk_state == BT_CLOSED) {
 			bt_accept_unlink(sk);
 			release_sock(sk);
+			sock_put(sk);
 			continue;
 		}
 
@@ -313,16 +311,6 @@ restart:
 			if (newsock)
 				sock_graft(sk, newsock);
 
-			/* Hand the caller a reference taken while sk is
-			 * still locked.  bt_accept_unlink() just dropped
-			 * the accept-queue reference; without this hold a
-			 * concurrent teardown (e.g. l2cap_conn_del() ->
-			 * l2cap_sock_kill()) could free sk between
-			 * release_sock() and the caller using it.  Every
-			 * caller drops this with sock_put() when done.
-			 */
-			sock_hold(sk);
-
 			release_sock(sk);
 			if (next)
 				sock_put(next);
@@ -330,6 +318,7 @@ restart:
 		}
 
 		release_sock(sk);
+		sock_put(sk);
 	}
 
 	return NULL;
net/bluetooth/l2cap_sock.c +2 -2
@@ -1420,8 +1420,8 @@ static void l2cap_sock_cleanup_listen(st
 
 	/* Close not yet accepted channels.
 	 *
-	 * bt_accept_dequeue() now returns sk with an extra reference held
-	 * (taken while sk was still locked) so a concurrent l2cap_conn_del()
+	 * bt_accept_dequeue() returns sk with its temporary queue-walk
+	 * reference held, so a concurrent l2cap_conn_del()
 	 * -> l2cap_sock_kill() cannot free sk under us.
 	 *
 	 * cleanup_listen() runs under the parent sk lock, so unlike
author maintainer
#88 lore raw

PATCH 85/699 Bluetooth: L2CAP: validate option length before reading conf opt value

In reply to Greg Kroah-Hartman

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

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

From: Muhammad Bilal <[email protected]>

commit 687617555cedfb74c9e3cb85d759b908dcb17856 upstream.

l2cap_get_conf_opt() derives the option length from the attacker-controlled opt->len field and immediately dereferences opt->val (as u8, get_unaligned_le16() or get_unaligned_le32(), or a raw pointer for the default case) before any caller has confirmed that opt->len bytes are present in the buffer. The callers (l2cap_parse_conf_req(), l2cap_parse_conf_rsp() and l2cap_conf_rfc_get()) only detect a malformed option afterwards, once the running length has gone negative, by which point the out-of-bounds read has already executed.

An existing post-hoc length check keeps the garbage value from being consumed, so this is not a data leak in the current control flow. It is still a validate-after-use ordering bug: up to 4 bytes are read past the end of the buffer before it is known to contain them, and it is fragile to future changes in the callers.

Fix it at the source. Pass the end of the buffer into l2cap_get_conf_opt() and refuse to touch opt->val unless the full option (header + value) fits. Each caller computes an end pointer once before the loop and checks the return value directly instead of inferring the error from a negative length.

Fixes 7c9cbd0b5e38 ("Bluetooth: Verify that l2cap_get_conf_opt provides large enough buffer")
---
 net/bluetooth/l2cap_core.c |   36 ++++++++++++++++++++++++++++--------
 1 file changed, 28 insertions(+), 8 deletions(-)
net/bluetooth/l2cap_core.c +28 -8
@@ -3166,13 +3166,24 @@ fail:
 	return NULL;
 }
 
-static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
-				     unsigned long *val)
+static inline int l2cap_get_conf_opt(void **ptr, void *end, int *type,
+				     int *olen, unsigned long *val)
 {
 	struct l2cap_conf_opt *opt = *ptr;
 	int len;
 
+	/* opt->len is attacker-controlled. Validate that the full option
+	 * (header + value) actually fits in the buffer before touching
+	 * opt->val, otherwise the switch below reads past the end of the
+	 * caller's buffer.
+	 */
+	if (end - *ptr < L2CAP_CONF_OPT_SIZE)
+		return -EINVAL;
+
 	len = L2CAP_CONF_OPT_SIZE + opt->len;
+	if (end - *ptr < len)
+		return -EINVAL;
+
 	*ptr += len;
 
 	*type = opt->type;
@@ -3578,6 +3589,7 @@ static int l2cap_parse_conf_req(struct l
 	void *ptr = rsp->data;
 	void *endptr = data + data_size;
 	void *req = chan->conf_req;
+	void *req_end = req + chan->conf_len;
 	int len = chan->conf_len;
 	int type, hint, olen;
 	unsigned long val;
@@ -3591,9 +3603,11 @@ static int l2cap_parse_conf_req(struct l
 	BT_DBG("chan %p", chan);
 
 	while (len >= L2CAP_CONF_OPT_SIZE) {
-		len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
-		if (len < 0)
+		int ret = l2cap_get_conf_opt(&req, req_end, &type, &olen, &val);
+
+		if (ret < 0)
 			break;
+		len -= ret;
 
 		hint  = type & L2CAP_CONF_HINT;
 		type &= L2CAP_CONF_MASK;
@@ -3827,6 +3841,7 @@ static int l2cap_parse_conf_rsp(struct l
 	struct l2cap_conf_req *req = data;
 	void *ptr = req->data;
 	void *endptr = data + size;
+	void *rsp_end = rsp + len;
 	int type, olen;
 	unsigned long val;
 	struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
@@ -3835,9 +3850,11 @@ static int l2cap_parse_conf_rsp(struct l
 	BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
 
 	while (len >= L2CAP_CONF_OPT_SIZE) {
-		len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
-		if (len < 0)
+		int ret = l2cap_get_conf_opt(&rsp, rsp_end, &type, &olen, &val);
+
+		if (ret < 0)
 			break;
+		len -= ret;
 
 		switch (type) {
 		case L2CAP_CONF_MTU:
@@ -4090,6 +4107,7 @@ static void l2cap_conf_rfc_get(struct l2
 {
 	int type, olen;
 	unsigned long val;
+	void *rsp_end = rsp + len;
 	/* Use sane default values in case a misbehaving remote device
 	 * did not send an RFC or extended window size option.
 	 */
@@ -4108,9 +4126,11 @@ static void l2cap_conf_rfc_get(struct l2
 		return;
 
 	while (len >= L2CAP_CONF_OPT_SIZE) {
-		len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
-		if (len < 0)
+		int ret = l2cap_get_conf_opt(&rsp, rsp_end, &type, &olen, &val);
+
+		if (ret < 0)
 			break;
+		len -= ret;
 
 		switch (type) {
 		case L2CAP_CONF_RFC:
author maintainer
#89 lore raw

PATCH 86/699 net: Drop the lock in skb_may_tx_timestamp()

In reply to Greg Kroah-Hartman

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

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

From: Sebastian Andrzej Siewior <[email protected]>

commit 983512f3a87fd8dc4c94dfa6b596b6e57df5aad7 upstream.

skb_may_tx_timestamp() may acquire sock::sk_callback_lock. The lock must not be taken in IRQ context, only softirq is okay. A few drivers receive the timestamp via a dedicated interrupt and complete the TX timestamp from that handler. This will lead to a deadlock if the lock is already write-locked on the same CPU.

Taking the lock can be avoided. The socket (pointed by the skb) will remain valid until the skb is released. The ->sk_socket and ->file member will be set to NULL once the user closes the socket which may happen before the timestamp arrives.
If we happen to observe the pointer while the socket is closing but before the pointer is set to NULL then we may use it because both pointer (and the file's cred member) are RCU freed.

Drop the lock. Use READ_ONCE() to obtain the individual pointer. Add a matching WRITE_ONCE() where the pointer are cleared.

[ adapted sk_set_socket() in include/net/sock.h to fix the conflict from
not having commit 5d6b58c932ec ("net: lockless sock_i_ino()") and the additional previous changes required by it.
It comes down to just now having the lines of

    if (sock) {
            WRITE_ONCE(sk->sk_uid, SOCK_INODE(sock)->i_uid);
            WRITE_ONCE(sk->sk_ino, SOCK_INODE(sock)->i_ino);
    }

below the changed line. ]

---
 include/net/sock.h |  2 +-
 net/core/skbuff.c  | 23 ++++++++++++++++++-----
 net/socket.c       |  2 +-
 3 files changed, 20 insertions(+), 7 deletions(-)
include/net/sock.h +1 -1
index f0e391afb511d2..b9c44e47cb7a78 100644
@@ -1981,7 +1981,7 @@ static inline int sk_rx_queue_get(const struct sock *sk)
 
 static inline void sk_set_socket(struct sock *sk, struct socket *sock)
 {
-	sk->sk_socket = sock;
+	WRITE_ONCE(sk->sk_socket, sock);
 }
 
 static inline wait_queue_head_t *sk_sleep(struct sock *sk)
net/core/skbuff.c +18 -5
index e4a39e0f55f242..90a63c356affb2 100644
@@ -4772,15 +4772,28 @@ static void __skb_complete_tx_timestamp(struct sk_buff *skb,
 
 static bool skb_may_tx_timestamp(struct sock *sk, bool tsonly)
 {
-	bool ret;
+	struct socket *sock;
+	struct file *file;
+	bool ret = false;
 
 	if (likely(READ_ONCE(sysctl_tstamp_allow_data) || tsonly))
 		return true;
 
-	read_lock_bh(&sk->sk_callback_lock);
-	ret = sk->sk_socket && sk->sk_socket->file &&
-	      file_ns_capable(sk->sk_socket->file, &init_user_ns, CAP_NET_RAW);
-	read_unlock_bh(&sk->sk_callback_lock);
+	/* The sk pointer remains valid as long as the skb is. The sk_socket and
+	 * file pointer may become NULL if the socket is closed. Both structures
+	 * (including file->cred) are RCU freed which means they can be accessed
+	 * within a RCU read section.
+	 */
+	rcu_read_lock();
+	sock = READ_ONCE(sk->sk_socket);
+	if (!sock)
+		goto out;
+	file = READ_ONCE(sock->file);
+	if (!file)
+		goto out;
+	ret = file_ns_capable(file, &init_user_ns, CAP_NET_RAW);
+out:
+	rcu_read_unlock();
 	return ret;
 }
 
net/socket.c +1 -1
index de838c3b004861..eb157ea2a3efbb 100644
@@ -608,7 +608,7 @@ static void __sock_release(struct socket *sock, struct inode *inode)
 		iput(SOCK_INODE(sock));
 		return;
 	}
-	sock->file = NULL;
+	WRITE_ONCE(sock->file, NULL);
 }
 
 /**
Signature · 1 line
2.53.0
author maintainer
#90 lore raw

PATCH 87/699 sched/rt: Have RT_PUSH_IPI be default off for non PREEMPT_RT

In reply to Greg Kroah-Hartman

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

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

From: Steven Rostedt <[email protected]>

commit dd29c017aed628076e915fe4cdfb5392fd4c5cab upstream.

RT migration is done aggressively. When a CPU schedules out a high priority RT task for a lower priority task, it will look to see if there's any RT tasks that are waiting to run on another CPU that is of higher priority than the task this CPU is about to run. If it finds one, it will pull that task over to the CPU and allow it to run there instead.

Normally, this pulling is done by looking at the RT overloaded mask (rto) which contains all the CPUs in the scheduler domain with RT tasks that are waiting to run due to a higher priority RT task currently running on their CPU. The CPU that is about to schedule a lower priority task will grab the rq lock of the overloaded CPU and move the RT task from that CPU's runqueue to the local one and schedule the higher priority RT task.

This caused issues when a lot of CPUs would schedule a lower priority task at the same time. They would all try to grab the same runqueue lock of the CPU with the overloaded RT tasks. Only the first CPU that got in will get that task. All the others would wait until they got the runqueue lock and see there's nothing to pull and do nothing. On systems with lots of CPUs, this caused a large latency (up to 500us) which is beyond what PREEMPT_RT is to allow.

The solution to that was to create an RT_PUSH_IPI logic. When any CPU wanted to pull a task, instead of grabbing the runqueue lock of the overloaded CPU, it would start by sending an IPI to the overloaded CPU, and that IPI handler would have the CPU with the waiting RT task do a push instead. Then that handler would send an IPI to the next CPU with overloaded RT tasks, and so on. Note, after the first CPU starts this process, if another CPU wanted to do a pull, it would see that the process has already begun and would only increment a counter to have the IPIs continue again.

The RT_PUSH_IPI solved the latency problem with PREEMPT_RT but could cause a new issue with non PREEMPT_RT. Namely, softirqs run in a threaded context on PREEMPT_RT but they can run in an interrupt context in non-RT.

If an IPI lands on a CPU that has just woken up multiple RT tasks and the current CPU is running a non RT or a low priority RT task, instead of doing a push, it would simply do a schedule on that CPU. But if a softirq was also executing on this CPU, the schedule would need to wait until the softirq finished. Until then, the CPU would still be considered overloaded as there are RT tasks still waiting to run on it.

A live lock occurred on a workload that was doing heavy networking traffic on a large machine where the softirqs would run 500us out of 750us. And it would also be waking up RT tasks, causing the RT pull logic to be constantly executed.

When a softirq triggered on a CPU with RT tasks queued but not running yet, and the other CPUs would see this CPU as being overloaded, they would send an IPI over to it. The CPU would notice that the waiting RT tasks are of higher priority than the currently running task and simply schedule that CPU instead. But because the softirq was executing, before it could schedule, it would receive another IPI to do the same. The amount of IPIs would slow down the currently running softirq so much that before it could return back to task context, it would execute another softirq never allowing the CPU to schedule. This live locked that CPU.

As RT_PUSH_IPI was created to help PREEMPT_RT, make it default off if PREEMPT_RT is not enabled.

---
 kernel/sched/features.h |    8 ++++++++
 1 file changed, 8 insertions(+)
kernel/sched/features.h +8 -0
@@ -73,8 +73,16 @@ SCHED_FEAT(WARN_DOUBLE_CLOCK, false)
  * rq lock and possibly create a large contention, sending an
  * IPI to that CPU and let that CPU push the RT task to where
  * it should go may be a better scenario.
+ *
+ * This is best for PREEMPT_RT, but for non-RT it can cause issues
+ * when preemption is disabled for long periods of time. Have
+ * it only default enabled for PREEMPT_RT.
  */
+# ifdef CONFIG_PREEMPT_RT
 SCHED_FEAT(RT_PUSH_IPI, true)
+# else
+SCHED_FEAT(RT_PUSH_IPI, false)
+# endif
 #endif
 
 SCHED_FEAT(RT_RUNTIME_SHARE, false)
author maintainer
#91 lore raw

PATCH 88/699 cpufreq: Fix hotplug-suspend race during reboot

In reply to Greg Kroah-Hartman

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

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

From: Tianxiang Chen <[email protected]>

commit a9029dd55696c651ee46912afa2a166fa456bb3e upstream.

During system reboot, cpufreq_suspend() is called via the kernel_restart() -> device_shutdown() path. Unlike the normal system suspend path, the reboot path does not call freeze_processes(), so userspace processes and kernel threads remain active.

This allows CPU hotplug operations to run concurrently with cpufreq_suspend(). The original code has no synchronization with CPU hotplug, leading to a race condition where governor_data can be freed by the hotplug path while cpufreq_suspend() is still accessing it, resulting in a null pointer dereference:

  Unable to handle kernel NULL pointer dereference
  Call Trace:
   do_kernel_fault+0x28/0x3c
   cpufreq_suspend+0xdc/0x160
   device_shutdown+0x18/0x200
   kernel_restart+0x40/0x80
   arm64_sys_reboot+0x1b0/0x200

Fix this by adding cpus_read_lock()/cpus_read_unlock() to cpufreq_suspend() to block CPU hotplug operations while suspend is in progress.

Fixes 65650b35133f ("cpufreq: Avoid cpufreq_suspend() deadlock on system shutdown")
Cc All applicable <[email protected]>
[ rjw: Changelog edits ]
---
 drivers/cpufreq/cpufreq.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/cpufreq/cpufreq.c +2 -0
@@ -1872,6 +1872,7 @@ void cpufreq_suspend(void)
 	if (!cpufreq_driver)
 		return;
 
+	cpus_read_lock();
 	if (!has_target() && !cpufreq_driver->suspend)
 		goto suspend;
 
@@ -1891,6 +1892,7 @@ void cpufreq_suspend(void)
 
 suspend:
 	cpufreq_suspended = true;
+	cpus_read_unlock();
 }
 
 /**
author maintainer
#92 lore raw

PATCH 89/699 cpufreq: pcc: fix use-after-free and double free in _OSC evaluation

In reply to Greg Kroah-Hartman

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

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

From: Yuho Choi <[email protected]>

commit 266d3dd8b757b48a576e90f018b51f7b7563cc32 upstream.

pcc_cpufreq_do_osc() calls acpi_evaluate_object() twice for the two-phase _OSC negotiation. Between the two calls it freed output.pointer but left output.length unchanged. Since acpi_evaluate_object() treats a non-zero length with a non-NULL pointer as an existing buffer to write into, the second call wrote into freed memory (use-after-free). The subsequent kfree(output.pointer) at out_free then freed the same pointer a second time (double free).

Reset output.pointer to NULL and output.length to ACPI_ALLOCATE_BUFFER after freeing the first result, so ACPICA allocates a fresh buffer for each phase independently.

Fixes 0f1d683fb35d ("[CPUFREQ] Processor Clocking Control interface driver")
Cc All applicable <[email protected]>
---
 drivers/cpufreq/pcc-cpufreq.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/cpufreq/pcc-cpufreq.c +2 -0
@@ -351,6 +351,8 @@ static int __init pcc_cpufreq_do_osc(acp
 	}
 
 	kfree(output.pointer);
+	output.pointer = NULL;
+	output.length = ACPI_ALLOCATE_BUFFER;
 	capabilities[0] = 0x0;
 	capabilities[1] = 0x1;
 
author maintainer
#93 lore raw

PATCH 90/699 posix-cpu-timers: Fix pid refcount leak in do_cpu_nanosleep() error path

In reply to Greg Kroah-Hartman

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

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

From: WenTao Liang <[email protected]>

commit 87bd2ad568e15b90d5f7d4bcd70342d05dad649c upstream.

In do_cpu_nanosleep(), posix_cpu_timer_create() takes a pid reference via get_pid() and stores it in timer.it.cpu.pid. If the subsequent posix_cpu_timer_set() call fails, the function returns immediately without calling posix_cpu_timer_del() to release the pid reference, causing a leak.

Fix it by calling posix_cpu_timer_del() before the unlock-and-return on the error path, consistent with the other exit paths in the same function.

---
 kernel/time/posix-cpu-timers.c |    1 +
 1 file changed, 1 insertion(+)
kernel/time/posix-cpu-timers.c +1 -0
@@ -1472,6 +1472,7 @@ static int do_cpu_nanosleep(const clocki
 		spin_lock_irq(&timer.it_lock);
 		error = posix_cpu_timer_set(&timer, flags, &it, NULL);
 		if (error) {
+			posix_cpu_timer_del(&timer);
 			spin_unlock_irq(&timer.it_lock);
 			return error;
 		}
author maintainer
#94 lore raw

PATCH 91/699 HID: wacom: stop hardware after post-start probe failures

In reply to Greg Kroah-Hartman

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

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

From: Myeonghun Pak <[email protected]>

commit ec2612b8ad9e642596db011dd8b6568ef1edeaa1 upstream.

wacom_parse_and_register() starts HID hardware before registering inputs and initializing pad LEDs/remotes. Those later steps can fail, but their error paths currently release Wacom resources without stopping the HID hardware.

Route post-hid_hw_start() failures through hid_hw_stop() before releasing driver resources.

This issue was identified during our ongoing static-analysis research while reviewing kernel code.

Fixes c1d6708bf0d3 ("HID: wacom: Do not register input devices until after hid_hw_start")
---
 drivers/hid/wacom_sys.c |   12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/hid/wacom_sys.c +6 -6
@@ -2427,16 +2427,16 @@ static int wacom_parse_and_register(stru
 
 	error = wacom_register_inputs(wacom);
 	if (error)
-		goto fail;
+		goto fail_hw_stop;
 
 	if (wacom->wacom_wac.features.device_type & WACOM_DEVICETYPE_PAD) {
 		error = wacom_initialize_leds(wacom);
 		if (error)
-			goto fail;
+			goto fail_hw_stop;
 
 		error = wacom_initialize_remotes(wacom);
 		if (error)
-			goto fail;
+			goto fail_hw_stop;
 	}
 
 	if (!wireless) {
@@ -2450,14 +2450,14 @@ static int wacom_parse_and_register(stru
 		cancel_delayed_work_sync(&wacom->init_work);
 		_wacom_query_tablet_data(wacom);
 		error = -ENODEV;
-		goto fail_quirks;
+		goto fail_hw_stop;
 	}
 
 	if (features->device_type & WACOM_DEVICETYPE_WL_MONITOR) {
 		error = hid_hw_open(hdev);
 		if (error) {
 			hid_err(hdev, "hw open failed\n");
-			goto fail_quirks;
+			goto fail_hw_stop;
 		}
 	}
 
@@ -2466,7 +2466,7 @@ static int wacom_parse_and_register(stru
 
 	return 0;
 
-fail_quirks:
+fail_hw_stop:
 	hid_hw_stop(hdev);
 fail:
 	wacom_release_resources(wacom);
author maintainer
#95 lore raw

PATCH 92/699 HID: lg-g15: cancel pending work on remove to fix a use-after-free

In reply to Greg Kroah-Hartman

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

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

From: Maoyi Xie <[email protected]>

commit 7705b4140d188ce22656f6e541ae7ef834c7e11a upstream.

lg_g15_data is allocated with devm and holds a work item. The report handlers schedule that work straight from device input. lg_g15_event() and lg_g15_v2_event() do it on the backlight cycle key, and lg_g510_leds_event() does it too. The worker dereferences the lg_g15_data back through container_of.

The driver had no remove callback and never cancelled the work. So if a report scheduled the work and the keyboard was then unplugged, devres freed lg_g15_data while the work was still pending or running, and the worker touched freed memory. This is a use-after-free. It is reachable as a race on device unplug.

Add a remove callback that cancels the work before devres frees the state. g15->work is only initialized for the models that schedule it (G15, G15 v2, G510). The G13 and Z-10 leave it zeroed, so guard the cancel on g15->work.func to avoid cancelling a work that was never set up. The g15 NULL test mirrors the one already in lg_g15_raw_event().

Fixes 97b741aba918 ("HID: lg-g15: Add keyboard and LCD backlight control")
---
 drivers/hid/hid-lg-g15.c |   16 ++++++++++++++++
 1 file changed, 16 insertions(+)
drivers/hid/hid-lg-g15.c +16 -0
@@ -894,11 +894,27 @@ static const struct hid_device_id lg_g15
 };
 MODULE_DEVICE_TABLE(hid, lg_g15_devices);
 
+static void lg_g15_remove(struct hid_device *hdev)
+{
+	struct lg_g15_data *g15 = hid_get_drvdata(hdev);
+
+	/*
+	 * g15->work is only initialized for the models that schedule it
+	 * (G15, G15 v2, G510). The G13 and Z-10 leave it zeroed, so only
+	 * cancel it when it was set up.
+	 */
+	if (g15 && g15->work.func)
+		cancel_work_sync(&g15->work);
+
+	hid_hw_stop(hdev);
+}
+
 static struct hid_driver lg_g15_driver = {
 	.name			= "lg-g15",
 	.id_table		= lg_g15_devices,
 	.raw_event		= lg_g15_raw_event,
 	.probe			= lg_g15_probe,
+	.remove			= lg_g15_remove,
 };
 module_hid_driver(lg_g15_driver);
 
author maintainer
#96 lore raw

PATCH 93/699 HID: sensor-hub: Add sensor_hub_input_attr_read_values() for multi-byte reads

In reply to Greg Kroah-Hartman

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

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

From: Srinivas Pandruvada <[email protected]>

commit f784fcea450617055d2d12eec5b2f6e0e38bf878 upstream.

sensor_hub_input_attr_get_raw_value() is limited to returning a single 32-bit value, which is insufficient for sensors that report data larger than 32 bits, such as a quaternion with four s16 elements.

Add sensor_hub_input_attr_read_values() that accepts a caller-provided buffer and accumulates incoming data until the buffer is full. The two paths are distinguished in sensor_hub_raw_event() by pending.max_raw_size being non-zero, preserving backward compatibility.

---
 drivers/hid/hid-sensor-hub.c   |   77 +++++++++++++++++++++++++++++++++++++----
 include/linux/hid-sensor-hub.h |   25 +++++++++++++
 2 files changed, 96 insertions(+), 6 deletions(-)
drivers/hid/hid-sensor-hub.c +71 -6
@@ -287,6 +287,54 @@ done_proc:
 }
 EXPORT_SYMBOL_GPL(sensor_hub_get_feature);
 
+int sensor_hub_input_attr_read_values(struct hid_sensor_hub_device *hsdev,
+				      u32 usage_id, u32 attr_usage_id,
+				      u32 report_id,
+				      enum sensor_hub_read_flags flag,
+				      u32 buffer_size, u8 *buffer)
+{
+	struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev);
+	struct hid_report *report;
+	unsigned long flags;
+	long cycles;
+	int ret;
+
+	report = sensor_hub_report(report_id, hsdev->hdev, HID_INPUT_REPORT);
+	if (!report)
+		return -EINVAL;
+
+	mutex_lock(hsdev->mutex_ptr);
+	if (flag == SENSOR_HUB_SYNC) {
+		memset(&hsdev->pending, 0, sizeof(hsdev->pending));
+		init_completion(&hsdev->pending.ready);
+		hsdev->pending.usage_id = usage_id;
+		hsdev->pending.attr_usage_id = attr_usage_id;
+		hsdev->pending.max_raw_size = buffer_size;
+		hsdev->pending.raw_data = buffer;
+
+		spin_lock_irqsave(&data->lock, flags);
+		hsdev->pending.status = true;
+		spin_unlock_irqrestore(&data->lock, flags);
+	}
+	mutex_lock(&data->mutex);
+	hid_hw_request(hsdev->hdev, report, HID_REQ_GET_REPORT);
+	mutex_unlock(&data->mutex);
+	ret = 0;
+	if (flag == SENSOR_HUB_SYNC) {
+		cycles = wait_for_completion_interruptible_timeout(&hsdev->pending.ready,
+								   HZ * 5);
+		if (cycles == 0)
+			ret = -ETIMEDOUT;
+		else if (cycles < 0)
+			ret = cycles;
+
+		hsdev->pending.status = false;
+	}
+	mutex_unlock(hsdev->mutex_ptr);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(sensor_hub_input_attr_read_values);
 
 int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev,
 					u32 usage_id,
@@ -480,6 +528,8 @@ static int sensor_hub_raw_event(struct h
 	struct hid_collection *collection = NULL;
 	void *priv = NULL;
 	struct hid_sensor_hub_device *hsdev = NULL;
+	u32 copy_size;
+	u32 avail;
 
 	hid_dbg(hdev, "sensor_hub_raw_event report id:0x%x size:%d type:%d\n",
 			 report->id, size, report->type);
@@ -519,12 +569,27 @@ static int sensor_hub_raw_event(struct h
 					      hsdev->pending.attr_usage_id ==
 					      report->field[i]->logical)) {
 			hid_dbg(hdev, "data was pending ...\n");
-			hsdev->pending.raw_data = kmemdup(ptr, sz, GFP_ATOMIC);
-			if (hsdev->pending.raw_data)
-				hsdev->pending.raw_size = sz;
-			else
-				hsdev->pending.raw_size = 0;
-			complete(&hsdev->pending.ready);
+			if (hsdev->pending.max_raw_size) {
+				if (hsdev->pending.index < hsdev->pending.max_raw_size) {
+					avail = hsdev->pending.max_raw_size - hsdev->pending.index;
+					copy_size = clamp(sz, 0U, avail);
+
+					memcpy(hsdev->pending.raw_data + hsdev->pending.index,
+					       ptr, copy_size);
+					hsdev->pending.index += copy_size;
+					if (hsdev->pending.index >= hsdev->pending.max_raw_size) {
+						hsdev->pending.raw_size = hsdev->pending.index;
+						complete(&hsdev->pending.ready);
+					}
+				}
+			} else {
+				hsdev->pending.raw_data = kmemdup(ptr, sz, GFP_ATOMIC);
+				if (hsdev->pending.raw_data)
+					hsdev->pending.raw_size = sz;
+				else
+					hsdev->pending.raw_size = 0;
+				complete(&hsdev->pending.ready);
+			}
 		}
 		if (callback->capture_sample) {
 			if (report->field[i]->logical)
include/linux/hid-sensor-hub.h +25 -0
@@ -43,6 +43,8 @@ struct hid_sensor_hub_attribute_info {
  * @attr_usage_id:	Usage Id of a field, E.g. X-AXIS for a gyro.
  * @raw_size:		Response size for a read request.
  * @raw_data:		Place holder for received response.
+ * @index:		Current write index into raw_data for multi-byte reads.
+ * @max_raw_size:	Total buffer size for multi-byte reads; 0 for single-value reads.
  */
 struct sensor_hub_pending {
 	bool status;
@@ -51,6 +53,8 @@ struct sensor_hub_pending {
 	u32 attr_usage_id;
 	int raw_size;
 	u8  *raw_data;
+	u32 index;
+	u32 max_raw_size;
 };
 
 /**
@@ -183,6 +187,27 @@ int sensor_hub_input_attr_get_raw_value(
 );
 
 /**
+ * sensor_hub_input_attr_read_values() - Synchronous multi-byte read request
+ * @hsdev:		Hub device instance.
+ * @usage_id:		Attribute usage id of parent physical device as per spec
+ * @attr_usage_id:	Attribute usage id as per spec
+ * @report_id:		Report id to look for
+ * @flag:		Synchronous or asynchronous read
+ * @buffer_size:	Size of the buffer in bytes
+ * @buffer:		Buffer to store the read data
+ *
+ * Issues a synchronous or asynchronous read request for an input attribute,
+ * accumulating data into the provided buffer until it is full.
+ * Return: 0 on success, -ETIMEDOUT if the device did not respond, or a
+ * negative error code.
+ */
+int sensor_hub_input_attr_read_values(struct hid_sensor_hub_device *hsdev,
+				      u32 usage_id, u32 attr_usage_id,
+				      u32 report_id,
+				      enum sensor_hub_read_flags flag,
+				      u32 buffer_size, u8 *buffer);
+
+/**
 * sensor_hub_set_feature() - Feature set request
 * @hsdev:	Hub device instance.
 * @report_id:	Report id to look for
author maintainer
#97 lore raw

PATCH 94/699 hfs/hfsplus: zero-initialize buffer in hfs_bnode_read

In reply to Greg Kroah-Hartman

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

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

From: Tristan Madani <[email protected]>

commit d67aadee19ffdf3cc8520c5a4f4d5b2916d30baf upstream.

hfs_bnode_read() can return early without writing to the output buffer when is_bnode_offset_valid() fails or when check_and_correct_requested_ length() corrects the length to zero. Callers such as hfs_bnode_read_ u16() and hfs_bnode_read_u8() pass stack-allocated buffers and use the result unconditionally, leading to KMSAN uninit-value reports.

Rather than initializing at each individual call site, zero the buffer at the start of hfs_bnode_read() before any validation checks. This ensures all callers in both hfs and hfsplus get a deterministic zero value regardless of which early-return path is taken.

---
 fs/hfs/bnode.c     |    2 ++
 fs/hfsplus/bnode.c |    2 ++
 2 files changed, 4 insertions(+)
fs/hfs/bnode.c +2 -0
@@ -65,6 +65,8 @@ void hfs_bnode_read(struct hfs_bnode *no
 	int bytes_to_read;
 	void *vaddr;
 
+	memset(buf, 0, len);
+
 	if (!is_bnode_offset_valid(node, off))
 		return;
 
fs/hfsplus/bnode.c +2 -0
@@ -25,6 +25,8 @@ void hfs_bnode_read(struct hfs_bnode *no
 	struct page **pagep;
 	int l;
 
+	memset(buf, 0, len);
+
 	if (!is_bnode_offset_valid(node, off))
 		return;
 
author maintainer
#98 lore raw

PATCH 95/699 nilfs2: reject CLEAN_SEGMENTS ioctl with out-of-range segment numbers

In reply to Greg Kroah-Hartman

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

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

From: Deepanshu Kartikey <[email protected]>

commit 0e7a690fe435f8d5ea3feb7c1d8d73ba7e8b8aa9 upstream.

Syzbot reported a hung task in nilfs_transaction_begin() where multiple tasks performing chmod() on a nilfs2 mount blocked for over 143 seconds waiting to acquire ns_segctor_sem for read:

  INFO: task syz.0.17:5918 blocked for more than 143 seconds.
  Call Trace:
   schedule+0x164/0x360
   rwsem_down_read_slowpath+0x6d9/0x940
   down_read+0x99/0x2e0
   nilfs_transaction_begin+0x364/0x710 fs/nilfs2/segment.c:221
   nilfs_setattr+0x124/0x2c0 fs/nilfs2/inode.c:921
   notify_change+0xc1a/0xf40
   chmod_common+0x273/0x4a0
   do_fchmodat+0x12d/0x230

The writer holding ns_segctor_sem was a concurrent NILFS_IOCTL_CLEAN_SEGMENTS caller, stuck inside printk while emitting per-element warnings from nilfs_sufile_updatev():

   __nilfs_msg+0x373/0x450 fs/nilfs2/super.c:78
   nilfs_sufile_updatev+0x21c/0x6d0 fs/nilfs2/sufile.c:186
   nilfs_sufile_freev fs/nilfs2/sufile.h:93 [inline]
   nilfs_free_segments fs/nilfs2/segment.c:1140 [inline]
   nilfs_segctor_collect_blocks fs/nilfs2/segment.c:1261 [inline]
   nilfs_segctor_do_construct+0x1f55/0x76c0
   nilfs_clean_segments+0x3bd/0xa50
   nilfs_ioctl_clean_segments fs/nilfs2/ioctl.c:922 [inline]
   nilfs_ioctl+0x261f/0x2780

The root cause is that user-supplied segment numbers are not validated before nilfs_clean_segments() begins doing work; the range check on each segnum is performed deep inside the call chain by nilfs_sufile_updatev(), which emits a nilfs_warn() per invalid entry while still holding the segctor lock and the sufile mi_sem. Under load (repeated invocations across multiple mounts saturating the global printk path), the cumulative printk latency keeps ns_segctor_sem held long enough to trip the hung_task watchdog, blocking concurrent operations such as chmod() that need ns_segctor_sem for read.

Fix by validating the contents of kbufs[4] in nilfs_clean_segments() immediately after acquiring ns_segctor_sem via nilfs_transaction_lock(). Holding ns_segctor_sem serializes the check against nilfs_ioctl_resize(), which can modify ns_nsegments, so the validation uses a consistent value. Out-of-range segment numbers are rejected with -EINVAL before any segment-cleaning work begins, so the bad entries never reach the per-element diagnostic path inside nilfs_sufile_updatev().

---
 fs/nilfs2/segment.c |   22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
fs/nilfs2/segment.c +22 -0
@@ -2505,12 +2505,33 @@ int nilfs_clean_segments(struct super_bl
 	struct nilfs_sc_info *sci = nilfs->ns_writer;
 	struct nilfs_transaction_info ti;
 	int err;
+	size_t i, nfreesegs = argv[4].v_nmembs;
+	__u64 *segnumv = kbufs[4];
 
 	if (unlikely(!sci))
 		return -EROFS;
 
 	nilfs_transaction_lock(sb, &ti, 1);
 
+	/*
+	 * Validate segment numbers under ns_segctor_sem (held for write
+	 * by nilfs_transaction_lock above) so the check is serialized
+	 * against nilfs_ioctl_resize(), which can modify ns_nsegments.
+	 * Rejecting bad input here, before any segment-cleaning work
+	 * begins, avoids the per-element diagnostic path inside
+	 * nilfs_sufile_updatev() that would otherwise run under this
+	 * same lock and stall concurrent readers.
+	 */
+	for (i = 0; i < nfreesegs; i++) {
+		if (segnumv[i] >= nilfs->ns_nsegments) {
+			nilfs_err(sb,
+				 "Segment number %llu to be freed is out of range",
+				 (unsigned long long)segnumv[i]);
+			err = -EINVAL;
+			goto bail_unlock;
+		}
+	}
+
 	err = nilfs_mdt_save_to_shadow_map(nilfs->ns_dat);
 	if (unlikely(err))
 		goto out_unlock;
@@ -2551,6 +2572,7 @@ int nilfs_clean_segments(struct super_bl
 	sci->sc_freesegs = NULL;
 	sci->sc_nfreesegs = 0;
 	nilfs_mdt_clear_shadow_map(nilfs->ns_dat);
+ bail_unlock:
 	nilfs_transaction_unlock(sb);
 	return err;
 }
author maintainer
#99 lore raw

PATCH 96/699 net: usb: kalmia: bound RX frame length in kalmia_rx_fixup()

In reply to Greg Kroah-Hartman

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

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

From: Maoyi Xie <[email protected]>

commit 47b6bcef6e679593d2e86e04ee72c46a4e2f7139 upstream.

kalmia_rx_fixup() computes usb_packet_length = skb->len - (2 * KALMIA_HEADER_LENGTH) as a u16, guarded only by a pre-loop check that skb->len is at least KALMIA_HEADER_LENGTH, which is 6. A device can deliver a short bulk-IN frame with skb->len in the 6 to 11 range, or leave a short trailing remainder on a later loop iteration. Either case underflows usb_packet_length to about 65530.

That bypasses the usb_packet_length < ether_packet_length truncation path. The device-supplied ether_packet_length, a le16 up to 65535 read from header_start[2], then drives a memcmp() and the following skb_trim() and skb_pull() past the end of the rx buffer. The rx buffer is hard_mtu * 10, which is 14000 bytes. That is an out of bounds read.

Require both the start and end framing headers to be present before subtracting them, on every loop iteration.

Fixes d40261236e8e ("net/usb: Add Samsung Kalmia driver for Samsung GT-B3730")
---
 drivers/net/usb/kalmia.c |    8 ++++++++
 1 file changed, 8 insertions(+)
drivers/net/usb/kalmia.c +8 -0
@@ -276,6 +276,14 @@ kalmia_rx_fixup(struct usbnet *dev, stru
 				"Received header: %6phC. Package length: %i\n",
 				header_start, skb->len - KALMIA_HEADER_LENGTH);
 
+		/* both framing headers must be present before we subtract
+		 * them, otherwise usb_packet_length underflows and the
+		 * device-supplied ether_packet_length drives an out of bounds
+		 * access below
+		 */
+		if (skb->len < 2 * KALMIA_HEADER_LENGTH)
+			return 0;
+
 		/* subtract start header and end header */
 		usb_packet_length = skb->len - (2 * KALMIA_HEADER_LENGTH);
 		ether_packet_length = get_unaligned_le16(&header_start[2]);
author maintainer
#100 lore raw

PATCH 97/699 usb: cdc_acm: Add quirk for Uniden BC125AT scanner

In reply to Greg Kroah-Hartman

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

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

From: Jared Baldridge <[email protected]>

commit 6eba58568f6cc3ff8515a00b05e258d8cfb72b72 upstream.

Uniden BC125AT radio scanner has a USB interface which fails to work with the cdc_acm driver:
usb 1-1: new full-speed USB device number 2 using uhci_hcd cdc_acm 1-1:1.0: Zero length descriptor references cdc_acm 1-1:1.0: probe with driver cdc_acm failed with error -22
usbcore: registered new interface driver cdc_acm

Adding the NO_UNION_NORMAL quirk for the device fixes the issue:

usb 1-1: new full-speed USB device number 2 using uhci_hcd cdc_acm 1-1:1.0: ttyACM0: USB ACM device
usbcore: registered new interface driver cdc_acm

lsusb -v of the device:

Bus 001 Device 002: ID 1965:0017 Uniden Corporation BC125AT Negotiated speed: Full Speed (12Mbps)
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00

   bDeviceClass            2 Communications
   bDeviceSubClass         0 [unknown]
   bDeviceProtocol         0
   bMaxPacketSize0        64
   idVendor           0x1965 Uniden Corporation
   idProduct          0x0017 BC125AT
   bcdDevice            0.01
   iManufacturer           1 Uniden America Corp.
   iProduct                2 BC125AT
   iSerial                 3 0001
   bNumConfigurations      1

Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x0030
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 500mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 2 Communications
bInterfaceSubClass 2 Abstract (modem)
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x87 EP 7 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 10
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 10 CDC Data
bInterfaceSubClass 0 [unknown]
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Device Status: 0x0000
(Bus Powered)

---
 drivers/usb/class/cdc-acm.c |    3 +++
 1 file changed, 3 insertions(+)
drivers/usb/class/cdc-acm.c +3 -0
@@ -1788,6 +1788,9 @@ static const struct usb_device_id acm_id
 	{ USB_DEVICE(0x1901, 0x0006), /* GE Healthcare Patient Monitor UI Controller */
 	.driver_info = DISABLE_ECHO, /* DISABLE ECHO in termios flag */
 	},
+	{ USB_DEVICE(0x1965, 0x0017), /* Uniden BC125AT */
+	.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
+	},
 	{ USB_DEVICE(0x1965, 0x0018), /* Uniden UBC125XLT */
 	.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
 	},
author maintainer
#101 lore raw

PATCH 98/699 USB: core: add USB_QUIRK_NO_LPM for VIA Labs USB 2.0 hub

In reply to Greg Kroah-Hartman

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

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

From: Rodrigo Lugathe da Conceição Alves <[email protected]>

commit bd728c3d9b1cc0bb0fda6a7055c5c8b55d7477b2 upstream.

The VIA Labs, Inc. USB 2.0 hub controller (2109:2817), found in a KVM switch, fails to enumerate high-power devices during cold boot and system restart.

Applying the kernel parameter
usbcore.quirks=2109:2817:k
resolves the issue.

Enumeration failure log:
usb 1-1.2.3: device descriptor read/64, error -32 usb 1-1.2.3: Device not responding to setup address. usb 1-1.2.3: device not accepting address 11, error -71 usb 1-1.2-port3: unable to enumerate USB device

Add USB_QUIRK_NO_LPM for this device.

---
 drivers/usb/core/quirks.c |    3 +++
 1 file changed, 3 insertions(+)
drivers/usb/core/quirks.c +3 -0
@@ -561,6 +561,9 @@ static const struct usb_device_id usb_qu
 	/* VLI disk */
 	{ USB_DEVICE(0x2109, 0x0711), .driver_info = USB_QUIRK_NO_LPM },
 
+	/* VIA Labs, Inc. USB2.0 Hub */
+	{ USB_DEVICE(0x2109, 0x2817), .driver_info = USB_QUIRK_NO_LPM },
+
 	/* Raydium Touchscreen */
 	{ USB_DEVICE(0x2386, 0x3114), .driver_info = USB_QUIRK_NO_LPM },
 
author maintainer
#102 lore raw

PATCH 99/699 usb: gadget: composite: fix dead empty check in the USB_DT_OTG handler

In reply to Greg Kroah-Hartman

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

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

From: Maoyi Xie <[email protected]>

commit f8f680609c2b3ab795ffcd6f21585b6dfc46d395 upstream.

The OTG branch of composite_setup() falls back to the first configuration when none is selected:

	if (cdev->config)
		config = cdev->config;
	else
		config = list_first_entry(&cdev->configs,
					  struct usb_configuration, list);
	if (!config)
		goto done;
	...
	memcpy(req->buf, config->descriptors[0], value);

list_first_entry() never returns NULL. On an empty list it returns container_of() of the list head. So the "if (!config)" check is dead.

When cdev->configs is empty, config points at the head inside struct usb_composite_dev. config->descriptors[0] reads whatever sits at that offset. The memcpy copies up to w_length bytes of it into the response buffer.

cdev->configs can be empty in two cases. One is a teardown race on gadget unbind with a control transfer in flight. The other is a driver that sets is_otg before it adds a config. A reproducer that holds cdev->configs empty triggers a KASAN fault in this branch.

Use list_first_entry_or_null() so the existing check does its job.

Fixes 53e6242db8d6 ("usb: gadget: composite: add USB_DT_OTG request handling")
Cc stable <[email protected]>
---
 drivers/usb/gadget/composite.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/usb/gadget/composite.c +3 -2
@@ -1747,9 +1747,10 @@ composite_setup(struct usb_gadget *gadge
 				if (cdev->config)
 					config = cdev->config;
 				else
-					config = list_first_entry(
+					config = list_first_entry_or_null(
 							&cdev->configs,
-						struct usb_configuration, list);
+							struct usb_configuration,
+							list);
 				if (!config)
 					goto done;
 
author maintainer
#103 lore raw

PATCH 100/699 USB: idmouse: fix use-after-free on disconnect race

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

commit ff002c153f9722caece3983cc23dc4d9d4652cb4 upstream.

mutex_unlock() may access the mutex structure after releasing the lock and therefore cannot be used to manage lifetime of objects directly (unlike spinlocks and refcounts). [1][2]

Use a kref to release the driver data to avoid use-after-free in mutex_unlock() when release() races with disconnect().

[1] a51749ab34d9 ("locking/mutex: Document that mutex_unlock() is non-atomic")
[2] 2b9d9e0a9ba0 ("locking/mutex: Clarify that mutex_unlock(), and most other sleeping locks, can still use the lock object after it's unlocked")

Fixes 54d2bc068fd2 ("USB: fix locking in idmouse")
Cc [email protected] # 2.6.24
Cc Oliver Neukum <[email protected]>
---
 drivers/usb/misc/idmouse.c |   45 ++++++++++++++++++++++-----------------------
 1 file changed, 22 insertions(+), 23 deletions(-)
drivers/usb/misc/idmouse.c +22 -23
@@ -63,6 +63,7 @@ MODULE_DEVICE_TABLE(usb, idmouse_table);
 
 /* structure to hold all of our device specific stuff */
 struct usb_idmouse {
+	struct kref kref;
 
 	struct usb_device *udev; /* save off the usb device pointer */
 	struct usb_interface *interface; /* the interface for this device */
@@ -209,8 +210,10 @@ static int idmouse_resume(struct usb_int
 	return 0;
 }
 
-static inline void idmouse_delete(struct usb_idmouse *dev)
+static inline void idmouse_delete(struct kref *kref)
 {
+	struct usb_idmouse *dev = container_of(kref, struct usb_idmouse, kref);
+
 	kfree(dev->bulk_in_buffer);
 	kfree(dev);
 }
@@ -254,6 +257,8 @@ static int idmouse_open(struct inode *in
 		/* increment our usage count for the driver */
 		++dev->open;
 
+		kref_get(&dev->kref);
+
 		/* save our object in the file's private structure */
 		file->private_data = dev;
 
@@ -277,16 +282,11 @@ static int idmouse_release(struct inode
 
 	/* lock our device */
 	mutex_lock(&dev->lock);
-
 	--dev->open;
+	mutex_unlock(&dev->lock);
+
+	kref_put(&dev->kref, idmouse_delete);
 
-	if (!dev->present) {
-		/* the device was unplugged before the file was released */
-		mutex_unlock(&dev->lock);
-		idmouse_delete(dev);
-	} else {
-		mutex_unlock(&dev->lock);
-	}
 	return 0;
 }
 
@@ -334,6 +334,7 @@ static int idmouse_probe(struct usb_inte
 	if (dev == NULL)
 		return -ENOMEM;
 
+	kref_init(&dev->kref);
 	mutex_init(&dev->lock);
 	dev->udev = udev;
 	dev->interface = interface;
@@ -342,8 +343,7 @@ static int idmouse_probe(struct usb_inte
 	result = usb_find_bulk_in_endpoint(iface_desc, &endpoint);
 	if (result) {
 		dev_err(&interface->dev, "Unable to find bulk-in endpoint.\n");
-		idmouse_delete(dev);
-		return result;
+		goto err_put_kref;
 	}
 
 	dev->orig_bi_size = usb_endpoint_maxp(endpoint);
@@ -351,8 +351,8 @@ static int idmouse_probe(struct usb_inte
 	dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
 	dev->bulk_in_buffer = kmalloc(IMGSIZE + dev->bulk_in_size, GFP_KERNEL);
 	if (!dev->bulk_in_buffer) {
-		idmouse_delete(dev);
-		return -ENOMEM;
+		result = -ENOMEM;
+		goto err_put_kref;
 	}
 
 	/* allow device read, write and ioctl */
@@ -364,14 +364,18 @@ static int idmouse_probe(struct usb_inte
 	if (result) {
 		/* something prevented us from registering this device */
 		dev_err(&interface->dev, "Unable to allocate minor number.\n");
-		idmouse_delete(dev);
-		return result;
+		goto err_put_kref;
 	}
 
 	/* be noisy */
 	dev_info(&interface->dev,"%s now attached\n",DRIVER_DESC);
 
 	return 0;
+
+err_put_kref:
+	kref_put(&dev->kref, idmouse_delete);
+
+	return result;
 }
 
 static void idmouse_disconnect(struct usb_interface *interface)
@@ -387,14 +391,9 @@ static void idmouse_disconnect(struct us
 	/* prevent device read, write and ioctl */
 	dev->present = 0;
 
-	/* if the device is opened, idmouse_release will clean this up */
-	if (!dev->open) {
-		mutex_unlock(&dev->lock);
-		idmouse_delete(dev);
-	} else {
-		/* unlock */
-		mutex_unlock(&dev->lock);
-	}
+	mutex_unlock(&dev->lock);
+
+	kref_put(&dev->kref, idmouse_delete);
 
 	dev_info(&interface->dev, "disconnected\n");
 }
author maintainer
#104 lore raw

PATCH 101/699 USB: ldusb: fix use-after-free on disconnect race

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

commit 19bdfc7b3c179331eafa423d87e1336f43bbfeb8 upstream.

mutex_unlock() may access the mutex structure after releasing the lock and therefore cannot be used to manage lifetime of objects directly (unlike spinlocks and refcounts). [1][2]

Use a kref to release the driver data to avoid use-after-free in mutex_unlock() when release() races with disconnect().

[1] a51749ab34d9 ("locking/mutex: Document that mutex_unlock() is non-atomic")
[2] 2b9d9e0a9ba0 ("locking/mutex: Clarify that mutex_unlock(), and most other sleeping locks, can still use the lock object after it's unlocked")

Fixes ce0d7d3f575f ("usb: ldusb: ld_usb semaphore to mutex")
Cc stable <[email protected]>
Cc Daniel Walker <[email protected]>
---
 drivers/usb/misc/ldusb.c |   38 ++++++++++++++++++--------------------
 1 file changed, 18 insertions(+), 20 deletions(-)
drivers/usb/misc/ldusb.c +18 -20
@@ -151,6 +151,7 @@ MODULE_PARM_DESC(min_interrupt_out_inter
 
 /* Structure to hold all of our device specific stuff */
 struct ld_usb {
+	struct kref		kref;
 	struct mutex		mutex;		/* locks this structure */
 	struct usb_interface	*intf;		/* save off the usb interface pointer */
 	unsigned long		disconnected:1;
@@ -202,8 +203,10 @@ static void ld_usb_abort_transfers(struc
 /*
  *	ld_usb_delete
  */
-static void ld_usb_delete(struct ld_usb *dev)
+static void ld_usb_delete(struct kref *kref)
 {
+	struct ld_usb *dev = container_of(kref, struct ld_usb, kref);
+
 	/* free data structures */
 	usb_free_urb(dev->interrupt_in_urb);
 	usb_free_urb(dev->interrupt_out_urb);
@@ -356,6 +359,8 @@ static int ld_usb_open(struct inode *ino
 		goto unlock_exit;
 	}
 
+	kref_get(&dev->kref);
+
 	/* save device in the file's private structure */
 	file->private_data = dev;
 
@@ -382,17 +387,8 @@ static int ld_usb_release(struct inode *
 
 	mutex_lock(&dev->mutex);
 
-	if (dev->open_count != 1) {
-		retval = -ENODEV;
+	if (dev->disconnected)
 		goto unlock_exit;
-	}
-	if (dev->disconnected) {
-		/* the device was unplugged before the file was released */
-		mutex_unlock(&dev->mutex);
-		/* unlock here as ld_usb_delete frees dev */
-		ld_usb_delete(dev);
-		goto exit;
-	}
 
 	/* wait until write transfer is finished */
 	if (dev->interrupt_out_busy)
@@ -402,7 +398,7 @@ static int ld_usb_release(struct inode *
 
 unlock_exit:
 	mutex_unlock(&dev->mutex);
-
+	kref_put(&dev->kref, ld_usb_delete);
 exit:
 	return retval;
 }
@@ -661,6 +657,8 @@ static int ld_usb_probe(struct usb_inter
 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 	if (!dev)
 		goto exit;
+
+	kref_init(&dev->kref);
 	mutex_init(&dev->mutex);
 	spin_lock_init(&dev->rbsl);
 	dev->intf = intf;
@@ -740,7 +738,7 @@ exit:
 	return retval;
 
 error:
-	ld_usb_delete(dev);
+	kref_put(&dev->kref, ld_usb_delete);
 
 	return retval;
 }
@@ -768,18 +766,18 @@ static void ld_usb_disconnect(struct usb
 
 	mutex_lock(&dev->mutex);
 
-	/* if the device is not opened, then we clean up right now */
-	if (!dev->open_count) {
-		mutex_unlock(&dev->mutex);
-		ld_usb_delete(dev);
-	} else {
-		dev->disconnected = 1;
+	dev->disconnected = 1;
+
+	if (dev->open_count) {
 		/* wake up pollers */
 		wake_up_interruptible_all(&dev->read_wait);
 		wake_up_interruptible_all(&dev->write_wait);
-		mutex_unlock(&dev->mutex);
 	}
 
+	mutex_unlock(&dev->mutex);
+
+	kref_put(&dev->kref, ld_usb_delete);
+
 	dev_info(&intf->dev, "LD USB Device #%d now disconnected\n",
 		 (minor - USB_LD_MINOR_BASE));
 }
author maintainer
#105 lore raw

PATCH 102/699 USB: iowarrior: fix use-after-free on disconnect

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

commit bc0e4f16c44e50daa0b1ea729934baa3b4815dee upstream.

Submitted write URBs are not stopped on close() and therefore need to be stopped unconditionally on disconnect() to avoid use-after-free in the completion handler.

Fixes b5f8d46867ca ("USB: iowarrior: fix use-after-free after driver unbind")
Fixes 946b960d13c1 ("USB: add driver for iowarrior devices.")
Reported-by [email protected]
Cc stable <[email protected]>
---
 drivers/usb/misc/iowarrior.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/usb/misc/iowarrior.c +3 -1
@@ -923,13 +923,15 @@ static void iowarrior_disconnect(struct
 	/* prevent device read, write and ioctl */
 	dev->present = 0;
 
+	/* write urbs are not stopped on close() so kill unconditionally */
+	usb_kill_anchored_urbs(&dev->submitted);
+
 	if (dev->opened) {
 		/* There is a process that holds a filedescriptor to the device ,
 		   so we only shutdown read-/write-ops going on.
 		   Deleting the device is postponed until close() was called.
 		 */
 		usb_kill_urb(dev->int_in_urb);
-		usb_kill_anchored_urbs(&dev->submitted);
 		wake_up_interruptible(&dev->read_wait);
 		wake_up_interruptible(&dev->write_wait);
 		mutex_unlock(&dev->mutex);
author maintainer
#106 lore raw

PATCH 103/699 USB: quirks: add NO_LPM for the Samsung T5 EVO Portable SSD

In reply to Greg Kroah-Hartman

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

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

From: Erich E. Hoover <[email protected]>

commit fc591787785b9709a0bb65a7df3ba2537d611c47 upstream.

The Samsung T5 EVO Portable SSD (04e8:6200) exhibit two forms of link instability when USB Link Power Management is enabled:

1. The units fail to initialize properly on first detection, resulting in a lockup in the drive where it must be power cycled or the kernel will not recognize the presence of the device.

2. If used for sustained operations (small amounts of continuous data are transferred to the unit) then the unit will "hiccup" after roughly 8 hours of use and will disconnect and reconnect. This has a certain probability of triggering the first issue, but also causes mount points to become invalid since the device gets issued a new letter.

---
 drivers/usb/core/quirks.c |    3 +++
 1 file changed, 3 insertions(+)
drivers/usb/core/quirks.c +3 -0
@@ -292,6 +292,9 @@ static const struct usb_device_id usb_qu
 	/* CarrolTouch 4500U */
 	{ USB_DEVICE(0x04e7, 0x0030), .driver_info = USB_QUIRK_RESET_RESUME },
 
+	/* Samsung T5 EVO Portable SSD */
+	{ USB_DEVICE(0x04e8, 0x6200), .driver_info = USB_QUIRK_NO_LPM },
+
 	/* Samsung Android phone modem - ID conflict with SPH-I500 */
 	{ USB_DEVICE(0x04e8, 0x6601), .driver_info =
 			USB_QUIRK_CONFIG_INTF_STRINGS },
author maintainer
#107 lore raw

PATCH 104/699 USB: legousbtower: fix use-after-free on disconnect race

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

commit 62fc8eb1b1481051f7bab4aa93d79809053dd09f upstream.

mutex_unlock() may access the mutex structure after releasing the lock and therefore cannot be used to manage lifetime of objects directly (unlike spinlocks and refcounts). [1][2]

Use a kref to release the driver data to avoid use-after-free in mutex_unlock() when release() races with disconnect().

[1] a51749ab34d9 ("locking/mutex: Document that mutex_unlock() is non-atomic")
[2] 2b9d9e0a9ba0 ("locking/mutex: Clarify that mutex_unlock(), and most other sleeping locks, can still use the lock object after it's unlocked")

Fixes 18bcbcfe9ca2 ("USB: misc: legousbtower: semaphore to mutex")
Cc stable <[email protected]>
Cc Daniel Walker <[email protected]>
---
 drivers/usb/misc/legousbtower.c |   37 +++++++++++++++++++------------------
 1 file changed, 19 insertions(+), 18 deletions(-)
drivers/usb/misc/legousbtower.c +19 -18
@@ -185,6 +185,7 @@ MODULE_DEVICE_TABLE(usb, tower_table);
 
 /* Structure to hold all of our device specific stuff */
 struct lego_usb_tower {
+	struct kref		kref;
 	struct mutex		lock;		/* locks this structure */
 	struct usb_device	*udev;		/* save off the usb device pointer */
 	unsigned char		minor;		/* the starting minor number for this device */
@@ -220,7 +221,6 @@ struct lego_usb_tower {
 /* local function prototypes */
 static ssize_t tower_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos);
 static ssize_t tower_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos);
-static inline void tower_delete(struct lego_usb_tower *dev);
 static int tower_open(struct inode *inode, struct file *file);
 static int tower_release(struct inode *inode, struct file *file);
 static __poll_t tower_poll(struct file *file, poll_table *wait);
@@ -286,8 +286,10 @@ static inline void lego_usb_tower_debug_
 /*
  *	tower_delete
  */
-static inline void tower_delete(struct lego_usb_tower *dev)
+static inline void tower_delete(struct kref *kref)
 {
+	struct lego_usb_tower *dev = container_of(kref, struct lego_usb_tower, kref);
+
 	/* free data structures */
 	usb_free_urb(dev->interrupt_in_urb);
 	usb_free_urb(dev->interrupt_out_urb);
@@ -381,6 +383,8 @@ static int tower_open(struct inode *inod
 
 	dev->open_count = 1;
 
+	kref_get(&dev->kref);
+
 unlock_exit:
 	mutex_unlock(&dev->lock);
 
@@ -404,14 +408,8 @@ static int tower_release(struct inode *i
 
 	mutex_lock(&dev->lock);
 
-	if (dev->disconnected) {
-		/* the device was unplugged before the file was released */
-
-		/* unlock here as tower_delete frees dev */
-		mutex_unlock(&dev->lock);
-		tower_delete(dev);
-		goto exit;
-	}
+	if (dev->disconnected)
+		goto out_unlock;
 
 	/* wait until write transfer is finished */
 	if (dev->interrupt_out_busy) {
@@ -425,7 +423,9 @@ static int tower_release(struct inode *i
 
 	dev->open_count = 0;
 
+out_unlock:
 	mutex_unlock(&dev->lock);
+	kref_put(&dev->kref, tower_delete);
 exit:
 	return retval;
 }
@@ -752,6 +752,7 @@ static int tower_probe(struct usb_interf
 	if (!dev)
 		goto exit;
 
+	kref_init(&dev->kref);
 	mutex_init(&dev->lock);
 	dev->udev = usb_get_dev(udev);
 	spin_lock_init(&dev->read_buffer_lock);
@@ -828,7 +829,7 @@ exit:
 	return retval;
 
 error:
-	tower_delete(dev);
+	kref_put(&dev->kref, tower_delete);
 	return retval;
 }
 
@@ -856,18 +857,18 @@ static void tower_disconnect(struct usb_
 
 	mutex_lock(&dev->lock);
 
-	/* if the device is not opened, then we clean up right now */
-	if (!dev->open_count) {
-		mutex_unlock(&dev->lock);
-		tower_delete(dev);
-	} else {
-		dev->disconnected = 1;
+	dev->disconnected = 1;
+
+	if (dev->open_count) {
 		/* wake up pollers */
 		wake_up_interruptible_all(&dev->read_wait);
 		wake_up_interruptible_all(&dev->write_wait);
-		mutex_unlock(&dev->lock);
 	}
 
+	mutex_unlock(&dev->lock);
+
+	kref_put(&dev->kref, tower_delete);
+
 	dev_info(&interface->dev, "LEGO USB Tower #%d now disconnected\n",
 		 (minor - LEGO_USB_TOWER_MINOR_BASE));
 }
author maintainer
#108 lore raw

PATCH 105/699 usb: sl811-hcd: disable controller wakeup on remove

In reply to Greg Kroah-Hartman

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

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

From: Myeonghun Pak <[email protected]>

commit 4e8ba83ac4d311992e6a4c21de5dd705010df06e upstream.

sl811h_probe() enables the HCD controller device as a wakeup source after usb_add_hcd() succeeds, but sl811h_remove() removes the HCD and releases the driver resources without disabling that wakeup source.

Disable controller wakeup after usb_remove_hcd() and before usb_put_hcd() so the wakeup source object is detached while the controller device pointer is still available.

This issue was identified during our ongoing static-analysis research while reviewing kernel code.

Fixes 3c9740a117d4 ("usb: hcd: move controller wakeup setting initialization to individual driver")
Cc stable <[email protected]>
---
 drivers/usb/host/sl811-hcd.c |    1 +
 1 file changed, 1 insertion(+)
drivers/usb/host/sl811-hcd.c +1 -0
@@ -1591,6 +1591,7 @@ sl811h_remove(struct platform_device *de
 
 	remove_debug_file(sl811);
 	usb_remove_hcd(hcd);
+	device_wakeup_disable(hcd->self.controller);
 
 	/* some platforms may use IORESOURCE_IO */
 	res = platform_get_resource(dev, IORESOURCE_MEM, 1);
author maintainer
#109 lore raw

PATCH 106/699 USB: storage: include US_FL_NO_SAME in quirks mask

In reply to Greg Kroah-Hartman

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

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

From: Xu Rao <[email protected]>

commit 2c00e09e3f9f06f8434f5ea2ee6179ce46692ee6 upstream.

usb_stor_adjust_quirks() parses the usb-storage.quirks module parameter into a new flag set and then applies it with the quirk mask to override built-in flags.

The mask is meant to cover the flags that can be overridden by the module parameter. The 'k' quirk character sets US_FL_NO_SAME, but US_FL_NO_SAME is not included in the mask.

As a result, the module parameter can set US_FL_NO_SAME, but it cannot clear a built-in US_FL_NO_SAME flag by providing an override entry that omits 'k'.

Add US_FL_NO_SAME to the mask so that the module parameter can override it in the same way as the other supported flags.

Fixes 8010622c86ca ("USB: UAS: introduce a quirk to set no_write_same")
Cc stable <[email protected]>
---
 drivers/usb/storage/usb.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/storage/usb.c +1 -1
@@ -488,7 +488,7 @@ void usb_stor_adjust_quirks(struct usb_d
 			US_FL_INITIAL_READ10 | US_FL_WRITE_CACHE |
 			US_FL_NO_ATA_1X | US_FL_NO_REPORT_OPCODES |
 			US_FL_MAX_SECTORS_240 | US_FL_NO_REPORT_LUNS |
-			US_FL_ALWAYS_SYNC);
+			US_FL_ALWAYS_SYNC | US_FL_NO_SAME);
 
 	p = quirks;
 	while (*p) {
author maintainer
#110 lore raw

PATCH 107/699 USB: misc: uss720: unregister parport on probe failure

In reply to Greg Kroah-Hartman

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

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

From: Myeonghun Pak <[email protected]>

commit b4ecbdc4f8830f5586c4a5cfc384c00f20f8f8b3 upstream.

uss720_probe() registers a parport before reading the 1284 register used to detect unsupported Belkin F5U002 adapters. If get_1284_register() fails, the error path drops the driver private data and the USB device reference, but leaves the parport device registered.

Leaving the port registered is more than a private allocation leak:
parport_register_port() has already reserved a parport number and registered the parport bus device, while pp->private_data still points at the private data that the common error path is about to release.

Undo the pre-announce registration in the get_1284_register() failure branch before jumping to the common private-data cleanup path. Clear priv->pp first, matching the disconnect path and avoiding a stale pointer in the private data.

This issue was identified during our ongoing static-analysis research while reviewing kernel code.

Fixes 3295f1b866bf ("usb: misc: uss720: check for incompatible versions of the Belkin F5U002")
Cc stable <[email protected]>
---
 drivers/usb/misc/uss720.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/usb/misc/uss720.c +4 -1
@@ -732,8 +732,11 @@ static int uss720_probe(struct usb_inter
 	 * here. */
 	ret = get_1284_register(pp, 0, &reg, GFP_KERNEL);
 	dev_dbg(&intf->dev, "reg: %7ph\n", priv->reg);
-	if (ret < 0)
+	if (ret < 0) {
+		priv->pp = NULL;
+		parport_del_port(pp);
 		goto probe_abort;
+	}
 
 	ret = usb_find_last_int_in_endpoint(interface, &epd);
 	if (!ret) {
author maintainer
#111 lore raw

PATCH 108/699 usb: mtu3: unmap request DMA on queue failure

In reply to Greg Kroah-Hartman

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

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

From: Haoxiang Li <[email protected]>

commit 0bddda5a11665c210339de76d27ebbd1a2e0b43c upstream.

mtu3_gadget_queue() maps the request before checking whether the QMU GPD ring can accept another transfer. the request is returned with -EAGAIN before it is linked on the endpoint request list if mtu3_prepare_transfer() fails.

Normal completion and dequeue paths unmap requests from mtu3_req_complete(), but this error path never reaches that helper, so the DMA mapping is left active. Unmap the request before returning from the failed queue path.

Fixes df2069acb005 ("usb: Add MediaTek USB3 DRD driver")
Cc stable <[email protected]>
---
 drivers/usb/mtu3/mtu3_gadget.c |    1 +
 1 file changed, 1 insertion(+)
drivers/usb/mtu3/mtu3_gadget.c +1 -0
@@ -305,6 +305,7 @@ static int mtu3_gadget_queue(struct usb_
 
 	if (mtu3_prepare_transfer(mep)) {
 		ret = -EAGAIN;
+		usb_gadget_unmap_request(&mtu->g, req, mep->is_in);
 		goto error;
 	}
 
author maintainer
#112 lore raw

PATCH 109/699 USB: serial: option: add Telit Cinterion FE990D50 compositions

In reply to Greg Kroah-Hartman

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

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

From: Fabio Porcedda <[email protected]>

commit b33ab1dd80f5c1742f49eb6ec7b337c5ffcf3d32 upstream.

Add support for Telit Cinterion FE990D50 compositions:

0x990: RNDIS + tty (AT/NMEA) + tty (AT) + tty (AT) + tty (AT) +
tty (diag) + ADPL + adb

T:  Bus=01 Lev=01 Prnt=01 Port=06 Cnt=03 Dev#=  3 Spd=480  MxCh= 0
D:  Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=1bc7 ProdID=0990 Rev=06.06
S:  Manufacturer=Telit Cinterion
S:  Product=FE990
S:  SerialNumber=90b6a3ed
C:  #Ifs=10 Cfg#= 1 Atr=e0 MxPwr=500mA
I:  If#= 0 Alt= 0 #EPs= 1 Cls=ef(misc ) Sub=04 Prot=01 Driver=rndis_host
E:  Ad=82(I) Atr=03(Int.) MxPS=   8 Ivl=32ms
I:  If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=rndis_host
E:  Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:  If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=84(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
I:  If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
E:  Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=86(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
I:  If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
E:  Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=88(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
I:  If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
E:  Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=8a(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
I:  If#= 6 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option
E:  Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=8b(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:  If#= 7 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=80 Driver=(none)
E:  Ad=8c(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:  If#= 8 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=70 Driver=(none)
E:  Ad=8d(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:  If#= 9 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none)
E:  Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms

0x991: rmnet + tty (AT/NMEA) + tty (AT) + tty (AT) + tty (AT) +
tty (diag) + ADPL + adb

T:  Bus=01 Lev=01 Prnt=01 Port=06 Cnt=03 Dev#=  9 Spd=480  MxCh= 0
D:  Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=1bc7 ProdID=0991 Rev=06.06
S:  Manufacturer=Telit Cinterion
S:  Product=FE990
S:  SerialNumber=90b6a3ed
C:  #Ifs= 9 Cfg#= 1 Atr=e0 MxPwr=500mA
I:  If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=50 Driver=(none)
E:  Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=82(I) Atr=03(Int.) MxPS=   8 Ivl=32ms
I:  If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=84(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
I:  If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
E:  Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=86(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
I:  If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
E:  Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=88(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
I:  If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
E:  Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=8a(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
I:  If#= 5 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option
E:  Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=8b(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:  If#= 6 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=80 Driver=(none)
E:  Ad=8c(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:  If#= 7 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=70 Driver=(none)
E:  Ad=8d(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:  If#= 8 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none)
E:  Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms

0x992: MBIM + tty (AT/NMEA) + tty (AT) + tty (AT) + tty (AT) +
tty (diag) + ADPL + adb

T:  Bus=01 Lev=01 Prnt=01 Port=06 Cnt=03 Dev#= 12 Spd=480  MxCh= 0
D:  Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=1bc7 ProdID=0992 Rev=06.06
S:  Manufacturer=Telit Cinterion
S:  Product=FE990
S:  SerialNumber=90b6a3ed
C:  #Ifs=10 Cfg#= 1 Atr=e0 MxPwr=500mA
I:  If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0e Prot=00 Driver=cdc_mbim
E:  Ad=82(I) Atr=03(Int.) MxPS=  64 Ivl=32ms
I:  If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim
E:  Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:  If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=84(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
I:  If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
E:  Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=86(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
I:  If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
E:  Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=88(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
I:  If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
E:  Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=8a(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
I:  If#= 6 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option
E:  Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=8b(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:  If#= 7 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=80 Driver=(none)
E:  Ad=8c(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:  If#= 8 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=70 Driver=(none)
E:  Ad=8d(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:  If#= 9 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none)
E:  Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms

0x993: ECM + tty (AT/NMEA) + tty (AT) + tty (AT) + tty (AT) +
tty (diag) + ADPL + adb

T:  Bus=01 Lev=01 Prnt=01 Port=06 Cnt=03 Dev#= 15 Spd=480  MxCh= 0
D:  Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=1bc7 ProdID=0993 Rev=06.06
S:  Manufacturer=Telit Cinterion
S:  Product=FE990
S:  SerialNumber=90b6a3ed
C:  #Ifs=10 Cfg#= 1 Atr=e0 MxPwr=500mA
I:  If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=06 Prot=00 Driver=cdc_ether
E:  Ad=82(I) Atr=03(Int.) MxPS=  16 Ivl=32ms
I:  If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_ether
E:  Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:  If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=84(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
I:  If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
E:  Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=86(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
I:  If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
E:  Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=88(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
I:  If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option
E:  Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=8a(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
I:  If#= 6 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option
E:  Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=8b(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:  If#= 7 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=80 Driver=(none)
E:  Ad=8c(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:  If#= 8 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=70 Driver=(none)
E:  Ad=8d(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:  If#= 9 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none)
E:  Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
---
 drivers/usb/serial/option.c |   16 ++++++++++++++++
 1 file changed, 16 insertions(+)
drivers/usb/serial/option.c +16 -0
@@ -1326,6 +1326,22 @@ static const struct usb_device_id option
 	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_SINGLE) },
 	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_DE910_DUAL) },
 	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UE910_V2) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0990, 0xff, 0xff, 0x30),	/* Telit FE990D50 (RNDIS) */
+	  .driver_info = NCTRL(6) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0990, 0xff, 0xff, 0x40) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0990, 0xff, 0xff, 0x60) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0991, 0xff, 0xff, 0x30),	/* Telit FE990D50 (rmnet) */
+	  .driver_info = NCTRL(5) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0991, 0xff, 0xff, 0x40) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0991, 0xff, 0xff, 0x60) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0992, 0xff, 0xff, 0x30),	/* Telit FE990D50 (MBIM) */
+	  .driver_info = NCTRL(6) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0992, 0xff, 0xff, 0x40) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0992, 0xff, 0xff, 0x60) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0993, 0xff, 0xff, 0x30),	/* Telit FE990D50 (ECM) */
+	  .driver_info = NCTRL(6) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0993, 0xff, 0xff, 0x40) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0993, 0xff, 0xff, 0x60) },
 	{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1031, 0xff),	/* Telit LE910C1-EUX */
 	 .driver_info = NCTRL(0) | RSVD(3) },
 	{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1033, 0xff),	/* Telit LE910C1-EUX (ECM) */
author maintainer
#113 lore raw

PATCH 110/699 USB: serial: digi_acceleport: fix broken rx after throttle

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

commit 83a3dfc018943b05b6daf3a6f891833e1aabfa1f upstream.

If the port is closed while throttled, the read urb is never resubmitted and the port will not receive any further data until the device is reconnected (or the driver is rebound).

Clear the throttle flags and submit the urb if needed when opening the port.

Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")
---
 drivers/usb/serial/digi_acceleport.c |   16 ++++++++++++++++
 1 file changed, 16 insertions(+)
drivers/usb/serial/digi_acceleport.c +16 -0
@@ -1070,6 +1070,7 @@ static int digi_open(struct tty_struct *
 	unsigned char buf[32];
 	struct digi_port *priv = usb_get_serial_port_data(port);
 	struct ktermios not_termios;
+	int throttled;
 
 	/* be sure the device is started up */
 	if (digi_startup_device(port->serial) != 0)
@@ -1097,6 +1098,21 @@ static int digi_open(struct tty_struct *
 		not_termios.c_iflag = ~tty->termios.c_iflag;
 		digi_set_termios(tty, port, &not_termios);
 	}
+
+	spin_lock_irq(&priv->dp_port_lock);
+	throttled = priv->dp_throttle_restart;
+	priv->dp_throttled = 0;
+	priv->dp_throttle_restart = 0;
+	spin_unlock_irq(&priv->dp_port_lock);
+
+	if (throttled) {
+		ret = usb_submit_urb(port->read_urb, GFP_KERNEL);
+		if (ret) {
+			dev_err(&port->dev, "failed to submit read urb: %d\n", ret);
+			return ret;
+		}
+	}
+
 	return 0;
 }
 
author maintainer
#114 lore raw

PATCH 111/699 USB: serial: digi_acceleport: fix hard lockup on disconnect

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

commit 5c1ea24b53bf3bfb859f0a05573997487975da23 upstream.

If submitting the OOB write urb fails persistently (e.g if the device is being disconnected) the driver would loop indefinitely with interrupts disabled.

Check for urb submission errors when sending OOB commands to avoid hanging if, for example, open(), set_termios() or close() races with a physical disconnect.

This is issue was flagged by Sashiko when reviewing an unrelated change to the driver.

---
 drivers/usb/serial/digi_acceleport.c |   12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)
drivers/usb/serial/digi_acceleport.c +7 -5
@@ -394,12 +394,14 @@ static int digi_write_oob_command(struct
 			len &= ~3;
 		memcpy(oob_port->write_urb->transfer_buffer, buf, len);
 		oob_port->write_urb->transfer_buffer_length = len;
+
 		ret = usb_submit_urb(oob_port->write_urb, GFP_ATOMIC);
-		if (ret == 0) {
-			oob_priv->dp_write_urb_in_use = 1;
-			count -= len;
-			buf += len;
-		}
+		if (ret)
+			break;
+
+		oob_priv->dp_write_urb_in_use = 1;
+		count -= len;
+		buf += len;
 	}
 	spin_unlock_irqrestore(&oob_priv->dp_port_lock, flags);
 	if (ret)
author maintainer
#115 lore raw

PATCH 112/699 USB: ulpi: fix memory leak on registration failure

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

commit 8af6812795869a66e9b26044f455b13deecdb69c upstream.

The allocated device name is never freed on early ULPI device registration failures.

Fix this by initialising the device structure earlier and releasing the initial reference whenever registration fails.

Fixes 289fcff4bcdb ("usb: add bus type for USB ULPI")
Cc stable <[email protected]>
Cc Heikki Krogerus <[email protected]>
---
 drivers/usb/common/ulpi.c |   23 ++++++++++-------------
 1 file changed, 10 insertions(+), 13 deletions(-)
drivers/usb/common/ulpi.c +10 -13
@@ -241,28 +241,24 @@ static int ulpi_register(struct device *
 	ulpi->dev.parent = dev; /* needed early for ops */
 	ulpi->dev.bus = &ulpi_bus;
 	ulpi->dev.type = &ulpi_dev_type;
+
+	device_initialize(&ulpi->dev);
+
 	dev_set_name(&ulpi->dev, "%s.ulpi", dev_name(dev));
 
 	ACPI_COMPANION_SET(&ulpi->dev, ACPI_COMPANION(dev));
 
 	ret = ulpi_of_register(ulpi);
-	if (ret) {
-		kfree(ulpi);
+	if (ret)
 		return ret;
-	}
 
 	ret = ulpi_read_id(ulpi);
-	if (ret) {
-		of_node_put(ulpi->dev.of_node);
-		kfree(ulpi);
+	if (ret)
 		return ret;
-	}
 
-	ret = device_register(&ulpi->dev);
-	if (ret) {
-		put_device(&ulpi->dev);
+	ret = device_add(&ulpi->dev);
+	if (ret)
 		return ret;
-	}
 
 	dev_dbg(&ulpi->dev, "registered ULPI PHY: vendor %04x, product %04x\n",
 		ulpi->id.vendor, ulpi->id.product);
@@ -291,9 +287,10 @@ struct ulpi *ulpi_register_interface(str
 	ulpi->ops = ops;
 
 	ret = ulpi_register(dev, ulpi);
-	if (ret)
+	if (ret) {
+		put_device(&ulpi->dev);
 		return ERR_PTR(ret);
-
+	}
 
 	return ulpi;
 }
author maintainer
#116 lore raw

PATCH 113/699 USB: usb-storage: ene_ub6250: restore media-ready check

In reply to Greg Kroah-Hartman

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

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

From: Xu Rao <[email protected]>

commit 5fc3f333c001f1e308bbcdeecdec0d054d24338b upstream.

Commit 1892bf90677a ("USB: usb-storage: Fix use of bitfields for hardware data in ene_ub6250.c") converted the media status fields from bitfields to bit masks.

The original ene_transport() test called ene_init() only when neither media type was ready:

        !(sd_ready || ms_ready)

The converted test became:

        !sd_ready || ms_ready

This is not equivalent. Restore the original semantics by testing that both ready bits are clear before calling ene_init().

Fixes 1892bf90677a ("USB: usb-storage: Fix use of bitfields for hardware data in ene_ub6250.c")
Cc stable <[email protected]>
---
 drivers/usb/storage/ene_ub6250.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/usb/storage/ene_ub6250.c +2 -1
@@ -2305,7 +2305,8 @@ static int ene_transport(struct scsi_cmn
 
 	/*US_DEBUG(usb_stor_show_command(us, srb)); */
 	scsi_set_resid(srb, 0);
-	if (unlikely(!(info->SD_Status & SD_Ready) || (info->MS_Status & MS_Ready)))
+	if (unlikely(!(info->SD_Status & SD_Ready) &&
+		     !(info->MS_Status & MS_Ready)))
 		result = ene_init(us);
 	if (result == USB_STOR_XFER_GOOD) {
 		result = USB_STOR_TRANSPORT_ERROR;
author maintainer
#117 lore raw

PATCH 114/699 usbip: tools: support SuperSpeedPlus devices

In reply to Greg Kroah-Hartman

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

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

From: Yichong Chen <[email protected]>

commit 195e667c8719480c320cd48ac0fbf1cb81d6ffe0 upstream.

USB devices running at SuperSpeedPlus report "10000" or "20000" in their sysfs speed attribute. usbip currently maps only "5000" to USB_SPEED_SUPER, so a SuperSpeedPlus device is imported as USB_SPEED_UNKNOWN.

The attach request is then rejected by vhci_hcd:

vhci_hcd: Failed attach request for unsupported USB speed: UNKNOWN

Map the SuperSpeedPlus sysfs speed values to USB_SPEED_SUPER_PLUS, use the SuperSpeed VHCI hub for SuperSpeedPlus devices, and recognize the gadget current_speed string used by the kernel.

Fixes b2316645ca5e ("usb: show speed "10000" in sysfs for USB 3.1 SuperSpeedPlus devices")
Cc stable <[email protected]>
---
 tools/usb/usbip/libsrc/usbip_common.c        |    2 ++
 tools/usb/usbip/libsrc/usbip_device_driver.c |    4 ++++
 tools/usb/usbip/libsrc/vhci_driver.c         |    1 +
 3 files changed, 7 insertions(+)
tools/usb/usbip/libsrc/usbip_common.c +2 -0
@@ -29,6 +29,8 @@ static const struct speed_string speed_s
 	{ USB_SPEED_HIGH, "480", "High Speed(480Mbps)" },
 	{ USB_SPEED_WIRELESS, "53.3-480", "Wireless"},
 	{ USB_SPEED_SUPER, "5000", "Super Speed(5000Mbps)" },
+	{ USB_SPEED_SUPER_PLUS, "10000", "Super Speed Plus(10000Mbps)" },
+	{ USB_SPEED_SUPER_PLUS, "20000", "Super Speed Plus(20000Mbps)" },
 	{ 0, NULL, NULL }
 };
 
tools/usb/usbip/libsrc/usbip_device_driver.c +4 -0
@@ -57,6 +57,10 @@ static struct {
 		.speed = USB_SPEED_SUPER,
 		.name = "super-speed",
 	},
+	{
+		.speed = USB_SPEED_SUPER_PLUS,
+		.name = "super-speed-plus",
+	},
 };
 
 static
tools/usb/usbip/libsrc/vhci_driver.c +1 -0
@@ -338,6 +338,7 @@ int usbip_vhci_get_free_port(uint32_t sp
 
 		switch (speed) {
 		case	USB_SPEED_SUPER:
+		case	USB_SPEED_SUPER_PLUS:
 			if (vhci_driver->idev[i].hub != HUB_SPEED_SUPER)
 				continue;
 		break;
author maintainer
#118 lore raw

PATCH 115/699 usbip: vudc: fix NULL deref in vep_dequeue()

In reply to Greg Kroah-Hartman

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

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

From: Sam Day <[email protected]>

commit c5371e0b91b24159a3ebaa61e70b0980bcf03c0a upstream.

vep_alloc_request() wasn't initializing vrequest->udc, so cancellations on the FunctionFS AIO path were arriving in vep_dequeue without a valid UDC reference.

Since vrequest->udc is never actually properly used anywhere, we opt to remove it, and update vep_dequeue to obtain a reference to the udc with ep_to_vudc(), consistent with the other vep_ ops.

AFAICT this bug has existed for ~10 years. Seems that nobody has really stressed the FunctionFS AIO path on usbip's vudc.

I tested this fix in a QEMU aarch64 guest driving FunctionFS endpoints via AIO. Before the fix, running usbip attach from the host would cause the guest to oops with the following backtrace:

Call trace:
 vep_dequeue+0x1c/0xe4 (P)
 usb_ep_dequeue+0x14/0x20
 ffs_aio_cancel+0x24/0x34
 __arm64_sys_io_cancel+0xb0/0x124
 do_el0_svc+0x68/0x100
 el0_svc+0x18/0x5c
 el0t_64_sync_handler+0x98/0xdc
 el0t_64_sync+0x154/0x158
Assisted-by opencode:openai/gpt-5.5
Cc stable <[email protected]>
Fixes b6a0ca111867 ("usbip: vudc: Add UDC specific ops")
---
 drivers/usb/usbip/vudc.h     |    1 -
 drivers/usb/usbip/vudc_dev.c |    4 +---
 2 files changed, 1 insertion(+), 4 deletions(-)
drivers/usb/usbip/vudc.h +0 -1
@@ -38,7 +38,6 @@ struct vep {
 
 struct vrequest {
 	struct usb_request req;
-	struct vudc *udc;
 	struct list_head req_entry; /* Request queue */
 };
 
drivers/usb/usbip/vudc_dev.c +1 -3
@@ -333,7 +333,6 @@ static int vep_queue(struct usb_ep *_ep,
 static int vep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
 {
 	struct vep *ep;
-	struct vrequest *req;
 	struct vudc *udc;
 	struct vrequest *lst;
 	unsigned long flags;
@@ -343,8 +342,7 @@ static int vep_dequeue(struct usb_ep *_e
 		return ret;
 
 	ep = to_vep(_ep);
-	req = to_vrequest(_req);
-	udc = req->udc;
+	udc = ep_to_vudc(ep);
 
 	if (!udc->driver)
 		return -ESHUTDOWN;