Frank Sorenson [Fri, 24 Jul 2026 16:30:35 +0000 (11:30 -0500)]
cifs: consolidate time_last_write stamp into _cifsFileInfo_put()
The time_last_write stamp was scattered across cifs_close(),
smb2_deferred_work_close(), and the three drain functions in misc.c.
This missed the case where background I/O holds the final reference
after userspace close() returns, and required explicit maintenance at
each close-path site.
Move the smp_store_release() into _cifsFileInfo_put(), immediately
before releasing open_file_lock. This single location covers all
close paths unconditionally: normal close, background I/O dropping the
final reference, deferred close via timer or external drain. The
spinlock's store-release/load-acquire pairing with is_inode_writable()
already provides the ordering guarantee documented in
is_size_safe_to_change().
Remove the now-redundant stamps from cifs_close(),
smb2_deferred_work_close(), and all six stamp sites in the misc.c
deferred-close drain functions.
Fixes: e8a8d54c2d50 ("cifs: prevent readdir from changing file size due to stale directory metadata") Signed-off-by: Frank Sorenson <sorenson@redhat.com> Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.org> Signed-off-by: Steve French <stfrench@microsoft.com>
Lenovo Legion 7 15ASH11 with AMD RYZEN AI MAX+ 392 (Strix Halo, ACP
7.0) uses Realtek ALC287 series codec and no any DMIC connected by ACP.
All DMICs directly connet with ALC codec.
Without this quirk, Input Device of Gnome Sound settings shows Internal
Stereo Microphone and Digital Microphone by default. In fact, Digital
Microphone of ACP doesn't work due to no connecting with ALC287 codec,
the Internal Stereo Microphone as analog device based on snd_hda_intel
driver can work well.
Add a DMI quirk to override the flag to 0, consistent with the existing
entry for the Lenovo Yoga Pro 7 15ASH11.
ASoC: sophgo: return 1 on volume change in cv1800b_adc_volume_set()
cv1800b_adc_volume_set() serves as the .put callback for the "Internal
I2S Capture Volume" control.
ALSA mixer control callbacks must return 1 when the register value is
modified, 0 if unchanged, or a negative error code on failure. Returning
0 unconditionally causes ALSA core to assume the value was unchanged,
suppressing SNDRV_CTL_EVENT_MASK_VALUE change notifications to userspace
sound servers (e.g. PipeWire/PulseAudio).
Fix this by comparing the new register value with the existing register
value. If unchanged, return 0; otherwise, write the updated value and
return 1.
David Corvaglia [Sun, 26 Jul 2026 06:26:05 +0000 (06:26 +0000)]
net: bridge: mrp: fix Option TLV length in MRP_Test frames
oui is a pointer, so sizeof(oui) is the pointer size. The MRA
Option TLV thus advertises a wrong length (15 vs 10 on x86_64),
causing misparsing of the frame on peers. Fix is to replace
with sizeof(*oui).
Fixes: f7458934b079 ("net: bridge: mrp: Update the Test frames for MRA") Signed-off-by: David Corvaglia <david@corvaglia.dev> Acked-by: Nikolay Aleksandrov <razor@blackwall.org> Link: https://patch.msgid.link/20260726062605.2746-1-david@corvaglia.dev Signed-off-by: Jakub Kicinski <kuba@kernel.org>
sctp_assoc_add_peer() increments the association's 16-bit transport_count
for every new unique peer. Adding the 65,536th transport wraps the count to
zero.
SCTP sock_diag uses transport_count to reserve the INET_DIAG_PEERS payload,
then copies one sockaddr_storage for every entry in transport_addr_list.
After the wrap, a diagnostic dump reserves an empty payload and writes
8 MiB of peer addresses past the skb tail.
Reject a new unique peer when transport_count has reached U16_MAX. Perform
the check after the existing-peer lookup so a duplicate address continues
to return its existing transport at the limit.
Fixes: 8f840e47f190 ("sctp: add the sctp_diag.c file") Cc: stable@vger.kernel.org Signed-off-by: Asim Viladi Oglu Manizada <manizada@pm.me> Acked-by: Xin Long <lucien.xin@gmail.com> Link: https://patch.msgid.link/20260725032053.521705-1-manizada@pm.me Signed-off-by: Jakub Kicinski <kuba@kernel.org>
netfs_alloc_folioq_buffer() may leave a partially allocated folio
queue attached to the caller's buffer pointer when it returns an error.
smb3_init_transform_rq() stores the buffer in the request only after
allocation succeeds, so the common error path cannot free a partial
allocation. Store the buffer pointer before checking the return value so
err_free releases it.
Signed-off-by: Yichong Chen <chenyichong@uniontech.com> Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Signed-off-by: Steve French <stfrench@microsoft.com>
Yuxiang Yang [Thu, 23 Jul 2026 22:56:23 +0000 (22:56 +0000)]
sctp: reject stale cookies with mismatched verification tags
sctp_unpack_cookie() skips cookie expiration checks whenever an
association already exists. This is broader than the exception in
RFC 9260 Section 5.2.4.
For an existing association, Section 5.2.4 permits an expired State
Cookie only when both Verification Tags in the cookie match the current
association. Otherwise, the packet SHOULD be discarded and a Stale
Cookie ERROR MUST be sent.
The broad check lets an expired Action A restart cookie reach
sctp_sf_do_dupcook_a(). In a runtime test with the default 60 second
cookie lifetime, replaying such a cookie after 65 seconds returned a
COOKIE-ACK and restarted the association.
Check cookie expiration unless both Verification Tags match. This
preserves the Action D exception for a lost COOKIE ACK while rejecting
expired cookies in all other cases.
Zhiling Zou [Thu, 23 Jul 2026 16:52:48 +0000 (00:52 +0800)]
net: bridge: stop fast-leave after deleting a port group
br_multicast_leave_group() iterates mp->ports with pp = &p->next in
its fast-leave path. After br_multicast_del_pg() removes p,
continuing the loop advances pp through the deleted entry.
If multicast-to-unicast was enabled, the bridge can hold multiple port
groups for the same port and group with different source MAC
addresses. Once multicast-to-unicast is disabled,
br_port_group_equal() matches those entries by port only. A fast leave
can then delete one entry and continue from its stale next pointer,
leaving mp->ports pointing at a deleted port group.
Fast leave only needs to remove one matching port group. Break after
br_multicast_del_pg() so the loop stops before dereferencing the
removed entry.
Fixes: 6db6f0eae605 ("bridge: multicast to unicast") Cc: stable@vger.kernel.org Reported-by: Vega <vega@nebusec.ai> Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai> Signed-off-by: Ren Wei <enjou1224z@gmail.com> Acked-by: Nikolay Aleksandrov <razor@blackwall.org> Link: https://patch.msgid.link/1cf0898872ef7c72d5f4c0304414a192c6dac591.1784707712.git.zhilinz@nebusec.ai Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Zhiling Zou [Thu, 23 Jul 2026 16:48:52 +0000 (00:48 +0800)]
net: ipv6: clear suppressed fib6 rule result
fib6_rule_suppress() drops a suppressed route with ip6_rt_put_flags(),
but leaves res->rt6 pointing at the released rt6_info.
If no later rule supplies a replacement, fib6_rule_lookup() still sees
res.rt6 and returns that stale dst to its caller. A suppressing rule can
therefore leak a released route back to rt6_lookup(), and the next put
hits rcuref_put_slowpath() from dst_release().
Clear res->rt6 when suppressing the route so suppressed lookups fall
through to the null dst instead of reusing the released one.
Zihan Xi [Thu, 23 Jul 2026 16:38:41 +0000 (00:38 +0800)]
tipc: avoid use-after-free in poll trace queue dumps
TIPC socket tracepoints dump queue state through tipc_sk_dump(). Most
queue-dump callsites already serialize that walk under the socket lock or
sk->sk_lock.slock, but tipc_poll() calls trace_tipc_sk_poll(...,
TIPC_DUMP_ALL, ...) without holding either lock.
That lets the poll trace path reach tipc_list_dump() and backlog head/tail
dumping while another context dequeues and frees an skb, leaving the trace
helper dereferencing a stale queue entry.
Stop the unlocked poll trace site from requesting queue dumps. Other queue
dump trace callsites keep their existing output under the locking they
already provide, while poll still emits the event itself without walking
live queue members from an unlocked context.
Fixes: b4b9771bcbbd ("tipc: enable tracepoints in tipc") Cc: stable@vger.kernel.org Reported-by: Vega <vega@nebusec.ai> Signed-off-by: Zihan Xi <zihanx@nebusec.ai> Signed-off-by: Ren Wei <enjou1224z@gmail.com> Reviewed-by: Tung Nguyen <tung.quang.nguyen@est.tech> Link: https://patch.msgid.link/f8119abd5e5ecc400597de667ae9d39656de56d0.1784794294.git.zihanx@nebusec.ai Signed-off-by: Jakub Kicinski <kuba@kernel.org>
====================
vxlan: fixes for skb header pulling, cloning, and concurrency in TX path
While working on RTNL-less fill_info for vxlan, Sashiko found annoying
pre-existing issues, adding noise to an already complex work.
This series addresses some of them in VXLAN transmit path,
primarily within route_shortcircuit(), header validation, and neighbour
lookup.
Patch 1 fixes a potential use-after-free in vxlan_xmit() caused by caching
the Ethernet header pointer ('eth') before calling route_shortcircuit(),
which can reallocate skb->head via pskb_may_pull().
Patch 2 calls skb_cow_head() in route_shortcircuit() before modifying the
Ethernet header in-place, preventing packet header corruption when the skb
is cloned (e.g., by packet sockets, tcpdump, or dev_queue_xmit).
Patch 3 replaces direct reads of n->ha in route_shortcircuit() with
neigh_ha_snapshot() to safely snapshot the neighbour hardware address
under seqlock protection, avoiding potential torn reads during
asynchronous updates.
Patch 4 changes route_shortcircuit() to use pskb_network_may_pull() instead
of pskb_may_pull(). Since skb->data points to the MAC header on transmit
(skb_network_offset(skb) == ETH_HLEN), pskb_may_pull() was only checking
6 bytes into the IP header, leaving the remainder un-pulled in non-linear
frags.
Patch 5 applies pskb_network_may_pull() to the remaining transmit-path
header pull checks in arp_reduce(), ND solicitation proxy checks, and
MDB entry lookup, where skb->data similarly points to the Ethernet header.
====================
Eric Dumazet [Thu, 23 Jul 2026 14:42:49 +0000 (14:42 +0000)]
vxlan: use pskb_network_may_pull() for transmit path header pulls
In vxlan_xmit(), arp_reduce(), and vxlan_mdb_entry_skb_get(), pskb_may_pull() was
being called to verify the availability of network layer headers (ARP, IPv6/ND,
IP/IPv6 MDB keys).
However, during transmit skb->data points to the MAC header, so skb_network_offset(skb)
is ETH_HLEN (14 bytes). Using pskb_may_pull(skb, len) only checks len bytes from skb->data
rather than skb_network_offset(skb) + len, which can leave part of the network header
in non-linear frags.
Replace these remaining pskb_may_pull() calls with pskb_network_may_pull() to properly
account for the MAC header offset.
Fixes: e4f67addf158 ("add DOVE extensions for VXLAN") Fixes: f564f45c4518 ("vxlan: add ipv6 proxy support") Fixes: 0f83e69f44bf ("vxlan: Add MDB data path support") Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: stable@vger.kernel.org Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/20260723144249.759100-6-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Eric Dumazet [Thu, 23 Jul 2026 14:42:48 +0000 (14:42 +0000)]
vxlan: use pskb_network_may_pull() in route_shortcircuit()
route_shortcircuit() currently calls pskb_may_pull(skb, sizeof(struct iphdr))
(or ipv6hdr), which checks if bytes are available starting from skb->data.
However, in vxlan_xmit(), skb->data points to the MAC header, so
skb_network_offset(skb) is ETH_HLEN (14 bytes). Using pskb_may_pull(skb, 20)
only checks 20 bytes from skb->data (which is 14 bytes MAC header + 6 bytes of
IP header), leaving the rest of the IP header potentially un-pulled in non-linear
frags. Subsequent dereferences of ip_hdr(skb)->daddr can read beyond the pulled
linear buffer length.
Fix this by using pskb_network_may_pull(), which adds skb_network_offset(skb) to
the length check to ensure the full network header is present in the linear buffer.
Fixes: e4f67addf158 ("add DOVE extensions for VXLAN") Cc: stable@vger.kernel.org Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev> Link: https://patch.msgid.link/20260723144249.759100-5-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Eric Dumazet [Thu, 23 Jul 2026 14:42:47 +0000 (14:42 +0000)]
vxlan: use neigh_ha_snapshot() in route_shortcircuit()
The neighbour hardware address n->ha can be updated asynchronously by the
neighbour subsystem, protected by n->ha_lock seqlock. Reading n->ha without
holding the seqlock loop can lead to torn reads or reading a partially updated
MAC address.
Use neigh_ha_snapshot() in route_shortcircuit() to safely copy n->ha under
read_seqbegin()/read_seqretry() lock protection before using it.
Note that arp_reduce() and neigh_reduce() seem to have the same issue
left for future patches.
Fixes: e4f67addf158 ("add DOVE extensions for VXLAN") Cc: stable@vger.kernel.org Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev> Link: https://patch.msgid.link/20260723144249.759100-4-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Eric Dumazet [Thu, 23 Jul 2026 14:42:46 +0000 (14:42 +0000)]
vxlan: unclone skb head before modifying eth header in route_shortcircuit()
When route_shortcircuit() performs L3 short-circuit routing, it modifies
the Ethernet header of the skb in-place:
memcpy(eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest, dev->addr_len);
memcpy(eth_hdr(skb)->h_dest, n->ha, dev->addr_len);
If the incoming skb is cloned (for example by packet sockets, tcpdump, or
dev_queue_xmit), modifying the Ethernet header without uncloning can corrupt
the packet header for other readers holding a reference to the cloned skb.
Ensure the skb header is writable and unshared by calling skb_cow_head(skb, 0)
prior to updating the Ethernet header. If skb_cow_head() fails, abort short-circuiting
and return false to allow standard packet processing fallback.
Eric Dumazet [Thu, 23 Jul 2026 14:42:45 +0000 (14:42 +0000)]
vxlan: re-fetch eth header after route_shortcircuit()
Before route_shortcircuit(), the eth header pointer is cached from eth_hdr(skb).
Inside route_shortcircuit(), pskb_may_pull() can be called, which may
reallocate skb->head.
In this case, returning to vxlan_xmit() leaves the cached eth pointer pointing to
freed memory, leading to a use-after-free when dereferencing eth->h_dest.
Fix this by updating eth = eth_hdr(skb) after calling route_shortcircuit().
Fixes: ae8840825605 ("VXLAN: Allow L2 redirection with L3 switching") Cc: stable@vger.kernel.org Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev> Link: https://patch.msgid.link/20260723144249.759100-2-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
hwmon: (nct6775-core) Prevent access to unsupported weight registers
Sashiko reports:
During initialization of the nct6116 chip, the driver sets data->pwm_num
to 5. However, it assigns several NCT6106 register arrays (such as
NCT6106_REG_WEIGHT_DUTY_STEP, NCT6106_REG_WEIGHT_TEMP_SEL, and
NCT6106_REG_WEIGHT_TEMP_*) to data->REG_PWM and data->REG_WEIGHT_TEMP.
These arrays only contain 3 elements.
In nct6775_update_pwm(), the driver iterates up to data->pwm_num. If
data->has_pwm has bits 3 or 4 set (which is structurally possible for
nct6116), the loop attempts to read elements at index 3 and 4 from these
3-element arrays. This results in a global out-of-bounds read, which can
be caught by KASAN.
Furthermore, the driver uses these garbage out-of-bounds values as
hardware register addresses for subsequent read and write operations. This
leads to invalid hardware register access, potentially causing hardware
misconfiguration or system crashes.
The underlying problem is that the chip does support up to five fan
control channels, but only the first three support weight control.
Fix the problem by extending the affected weight register arrays with
zeroed fields. The driver uses zeroed register addresses to determine
if a register is supported or not, and skips accesses for unsupported
registers.
Reported-by: Sashiko <sashiko-bot@kernel.org> Fixes: 29c7cb485b32 ("hwmon: (nct6775) Integrate new model nct6116") Cc: Björn Gerhart <gerhart@posteo.de> Cc: Florian Bezdeka <florian.bezdeka@siemens.com> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Merge tag 'mm-hotfixes-stable-2026-07-27-14-18' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
Pull misc fixes from Andrew Morton:
"13 hotfixes. All are cc:stable. 11 are for MM. All are singletons -
please see the changelogs for details"
* tag 'mm-hotfixes-stable-2026-07-27-14-18' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm:
fs/proc/task_mmu: fix PAGEMAP_SCAN written state for PMD holes
mm/hugetlb: fix list corruption in allocate_file_region_entries()
mm: mglru: fix stale batch updates after memcg reparenting
selftest: fix headers in fclog.c
ocfs2: fix boundary check in ocfs2_check_dir_entry() to use buffer offset
mm/percpu-km: fix bitmap overflow and accounting in pcpu_create_chunk()
mm/util: don't read __page_2 for order-1 folios in snapshot_page()
mm/hugetlb: fix swap entry corruption when clearing uffd-wp at fork()
mm: migrate_device: fix pte_pfn/pte_dirty called on non-present PTE
fs/proc/task_mmu: fix PAGEMAP_SCAN written state for unpopulated ptes
userfaultfd: wait on source PMD during UFFDIO_MOVE
lib: test_hmm: use device devt for coherent device range selection
mm/vmstat: fold stranded per-cpu node stats when a node comes online
hwmon: (lm63) Mask PWM frequency multiplier to supported bits
Sashiko is concerned that reading a PWM frequency multiplier outside
the supported range of [1, 31] might result in bad PWM values written
to the chip. Technically, the chip should never return a value with
the upper 3 bits set, so this should never happen. However, it is
unknown if there are LM63 variants where the upper bits of the register
can be written.
Mask the register value read from the chip to only accept the lower 5 bit
when reading it from the chip to avoid the problem.
Merge tag 'for-next-keys-7.2-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd
Pull keys fixes from Jarkko Sakkinen:
- An unprivileged keyring whose keys collide through the
description-chunk path can drive assoc_array node splitting
into an out-of-bounds slot write. Fix it.
- Fix the DCP trusted keys backend
* tag 'for-next-keys-7.2-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd:
assoc_array: trim the final shortcut word using the current chunk end
keys: make keyring key-chunk byte order agree with keyring_diff_objects()
keys: fix out-of-bounds read in keyring_get_key_chunk()
KEYS: trusted: dcp: fix key_len validation and calc_blob_len() return type
i2c: jz4780: Cache host clock rate at probe to prevent CCF prepare_lock deadlock
Fix a severe AB/BA deadlock between the Common Clock Framework (CCF)
and the I2C adapter lock, which triggers when an I2C-controlled clock
generator client (like the Si5351) is registered or modified under the CCF.
During an i2c client clock (generator) frequency change, the CCF acquires its global
'prepare_lock' mutex and the driver calls i2c_transfer() to update the client's
chip registers, stalling for the adapter's I2C bus lock.
Concurrently, an independent, parallel transfer on the same bus (e.g., a GPIO
expander handling LEDs) can hold the I2C adapter lock. Inside this parallel
transfer path, jz4780_i2c_set_speed() calls clk_get_rate() on the host
controller's input clock to calculate bus timings. This call attempts to acquire
the blocked CCF 'prepare_lock', creating a circular dependency that freezes
the system.
The jz4780 host controller clock itself is static and never changes at runtime.
However, calling clk_get_rate() inside the active transfer path introduces
an unnecessary dependency on the CCF internal locks.
Eliminate this synchronous clk_get_rate() call from the active transfer
path by caching the static host peripheral clock rate once - inside the private
jz4780_i2c structure during jz4780_i2c_probe(). Update jz4780_i2c_set_speed()
to use this cached value, safely decoupling active I2C transactions from the
CCF internal locks without any risk of stale timings.
Assisted-by web based Google AI (pinpointing the bug and writing the message).
Eric Dumazet [Fri, 24 Jul 2026 07:29:01 +0000 (07:29 +0000)]
net: do not send ICMP/NDISC Redirects when peer allocation fails
When inet_getpeer_v4() or inet_getpeer_v6() fails to allocate a peer entry
under memory pressure or tree size caps, redirect handlers previously fell
back to sending un-rate-limited ICMP/NDISC Redirect messages.
In IPv4, ip_rt_send_redirect() called icmp_send() directly when peer == NULL.
In IPv6, ip6_forward() and ndisc_send_redirect() passed a NULL peer into
inet_peer_xrlim_allow(), which returned true when peer == NULL.
Because ICMP/NDISC Redirects are not part of the default global rate limit
mask (sysctl_icmp_ratemask), sending redirects when peer == NULL creates
an un-rate-limited ICMP packet storm.
Fix this by failing closed in ip_rt_send_redirect(), ip6_forward(), and
ndisc_send_redirect() when peer is NULL.
Fixes: 92d868292634 ("inetpeer: Move ICMP rate limiting state into inet_peer entries.") Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/20260724072901.1633601-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Myeonghun Pak [Tue, 21 Jul 2026 14:41:47 +0000 (23:41 +0900)]
i2c: amd-mp2: Unregister callback on adapter add failure
amd_mp2_register_cb() stores the platform I2C context in the MP2 PCI
driver's callback table before the adapter is registered. If
i2c_add_adapter() fails, probe returns and devres frees the context,
but the PCI driver can still dereference the stale pointer from its IRQ
and system-sleep callbacks.
Unregister the callback before returning the adapter registration error.
Fixes: 529766e0a011 ("i2c: Add drivers for the AMD PCIe MP2 I2C controller") Co-developed-by: Ijae Kim <ae878000@gmail.com> Signed-off-by: Ijae Kim <ae878000@gmail.com> Signed-off-by: Myeonghun Pak <mhun512@gmail.com> Cc: <stable@vger.kernel.org> # v5.2+ Signed-off-by: Andi Shyti <andi.shyti@kernel.org> Link: https://lore.kernel.org/r/20260721144147.31150-1-mhun512@gmail.com
Linmao Li [Thu, 23 Jul 2026 02:11:40 +0000 (10:11 +0800)]
i2c: spacemit: request IRQ after controller initialization
spacemit_i2c_probe() requests the IRQ before it enables the clocks, resets
the controller and runs init_completion(). If an interrupt is already
pending, the handler runs too early: it reads registers while the clocks
are still off and calls complete() on an uninitialized completion. Request
the IRQ after the controller and completion are initialized, but still
before the adapter is registered.
Fixes: 5ea558473fa3 ("i2c: spacemit: add support for SpacemiT K1 SoC") Signed-off-by: Linmao Li <lilinmao@kylinos.cn> Cc: <stable@vger.kernel.org> # v6.15+ Reviewed-by: Troy Mitchell <troy.mitchell@linux.spacemit.com> Reviewed-by: Alex Elder <elder@riscstar.com> Signed-off-by: Andi Shyti <andi.shyti@kernel.org> Link: https://lore.kernel.org/r/20260723021140.2293844-1-lilinmao@kylinos.cn
When send_output_report() calls hid_hw_output_report(), the underlying USB
HID core calls usb_interrupt_msg() which maps this buffer directly for DMA.
When the DMA mapping flushes or invalidates the cacheline, it will corrupt
the adjacent variables (mutex, update_interval) that were modified
concurrently by the CPU. This causes memory corruption due to cacheline
sharing on non-coherent CPU architectures (such as ARM or MIPS). The DMA
API debugging tool (CONFIG_DMA_API_DEBUG) will trigger runtime warnings
for this violation.
Any operation that triggers send_output_report() (like setting a fan speed
or updating the interval) causes the USB DMA mapping. On systems with
non-coherent caches, this structural bug causes immediate and deterministic
memory corruption.
Align the output buffer to ARCH_DMA_MINALIGN to fix the problem.
Reported-by: Sashiko <sashiko-bot@kernel.org> Fixes: 53e68c20aeb1 ("hwmon: add driver for NZXT RGB&Fan Controller/Smart Device v2.") Cc: Aleksandr Mezin <mezin.alexander@gmail.com> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
hwmon: (lm90) Only report alarms if driver is ready
Userspace can read sysfs attributes before driver registration is complete,
immediately after devm_hwmon_device_register_with_info() has been called.
At that time, data->hwmon_dev is not yet initialized. This can trigger
a NULL pointer access since lm90_update_device() and with it
lm90_update_alarms_locked() will be called. This call schedules
report_work and lm90_report_alarms(), which passes the still-NULL
data->hwmon_dev to hwmon_notify_event() and triggers a NULL pointer
dereference.
Fix the problem by only scheduling the report and alert workers
data->hwmon_dev is set.
In sht3x_update_client(), the 16-bit temperature and humidity values are
extracted from a stack-allocated byte array using be16_to_cpup(). The
pointers passed to this function are calculated as buf and buf + 3. Since
the difference between the two pointers is an odd number of bytes, at
least one of them is guaranteed to be at an unaligned offset.
This will trigger an alignment fault on strict-alignment architectures
such as ARMv5 or SPARC, resulting in a kernel panic.
Fix the problem by using get_unaligned_be16() instead of be16_to_cpup(),
and put_unaligned_be16() instead of cpu_to_be16().
Fixes: 7c84f7f80d6f ("hwmon: add support for Sensirion SHT3x sensors") Reported-by: Sashiko <sashiko-bot@kernel.org> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Guenter Roeck [Wed, 5 Feb 2025 20:27:15 +0000 (12:27 -0800)]
hwmon: (ltc4282) Fix reading the minimum alarm voltage
Coverity reports an out-of-bounds access when reading the minimum alarm
voltage for the VGPIO channel. Add the missing return statement to fix
the problem.
Fixes: cbc29538dbf7 ("hwmon: Add driver for LTC4282") Cc: Nuno Sa <nuno.sa@analog.com> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Guenter Roeck [Wed, 10 Jun 2026 14:46:16 +0000 (07:46 -0700)]
hwmon: (ina2xx) Fix various overflow issues
Sashiko reports several integer overflow problems in the ina2xx driver
caused by unbounded multiplications and inadequate types for intermediate
calculations.
Specifically:
- In ina2xx_get_value(), the return type is changed from int to long.
Intermediate calculations for current are now performed using 64-bit
types to prevent 32-bit integer overflow before the division by 1000.
- When calculating power in ina2xx_get_value() and
sy24655_average_power_read(), interim values are cast to u64 and clamped
to LONG_MAX. This prevents overflow when regval or accumulator_24 is
multiplied by power_lsb_uW.
- In ina226_alert_to_reg(), the clamping logic is rewritten using min_t().
This safely avoids integer overflows when scaling user-provided values
for shunt voltage, bus voltage, power, and current limits.
Vincent Jardin [Thu, 23 Jul 2026 15:44:56 +0000 (17:44 +0200)]
hwmon: (pmbus/core) notify on the hwmon device, not the i2c client
pmbus_notify() calls sysfs_notify() and kobject_uevent() on the i2c
client's kobject, but the alarm attributes live on the hwmon class
device registered by pmbus_do_probe(). Notifying the parent i2c device
is a no-op for both poll(POLLPRI) waiters and udev listeners: the named
attribute does not exist on that kobject.
Notify the hwmon device instead, so poll() wakes up and "change"
uevents fire on the inX_alarm/tempX_alarm attributes when SMBALERT#
reports a fault.
hwmon: (nct6775-core) Fix number of temperature registers for NCT6116
Unlike NCT6106, NCT6116 only has three temperature registers, and with
it only three temperature source and temperature source configuration
registers. The register addresses match those of NCT6106 and can be
re-used.
The code used a separate array to list the temperature source registers
for NCT6116, but used the size of the NCT6106 register array to set
the number of registers. The NCT6106 register array provides six addresses,
while the temperature source register array for NCT6116 only provides three
addresses. This causes a KASAN report.
BUG: KASAN: global-out-of-bounds in nct6775_probe+0x936/0x46f0 [nct6775]
Read of size 2 at addr ffffffffc19561a6 by task modprobe/954
...
Call Trace:
dump_stack+0x7d/0xa7
print_address_description.constprop.0+0x1c/0x220
? __kasan_kmalloc.constprop.0+0xc9/0xd0
? __kmalloc_node_track_caller+0x194/0x5b0
? nct6775_probe+0x936/0x46f0 [nct6775]
? nct6775_probe+0x936/0x46f0 [nct6775]
...
Fix the problem by hard-coding the number of temperature and temperature
configuration registers to three for NCT6116. Drop the unnecessary
NCT6116_REG_TEMP_SOURCE array and re-use NCT6106_REG_TEMP_SOURCE.
Reported-by: Florian Bezdeka <florian.bezdeka@siemens.com> Closes: https://lore.kernel.org/linux-hwmon/57cfc3fa-d4e9-4c10-8aa7-4ad0af7ebebe@roeck-us.net/T/#t Fixes: 29c7cb485b32 ("hwmon: (nct6775) Integrate new model nct6116") Cc: Björn Gerhart <gerhart@posteo.de> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
spi: spi-cadence: Move TX FIFO full busy-wait into FIFO
SPI host transfers could intermittently stall with spi_transfer timeouts.
The TXFULL condition was checked only once in cdns_transfer_one() before
cdns_spi_process_fifo(), so if the FIFO became full again during refill,
writes could be dropped and the transfer would never complete.
Move the TXFULL busy-wait into the TX path of cdns_spi_process_fifo() so
the 10µs back-off is applied per FIFO entry during filling, ensuring
forward progress and eliminating spurious timeouts.
Restrict the delay to host mode using spi_controller_is_target(), the
controller is passed into cdns_spi_process_fifo() so the check is made at
the point of use. In target mode this delay must not run as it causes the
target to miss its transfer window and corrupt data.
Fixes: 49530e641178 ("spi: cadence: Add usleep_range() for cdns_spi_fill_tx_fifo()") Signed-off-by: Srikanth Boyapally <srikanth.boyapally@amd.com> Reviewed-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com> Link: https://patch.msgid.link/20260720125510.60166-1-srikanth.boyapally@amd.com Signed-off-by: Mark Brown <broonie@kernel.org>
ASoC: tas2781: Use correct calibration data for SINEGAIN2 register
The SINEGAIN2_REG case in cali_reg_update() references t->sin_gn[]
rather than t->sin_gn2[], causing the second pilot tone gain
calibration to be programmed with the wrong register address.
These are distinct fields in struct fct_param_address and are
populated from separate firmware parameters by the parser in
tas2781-fmwlib.c.
Mark Brown [Mon, 27 Jul 2026 17:47:11 +0000 (18:47 +0100)]
ASoC: Fix races on creation of SDCA jack detection
Charles Keepax <ckeepax@opensource.cirrus.com> says:
Currently there exists a couple races that can result in the DAPM graph
coming up in a state that doesn't match the hardware with respect to
SDCA jack detection. This series fixes these up by adding a component
level fixup_controls helper into the asoc core and shuffling around the
IRQ requests from the SDCA side.
The core creates DAPM widgets/routes quite a long time before
it creates the associated ALSA control, and the jack detection
IRQ is currently registered in component probe. At the time of
component probe, the DAPM widgets exist, shortly after this the
DAPM routes are added. At the time the DAPM routes are added the
register value for the control is checked and the appropriate path
is connected. The existing handling in the SDCA jack IRQ handles
the case the control doesn't exist and updates the registers
directly, which works until the DAPM routes are added. After the
routes are added the DAPM graph has already set connected on a
particular DAPM path, which will not be updated until an IRQ is
received when the control is present. Thus those updates are
usually not reflected in the resulting DAPM graph which can lead
to the audio path being erroneously powered on/off.
Charles Keepax [Tue, 21 Jul 2026 14:36:36 +0000 (15:36 +0100)]
ASoC: SDCA: Move kcontrol search out of IRQ
Now that the IRQs are always registered after all the ALSA
controls are created it is possible to search for the control
at the point the IRQ is requested. Move the control search out
of the IRQ handler and do it at IRQ request time.
This also fixes a potential issue when the card was torn down
and reprobed without destroying the codec device, the kctl
pointer stored by the IRQ handler would not be updated to the
new control on the second probe.
Charles Keepax [Tue, 21 Jul 2026 14:36:35 +0000 (15:36 +0100)]
ASoC: SDCA: Switch to fixup_controls callback for IRQ registration
Currently there are some race conditions around the boot of SDCA
jack detection. The core creates DAPM widgets/routes quite a
long time before it creates the associated ALSA control, and
the jack detection IRQ is currently registered in component
probe. At the time of component probe, the DAPM widgets exist,
shortly after this the DAPM routes are added. At the time the DAPM
routes are added the register value for the control is checked
and the appropriate path is connected. The existing handling
in the SDCA jack IRQ handles the case the control doesn't exist
and updates the registers directly, which works until the DAPM
routes are added. After the routes are added the DAPM graph has
already set connected on a particular DAPM path, which will not
be updated until an IRQ is received when the control is present.
Thus those updates are usually not reflected in the resulting
DAPM graph which can lead to the audio path being erroneously
powered on/off.
Switch to the new fixup_controls callback to register the
IRQs, this is guaranteed to run after all the controls have
been created. Which means we can avoid the aforementioned race
condition and as a bonus no longer need to concern ourselves
with a case where the IRQ handler runs and the ALSA control
is unavailable.
This allowed the machine driver to take actions after all the
card controls have been added. However, there are times when a
codec driver would also want to do things like obtain references
to controls for later use, which require all the controls to be
present. Add a component level fixup_controls callback, echoing
the card level option.
Charles Keepax [Tue, 21 Jul 2026 14:36:33 +0000 (15:36 +0100)]
ASoC: SDCA: Populate IRQ data earlier
Currently, the IRQ data (attached Entity/Control/etc) is populated
as the IRQ is requested. However, this can cause issues as
occasionally the setup process wants to access specifics of
an IRQ before the IRQ is actually enabled. To facilitate this
cache all the IRQ data during sdca_irq_populate_early() and make
sdca_irq_populate() simply request the outstanding IRQs. This
also has the advantage that sdca_irq_populate() can now just
iterate through the IRQ array which is much smaller/faster than
going through every Entity in the Function for Controls.
Charles Keepax [Tue, 21 Jul 2026 14:36:31 +0000 (15:36 +0100)]
ASoC: SDCA: Add sdca_irq_cleanup_late()
The SDCA IRQs are split into two groups, those registered at bus probe
time (basically just FDL) and those registered at component time.
There currently exists only a single cleanup function, if the FDL IRQ
is freed at component time, then nothing would re-register it if the
component is probed again. But the IRQs depending on a component need
to be freed if the card is destroyed so they can't use stale
components.
Split the clean up into two functions one for the component level and
one for the bus level.
Ming Lei [Sun, 26 Jul 2026 14:50:25 +0000 (09:50 -0500)]
ublk: reset kernel-owned dev_info fields in ublk_ctrl_add_dev()
ublk_ctrl_add_dev() memcpy()s the userspace ublksrv_ctrl_dev_info into
ub->dev_info and then fixes up the fields the driver owns, but misses
->state and ->ublksrv_pid.
A device added with ->state = UBLK_S_DEV_LIVE passes the
"->state != UBLK_S_DEV_DEAD" test that ublk_stop_dev_unlocked() uses as its
proxy for "a disk is attached", while ->ub_disk is still NULL, so DEL_DEV
right after ADD_DEV oopses in del_gendisk(). UBLK_S_DEV_QUIESCED plus
UBLK_F_USER_RECOVERY dies one step earlier, in ublk_force_abort_dev(). A
poisoned ->state also gets START_USER_RECOVERY and the char device
read/write path onto a device that was never started, and wedges START_DEV
at -EEXIST. A poisoned ->ublksrv_pid just makes GET_DEV_INFO report an
unrelated task as the ublk server.
Reset both after the memcpy(), as ublk_detach_disk() does. Userspace only
ever reads these back, so correcting them silently breaks nothing.
ADD_DEV has copied ->state in unsanitized since ublk was merged, but back
then it was harmless: the gendisk was allocated during ADD_DEV, and both
teardown and the START_DEV -EEXIST check keyed off disk_live() rather than
->state. The oops became reachable once the disk allocation moved to
START_DEV and those checks switched to ->state.
Fixes: 6d9e6dfdf3b2 ("ublk: defer disk allocation") Cc: stable@vger.kernel.org Signed-off-by: Ming Lei <tom.leiming@gmail.com> Reviewed-by: Caleb Sander Mateos <csander@purestorage.com> Link: https://patch.msgid.link/20260726145025.1507383-1-tom.leiming@gmail.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
Merge tag 'erofs-for-7.2-rc6-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs
Pull erofs fixes from Gao Xiang:
"Fix a regression in page cache sharing which can cause a NULL pointer
dereference, and limit LZMA stream memory usage on systems with many
CPUs.
- Keep a valid f_path for page cache sharing to fix a recent
mincore() NULL pointer dereference
- Limit LZMA stream pool size when too many processors are available
- Sync up with Hongbo Li's latest email address"
* tag 'erofs-for-7.2-rc6-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs:
erofs: cap LZMA stream pool size
erofs: ensure valid f_path for page cache sharing
MAINTAINERS: update Hongbo Li's email address
Merge tag 'pinctrl-v7.2-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl
Pull pin control fixes from Linus Walleij:
"The most interesting commit is the S4 fix for AMD, which probably is
helpful to a whole bunch of important machines.
- Wakeup nits on the Qualcomm SC8280XP
- Double-free issues on the device tree parsing error path
- Fixup of the S4 sleep state handling on AMD pin control
- Missing Kconfig select REGMAP_MMIO for the Microchip driver leading
to compile stalls
- Missing Kconfig select GENERIC_PINCONF for the Bitmain BM1880
leading to compile stalls"
* tag 'pinctrl-v7.2-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl:
pinctrl: bm1880: add missing select GENERIC_PINCONF
pinctrl-amd: Don't clear S4 wake bits at probe
pinctrl: microchip-sgpio: add missing select REGMAP_MMIO
pinctrl: devicetree: don't free uninitialized dev_name on error path
pinctrl: qcom: sc8280xp: Add missing wakeup entries for GPIO143/151
pinctrl: qcom: Unconditionally mark gpio as wakeup enable
Zack Rusin [Tue, 5 May 2026 22:22:33 +0000 (18:22 -0400)]
drm/vmwgfx: validate external BO copy bounds for both stride paths
vmw_external_bo_copy() trusts caller-supplied offsets, strides, and
heights and operates on imported dma-buf vmaps:
- The equal-stride memcpy() bound was clamped after subtracting the
offsets from dst_size and src_size; an offset larger than the BO
size wraps the unsigned subtraction to a huge value and the
resulting memcpy() runs off the end of the vmap. dst_stride *
height is also a u32 multiplication that can overflow.
- The non-equal-stride row-by-row path had no bound at all. The
loop touches bytes through offset + (height - 1) * stride +
width_in_bytes, with only a WARN_ON(dst_stride < width_in_bytes),
and could likewise step past the end of either mapping.
The offsets and strides are derived from STDU/SOU plane state, so a
configured CRTC submitting a crafted atomic commit on an imported
framebuffer can reach this path.
Validate the exact row-copy endpoint against each BO's size up front
using check_mul_overflow() and check_add_overflow(). Use the bulk
memcpy() path only when width_in_bytes covers the whole stride;
otherwise copy one row at a time so partial-row updates near the bottom
of a framebuffer remain valid. Also reject zero strides and stride <
width_in_bytes, both of which the row-by-row path cannot represent
safely.
Fixes: 50f119925091 ("drm/vmwgfx: Fix prime with external buffers") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-4.7 Signed-off-by: Zack Rusin <zack.rusin@broadcom.com> Reviewed-by: Ian Forbes <ian.forbes@broadcom.com> Link: https://patch.msgid.link/20260505222728.519626-13-zack.rusin@broadcom.com
drm_vmw_shader_create_arg::offset is __u64 in the uapi; when it is
near U64_MAX the unsigned addition wraps and the resulting tiny value
passes the check. The unbounded offset is then stored in
res->guest_memory_offset and forwarded to host SVGA shader-create
commands.
Use check_add_overflow() to detect the wrap and compare the resulting
endpoint against the buffer size.
Fixes: 668b206601c5 ("drm/vmwgfx: Stop using raw ttm_buffer_object's") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-4.7 Signed-off-by: Zack Rusin <zack.rusin@broadcom.com> Reviewed-by: Ian Forbes <ian.forbes@broadcom.com> Link: https://patch.msgid.link/20260505222728.519626-12-zack.rusin@broadcom.com
Zack Rusin [Tue, 5 May 2026 22:22:31 +0000 (18:22 -0400)]
drm/vmwgfx: skip hash_del_rcu when validation context has no hash table
vmw_validation_add_resource() calls hash_add_rcu() only when
ctx->sw_context is non-NULL, but the doomed-resource error path calls
hash_del_rcu() unconditionally. The validation contexts declared with
DECLARE_VAL_CONTEXT(_, NULL, 0) in vmwgfx_kms.c, vmwgfx_scrn.c,
vmwgfx_stdu.c and vmwgfx_execbuf.c consequently reach a delete for a
node that was never added to any hash chain.
That is harmless today, but only incidentally so. hash_del_rcu() is
hlist_del_init_rcu(), which is guarded by hlist_unhashed(), and
vmw_validation_mem_alloc() hands out memory from __GFP_ZERO pages that
are never recycled within a context's lifetime, so
node->hash.head.pprev is always NULL and the delete does nothing.
Neither property is apparent at the call site, and the asymmetry with
the add side invites a real bug the first time either one changes.
Mirror the condition from the add side so the node is only unlinked
when it was actually linked. No functional change.
Zack Rusin [Tue, 5 May 2026 22:22:30 +0000 (18:22 -0400)]
drm/vmwgfx: enforce cursor size limits for MOB cursors
vmw_cursor_plane_atomic_check() bounds cursor width and height only
on the legacy update path; the SVGA_CAP2_CURSOR_MOB path -- the
default on modern hosts -- accepts any size. When the requested size
exceeds SVGA_REG_CURSOR_MAX_DIMENSION or SVGA_REG_MOB_MAX_SIZE,
vmw_cursor_mob_get() returns -EINVAL and leaves vps->cursor.mob NULL.
Its return value is then discarded in vmw_cursor_plane_prepare_fb(),
so the subsequent vmw_cursor_update_mob() calls
vmw_bo_map_and_cache(NULL) and oopses inside
vmw_bo_map_and_cache_size() on the tbo.base.size load.
Reachable from any DRM master via DRM_IOCTL_MODE_CURSOR2 with a
sufficiently large width or height (e.g. cursor_max_dim + 1).
Reject oversized cursors in atomic_check for both MOB-backed cursor
update types. The MOB byte-size limit only applies to the
SVGA_CAP2_CURSOR_MOB path (vmw_cursor_mob_size() returns 0 for
GB_ONLY); compute the required MOB size in 64-bit to avoid overflow
when very large dimensions are requested.
In prepare_fb only call vmw_cursor_mob_get()/_map() for
VMW_CURSOR_UPDATE_MOB -- the GB_ONLY path uses bo->map.virtual
directly and would otherwise be silently downgraded to NONE on hosts
without SVGA_CAP2_CURSOR_MOB (where vmw_cursor_mob_get() always
returns -EINVAL). Degrade the update to NONE if vmw_cursor_mob_get()
or vmw_cursor_mob_map() fails so the update path does not run with a
NULL backing MOB.
Zack Rusin [Tue, 5 May 2026 22:22:29 +0000 (18:22 -0400)]
drm/vmwgfx: avoid destroy_workqueue(NULL) on vkms init failure
Two paths through vmw_vkms_init() can leave vmw->crc_workq NULL while
still leaving the rest of the driver in a state that calls
vmw_vkms_cleanup() at module unload:
1. vmw_host_get_guestinfo(GUESTINFO_VBLANK, ...) failing or
returning an oversized buffer -- the common case on hosts
without a VBLANK guestinfo entry -- early-returned before the
workqueue allocation.
2. alloc_ordered_workqueue() returning NULL on memory pressure.
vmw_vkms_cleanup() then calls destroy_workqueue(NULL), which
dereferences wq->name and panics.
Fix the first case by removing the early return: vmw->vkms_enabled
is already false on the rpci-failure path so no work will ever be
queued, and allocating the workqueue unconditionally keeps the
control flow simple. Fix the second case by guarding the cleanup
with a NULL check, since alloc_ordered_workqueue() can still fail
under low memory.
without checking that header->size is large enough to contain both
cmd->body and the suffix. An undersized header makes the suffix
pointer underflow back into the previous command in the bounce
buffer. The verifier later writes suffix->maximumOffset, clobbering
verified fields of an already-relocated earlier command -- a TOCTOU
on the device-visible command stream that lets one command rewrite
another's GMR id, surface id, or other authenticated fields.
Reject the command if the body is too small for the suffix to fit.
Fixes: 4e4ddd477743 ("drm/vmwgfx: Fix queries if no dma buffer thrashing is occuring.") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-4.7 Signed-off-by: Zack Rusin <zack.rusin@broadcom.com> Reviewed-by: Ian Forbes <ian.forbes@broadcom.com> Link: https://patch.msgid.link/20260505222728.519626-8-zack.rusin@broadcom.com
where header->size is u32 and is taken straight from the user-supplied
command stream. When header->size is less than sizeof(cmd->body) the
unsigned subtraction wraps to nearly 4 GiB, producing a huge maxnum.
Any user-controlled cmd->body.numVertexDecls then passes the bound and
the loop dereferences decl[i] far past the end of the kernel command
bounce buffer, producing an out-of-bounds read of kernel memory.
Reject undersized headers up front.
Fixes: 7a73ba7469cb ("drm/vmwgfx: Use TTM handles instead of SIDs as user-space surface handles.") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-4.7 Signed-off-by: Zack Rusin <zack.rusin@broadcom.com> Reviewed-by: Ian Forbes <ian.forbes@broadcom.com> Link: https://patch.msgid.link/20260505222728.519626-7-zack.rusin@broadcom.com
Zack Rusin [Tue, 5 May 2026 22:22:26 +0000 (18:22 -0400)]
drm/vmwgfx: drop dma_buf reference on foreign-fd prime import
ttm_prime_fd_to_handle() returns -ENOSYS when the imported fd's
dma_buf->ops do not match the ttm_object_device's ops, but does so
without releasing the reference acquired by dma_buf_get(). Any
unprivileged renderD client passing a non-vmwgfx prime fd through the
DRM_VMW_GB_SURFACE_REF{,_EXT} path leaks one dma_buf reference per
call and indefinitely pins the foreign exporter's GEM resources.
Funnel the error path through the existing dma_buf_put() so the
reference is always dropped.
Fixes: 65981f7681ab ("drm/ttm: Add a minimal prime implementation for ttm base objects") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-4.7 Signed-off-by: Zack Rusin <zack.rusin@broadcom.com> Reviewed-by: Ian Forbes <ian.forbes@broadcom.com> Link: https://patch.msgid.link/20260505222728.519626-6-zack.rusin@broadcom.com
Zack Rusin [Tue, 5 May 2026 22:22:25 +0000 (18:22 -0400)]
drm/vmwgfx: take fman->lock around fence list mutation in fifo_down
vmw_fence_fifo_down() drops fman->lock to wait on a fence and, on
timeout, mutates fman->fence_list via list_del_init() and signals
the fence without re-acquiring the lock. __vmw_fences_update() walks
and removes entries from the same list under fman->lock from any
other waiter, the fence-IRQ thread, or vmw_fences_update(), so the
unlocked list_del_init() can corrupt the list head.
Re-take fman->lock before manipulating fence->head and use
dma_fence_signal_locked(). Wrap the locked signalling in
dma_fence_begin_signalling() / dma_fence_end_signalling() so the
lockdep annotation that dma_fence_signal() previously provided is
preserved (the same pattern as __vmw_fences_update()).
dma_fence_put() is moved outside the lock to avoid a recursive
acquire from vmw_fence_obj_destroy(), which also takes fman->lock.
Zack Rusin [Tue, 5 May 2026 22:22:24 +0000 (18:22 -0400)]
drm/vmwgfx: clamp dirty-page range with min, not max
vmw_bo_dirty_transfer_to_res() and vmw_bo_dirty_clear() compute the
intersection of a resource's page range with the BO's tracked dirty
range, but clamp res_end against dirty->end with max() instead of
min(). When dirty->end exceeds the resource end, the loop walks past
the resource's pages, calls vmw_resource_dirty_update() for ranges
owned by other resources sharing the same backing MOB and clears
their pending dirty bits via bitmap_clear(). The result is silent
loss of writeback for unrelated resources whenever two resources
share a MOB.
Use min() in both functions so the loop is bounded to the
intersection of the resource and dirty ranges.
Fixes: b7468b15d271 ("drm/vmwgfx: Implement an infrastructure for write-coherent resources") Fixes: 965544150d1c ("drm/vmwgfx: Refactor cursor handling") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-4.7 Signed-off-by: Zack Rusin <zack.rusin@broadcom.com> Reviewed-by: Ian Forbes <ian.forbes@broadcom.com> Link: https://patch.msgid.link/20260505222728.519626-4-zack.rusin@broadcom.com
Zack Rusin [Tue, 5 May 2026 22:22:23 +0000 (18:22 -0400)]
drm/vmwgfx: reject DX_BIND_QUERY without a DX context
vmw_cmd_dx_bind_query() unconditionally dereferences
sw_context->dx_ctx_node->ctx. Userspace can trigger a NULL pointer
dereference from any render-node fd by submitting an execbuf with
dx_context_handle == SVGA3D_INVALID_ID and a SVGA_3D_CMD_DX_BIND_QUERY
opcode in the command stream: dx_ctx_node is left NULL and the kernel
oopses on the assignment. The same NULL is then re-read in
vmw_resources_reserve() via vmw_context_get_dx_query_mob().
All sibling DX handlers fail-close on a missing dx_ctx_node using
VMW_GET_CTX_NODE(). Use the same pattern here, returning -EINVAL up
front before any relocation state is published.
Fixes: 9c079b8ce8bf ("drm/vmwgfx: Adapt execbuf to the new validation api") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-4.7 Signed-off-by: Zack Rusin <zack.rusin@broadcom.com> Reviewed-by: Ian Forbes <ian.forbes@broadcom.com> Link: https://patch.msgid.link/20260505222728.519626-3-zack.rusin@broadcom.com
Zack Rusin [Tue, 5 May 2026 22:22:22 +0000 (18:22 -0400)]
drm/vmwgfx: fix guest_memory_dirty bitfield clobbered as size
Two sites in vmwgfx_resource.c assign boolean literals to
res->guest_memory_size, which is an unsigned long allocation-size
field; the intended target is the adjacent res->guest_memory_dirty
bitfield. After the assignments the field holds 0 or 1 instead of
the resource's MOB allocation size:
Subsequent revalidation paths read guest_memory_size when computing
the dirty page range (vmw_bo_dirty_transfer_to_res()) and the buffer
allocation size (vmw_resource_buf_alloc()), producing zero-length
walks or wrap-around ranges that read or write past the MOB bitmap.
The dirty-tracking intent of the original code (mark the resource as
dirtied since the last sync) is also lost, since guest_memory_dirty
is never updated.
Rename both assignments to guest_memory_dirty.
Fixes: 668b206601c5 ("drm/vmwgfx: Stop using raw ttm_buffer_object's") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-4.7 Signed-off-by: Zack Rusin <zack.rusin@broadcom.com> Reviewed-by: Ian Forbes <ian.forbes@broadcom.com> Link: https://patch.msgid.link/20260505222728.519626-2-zack.rusin@broadcom.com
wifi: ath12k: resolve PENDING ML peer ID from MLO_PEER_MAP HTT event
Add ath12k_dp_peer_fixup_peer_id() and call it from the
HTT_T2H_MSG_TYPE_MLO_RX_PEER_MAP handler. For devices where the
firmware allocates the MLD peer ID, this is the point at which
all data structures that were left with ATH12K_MLO_PEER_ID_PENDING
or ATH12K_MLO_PEER_ID_INVALID get their real ID:
- dp_peer->peer_id is updated and the dp_peer is published into
dp_hw->dp_peers[];
- every existing dp_link_peer in dp_peer->link_peers[] gets its
ml_id set to the same value;
- ahsta->ml_peer_id is updated to the same value so peer_assoc,
sta_state and cleanup paths see a consistent ID.
Devices with host_alloc_ml_id == true also receive the same HTT
event, but the firmware-reported ID always matches the
host-allocated one and everything has already been populated by
ath12k_dp_peer_create(); Skips the helper entirely on those devices.
wifi: ath12k: defer dp_peer registration when firmware allocates MLD peer ID
For chips with host_alloc_ml_id=true (QCN9274 etc.), the host allocates
the MLD peer ID up front; ath12k_dp_peer_create() publishes the dp_peer
into dp_hw->dp_peers[] using that ID immediately. WCN7850/QCC2072 does
not work that way: the firmware picks the ID and only tells the host
afterwards via HTT_T2H_MSG_TYPE_MLO_RX_PEER_MAP, so the publication has
to be delayed until the event arrives.
Introduce ATH12K_MLO_PEER_ID_PENDING (0xFFFE) as a sentinel for "is_mlo,
but ID not yet known". On the firmware-allocates path:
- ath12k_mac_op_sta_state(NOTEXIST->NONE) skips ath12k_peer_ml_alloc()
and stores PENDING in ahsta->ml_peer_id and dp_params.peer_id;
- ath12k_dp_peer_create() skips dp_peer registration until a real ID is
known;
- ath12k_peer_create() leaves peer->ml_id at INVALID so consumer sites
do not treat PENDING as a real ID;
- ath12k_peer_ml_free() and ath12k_mac_dp_peer_cleanup() skip the
dp_peers[] write and the free_ml_peer_id_map clear when
host_alloc_ml_id is false or the ID is still PENDING.
The HTT handler change that resolves the PENDING ID is added in a
follow-up patch.
wifi: ath12k: do not advertise MLD peer ID for firmware-allocate devices
ath12k_peer_assoc_h_mlo() unconditionally sets ml->peer_id_valid and copies
ahsta->ml_peer_id (with the ATH12K_PEER_ML_ID_VALID bookkeeping bit masked
off) into the WMI_PEER_ASSOC_CMDID ML params, which causes
ath12k_wmi_send_peer_assoc_cmd() to set ATH12K_WMI_FLAG_MLO_PEER_ID_VALID.
This needs to be gated on chips where the firmware allocates the MLD peer
ID:
- WCN7850/QCC2072 firmware always picks the ID itself and does not honor
a host-supplied one, so the value would be silently ignored anyway;
- QCC2072 firmware additionally crashes during MLO disconnect when
ATH12K_WMI_FLAG_MLO_PEER_ID_VALID was set in the preceding peer assoc,
so the bit must not be sent at all.
Branch on ah->host_alloc_ml_id:
- When true (QCN9274 etc.), behavior is unchanged: peer_id_valid is set
and the raw ahsta->ml_peer_id (without the VALID bit) is sent down.
- When false (WCN7850, QCC2072), peer_id_valid stays unset and
ml_peer_id is sent as 0. The firmware ignores both fields and reports
the ID it allocated through HTT_T2H_MSG_TYPE_MLO_RX_PEER_MAP.
The early-return on ahsta->ml_peer_id == ATH12K_MLO_PEER_ID_INVALID only
applies on the host-alloc path, since on the firmware-alloc path the value
is ATH12K_MLO_PEER_ID_PENDING here, not INVALID.
Different ath12k devices diverge on who allocates MLD peer id:
WCN7850/QCC2072 have the firmware allocate it and notify the host via
HTT_T2H_MSG_TYPE_MLO_RX_PEER_MAP event; While others let the host allocate
it and pass it down through WMI_PEER_ASSOC_CMDID with
ATH12K_WMI_FLAG_MLO_PEER_ID_VALID set.
Currently ath12k host allocates this ID and sends it to firmware by
default for all devices. This breaks WCN7850/QCC2072, because the host
maintained ID may be different from the firmware-allocated one.
Consequently data path may fail to find the dp peer and drop some received
packets. From user point of view, this results in bugs reported in [1] or
the 4-way handshake timeout issue.
Add host_alloc_ml_id flag to struct ath12k_hw_params (and a copy on struct
ath12k_hw for hot-path access) so subsequent patches can branch on it. Set
true for QCN9274/IPQ5332/IPQ5424, false for WCN7850/QCC2072. The flag will
be consumed by subsequent patches.
wifi: ath12k: add support for HTT_T2H_MSG_TYPE_MLO_RX_PEER_MAP
Firmware on chips that allocate the MLD peer ID itself (WCN7850 and
QCC2072) reports the assignment back to the host through
HTT_T2H_MSG_TYPE_MLO_RX_PEER_MAP. The message carries the chosen
MLD peer id, the MLD MAC address etc.
Add the message type, the on-the-wire struct, the field masks and a
handler that parses them out. The host-side state update (publishing the
dp peer into ath12k_dp_hw::dp_peers[], propagating the ID to
ath12k_dp_link_peer::ml_id and ath12k_sta::ml_peer_id) is added in a
follow-up patch;
wifi: ath12k: keep ATH12K_PEER_ML_ID_VALID set in ath12k_sta::ml_peer_id
Several pieces of host bookkeeping for MLD peer IDs encode the
same fact in different ways:
- ath12k_sta::ml_peer_id stores the raw ID in [0, ATH12K_MAX_MLO_PEERS);
- ath12k_dp_peer::peer_id, ath12k_dp_link_peer::ml_id and the index used
on ath12k_dp_hw::dp_peers[] always carry the ATH12K_PEER_ML_ID_VALID
bit (BIT(13)) when the ID is real;
- WMI_MLO_PEER_ASSOC_PARAMS::ml_peer_id sent down to firmware is
raw, without the bookkeeping bit.
The mismatch leaks into call sites that have to remember to OR
the bit in (ath12k_peer_create(), ath12k_mac_op_sta_state()) or
remember not to (ath12k_peer_assoc_h_mlo()).
Make ath12k_sta::ml_peer_id carry the VALID bit when valid, the same
way ath12k_dp_peer::peer_id and ath12k_dp_link_peer::ml_id do:
- ath12k_peer_ml_alloc() OR-s the bit in once on the way out;
the internal bitmap stays raw [0, ATH12K_MAX_MLO_PEERS);
- ath12k_peer_create() and ath12k_mac_op_sta_state() drop the
explicit OR;
- ath12k_peer_assoc_h_mlo() masks the bit off when populating
the WMI ml_peer_id;
While there, introduce ath12k_peer_ml_free() to mirror
ath12k_peer_ml_alloc(), which helps avoid code duplication.
wifi: ath12k: factor out peer assoc send-and-wait into a helper
ath12k_bss_assoc(), ath12k_mac_station_assoc() and
ath12k_sta_rc_update_wk() all open-code the same sequence: reinit the
peer_assoc_done completion, send the peer assoc WMI command, then wait
for the firmware confirmation event. The reinit_completion() was buried
in ath12k_peer_assoc_prepare(), far from the wait_for_completion_timeout()
that consumes it, making the reinit/send/wait sequence hard to follow,
and the three open-coded copies are easy to get out of sync.
Move the sequence into a new helper ath12k_mac_peer_assoc() and call it
from all three sites. The reinit, send and wait now live together so the
completion's lifecycle is easy to read.
While at it, ath12k_sta_rc_update_wk() previously warned but still
waited the full timeout when the peer assoc command failed to send. Now
a send failure returns immediately and skips the pointless 1 second
wait, matching the other two callers.
wifi: ath12k: fix out-of-bounds clear_bit in ath12k_mac_dp_peer_cleanup()
ath12k_mac_dp_peer_cleanup() clears the ML peer ID slot on the
free_ml_peer_id_map bitmap by indexing it with dp_peer->peer_id. That is
wrong: dp_peer->peer_id for an MLO peer always carries the
ATH12K_PEER_ML_ID_VALID bit (BIT(13)), so clear_bit() is invoked with
index >= 0x2000, which is far outside the bitmap of ATH12K_MAX_MLO_PEERS
(256) bits and corrupts memory adjacent to ah->free_ml_peer_id_map. The
intended bitmap entry also never gets cleared, so subsequent
ath12k_peer_ml_alloc() calls eventually run out of IDs.
The ID without the VALID bit is what ath12k_peer_ml_alloc() returned and
is stored in ahsta->ml_peer_id. Use that instead.
While there, also reset ahsta->ml_peer_id to ATH12K_MLO_PEER_ID_INVALID so
the bitmap and ahsta->ml_peer_id stay in sync.
cpufreq: powernow-k8: Fix possible memory leak in powernowk8_cpu_init()
The memory allocated for data->powernow_table inside
powernow_k8_cpu_init_acpi() or find_psb_table() is not freed in one of
the error paths in powernowk8_cpu_init(). Fix that by adding a kfree().
Fixes: 1ff6e97f1d99 ("[CPUFREQ] cpumask: avoid playing with cpus_allowed in powernow-k8.c") Cc: stable@vger.kernel.org Signed-off-by: Abdun Nihaal <nihaal@cse.iitm.ac.in> Acked-by: Viresh Kumar <viresh.kumar@linaro.org> Reviewed-by: Zhongqiu Han <zhongqiu.han@oss.qualcomm.com> Link: https://patch.msgid.link/20260727093553.98246-1-nihaal@cse.iitm.ac.in Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Michael Diesen [Mon, 27 Jul 2026 09:19:21 +0000 (09:19 +0000)]
ALSA: hda/realtek: Add quirk for HP Dragonfly Folio G3 2-in-1 (103c:8a05)
The HP Dragonfly Folio G3 2-in-1 also ships with PCI SSID 103c:8a05.
On this unit the ALC245 codec reports subsystem id 103c:8a06 - the SSID
that is already covered by commit 0a10faad5ca5 ("ALSA: hda/realtek: add
quirk for HP Dragonfly Folio G3 2-in-1") - while the PCI SSID that
SND_PCI_QUIRK matches against is 103c:8a05:
ALSA:hda/realtek:ALC269 fixup for Legion 7 15ASH11 Mic Mute LED
Lenovo Legion 7 15ASH11 with AMD RYZEN AI MAX+ 392 (Strix Halo, ACP
7.0) uses Realtek ALC287 series codec. Its audio subsystem adopts a
hardware design similar to that of the Yoga Pro 7 15ASH11.
It shares PCI SSID 17aa:38f9 with Thinkbook 16P Gen5.
Therefore, use HDA_CODEC_QUIRK to apply ALC287_FIXUP_LENOVO_YOGA_PRO7
for identification.
After added the HDA_CODEC_QUIRK quirk special for Lenovo Legion 7
15ASH11, the mic mute LED works well.
Christian Loehle [Fri, 24 Jul 2026 10:40:42 +0000 (11:40 +0100)]
ACPI: CPPC: Skip writes to unsupported performance controls
MIN_PERF and MAX_PERF are optional CPPC controls. DESIRED_PERF is also
optional with CPPC2 when autonomous selection is supported.
The cppc-cpufreq target callbacks populate both limits for every request
without checking whether the controls are implemented. cppc_set_perf()
consequently passes NULL register descriptors to cpc_write(). The writes
fail width validation and their return values are ignored, so the failed
access paths are repeated on every target request. An autonomous-only
platform can take the same path for DESIRED_PERF.
Check that each performance control is supported before calling
cpc_write().
Fixes: ea3db45ae476 ("cpufreq: cppc: Update MIN_PERF/MAX_PERF in target callbacks") Reviewed-by: Sumit Gupta <sumitg@nvidia.com> Signed-off-by: Christian Loehle <christian.loehle@arm.com> Reviewed-by: Lifeng Zheng <zhenglifeng1@huawei.com> Link: https://patch.msgid.link/20260724104042.1481804-1-christian.loehle@arm.com Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Junjie Cao [Thu, 23 Jul 2026 01:41:29 +0000 (09:41 +0800)]
gpio: pch: use raw_spinlock_t for the register lock
pch_irq_type() is registered as the irq_chip .irq_set_type callback and
takes chip->spinlock with spin_lock_irqsave(). This callback is reached
from __setup_irq() -> __irq_set_trigger() -> chip->irq_set_type() while
the caller holds desc->lock, a raw_spinlock_t, with hardirqs disabled.
That context is not sleepable, but on PREEMPT_RT a regular spinlock_t is
an rtmutex-backed sleeping lock, so acquiring it there is invalid.
This was confirmed on a PREEMPT_RT kernel with lockdep
(PROVE_RAW_LOCK_NESTING and DEBUG_ATOMIC_SLEEP). A grounded PoC mirrored
pch_irq_type()'s locking and drove it through the real genirq carrier
irq_set_irq_type() -> __irq_set_trigger() -> chip->irq_set_type(), i.e.
the same __irq_set_trigger() edge that __setup_irq() takes for a
requested IRQ. With the original spin_lock_irqsave() edge lockdep
reported an invalid wait context, immediately followed by:
BUG: sleeping function called from invalid context at kernel/locking/spinlock_rt.c:48
in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 95, name: insmod
hardirqs last disabled at (3784): _raw_spin_lock_irqsave+0x4f/0x60
rt_spin_lock+0x3a/0x1c0
repro_irq_set_type+0x64/0xa0 [pch_repro]
__irq_set_trigger+0x69/0x140
irq_set_irq_type+0x78/0xd0
Switching the mirrored lock to raw_spinlock_t made both splats go away.
Convert the register lock to raw_spinlock_t. The same lock also
serializes the GPIO direction/value callbacks and the suspend/resume
register save/restore, but all of those critical sections only perform
MMIO register accesses (ioread32()/iowrite32()) and
irq_set_handler_locked(); none of them contain sleepable operations.
Keeping this register lock non-sleeping is therefore appropriate for the
irqchip callbacks and does not change the GPIO-side locking contract.
This is the same class of issue and fix as recently addressed for other
GPIO controllers, e.g. commit 286533cb14a3 ("gpio: sch: use raw_spinlock_t
in the irq startup path") and commit 90f0109019e6 ("gpio: eic-sprd: use
raw_spinlock_t in the irq startup path").
gpio: pca953x: fix cache_only and IRQ state on restore_context() failure
When pca953x_restore_context() fails, cache_only is left disabled and
the IRQ left enabled, even though register synchronization may not have
completed successfully. Restore cache_only and disable the IRQ again on
failure, matching the state set by pca953x_save_context().
Fixes: ec5bde62019b ("gpio: pca953x: Split pca953x_restore_context() and pca953x_save_context()") Fixes: 3e38f946062b ("gpio: pca953x: fix IRQ storm on system wake up") Cc: stable@vger.kernel.org Reviewed-by: Linus Walleij <linusw@kernel.org> Signed-off-by: bui duc phuc <phucduc.bui@gmail.com> Link: https://patch.msgid.link/20260727080205.16353-1-phucduc.bui@gmail.com Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
If the probe function returns an error after getting the I2C adapter for
DDC, the reference to the adapter is never released. Fix it by releasing
it in the bridge .destroy() handler.
There is no need to test the ddc pointer with !IS_ERR(), as
of_get_i2c_adapter_by_node() returns NULL on error.
Alex Tran [Fri, 24 Jul 2026 16:42:28 +0000 (09:42 -0700)]
gpio: gpio-by-pinctrl: Apply initial value in direction output wrapper
After successfully configuring gpio pin as output, set the
requested initial output value via the existing gpio set
wrapper, so that the pin is not left at its previous level.
Jaehoon Kim [Fri, 24 Jul 2026 13:39:43 +0000 (08:39 -0500)]
KVM: s390: Fall back to short-term pinning in MAP ioctl
FOLL_LONGTERM pinning fails for some memory types, such as file-backed
guest memory. As a result, kvm_s390_adapter_map() returns -EINVAL and
irqfd adapter registration fails even though interrupt delivery could
still work via the existing non-atomic path.
When FOLL_LONGTERM pinning fails, verify that the page is accessible
using a short-term pin instead. If the short-term pin succeeds, unpin
the page and add a map entry with pinned=false to preserve MAP/UNMAP
symmetry. The non-atomic irqfd path already performs short-term pinning
for interrupt delivery, so this restores the previous behavior for
memory that cannot be pinned long-term.
get_map_info() is updated to return NULL for unpinned entries so that
the atomic irqfd fast path falls back to the non-atomic path.
kvm_s390_adapter_unmap() and kvm_s390_unmap_all_adapters() skip dirty
marking and unpin for unpinned entries.
Update Documentation/virt/kvm/devices/s390_flic.rst to reflect the
new MAP/UNMAP behavior.
Fixes: c9a568838086 ("KVM: s390: Add map/unmap ioctl and clean mappings post-guest") Signed-off-by: Jaehoon Kim <jhkim@linux.ibm.com> Reviewed-by: Douglas Freimuth <freimuth@linux.ibm.com> Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@linux.ibm.com>
fs/erofs/decompressor_lzma.c sizes the module-global MicroLZMA stream
pool from num_possible_cpus() when the lzma_streams module parameter is
unset, then z_erofs_load_lzma_config() preallocates one image-supplied
dictionary per stream, accepting dictionaries up to 8 MiB. On high-CPU
systems, a small EROFS image can pin hundreds of MiB of vmalloc-backed
decoder state until the erofs module is unloaded.
Impact: An EROFS image mounted by the system can pin up to 8 MiB of
vmalloc memory per LZMA stream, either as intended or unexpectedly.
Bound the default stream count by a new
CONFIG_EROFS_FS_ZIP_LZMA_DEFAULT_MAX_STREAMS option, default 16, so the
worst-case default preallocation is 128 MiB if the number of CPUs is no
less than 16 while preserving the existing per-image dictionary limit.
An explicit lzma_streams module parameter is still honoured as-is, so
administrators who deliberately size the pool are not affected.
Previously, backing files for page cache sharing were set up with
f_path left as NULL (only f_inode was valid). It worked, but a recent
mincore fix relies on f_path.mnt and crashes (found by "erofs/028" on
7.2-rc4):
Specify valid paths using valid disconnected dentries together with
erofs_ishare_mnt instead of leaving f_path empty, so they are more
like real backing files in a pseudo filesystem and standard
backing_file_open() can be used directly.
Fixes: e187bc02f8fa ("mm: do file ownership checks with the proper mount idmap") Acked-by: Hongbo Li <hongbohbli@tencent.com> Signed-off-by: Gao Xiang <xiang@kernel.org>
Li Qiang [Sat, 18 Jul 2026 16:22:27 +0000 (00:22 +0800)]
cifs: validate idmap key payload length
The cifs.idmap key type stores its payload length in key->datalen, which
is limited to U16_MAX. Accepting a larger key payload truncates the
recorded length and can make later users interpret the payload using
inconsistent bounds.
Reject oversized preparsed payloads before allocating or copying them.
This keeps key->datalen consistent with the stored data for both inline
and separately allocated idmap payloads.
Signed-off-by: Li Qiang <liqiang01@kylinos.cn> Signed-off-by: Steve French <stfrench@microsoft.com>
Dawei Feng [Sun, 28 Jun 2026 06:59:09 +0000 (14:59 +0800)]
smb: client: fix buffer leaks in SMB1 read and write
CIFSSMBRead(), CIFSSMBWrite() and CIFSSMBWrite2() allocate a request
buffer before checking whether tcon->ses->server is NULL. If that
defensive check ever fails, the helper returns -ECONNABORTED without
releasing the request buffer.
Fix these leaks by releasing the allocated request buffer before
returning from these error paths. Use cifs_small_buf_release() for the
buffers allocated by small_smb_init() and cifs_buf_release() for the
buffer allocated by smb_init().
The bug was first flagged by an experimental analysis tool we are
developing for kernel memory-management bugs while analyzing
v6.13-rc1. The tool is still under development and is not yet publicly
available. Manual inspection confirms that the bug is still
present in v7.1.1.
An x86_64 allyesconfig build showed no new warnings.
Runtime validation used a temporary fault-injection hook to force
tcon->ses->server to NULL after request-buffer initialization. On the
unfixed kernel, the harness observed two leaked small request buffers and
one leaked large request buffer, with directed kmemleak dumps confirming
the CIFS buffer allocation stacks. After the fix, no CIFS request-buffer
deltas remained.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Dawei Feng <dawei.feng@seu.edu.cn> Signed-off-by: Steve French <stfrench@microsoft.com>
smb: client: use GFP_KERNEL for registry allocation
Currently, cifs_get_swn_reg() allocates new registry entries using
GFP_ATOMIC. Since we lock a mutex here, this is clearly not an atomic
context. Use GFP_KERNEL instead.
Also, fix a minor grammatical error in the comment above the function.
Signed-off-by: Fredric Cover <fredric.cover.lkernel@gmail.com> Signed-off-by: Steve French <stfrench@microsoft.com>
Merge tag 'vfs-7.2-rc5.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull vfs fixes from Christian Brauner:
- vfs: Preserve the ACL_DONT_CACHE state in forget_cached_acl().
ACL_DONT_CACHE is meant to be a permanent opt-out from ACL caching
which FUSE relies on for servers that don't negotiate FUSE_POSIX_ACL.
The helper replaced it with ACL_NOT_CACHED, silently re-enabling the
cache, and as fuse doesn't invalidate the cache for such servers a
properly timed get_acl() returned stale ACLs. Comes with a fuse
selftest reproducing this.
- pidfs:
- Preserve PIDFD_THREAD when a thread pidfd is reopened via
open_by_handle_at(). PIDFD_THREAD shares the O_EXCL bit which
do_dentry_open() strips after the flags have been validated, so
the reopened pidfd silently became a process pidfd. Comes with a
selftest.
- Add a pidfs_dentry_open() helper so the regular pidfd allocation
path and the file handle path share the code that forces O_RDWR
and reapplies the pidfd flags that do_dentry_open() strips.
- Handle FS_IOC32_GETVERSION in the compat ioctl path.
- Make pidfs_ino_lock static.
- iomap:
- Fix the block range calculation in ifs_clear_range_dirty() so a
partial clear doesn't drop the dirty state of blocks the range
only partially covers.
- Support invalidating partial folios so a partial truncate or hole
punch with blocksize < foliosize doesn't leave stale dirty bits
behind.
- Only set did_zero when iomap_zero_iter() actually zeroed
something.
- Guard ifs_set_range_dirty() and ifs_set_range_uptodate() against
zero-length ranges where the unsigned last-block calculation
underflows and bitmap_set() writes far beyond the ifs->state
allocation.
- Don't merge ioends with different io_private values as the merge
could leak or corrupt the private data of the individual ioends.
- exec:
- Raise bprm->have_execfd only once the binfmt_misc interpreter has
actually been opened. The flag was set as soon as a matching 'O'
or 'C' entry was found. If the interpreter open failed with
ENOEXEC the exec fell through to the next binary format with
have_execfd raised but no executable staged and begin_new_exec()
NULL derefed past the point of no return.
- Fix an unsigned loop counter wrap in transfer_args_to_stack() on
nommu. An overlong argument or environment string pushes bprm->p
below PAGE_SIZE, the stop index becomes zero, and the loop never
terminates, wrapping its counter and copying garbage from in
front of the page array into the new process stack.
- Make binfmt_elf_fdpic only honour the first PT_INTERP like
binfmt_elf does. Each additional PT_INTERP overwrote the previous
interpreter, leaking the name allocation and the interpreter file
reference together with the write denial open_exec() took,
leaving the file unwritable for as long as the system runs.
- overlayfs:
- Compare the full escaped xattr prefix including the trailing dot.
An xattr like "trusted.overlay.overlayfoo" was misclassified as
an escaped overlay xattr.
- Check read access to the copy_file_range() source with the
source's mounter credentials.
- super: Thawing a filesystem whose block device was frozen with
bdev_freeze() deadlocked. Dropping the last block layer freeze
reference from under s_umount ends up in fs_bdev_thaw() which
reacquires s_umount on the same task. Pin the superblock with an
active reference instead and call bdev_thaw() without holding
s_umount.
- procfs: Return EACCES instead of success when the ptrace access check
for namespace links fails.
- afs: Use afs_dir_get_block() rather than afs_dir_find_block() for
block 0 in afs_edit_dir_remove(), matching afs_edit_dir_add().
- Push the memcg gating of ->nr_cached_objects() down into the btrfs
and shmem callbacks instead of skipping every callback during
non-root memcg reclaim. The blanket check short-circuited XFS whose
inode reclaim hook is intentionally driven from per-memcg contexts to
free memcg-charged slab.
- eventpoll: Pin files while checking reverse paths.
Since struct file became SLAB_TYPESAFE_BY_RCU a concurrent close
could free and recycle the file under the check which then took and
dropped the f_lock of whatever live file now occupies that slot.
* tag 'vfs-7.2-rc5.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (24 commits)
super: fix emergency thaw deadlock on frozen block devices
pidfs: make pidfs_ino_lock static
eventpoll: pin files while checking reverse paths
fs: push nr_cached_objects memcg gating into individual filesystems
afs: Fix afs_edit_dir_remove() to get, not find, block 0
iomap: prevent ioend merge when io_private differs
iomap: add comments for ifs_clear/set_range_dirty()
iomap: fix out-of-bounds bitmap_set() with zero-length range
iomap: fix incorrect did_zero setting in iomap_zero_iter()
iomap: support invalidating partial folios
iomap: correct the range of a partial dirty clear
fs/super: fix emergency thaw double-unlock of s_umount
pidfs: handle FS_IOC32_GETVERSION in compat ioctl
ovl: check access to copy_file_range source with src mounter creds
proc: Fix broken error paths for namespace links
pidfs: add pidfs_dentry_open() helper
selftests/pidfd: check PIDFD_THREAD survives open_by_handle_at()
pidfs: preserve thread pidfds reopened by file handle
ovl: fix trusted xattr escape prefix matching
selftests/fuse: add ACL_DONT_CACHE regression test
...
Merge tag 'regulator-fix-v7.2-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator
Pull regulator fixes from Mark Brown:
"One driver specific fix where one of the MediaTek drivers duplicated
some core code buggily, and a core fix for an ordering issue on
startup where we could end up configuring a voltage outside of
constraints due to the order in which we applied constraints"
* tag 'regulator-fix-v7.2-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator:
regulator: core: clamp voltage constraints before applying apply_uV
regulator: mt6358: use regmap helper to read fixed LDO calibration
Merge tag 'char-misc-7.2-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver fixes from Greg KH:
"Here are a number of small char/misc/etc driver fixes for 7.2-rc5 that
resolve a bunch of different reported issues. Included in here are:
- rust_binder error message reporting fix
- stratix10-svc firmware driver fixes
- mei driver fix
- intel_th hardware tracing driver fix
- comedi driver fix
- uio_hv_generic driver fix
- ntsync selftest fix
- nsm misc driver fix
- some MAINTAINER file updates
All of these have been in linux-next for over a week with no reported
issues"
* tag 'char-misc-7.2-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc:
MAINTAINERS: Update wine-devel list address
rust_binder: only print failure if error has source
intel_th: fix MSC output device reference leak
misc: nsm: pin the module while the device is open
mei: bus: access mei_device under device_lock on cleanup
misc: nsm: only unlock nsm_dev on post-lock error paths
selftests: ntsync: correct CONFIG_NTSYNC name
comedi: comedi_parport: deal with premature interrupt
uio_hv_generic: Bind to FCopy device by default
MAINTAINERS: Add Greg Kroah-Hartman to GPIB
firmware: stratix10-svc: fix teardown order in remove to prevent race
firmware: stratix10-svc: handle NO_RESPONSE in async poll
firmware: stratix10-svc: fix FCS SMC call kernel-doc
firmware: stratix10-svc: fix memory leaks and list corruption bugs
Merge tag 'staging-7.2-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging driver fixes from Greg KH:
"Here are two small staging driver fixes for 7.2-rc5. They both resolve
some reported bugs in the rtl8723bs staging driver and have been in
linux-next for over a week with no reported issues"
* tag 'staging-7.2-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging:
staging: rtl8723bs: fix OOB reads in rtw_get_wps_ie()
staging: rtl8723bs: fix inverted HT40 secondary channel offset
Peiyang He [Mon, 20 Jul 2026 08:50:16 +0000 (16:50 +0800)]
iommu/iommufd: Fix IOPF group ownership UAF
iopf_group_alloc() links each last-page IOPF group into the generic IOPF
pending list before invoking the domain fault handler.
iommufd_fault_iopf_handler() also queued an accepted group in the
IOMMUFD deliver list without removing it from the generic pending list.
When detach or HWPT replacement drops the device's IOPF reference count
to zero, an IOMMU driver may call iopf_queue_remove_device(). That
function responds to and frees groups through the generic pending list
without removing the same groups from IOMMUFD's deliver list or response
xarray. A later read, response, or cleanup can then access the freed
group and cause a UAF.
Fix this by dequeuing an accepted group from the generic pending list
before IOMMUFD queues it for userspace response.
Make iopf_group_response() send a response regardless of pending-list
membership, so the dequeued group can still be completed by IOMMUFD.
Link: https://patch.msgid.link/r/3CFD314D0FE4D7EC+20260720085017.3998878-2-peiyang_he@smail.nju.edu.cn Closes: https://lore.kernel.org/all/B4F28798E2E784CA+d29f723c-b2b5-4b67-8d1c-4f7b9b0b27cb@smail.nju.edu.cn/ Fixes: 34765cbc679c ("iommufd: Associate fault object with iommufd_hw_pgtable") Cc: stable@vger.kernel.org Tested-by: Peiyang He <peiyang_he@smail.nju.edu.cn> Assisted-by: Codex:gpt-5.6-sol Signed-off-by: Peiyang He <peiyang_he@smail.nju.edu.cn> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Merge tag 'trace-v7.2-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace
Pull tracing fixes from Steven Rostedt:
- Move rb_desc->nr_page_va before updating dynamic array
The rb_descr->page_va is a dynamic array counted by nr_page_va. But
the updating of the page_va[] is done before the nr_page_va is
incremented causing a build with CONFIG_UBSAN_BOUNDS to flag it as an
overflow.
Move the increment of the counted by value before the array element
is updated.
- Propagate errors from remote event bulk updates
The return value of trace_remote_enable_event() was not being checked
by remote_events_dir_enable_write() where it would silently fail.
Have it check the return value and propagate that back up to user
space.
- Fix resource leak on mmiotrace trace_pipe close
The mmiotrace tracer was created in 2008 before the trace_pipe had a
close callback to allow tracers to do clean up from trace_pipe open.
The trace_pipe close cleanup callback was added in 2009 but the
mmiotrace tracer was not updated. It had a hack to do the cleanup in
the read call, where it may leak if user space did not read the
entire buffer.
Add a callback to mmiotrace trace_pipe close do to the cleanup
properly.
- Fix a possible NULL pointer dereference in the mmiotrace tracer
If the mmio_pipe_open() fails to find a PCI device, it will set the
hiter->dev pointer to NULL. The read function will blindly
dereference that pointer. Fix the read call to check to see if that
pointer is populated before dereferencing it.
- Fix union collision of module and refcnt for dynamic events
In 'struct trace_event_call', the 'module' pointer and the 'refcnt'
atomic variable share the same memory space in a union. The filter on
module logic only checked if the 'module' was set to determine if the
event belonged to the module. As dynamic events are always builtin,
it doesn't need the 'module' field of the structure and used a
refcount. But the module filtering logic would then mistaken these
dynamic events as a module and call module_name(event->module) on it.
Add a check to see if the event is a dynamic event and if so, do not
check it for being part of the given module.
- Reset the top level buffer in selftests before running instances
The ftracetest selftest initializes each instance before executing
the tests. But it does not reset the top level buffer. Dynamic events
are only added and removed by the top level so any left over dynamic
events will not be removed by the reset in the instances.
Left over dynamic events can cause the tests to incorrectly fail.
Reset the top level buffer before running the instances.
- Make the context_switch counter 64 bit
The code to read user space for a system call trace event or for a
trace_marker will disable migration, enable preemption, read user
space into a per CPU buffer, disable preemption and enable migration
again. It checks if the per CPU context switch counter to see if it
changed, and if it did not, it would know that the per CPU buffer was
not touched by another task.
But the save counter was 32 bit and it would compare it to the 64 bit
context_switch variable. A long running system could have the
context_switch variable greater that 1<<32 in which case the compare
will always fail. The compare will promote the 32 bit int saved value
to 64 bit and compare it to the full 64 bit counter. Since the top 32
bits of the saved value was zero, it would never match.
- Fix a use-after-free of the event_enable trigger
The event_enable trigger allows for enabling one event when another
event is triggered. When the trigger is removed, it must go through a
synchronization phase to make sure it is not triggered again. The
trigger itself is delayed by the "bulk delay" logic that was recently
added. But the code that frees the event_enable data used to rely on
the trigger code to do the synchronization. Now that the code uses
the call RCU functions (and a workqueue), that delay no longer is
there.
Add a callback private_data_free() function that allows triggers to
clean up data after the synchronization phase has completed.
- Move the module_ref counter into the delay callback
Since an event of the event_enable trigger can enable an event for a
module, it ups the module ref count for that event's module. This
prevents the event from trying to enable an event that no longer
exists and cause a use-after-free bug.
The ref counter was set back down when the trigger was removed but
not after thy synchronization phase. This could lead to the module
data being accessed after module was unloaded.
Move the module ref decrement into the private_data_free() callback
of the event_enable trigger.
- Add mutex to protect parser in ftrace filtering
The set_ftrace_filter file uses a parsing descriptor that is
allocated at open and modified by writes. If multiple threads were to
write to the descriptor at the same time, it can corrupt the parser.
Add a mutex around the modifications of the parser descriptor.
- Fix possible corruption in perf syscall tracing
The perf system call trace events can now read user space. To do so,
the reads of user space enable preemption and disables it again.
During this time that preemption is enabled, the task can migrate.
The perf event list head is assigned via a per CPU pointer. It is
done before the user space part is called. If the user space reading
migrates the task to another CPU, then the head pointer is no longer
valid.
Re-assign the head pointer after the reading of user space to keep it
using the correct data.
* tag 'trace-v7.2-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace:
tracing: perf: Fix stale head for perf syscall tracing
ftrace: Add global mutex to serialize trace_parser access
tracing: Delay module ref count for "enable_event" trigger
tracing: Fix use-after-free freeing trigger private data
tracing: Fix context switch counter truncation
selftests/ftrace: Reset triggers at top level before instance loop
tracing: Fix union collision of module and refcnt for dynamic events
tracing: Fix mmiotrace possible NULL dereferencing of hiter->dev
tracing: Fix resource leak on mmiotrace trace_pipe close
tracing: Propagate errors from remote event bulk updates
tracing/remotes: Fix page_va[] access before counter update in trace_remote_alloc_buffer()
Merge tag 'm68knommu-fixes-on-top-off-7.2-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu
Pull m68knommu fix from Greg Ungerer:
- fix broken local SoC IO accesses for ColdFire
* tag 'm68knommu-fixes-on-top-off-7.2-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu:
m68k: coldfire: fix breakage of missed IO access update
Merge tag 'x86-urgent-2026-07-26' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fix from Ingo Molnar:
- Disable jump/lookup tables in the x86 boot decompressor code
a bit more widely, because newer versions of LLVM started
optimizing it a bit better and introduced run-time relocations
in PIE code (Nathan Chancellor)
* tag 'x86-urgent-2026-07-26' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/boot/compressed: Disable jump tables
Merge tag 'smp-urgent-2026-07-26' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull SMP debug fixes from Ingo Molnar:
- SMP-call fixes when CSD lock debugging is enabled (Chuyi Zhou)
* tag 'smp-urgent-2026-07-26' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
smp: Make CSD lock acquisition atomic for debug mode
smp: Avoid invalid per-CPU CSD lookup with CSD lock debug
super: fix emergency thaw deadlock on frozen block devices
do_thaw_all_callback() calls bdev_thaw() while holding sb->s_umount
exclusively. If the block device was frozen via bdev_freeze() dropping
the last block layer freeze reference calls fs_bdev_thaw() which
reacquires s_umount:
The emergency thaw worker deadlocks against itself holding both
s_umount and bd_fsfreeze_mutex. That fscks any subsequent unmount,
freeze, or thaw of that filesystem and block device.
bdev_super_lock() even documents the violated requirement with
lockdep_assert_not_held(&sb->s_umount).
Acquiring bd_fsfreeze_mutex under s_umount also inverts the
bd_fsfreeze_mutex vs. s_umount ordering established by
bdev_{freeze,thaw}() and can thus ABBA against a concurrent block-layer
freeze even when the recursive path isn't hit.
Fix this by not holding s_umount around the bdev_thaw() loop at all. Pin
the superblock with an active reference instead as
filesystems_freeze_callback() does. The active reference keeps the
superblock from being shut down and so ->s_bdev stays valid without
holding s_umount. The block-layer-held freeze is dropped by
fs_bdev_thaw() with FREEZE_MAY_NEST | FREEZE_HOLDER_USERSPACE exactly as
a regular unfreeze would and thaw_super_locked() handles
filesystem-level freezes as before.
The emergency thaw path has deadlocked like this in one form or
another for a long long time but the current exclusively-held
shape dates back to commit [1] where thaw_bdev() already ended in
thaw_super() with s_umount held by do_thaw_all_callback().
ALSA: timer: Clear SNDRV_TIMER_IFLG_DEAD once the close completes
snd_timer_close_locked() marks an instance with SNDRV_TIMER_IFLG_DEAD
and returns early when the flag is already set, but the flag is never
cleared again. A completed close ends in remove_slave_links(), which
leaves timeri->timer NULL, so a second close is already harmless through
the timer == NULL path; the early return can only be reached by an
instance that was opened again in between. For such an instance the
close unlinks nothing, so snd_timer_instance_free() frees an object that
is still on timer->open_list_head, still on snd_timer_master_list if it
was opened with a slave key, still owns any adopted slaves, and still
holds its timer and module references.
snd_seq_timer_open() reopens an instance exactly like that: it retries
its fallback open on the same object after a failure that has already
run snd_timer_close_locked() internally. An unprivileged user with
access to /dev/snd/timer and /dev/snd/seq can force that failure, since
snd_timer_check_master() returns -EBUSY when a pending slave matches the
new master's (slave_class, slave_id) key and the target timer has
reached max_instances, and SNDRV_TIMER_IOCTL_SELECT with dev_class =
SNDRV_TIMER_CLASS_SLAVE keeps the caller-supplied dev_sclass, so a
sequencer queue's key can be forged. The freed instance is afterwards
dereferenced by any further snd_timer_open() on that timer, by
snd_timer_check_slave(), and by /proc/asound/timers, which faults on the
stale ti->owner pointer.
The flag only has to be visible while the close is in progress, which is
all its other users need. Clear it in remove_slave_links(), under the
same timer->lock that sets it, once the instance is off every list.
ALSA: hda/realtek: Add quirk for Infinix INBOOK X3 Slim
The Infinix INBOOK X3 Slim (ALC269VB, subsystem 0x2782:0250) has its
internal speakers wired to pin 0x1b, but the BIOS pin configuration
table declares 0x1b as "no physical connection" (0x411111f0). It instead
declares pin 0x14 as the internal speaker, although nothing is connected
to 0x14.
As a result the internal speakers are silent under Linux while the
headphone jack works correctly. The codec output path to 0x14 is fully
open (DAC assigned and streaming, mixer and pin unmuted, EAPD asserted),
so the failure is silent with no error reported. The speakers work under
Windows, where the vendor driver supplies its own pin table.
Add a fixup that disables the unconnected pin 0x14 and declares pin
0x1b as the internal speaker.
Reusing the existing ALC269VC_FIXUP_INFINIX_Y4_MAX was tried first, since
it also remaps 0x1b to an internal speaker. It is not sufficient here: it
leaves 0x14 declared, so autoconfig finds two line_outs
line_outs=2 (0x14/0x1b/0x0/0x0/0x0) type:speaker
and binds the primary "Speaker" control to the unconnected pin 0x14 while
demoting the working speaker at 0x1b to "Bass Speaker". Audio is audible
that way, but the volume and mute controls a desktop actually uses end up
attached to a pin that is not wired to anything. Disabling 0x14 is what
produces a single correct Speaker output.
Verified on the affected machine: with the corrected pin
configuration the driver's autoconfig reports
line_outs=1 (0x1b/0x0/0x0/0x0/0x0) type:speaker
both channels play, headphone auto-mute switches correctly in both
directions, and audio survives codec runtime suspend (D3) and resume.
ALSA: 6fire: Fix UAF at error handling during probe
Although 6fire driver had a few fixes for dealing with the early error
handling during the probe phase, it forgot a pending URB before
freeing the resources, which may lead to a UAF.
This patch addresses it by doing the almost same cleanup procedure
like the normal disconnect phase at the error path.
as a signed int, so a small device-advertised bulk-OUT max_transfer
makes buf_end negative. The loop guard then compares the u32
urb->transfer_buffer_length against that negative int: the usual
arithmetic conversion turns buf_end into a large unsigned value, so the
guard stays true and each iteration keeps appending SysEx framing and
payload bytes past the end of the URB transfer buffer, which is only
max_transfer bytes long.
A USB device that advertises a tiny bulk-OUT endpoint can therefore
trigger an attacker-length- and content-controlled heap out-of-bounds
write when a process writes to the created /dev/snd/midiC*D* node.
Return early when there is no room for even one SysEx, so the loop is
never entered with a bound that would wrap. The loop is the last
statement of the function, so bailing out is equivalent to it not
running.
Discovered by XBOW, triaged by Baul Lee <baul.lee@xbow.com>
Fixes: 4434ade8c933 ("ALSA: usb-audio: add support for Akai MPD16") Suggested-by: Takashi Iwai <tiwai@suse.de> Reported-by: Federico Kirschbaum <federico.kirschbaum@xbow.com> Reported-by: Baul Lee <baul.lee@xbow.com> Cc: stable@vger.kernel.org Signed-off-by: Baul Lee <baul.lee@xbow.com> Link: https://patch.msgid.link/20260726074500.50145-1-baul.lee@xbow.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
Baul Lee [Sun, 26 Jul 2026 06:50:20 +0000 (15:50 +0900)]
ALSA: usb-audio: fix stack info leak in RME Digiface status
snd_rme_digiface_read_status() reads a four-word status block from the
device into an uninitialised on-stack __le32 buf[4] and, whenever the
vendor control-IN transfer does not return a negative error, copies all
four words into the caller's status[].
snd_usb_ctl_msg() copies the full requested size back into the caller's
buffer regardless of how many bytes the data stage actually delivered:
usb_control_msg() returns the transferred length on a short control-IN,
which is a non-negative value, and writes only that many bytes. The
remainder of the copy back is the kmemdup()ed image of the caller's
buffer, so a device answering with a short data stage leaves the
trailing words of buf[] holding leftover kernel stack. The only guard
in the caller is err < 0, so those words are stored into status[].
They then reach user space: snd_rme_digiface_get_status_val() selects a
16-bit halfword of status[] per the control's reg/mask, and the eight
Digiface status controls together expose the whole 16-byte frame to an
unprivileged reader of /dev/snd/controlC*.
Zero-initialise the buffer so a short read yields zeros instead of stack
residue. This mirrors snd_rme_get_status1(), which already clears its
output word before the same kind of vendor read.
Discovered by XBOW, triaged by Baul Lee <baul.lee@xbow.com>