UMOUNT_CONNECTED as implemented allows for the creation of reference
count cycles. Here's a simple example
mkdir /x; mkfifo /ready /go
unshare -m sh -c 'mount -t tmpfs tmpfs /x
truncate -s 8M /x/img; mkfs.ext4 -q /x/img
dev=$(losetup -f --show /x/img)
mkdir /x/mp; mount $dev /x/mp
echo $dev > /ready; read r < /go' &
read dev < /ready
rmdir /x
echo > /go
wait
losetup -d $dev
losetup -a
Take a directory /x on the host, create a new mount namespace, mount a
tmpfs on /x, use a file on that tmpfs as the backing file for a loop
device, mount that loop device on that tmpfs. Now rmdir /x on the host.
This will lazily unmount the mount on top of /x in the container with
UMOUNT_CONNECTED. Once the namespace exits nothing references the mount
anymore. Now the tmpfs is pinned by the backing file of the loop device
and the loop mount is owned by the tmpfs superblock.
Fun fact, such cycles can be formed by at least the following
subsystems and I have added reproducers for all of them:
(1) a loop mount P from an image on a tmpfs next to it, so that P's
death shows as the loop device giving up its backing file
(2) autofs with a FIFO on P as its pipe, zram with a device node on P as
its writeback device, both on a minix image since vfat has neither
(3) ecryptfs with its lower directory on P, under a passphrase token
added to the session keyring
(4) binfmt_misc in a new user namespace with an 'F' interpreter on P
(5) a fuse server that answers FUSE_INIT with passthrough on and
registers a file on P as a backing file
(6) zloop with its zone files in a directory on P
(7) a mass storage gadget on the dummy UDC with its LUN file on P,
mounted from the SCSI disk the gadget shows up as
(8) md with a RAID1 of one loop device and its bitmap file on P, which
skips while SET_BITMAP_FILE has no way to succeed
(9) rmdir of P's mountpoint from the parent, then the child exits, then
the device must be free and LOOP_CLR_FD must release the file
The underlying mechanism is UMOUNT_CONNECTED (MNT_LOCKED falls into the
same class). With UMOUNT_CONNECTED an unmounted mount stays attached to
its parent. This is used to protect revealing the underlying mount and
is a non-negotiable security mechanism. So now the parent owns that
mount and is put on the parent's final mntput(). That moves it to
mnt_stuck_children and ultimately it's cleaned up by cleanup_mnt().
The fact that ownership of the child mount gets transferred to the
parent turns every reference from a child's superblock back to one of
its ancestors into a cycle.
Don't keep the child attached at all. What the parent needs is that a
lookup at the child's mountpoint keeps finding some mount, not the child
itself and it's not a guarantee we have given really.
When an unmounted mount would have stayed attached to its unmounted
parent disconnect it like every other unmounted mount and leave a
marker behind.
A lookup on the parent that misses the mount hash and hits a marker
finds knullfs. Either a file or a directory. Nothing leads from a marker
to any other mount.
The marker is owned by the parent and dropped by the parent's final
mntput() or by __detach_mounts() when the mountpoint is deleted from
under it. It is allocated together with the mount.
With that every unmounted mount is a root and holds only its own
reference which namespace_unlock() drops. No unmounted mount owns
another one. A superblock that pins an ancestor can't form a cycle.
It has a visible change. Mounts left connected (rmdir etc.) used to stay
traversable through the parent for as long as something held the parent.
Now it is detached with the umount. It lives as long as something
references it but it isn't reachable through the parent anymore and ".."
inside it leads nowhere which is the same as for every other lazily
unmounted mount.
Link: https://gist.github.com/mvo5/63ef46482349f3b1c3957d463a0c9c6f
Link: https://patch.msgid.link/20261002-work-mount-cover-v1-2-232a8f52b43c@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Add nullfs_new_file() to allocate an empty immutable regular file on a
nullfs instance as a dentry of its own. It is never hashed under the
root and so can't be found by lookup. Reads return nothing, changes are
refused, file locks, leases and delegations are refused as.
Link: https://patch.msgid.link/20261002-work-mount-cover-v1-1-232a8f52b43c@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Eric Dumazet says:
====================
net: always dissect GSO packets in __virtio_net_hdr_to_skb()
This series fixes a bypass of untrusted GSO flow dissection in
__virtio_net_hdr_to_skb() when VIRTIO_NET_HDR_F_NEEDS_CSUM is not set,
and adds a kselftest covering VLAN-tagged GSO packets without NEEDS_CSUM:
- Patch 1 fixes __skb_flow_dissect(), which computes key_control->thoff
with min_t(u16, ...). This truncates skb->len and returns a bogus small
transport offset when skb->len modulo 65536 is smaller than the
transport offset. Offsets that do not fit in the u16 thoff now fail the
dissection instead of being silently truncated.
- Patch 2 initializes skb->dev and skb->network_header before calling
virtio_net_hdr_*_to_skb() in tun_get_user(), tun_xdp_one(),
virtnet_receive_done(), and raw_verify_header(), removes the
'&& skb->network_header' condition and the unvalidated
'else if (gso_type)' fallback in __virtio_net_hdr_to_skb(), and moves
virtio_net_hdr_match_proto() after skb_flow_dissect_flow_keys_basic()
so it validates the dissected L3 protocol (keys.basic.n_proto) rather
than the outer L2 protocol.
- Patch 3 adds kselftests in tools/testing/selftests/net/tun.c verifying
that VLAN-tagged (802.1Q) TCPv4 GSO packets without NEEDS_CSUM (both
flags = 0 and flags = VIRTIO_NET_HDR_F_DATA_VALID) are accepted on a
TAP device, that mismatched GSO types and truncated TCP headers without
NEEDS_CSUM are rejected with -EINVAL, and that a 65540-byte frame is
accepted.
====================
Link: https://patch.msgid.link/20261001191140.2818991-1-edumazet@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Add selftests in tun.c verifying that a VLAN-tagged (802.1Q) TCPv4 GSO
packet without VIRTIO_NET_HDR_F_NEEDS_CSUM (both flags = 0 and
flags = VIRTIO_NET_HDR_F_DATA_VALID) is accepted when written to a TAP
device (/dev/net/tun with IFF_TAP | IFF_NO_PI | IFF_VNET_HDR).
Also verify that the following are rejected with -EINVAL:
- a mismatched GSO type (VIRTIO_NET_HDR_GSO_TCPV6 on a VLAN-tagged IPv4
packet).
- a frame whose TCP header is truncated after 10 bytes. Pulling only
sizeof(struct iphdr) + sizeof(struct tcphdr) bytes would accept it,
so this requires the transport offset found by flow dissection.
Finally, verify that a 65540-byte frame is accepted. Its skb->len is
above U16_MAX while it is flow-dissected, before eth_type_trans() pulls
the Ethernet header.
Based on a reproducer by Michael S. Tsirkin <mst@redhat.com>.
Signed-off-by: Eric Dumazet <edumazet@kernel.org>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20261001191140.2818991-4-edumazet@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Commit 9e8db59132 ("net: avoid false positives in untrusted gso
validation") added a '&& skb->network_header' check before flow-dissecting
GSO packets without VIRTIO_NET_HDR_F_NEEDS_CSUM in
__virtio_net_hdr_to_skb(), because some callers (such as tun_get_user(),
tun_xdp_one(), virtnet_receive_done(), and raw_verify_header()) called
virtio_net_hdr_*_to_skb() before initializing skb->network_header and
skb->dev.
Because __alloc_skb() and __build_skb_around() zero-initialize
skb->network_header to 0 (unlike mac_header and transport_header which
are initialized to ~0U), those four callers always had
skb->network_header == 0 and bypassed flow dissection in
__virtio_net_hdr_to_skb(). More generally, skb->network_header is an
offset from skb->head (where 0 is also a valid offset whenever
skb_headroom(skb) is 0), not a boolean flag.
Whenever the 'if (gso_type && skb->network_header)' branch was skipped,
the fallback 'else if (gso_type)' only pulled nh_min_len + thlen (40 bytes
for TCPv4) without dissecting the packet, without validating ip_proto or
n_proto, and without setting skb->transport_header.
If the packet has a malformed network header, it is not rejected and a
subsequent skb_probe_transport_header() also fails, leaving
skb->transport_header at ~0U (0xffff). Similarly, if an IPv4 packet
carries IP options (ihl > 5) or an IPv6 packet carries extension headers,
pulling only nh_min_len + thlen can leave the TCP header outside
skb->head. In both cases, tcp_hdrlen(skb) in skb_gso_transport_seglen()
reads out-of-bounds:
BUG: KASAN: slab-out-of-bounds in skb_gso_transport_seglen
Read of size 2 by task poc/133
skb_gso_transport_seglen (net/core/gso.c:155)
skb_gso_validate_mac_len (net/core/gso.c:270)
tbf_enqueue (net/sched/sch_tbf.c:260)
dev_qdisc_enqueue (net/core/dev.c:4227)
__dev_queue_xmit (net/core/dev.c:4884)
In addition, checking virtio_net_hdr_match_proto() only inside
'if (!skb->protocol)' before flow dissection both skipped validation when
skb->protocol was pre-set by the caller and rejected VLAN-tagged frames
whose outer L2 protocol is ETH_P_8021Q or ETH_P_8021AD.
Fix this by:
1. Initializing skb->dev and skb->network_header (plus skb->protocol for
IFF_TUN) before virtio_net_hdr_*_to_skb() in tun_get_user(),
tun_xdp_one(), virtnet_receive_done(), and raw_verify_header(). In
tun_get_user(), drop the redundant skb_reset_mac_header(skb) in the
IFF_TUN case since __virtio_net_hdr_to_skb() unconditionally resets
mac_header.
2. Removing '&& skb->network_header' and the unvalidated
'else if (gso_type)' fallback in __virtio_net_hdr_to_skb() so all GSO
packets without VIRTIO_NET_HDR_F_NEEDS_CSUM are flow-dissected, have
their transport header pulled into linear data, and have
skb->transport_header set.
3. Moving the virtio_net_hdr_match_proto() check to after
skb_flow_dissect_flow_keys_basic(), validating keys.basic.n_proto
against hdr_gso_type.
Fixes: 9e8db59132 ("net: avoid false positives in untrusted gso validation")
Fixes: d5be7f632b ("net: validate untrusted gso packets without csum offload")
Fixes: 924a9bc362 ("net: check if protocol extracted by virtio_net_hdr_set_proto is correct")
Reported-by: Weiming Shi <bestswngs@gmail.com>
Closes: https://lore.kernel.org/netdev/20260927163117.746432-2-bestswngs@gmail.com/
Signed-off-by: Eric Dumazet <edumazet@kernel.org>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Cc: Michael S. Tsirkin <mst@redhat.com>
Link: https://patch.msgid.link/20261001191140.2818991-3-edumazet@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
__skb_flow_dissect() computes key_control->thoff using:
key_control->thoff = min_t(u16, nhoff, skb ? skb->len : hlen);
min_t(u16, ...) casts both arguments to u16 before comparing them.
Whenever skb->len (or hlen) modulo 65536 is smaller than nhoff, the
truncated length wins and thoff is set to a bogus small value, even
when the dissection succeeded. For example, an IPv4/TCP frame with
skb->len == 65540 and nhoff == 34 gets thoff == 4, so callers such as
skb_probe_transport_header() point the transport header inside the
Ethernet header.
Such skbs are not exotic:
- At the time of commit d0c081b491 ("flow_dissector: properly cap
thoff field"), AF_PACKET with PACKET_VNET_HDR could already build GSO
skbs larger than 64KB (MTU checks are skipped for GSO, and
alloc_skb_with_frags() accepted up to MAX_SKB_FRAGS (17) order-0
pages on top of the linear part).
- BIG TCP now makes skbs larger than 64KB common.
- The following patch makes tun_get_user() dissect IFF_TAP frames
before eth_type_trans() pulls the Ethernet header, so a GSO frame
carrying a 65522..65535 byte L3 packet will be dissected with
skb->len in [65536, 65549].
Compare as u32 instead. If the resulting offset cannot be represented
in the u16 key_control->thoff, cap it to U16_MAX and report the
dissection as failed rather than silently returning a wrong transport
offset. thoff is still set on failure, as some callers (such as
eth_get_headlen()) use it regardless of the return value.
Fixes: d0c081b491 ("flow_dissector: properly cap thoff field")
Signed-off-by: Eric Dumazet <edumazet@kernel.org>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20261001191140.2818991-2-edumazet@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
It is reported by sashiko that calling is_in_v2_mode() outside of
cpuset_mutex critical section in cpuset_handle_hotplug() can introduce
a TOCTOU race where cgroup hierarchy may have changed from v1 to v2 or
vice versa after is_in_v2_mode() is called leading to erroneously skip
the allocation of tmpmasks or incorrectly modify cpus_allowed masks,
resulting in cpuset state corruption. Fix that by calling is_in_v2_mode()
after acquiring the cpuset_mutex.
Fixes: b8d1b8ee93 ("cpuset: Allow v2 behavior in v1 cgroup")
Signed-off-by: Waiman Long <longman@redhat.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
HRST (0x1e) and CLIRQ (0x1f) are write-only command strobes. Writing HRST
triggers a hard reset of the chip and writing CLIRQ clears the interrupt;
reading them returns nothing useful, and the read itself fires the command.
The result is that a plain register dump resets the board:
cat /sys/kernel/debug/regmap/2-003c/registers
walks every readable register, hits HRST, and the board reboots.
Split the callback back in two so HRST and CLIRQ stay writable but are no
longer readable. The readable range is left unchanged
(LTC3676_BUCK1 ... LTC3676_IRQSTAT).
Fixes: 37b918a034 ("regulator: Add LTC3676 support")
Cc: stable@vger.kernel.org
Signed-off-by: Abhishek Ojha <Abhishek.ojha@savoirfairelinux.com>
Link: https://patch.msgid.link/20260902010701.3360310-1-Abhishek.ojha@savoirfairelinux.com
Signed-off-by: Mark Brown <broonie@kernel.org>
The fixed divider ignores device and operation clock limits. Calculate
the divider before each transfer so SCK does not exceed either limit.
Advertise the controller maximum speed so the SPI core supplies a default
when the device omits its maximum speed. Use the fastest divider when no
speed limit is supplied.
Fixes: de16c322ee ("spi: sophgo: add SG2044 SPI NOR controller driver")
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
Link: https://patch.msgid.link/20261001-fix-sg204xspi-v2-2-014dbaf22b5e@iscas.ac.cn
Signed-off-by: Mark Brown <broonie@kernel.org>
The transfer helpers return errors, but both dispatchers discard them.
Return these errors to the SPI memory layer instead of reporting success.
Fixes: de16c322ee ("spi: sophgo: add SG2044 SPI NOR controller driver")
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
Link: https://patch.msgid.link/20261001-fix-sg204xspi-v2-1-014dbaf22b5e@iscas.ac.cn
Signed-off-by: Mark Brown <broonie@kernel.org>
The probe function puts the device into the runtime PM active state with
only the "iis" bus clock enabled, but it also sets priv->op_clk to the
parent of the RCLK_SRC mux without enabling it. The runtime PM suspend
callback disables both clocks, so the first runtime suspend after probe
disables op_clk once more than it was enabled.
On Exynos5250 Arndale both clocks resolve to the same EXYNOS_I2S_BUS gate,
so this triggers the following warning during boot:
WARNING: drivers/clk/clk.c:1270 at clk_core_disable+0xe4/0x23c, CPU#0: kworker/u8:3/45
i2s_bus already disabled
...
Workqueue: pm pm_runtime_work
Call trace:
...
clk_core_disable from clk_disable+0x28/0x34
clk_disable from i2s_runtime_suspend+0x58/0x68 [snd_soc_i2s]
i2s_runtime_suspend [snd_soc_i2s] from genpd_runtime_suspend+0xc4/0x298
genpd_runtime_suspend from __rpm_callback+0x48/0x18c
__rpm_callback from rpm_callback+0x4c/0x50
rpm_callback from rpm_suspend+0xf4/0x718
rpm_suspend from pm_runtime_work+0x9c/0xa0
...
Fix this by enabling op_clk in probe right after getting it, so the clock
state matches the runtime PM active state, and by disabling it in remove.
Fixes: 48279c53fd ("ASoC: samsung: i2s: Prevent external abort on exynos5433 I2S1 access")
Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Link: https://patch.msgid.link/20261002092116.585466-1-m.szyprowski@samsung.com
Signed-off-by: Mark Brown <broonie@kernel.org>
The chip has strange power-on reset values for the registers that
control the output ASRC and DAC source muxes - the values are actually
marked "Reserved" in the datasheet [1]. This means that until the
underlying kcontrols are modified, the codec will not function as
expected.
The registers in question are:
register / field reset value valid values
ASRCO_SOURCE_0_1 0x10
ASRC_OUT_SOURCE0 0 4 .. 16
ASRC_OUT_SOURCE1 1 4 .. 16
ASRCO_SOURCE_2_3 0x10
ASRC_OUT_SOURCE2 2 4 .. 16
ASRC_OUT_SOURCE3 3 4 .. 16
DAC_SOURCE_0_1 0x10
DAC_SOURCE_0 0 12 .. 13
DAC_SOURCE_1 1 12 .. 13
Set some sane defaults during the driver probe:
ADC Decimator0 -> Output ASRC0
ADC Decimator1 -> Output ASRC1
ADC Decimator2 -> Output ASRC2
ADC Decimator3 -> Output ASRC3
Input ASRC0 -> DAC0
Input ASRC1 -> DAC1
With this, the chip will behave as advertised by the default kcontrol
state exposed by the driver.
[1] https://www.analog.com/media/en/technical-documentation/data-sheets/ADAU1372.pdf
Fixes: 6cd4c6459e ("ASoC: Add ADAU1372 audio CODEC support")
Signed-off-by: Alvin Šipraga <alvin.sipraga@analog.com>
Acked-by: Nuno Sá <nuno.sa@analog.com>
Link: https://patch.msgid.link/20261006-asoc-adau1372-fixes-v1-2-599cc17fb5f6@analog.com
Signed-off-by: Mark Brown <broonie@kernel.org>
gpiod_set_value() emits a WARN when the GPIO provider indicates that it
can sleep, as is typical for I2C controlled GPIO expanders. Since the
powerdown GPIO is only manipulated in process context, use the _cansleep
variant instead. This lets the driver use sleepy GPIOs to power off the
chip.
Fixes: 6cd4c6459e ("ASoC: Add ADAU1372 audio CODEC support")
Signed-off-by: Alvin Šipraga <alvin.sipraga@analog.com>
Acked-by: Nuno Sá <nuno.sa@analog.com>
Link: https://patch.msgid.link/20261006-asoc-adau1372-fixes-v1-1-599cc17fb5f6@analog.com
Signed-off-by: Mark Brown <broonie@kernel.org>
- Set CHECK CONDITION for failed ATAPI commands.
Since commit 2e1d2e65e7 ("ata: libata-scsi: terminate deferred
commands on time out") failed ATAPI commands incorrectly stopped
having CHECK CONDITION set for commands that had a SCSI midlayer
byte set by scsi_check_sense(). SG_IO users therefore saw failed
ATAPI commands as successful. (Hengyu)
-----BEGIN PGP SIGNATURE-----
iHUEABYKAB0WIQRN+ES/c4tHlMch3DzJZDGjmcZNcgUCasTQfAAKCRDJZDGjmcZN
cnMHAQC6ethce6SCEyq3vR72ndKa/y9YiHjXpdvVczmBw3+oWQD/Q1fQJ47XFI81
celGTxa7tm+8rV1o30rVZc3S8dy76g8=
=UXqK
-----END PGP SIGNATURE-----
Merge tag 'ata-7.3-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/libata/linux
Pull ata fix from Niklas Cassel:
- Set CHECK CONDITION for failed ATAPI commands.
Since commit 2e1d2e65e7 ("ata: libata-scsi: terminate deferred
commands on time out") failed ATAPI commands incorrectly stopped
having CHECK CONDITION set for commands that had a SCSI midlayer
byte set by scsi_check_sense(). SG_IO users therefore saw failed
ATAPI commands as successful (Hengyu)
* tag 'ata-7.3-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/libata/linux:
ata: libata-scsi: do not lose CHECK CONDITION for failed ATAPI commands
The RCU guard is declared in the body of the per-TID loop, so it is still
held across the teardown pass. nxpwifi_del_rx_reorder_entry() flushes the
Rx workqueue and deletes the reorder timer synchronously, both of which
sleep, so a station deauthenticating from the AP splats under
CONFIG_DEBUG_ATOMIC_SLEEP.
Scope the guard to the collection walk. The teardown does not need RCU: it
serialises on priv->rx_reorder_tbl_lock[] and frees with kfree_rcu().
Fixes: 73b01e57ed ("wifi: nxp: add nxpwifi driver for IW61x")
Assisted-by: Claude:claude-opus-5
Signed-off-by: David Carlier <devnexen@gmail.com>
Signed-off-by: Jeff Chen <jeff.chen_1@nxp.com>
nxpwifi_is_tx_ba_stream_ptr_valid() returns true when the entry is still
linked, and every caller passes an entry that is on the list, so the early
return always fires and nothing is ever unlinked or freed. Entries leak on
every teardown and, since nxpwifi_space_avail_for_new_ba_stream() counts
them, Tx aggregation stops being negotiated once the stale count reaches
the maximum.
Changing the original dead && test to || to silence a NULL dereference
report inverted the validity test along with it.
Fixes: 00c786a758 ("wifi: nxpwifi: fix multiple static analysis errors and warnings")
Assisted-by: Claude:claude-opus-5
Signed-off-by: David Carlier <devnexen@gmail.com>
Signed-off-by: Jeff Chen <jeff.chen_1@nxp.com>
nxpwifi_cfg80211_authenticate() allocates the buffer it builds the
management frame in and never checks the result:
mgmt = kzalloc(frame_len, GFP_KERNEL);
skb = dev_alloc_skb(...);
if (!skb) {
...
return -ENOMEM;
}
...
memcpy(mgmt->da, req->bss->bssid, ETH_ALEN);
On allocation failure the memcpy() a dozen lines later dereferences NULL.
The same sequence leaks mgmt when dev_alloc_skb() fails: that path
returns without freeing it, while the success path drops it after
nxpwifi_form_mgmt_frame().
Bail out when the allocation fails, and free it before returning on the
skb error path.
Fixes: 73b01e57ed ("wifi: nxp: add nxpwifi driver for IW61x")
Signed-off-by: Linmao Li <lilinmao@kylinos.cn>
Signed-off-by: Jeff Chen <jeff.chen_1@nxp.com>
nxpwifi_cfg80211_authenticate() builds a 3-address management frame in a
temporary buffer and hands it to nxpwifi_form_mgmt_frame(), which copies
it into the skb and splices in address4. The frame length is tracked in
a single u16 that conflates the two lengths, and it gets both wrong.
Truncation. req->ie_len and req->auth_data_len are both size_t. The IE
policy caps req->ie_len at IEEE80211_MAX_DATA_LEN, but
NL80211_ATTR_AUTH_DATA only has a four-byte minimum length policy. Since
nla_len is a u16, a single authentication data attribute can carry up to
65531 bytes, enough for the combined frame length to exceed U16_MAX
before it is assigned to pkt_len. With auth_data_len == 65510 and no IEs
the length wraps to 6, kzalloc(6) succeeds, and the memcpy() below then
writes 65506 user-provided bytes past a 6-byte heap object.
Geometry. NXPWIFI_MGMT_HEADER_LEN is 30, which is the 24-byte 3-address
header plus the address4 that the firmware expects. The temporary buffer
only holds a struct ieee80211_hdr_3addr, so six of the bytes accounted
for are never used, and passing that length to nxpwifi_form_mgmt_frame()
makes it append ETH_ALEN on top of a length that already included it.
The skb is sized without those six bytes, so the last skb_put_data()
overruns the tailroom by exactly ETH_ALEN. It usually goes unnoticed
because SKB_DATA_ALIGN() rounding leaves slack. The driver's other
caller of the helper, nxpwifi_cfg80211_mgmt_tx(), adds ETH_ALEN to the
skb size before allocating and passes the 3-address length, which is what
this path should do too.
Keep the two lengths apart. frame_len is the 3-address frame the driver
builds: it sizes the temporary buffer and is what the helper is told.
pkt_len is what the firmware sees, frame_len plus address4: it sizes the
skb and goes into tx_info. Computing frame_len in size_t and rejecting
anything that cannot be represented once ETH_ALEN is added removes the
wrap.
The value handed to the firmware is unchanged, so this is not a
behavioural change for frames that were already valid. A tighter 802.11
bound may make sense, but that depends on the firmware's frame format and
is a separate decision.
Fixes: 73b01e57ed ("wifi: nxp: add nxpwifi driver for IW61x")
Signed-off-by: Linmao Li <lilinmao@kylinos.cn>
Signed-off-by: Jeff Chen <jeff.chen_1@nxp.com>
adapter->chan_stats comes from vmalloc(), which does not clear the
memory, and nxpwifi_cfg80211_dump_survey() reads it as soon as user
space asks for survey data. For the entries no scan has filled in, a
non-zero cca_scan_dur passes the validity check and stale bytes are
reported to user space as noise, time and time_busy.
Use kcalloc() instead. The array holds two entries per supported
channel, small enough not to need vmalloc(), and the two callers change
to kfree() accordingly.
mwifiex fixed the same issue in commit 0e20450829 ("wifi: mwifiex:
Initialize the chan_stats array to zero").
Fixes: 73b01e57ed ("wifi: nxp: add nxpwifi driver for IW61x")
Signed-off-by: Linmao Li <lilinmao@kylinos.cn>
Reviewed-by: Jeff Chen <jeff.chen_1@nxp.com>
Signed-off-by: Jeff Chen <jeff.chen_1@nxp.com>
nxpwifi_11n_aggregate_pkt() drops ra_list_spinlock while it copies each
subframe, so it rechecks the RA list after taking the lock again. The
check inside the aggregation loop returns without releasing the
skb_aggr it has been filling, leaking one tx_buf_size buffer along with
the subframes already aggregated into it.
Release skb_aggr there, the way the same check on the -EBUSY path
already does.
mwifiex fixed the same issue in commit 990a73dec3 ("wifi: mwifiex: Fix
memory leak in mwifiex_11n_aggregate_pkt()").
Fixes: 73b01e57ed ("wifi: nxp: add nxpwifi driver for IW61x")
Signed-off-by: Linmao Li <lilinmao@kylinos.cn>
Reviewed-by: Jeff Chen <jeff.chen_1@nxp.com>
Signed-off-by: Jeff Chen <jeff.chen_1@nxp.com>
nxpwifi_adapter_cleanup() stops adapter->wakeup_timer with
timer_delete(), which does not wait for a running callback. The
callback goes on using the adapter: wakeup_timer_fn() sets
adapter->hw_status, walks the command queues through
nxpwifi_cancel_all_pending_cmd() and calls adapter->if_ops.card_reset().
Both paths that reach nxpwifi_adapter_cleanup() free the adapter right
afterwards, through nxpwifi_free_adapter() in nxpwifi_remove_card() and
in the nxpwifi_add_card() error unwind.
Use timer_delete_sync() so the callback has finished before the adapter
is released.
mwifiex fixed the same issue in commit ae5e95d415 ("wifi: mwifiex: fix
use-after-free in mwifiex_adapter_cleanup()").
Fixes: 73b01e57ed ("wifi: nxp: add nxpwifi driver for IW61x")
Signed-off-by: Linmao Li <lilinmao@kylinos.cn>
Reviewed-by: Jeff Chen <jeff.chen_1@nxp.com>
Signed-off-by: Jeff Chen <jeff.chen_1@nxp.com>
When a station leaves, the firmware reports EVENT_UAP_STA_DEAUTH.
nxpwifi_uap_event_sta_deauth() tears down the reorder, BA and WMM state
for that peer but leaves its nxpwifi_sta_node on priv->sta_list.
Nothing else removes it. cfg80211_del_sta() only reports the departure
upwards, it does not call back into cfg80211_ops.del_station, and that
callback is the only caller of nxpwifi_del_sta_entry(). The entry
therefore survives until the BSS goes idle and
nxpwifi_del_all_sta_list() drops everything.
Until then the departed station still looks associated to the driver.
nxpwifi_handle_uap_rx_forward() finds the stale node for that address,
treats the frame as intra-BSS traffic and requeues it for transmission
instead of passing it up the stack, so traffic for that address is
misrouted. The list also keeps one entry per station that has ever
associated, and a station that comes back reuses the stale node along
with its old statistics.
mwifiex, which nxpwifi was derived from, deletes the entry in the same
event handler.
Fixes: 73b01e57ed ("wifi: nxp: add nxpwifi driver for IW61x")
Signed-off-by: Linmao Li <lilinmao@kylinos.cn>
Tested-by: Jeff Chen <jeff.chen_1@nxp.com>
Reviewed-by: Jeff Chen <jeff.chen_1@nxp.com>
Signed-off-by: Jeff Chen <jeff.chen_1@nxp.com>
nxpwifi_del_sta_entry() unlinks an entry from priv->sta_list without
holding priv->sta_list_spinlock. The comment above it gives the
reason: the function is only reached from cfg80211_ops.del_station,
which runs under the wiphy mutex.
That mutex serialises this callback against other users of the same
lock, including wiphy_work items. It covers neither of the two other
writers of the same list:
nxpwifi_add_sta_entry() from nxpwifi_uap_event_sta_assoc()
nxpwifi_del_all_sta_list() from nxpwifi_uap_event_bss_idle()
Both run from nxpwifi_process_event() on the driver's main work queue,
a plain workqueue that never takes the wiphy lock, and both take
sta_list_spinlock around their update. A station associating, or the
BSS going idle, can therefore modify priv->sta_list while a hostapd
del_station is walking it and unlinking an entry.
Take the lock here too. As the traversal then runs under the write
lock, list_for_each_entry() replaces the _rcu variant, matching
nxpwifi_del_all_sta_list().
The same call path reaches nxpwifi_get_sta_entry() without
rcu_read_lock(). Entries are freed with kfree_rcu() and every other
caller holds it, so take it around the lookup as well.
Fixes: 73b01e57ed ("wifi: nxp: add nxpwifi driver for IW61x")
Signed-off-by: Linmao Li <lilinmao@kylinos.cn>
Tested-by: Jeff Chen <jeff.chen_1@nxp.com>
Reviewed-by: Jeff Chen <jeff.chen_1@nxp.com>
Signed-off-by: Jeff Chen <jeff.chen_1@nxp.com>
The mailbox header was defined as __le32, which required
cpu_to_le32() and le32_to_cpu() conversions whenever it was
write or read.
These conversions are unnecessary because the header is always
handled as a 32-bit value, not as raw bytes. It is written with
xe_mmio_write32() and read with xe_mmio_read32(), which already
handle any required byte-order conversion through the underlying
writel()/readl() accessors.
As a result, the header value is already in CPU byte order when
used by the driver. Keeping the extra conversions had no effect
on little-endian systems and could cause an incorrect on
big-endian systems.
So use u32 for the mailbox header and remove the unnecessary
endianness conversions.
Fixes: 1f95f61818 ("drm/xe/xe_sysctrl: Add System Controller mailbox communication support")
Suggested-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
Signed-off-by: Mallesh Koujalagi <mallesh.koujalagi@intel.com>
Tested-by: Anoop Vijay <anoop.c.vijay@intel.com>
Reviewed-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
Signed-off-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
Link: https://patch.msgid.link/20260924060900.146167-18-mallesh.koujalagi@intel.com
(cherry picked from commit 5137b391599579371c32f555958d3cf55e19bd88)
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
There is a small race window between intel_rps_boost() reading
a stale ACTIVE state and queuing rps->work, where ACTIVE may be
changed via asynchronous calls triggered by wakeref drop.
This means that rps_work() could be triggered after the GT has
been parked, so unmasking RPS PM interrupts would happen without
holding PM wakelock. This sequence of events may be observed
during live_rc6_ctx_wa() selftest:
1) live_rc6_ctx_wa()
-> intel_engine_pm_put()
-> wakeref_put()
ASYNC1) wakeref_put() callback
-> __engine_park()
-> intel_gt_pm_put_async()
-> intel_gt_pm_put_async_untracked()
-> intel_wakeref_put_async()
ASYNC2) wakeref_put_async() callback
-> __gt_park()
-> intel_rps_park()
-> intel_rps_clear_active() [clear ACTIVE]
WITH INTERRUPTS:
-> rps_disable_interrupts()
-> cancel_work_sync(rps->work)
-> rps_reset_interrupts() [rps->pm_iir = 0]
WITHOUT INTERRUPTS (TIMER mode):
-> rps_stop_timer()
-> cancel_work_sync(rps->work)
2) live_rc6_ctx_wa()
-> intel_gt_wait_for_idle()
-> intel_gt_retire_requests_timeout()
-> dma_fence_wait_timeout()
-> ops->wait() [i915_fence_wait()]
-> i915_request_wait_timeout()
-> intel_rps_boost()
-> intel_rps_is_active() [check ACTIVE]
[OPEN RACE WINDOW]
-> queue_work(rps->work)
-> retire_requests()
-> i915_request_retire()
-> intel_rps_dec_waiters() [from 1 to 0]
If ASYNC1 and ASYNC2 would execute during [OPEN RACE WINDOW],
then:
3) rps_work() executes from the workqueue and may satisfy
"(!pm_iir && !client_boost)" test (in TIMER mode rps->pm_iir
is zeroed by an earlier rps_work() call or never gets a new
value after previous intel_rps_unpark() event), so it jumps
to "out" label, bypassing intel_rps_is_active() guard and
executes gen6_gt_pm_unmask_irq();
4) GT is parked and runtime PM wakelock is dropped, so only
a raw reference in __gt_park() ->
intel_display_power_put_async() remains for 100ms, then the
MMIO write in gen6_gt_pm_unmask_irq() detects missing
wakelock via assert_rpm_wakelock_held() and emits
"RPM wakelock ref not held during HW access" tainting kernel.
Commit 3e7abf8141 ("drm/i915: Extract GT render power state management")
dropped the "if (rps->interrupts_enabled)" guard that
gen6_pm_rps_work() had around this unmask in i915_irq.c.
INTEL_RPS_ACTIVE brackets the same window, since it is set in
intel_rps_unpark() before rps_enable_interrupts() and
rps_start_timer() and cleared in intel_rps_park() before
rps_stop_timer() and rps_disable_interrupts().
Skip unmasking when RPS is no longer active (reaching unmask
operation is independent of INTERRUPT mode). This does not
prevent RPS operation from resuming on the next unpark.
In interrupt mode, intel_rps_unpark() calls
rps_enable_interrupts(), which enables and unmasks the PM
interrupts. In timer mode, it calls rps_start_timer(),
restarting periodic engine-busyness evaluation. The timer
generates software RPS events and queues rps_work() directly,
independently of PM interrupt delivery. Neither mode requires
the late worker to unmask interrupts while the GT is parked
Fixes: 3e7abf8141 ("drm/i915: Extract GT render power state management")
Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/16562
Cc: stable@vger.kernel.org # v5.5+
Assisted-by: GitHub-Copilot:claude-opus-5
Assisted-by: GitHub-Copilot:gpt-6-astra
Signed-off-by: Krzysztof Karas <krzysztof.karas@intel.com>
Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com>
Signed-off-by: Andi Shyti <andi.shyti@linux.intel.com>
Link: https://patch.msgid.link/20260910081329.3300417-1-krzysztof.karas@intel.com
(cherry picked from commit ca4a6deada)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
It is possible for eb_relocate_parse_slow() to call kvfree() on
entries outside the original exec array during following
scenario inside eb_relocate_parse_slow():
1) eb_copy_relocations() allocates as many as eb->buffer_count
copies for exec entries;
2) eb_parse() appends up to two VMAs, right after incrementing
eb->buffer_count;
3) cleanup under "out" label uses this incremented buffer_count
to release relocation pointers from exec array via kvfree(),
not from VMA array.
To amend this problem, ensure that relocation cleanup uses the
original exec object count, excluding the VMAs appended by the
command parser.
Fixes: 8e4ba491b0 ("drm/i915: Parse command buffer earlier in eb_relocate(slow)")
Signed-off-by: Krzysztof Karas <krzysztof.karas@intel.com>
Assisted-by: GitHub-Copilot:gpt-6-astra
Cc: stable@vger.kernel.org # 5.10+
Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com>
Signed-off-by: Andi Shyti <andi.shyti@linux.intel.com>
Link: https://patch.msgid.link/20260911061145.3535489-1-krzysztof.karas@intel.com
(cherry picked from commit 2a0158925f)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
If the 'for_each_new_connector_in_state()' loop finishes without
hitting the break, connector_state is left pointing at the last
connector visited, which has no CRTC, instead of
staying NULL.
That skips the "if (!connector_state)" fallback below the loop, which
looks up the active connector when the state contains none. The
function then carries on with a connector that is not driven.
Fix by resetting connector_state to NULL for each connector visited that
has no CRTC, so that it is NULL when none was found and the fallback runs.
Fixes: 40e1a70b4a ("drm: Add GUD USB Display driver")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Link: https://sashiko.dev/#/patchset/20260902123254.36987-1-sajal2005gupta@gmail.com?part=1
Signed-off-by: Sajal Gupta <sajal2005gupta@gmail.com>
Acked-by: Ruben Wauters <rubenru09@aol.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Ruben Wauters <rubenru09@aol.com>
Link: https://patch.msgid.link/20260922084026.15481-1-sajal2005gupta@gmail.com
When the eFuse block covering MT7976C_EFUSE_OFFSET is invalid,
mt7996_mcu_get_eeprom() returns -EINVAL without writing buf, but
mt7996_variant_fem_init() tolerates -EINVAL and keeps running, so
buf[idx] == 0xc reads uninitialized stack memory. A stale 0x0c byte
misclassifies a 0x7976 aDie as 7976C, selects MT7996_FEM_INT and the
wrong default EEPROM, overriding valid calibration data. Only consult
the eFuse byte when the read succeeded; with an invalid eFuse, fall
back to the three explicit aDie version checks.
Fixes: e8cb33ad54 ("wifi: mt76: mt7996: add support for more variants")
Cc: stable@vger.kernel.org
Signed-off-by: Lu Huang <huanglu@kylinos.cn>
Link: https://patch.msgid.link/20260930085435.1424493-1-huanglu@kylinos.cn
Signed-off-by: Felix Fietkau <nbd@nbd.name>
The SAR power tables are parsed with a version byte from a different
ACPI table, never their own.
Some firmware declares version 1 and ships version 2 tables. The
entries then start a byte early, and the 6 GHz limits the table
carries are dropped, because the older layout has no room for them.
ASUS GA503RM, MTCL declares v1:
MTGS 28 bytes v1: (28-6) % 5 = 2, no fit v2: 3 tables
MTDS 19 bytes v1: (19-6) % 6 = 1, no fit v2: 1 table
The layouts accept disjoint lengths, so take whichever one fits and
keep it per table.
Reported-by: Sagun Kayastha <sgn.kayastha@gmail.com>
Closes: https://github.com/morrownr/mt76/issues/62
Fixes: f965333e49 ("mt76: mt7921: introduce ACPI SAR support")
Signed-off-by: Devin Wittmayer <lucid_duck@justthetip.ca>
Link: https://patch.msgid.link/20260905013551.24635-1-lucid_duck@justthetip.ca
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Some ASUS firmware carries 0xff in MTGS power slots. The driver narrows
the byte to s8, so the slot reads as -1 in its 0.5 dBm units, wins the
min() against the regulatory limit and caps every rate the driver
programs. On an ASUS Zenbook 14 UM3406HA (MT7922) all six MTGS tables
hold 0xff in every power byte, and txpower_sku shows tmac 3 on every
supported OFDM/HT/VHT/HE rate against EEPROM entries of 25-39, under
both the FR and the world regulatory domain. Huy Nguyen Dinh Quang saw
the same clamp on a Vivobook S 14 M5406WA, with 5 GHz TX at ~40 Mbps,
and proposed skipping the geo entry.
Skip a geo entry whose power byte is 0xff. The MTDS entry is narrowed
the same way on its way into the geo lookup, so give it the same
treatment, and clamp the dynamic value plus offset at 127 so a no-limit
entry cannot wrap.
Fixes: f965333e49 ("mt76: mt7921: introduce ACPI SAR support")
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2515420
Reported-by: Huy Nguyen Dinh Quang <huynguyendinhquang@gmail.com>
Closes: https://lore.kernel.org/linux-wireless/20260827134820.2607530-1-huynguyendinhquang@gmail.com/
Signed-off-by: Junjie Cao <junjie.cao@intel.com>
Tested-by: Cristian Fleischer <cristian.fleischer@gmail.com>
Link: https://patch.msgid.link/acb947435fc78d5c06039c7bd5609c735468b0ee.1789002236.git.junjie.cao@intel.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
mt7603 uses a driver-private global station WCID for frames that have
neither a station nor a vif, including frames injected through a monitor
interface. Unlike the core global WCID initialized by
mt76_register_device(), this WCID is published without ever being passed
to mt76_wcid_init().
Since commit 0335c034e7 ("wifi: mt76: fix race condition related to
checking tx queue fill status"), mt76_tx() queues every such frame on the
WCID's tx_pending or tx_offchannel queue and links its tx_list. The first
injected frame therefore reaches __skb_queue_tail() with an uninitialized
sk_buff_head and dereferences a NULL prev pointer.
Initialize the WCID before publishing it.
The fix was tested on an MT7603 PCIe device. Three wildcard probe requests
were injected through a monitor interface. The hardware queue head and tail
advanced from 0 to 3 and a second radio captured the third request over the
air. No oops or reset occurred. After restoring AP mode, a 150 MB transfer
also completed without a reset.
Fixes: 0335c034e7 ("wifi: mt76: fix race condition related to checking tx queue fill status")
Cc: stable@vger.kernel.org
Signed-off-by: Cristian Papa <pcristian292@gmail.com>
Link: https://patch.msgid.link/20260904010702.16306-1-pcristian292@gmail.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
band_idx starts out as 0xff, which tells the firmware to pick the band on
its own. A remain-on-channel grant normally writes a real index over it
before anything else looks. Two cases never see that: an MLD station
throws the grant away, and an AP has no association to trigger one.
The TX descriptor reads the same field into a two-bit slot, so the marker
comes out as 3. Every data frame from those two goes out tagged band 3.
Beacons are fine, they reach the firmware separately and never build a
descriptor.
Same numbers on an MT7925 and on a Netgear A9000:
stock patched
station, one link 0x00000001 0x00000001
station, two links 0x00003001 0x00000001
AP 0x00003013 0x00000013
real band index, STA 0x00001001 0x00001001
real band index, AP 0x00001013 0x00001013
Only the marker cases move.
Fixes: 0cb349d742 ("wifi: mt76: mt7925: update mt7925_mac_link_bss_add for MLO")
Signed-off-by: Devin Wittmayer <lucid_duck@justthetip.ca>
Link: https://patch.msgid.link/20260911024428.65244-1-lucid_duck@justthetip.ca
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Unloading the mt7915e module with a MT7916 triggers multiples WARN in
__netif_napi_del_locked() and in page_pool_disable_direct_recycling()
because the driver does not disable the napi before destroying it.
This is troublesome since on MT7916 it is required to unload the module
and reinsert it with a different enable_6ghz parameter to change the
frequency. The system generally becomes unstable after reinserting the
module.
Fix it by disabling rx napi inside mt7915e itself, even through napi rx is
enabled in the mt76 generic code. Disabling it in the mt76 generic code
was previously attempted and reverted because napi was disabled too
late and rx handlers could access freed structures. Note that the tx
side is enabled and disabled by the mt76 generic code.
It is disabled in mt7915_stop_hardware() since, unlike
mt7915_unregister_device(), is it also called in the probe path if an
error happens after rx napi is enabled.
Fixes: e57b790146 ("mt76: add mac80211 driver for MT7915 PCIe-based chipsets")
Signed-off-by: Nicolas Cavallari <nicolas.cavallari@green-communications.fr>
Link: https://patch.msgid.link/20260810154923.32546-1-nicolas.cavallari@green-communications.fr
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Correct the definition of struct mt7996_mcu_wed_rro_ba_delete_event to
match the 12-byte event record layout observed from firmware.
The event TLV sent by firmware is 12 bytes in length rather than 8 bytes.
It contains an additional 4 bytes that appear to be wlan_id and tid.
For example, a captured batch deletion of sessions 8, 9, and 10 (TIDs 6,
0, and 1) shows:
00000000: 02 00 0c 00 08 00 01 00 06 00 00 00 02 00 0c 00
00000010: 09 00 01 00 00 00 00 00 02 00 0c 00 0a 00 01 00
00000020: 01 00 00 00
The previous 8-byte structure corrupts the parsing of subsequent TLVs,
leading to unhandled delete events and erroneous session deletions.
Consequently, clients that create and tear down BA sessions in batches
(such as Apple Wi-Fi clients) fail to properly clean up stale sessions,
causing HW_RRO to be lost upon subsequent reassociations.
Fixes: a5d028d668 ("wifi: mt76: mt7996: add wed rro delete session garbage collector")
Signed-off-by: Tao Gong <gongtao0607@gmail.com>
Link: https://patch.msgid.link/20260823053739.186748-1-gongtao0607@gmail.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Removing the last link of an MLD interface leaves the firmware with the
MLD BSS and DEV entry: the removal loop skips the deflink, and the
hweight16(mvif->valid_links) fallback reads the stale pre-update
valid_links, which is still non-zero. The entry keeps the per-link MAC
address, so every subsequent legacy association fails authentication
until the interface is removed or the module is reloaded.
Remove the deflink BSS and add it back as a legacy BSS on the transition
to zero links.
Fixes: 69acd6d910 ("wifi: mt76: mt7925: add mt7925_change_vif_links")
Signed-off-by: Aaron Ma <aaron.ma@canonical.com>
Link: https://patch.msgid.link/20260826043658.2255553-1-aaron.ma@canonical.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Running these packets through regular buffering queues could cause them
to hang, especially when the packets were for stations that in disassoc
state.
Fixes: dedf2ec30f ("wifi: mt76: fix queue assignment for deauth packets")
Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20260901092232.461379-1-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
The driver increments wcid->non_aql_packets when a frame goes to the
hardware queue. The completion path decrements the counter again.
For an MLO peer, the hardware reports the completion on the link that it
used for the transmission. This link can differ from the link that the
driver queued the frame on. In that case, the increment and the
decrement go to different link wcids, and the count drifts upwards until
it blocks the station.
Keep the count on the wcid of the primary link, like the other peer-wide
state.
Fixes: 86c051f2c4 ("wifi: mt76: mt7925: enabling MLO when the firmware supports it")
Link: https://patch.msgid.link/20260818125825.395538-5-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
mt76 runs its own beacon monitor. mt76_beacon_mon_check() counts a miss
for each affiliated link of an MLD, and it stops the count while the phy
is off channel. mt7996 supplies it through mt76_rx_beacon(), but it does
not set CONNECTION_MONITOR. Therefore mac80211 also starts its legacy
monitor.
The legacy monitor knows one interface, not a set of links. It also
counts while the radio serves a different link. After seven beacon
intervals it removes an association that still carries traffic on the
other links.
Set the CONNECTION_MONITOR flag to disable the legacy monitor.
Fixes: 4df75606ec ("wifi: mt76: add per-link beacon monitoring for MLO")
Link: https://patch.msgid.link/20260818125825.395538-3-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
-----BEGIN PGP SIGNATURE-----
iQJPBAABCAA5FiEESH4wyp42V4tXvYsjUqAMR0iAlPIFAmrElacbFIAAAAAABAAO
bWFudTIsMi41KzEuMTIsMiwyAAoJEFKgDEdIgJTyEgwP/3SNJc5pKblEeXNjwHJK
ezaA9s8cGua0hHYWlrveqeWqiJ40pqhEzIxNDqrfq7eqK9sNSPB5sfFamcN6Kahx
KLd8sRpTe56z76mwg7Bj6zOjYl91EpcPAD5cKbMAaRyPziJ5CbYfNPMMD9UO37sS
KvYD3KnmZ8CvZDadHJkb051SVnvpNN+uX6JmQxBovZQtW/o7dl3BKFF1TZZsZ/E5
ekYVR/kGiZk5mCL8B192r0bssqrlbMvalVeO2dIZiEMdcJDWDPc1Qpw0Ry4nViCh
VF18bNmhIVCYWEZbc8YNqjk6U/MXxYWQUyCZkEGfwvMfOYb2nkfzCDGT6Qzl0WLc
jpEKaXBAJF3py2as+QGyDWH0oiYkDtyZLavjIHvAXJ9SwGYCyM7Nh3iU2bBRwysu
I/pqpahDaSZ6t5gh/Qp3VKl6WXEwng313Alyxxn/Fg3cYhPXyKt3wfzVThRouyfk
X3PJr2Qmksp8iDNIm/Nktgt/rppmPQcW70fQiy13WOha/7/klrJAy6i2UVtcGrqI
gmC3YkLcMmD0Ux2Siyi1y676oNx5Gp3ZOLVBDdmgDVQVNj28sCxeyydbPIz7421H
jG6eUldW1tHq0YMb/p5MJ6Evjofak8yPXOouHGyaZVI5REPcwdrMSXd2Qwk66FVJ
P5EPL9nIWEBYRrNuWNkYBUk0
=qEv0
-----END PGP SIGNATURE-----
Merge tag 'printk-for-7.3-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux
Pull printk fix from Petr Mladek:
- Allow using Braille console with a serial console driver converted
to NBCON API
* tag 'printk-for-7.3-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux:
braille: nbcon: Allow to use a serial console with NBCON API as Braille console
The pingroup table has gcc_plltest at function 5 of gpio12 and does not
offer pwm2 on that pin, so the pinmux core rejects a request for pwm2 on
gpio12 as an invalid group. On the hardware, function 5 of gpio12
carries the PWM2 output: the Xiaomi AX3000T v2 drives its blue status
LED from PWM2 on gpio12.
The vendor kernel shipped on that router (Linux 4.4, stock firmware
2.0.28) has pwm2 in this slot. Its pingroup table, as read from the
firmware image, lists these functions for gpio12:
gpio, blsp0_spi, blsp0_i2c, blsp1_uart0, _, pwm2, qdss_tracedata_a,
_, _, _
and has pwm3 at function 4 of gpio13, matching commit c6c159fcdb
("pinctrl: qcom: ipq5018: add missing pwm3 function on gpio13").
Measured on the board: with gpio12 set to each of the 16 function
values in turn, and PWM2 held at 0% and then at 100% duty, the pad
level read back from GPIO_IN follows PWM2 only at function 5. There it
does not follow PWM channels 0, 1 or 3, and the LED switches with PWM2.
Functions 4 and 7, which the table leaves empty, do not carry PWM2.
Put pwm2 in function 5 of gpio12 and list gpio12 in pwm2_groups. Drop
gpio12 from gcc_plltest_groups: none of its functions is gcc_plltest
any more, and selecting it would trigger the WARN_ON() in
msm_pinmux_set_mux().
Fixes: 725d1c8916 ("pinctrl: qcom: Add IPQ5018 pinctrl driver")
Assisted-by: LLM
Signed-off-by: Adriel Santos <adriel@adriel.eu>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Link: https://patch.msgid.link/20261002160958.908424-1-adriel@adriel.eu
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
This pull request contains two critical bug fixes, which can be briefly
descibed as follows:
1. key_get_persistent() creates a new persisten keyring for UID if it does
not exist yet, and creates a link from it to the nominated keyring.
Function did not set timeout when linking failed, therefore preventing
GC. The bug was addressed by calling key_set_timeout() regardless of
key_link() result when the persistent keyring gets created by
key_get_persistent().
2. __key_create_or_update() made a copy of keyring->restrict_link before
holding keyring->sem, which can cause add_key() to be executed against
stale keyring restrictions. The bug was fixed by copying the value only
after keyring->sem was taken.
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
-----BEGIN PGP SIGNATURE-----
iHUEABYKAB0WIQRE6pSOnaBC00OEHEIaerohdGur0gUCasQmRQAKCRAaerohdGur
0pa7APwKavlgnkGcbJNLA7kUz+2zt+tI9K/eT/5kgOaelesvmgEA5Xe6gvaXOtjr
YaxQ2ySKAo4JvTtsPMWgaCn8p2hqVwc=
=+UWf
-----END PGP SIGNATURE-----
Merge tag 'keys-v7.3-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd
Pull keys fixes from Jarkko Sakkinen:
- key_get_persistent() created a new persistent keyring if one did not
exist, but failed to set a timeout on it in an error path, preventing
GC.
Call key_set_timeout() regardless of key_link() result if a
persistent keyring was created.
- __key_create_or_update() made a copy of keyring->restrict_link before
holding keyring->sem, which could cause add_key() to be executed
against stale keyring restrictions. Fix it by copying the value only
after taking keyring->sem
* tag 'keys-v7.3-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd:
KEYS: Fix add_key() race with keyring restriction
keys: finalize persistent keyring timeout after link attempt
In MCQ mode, ufshcd_mcq_compl_pending_transfer() uses
blk_mq_tagset_busy_iter() to iterate over busy requests during error
recovery and host reset. However, both iterator callbacks perform
whole-queue operations redundantly for each visited request:
- force_compl == true: ufshcd_mcq_force_compl_one() calls
ufshcd_mcq_compl_all_cqes_lock() on every busy request, sweeping the
entire completion ring (hwq->max_entries slots) once per active request
under spin_lock_irqsave even though the first sweep already cleared all
completion entries.
- force_compl == false: ufshcd_mcq_compl_one() acquires cq_lock and polls
CQTPy over MMIO via ufshcd_mcq_poll_cqe_lock() for every busy request
without doing any per-request work.
Sweep or poll each hardware queue (hba->uhq[i]) once at the start of
ufshcd_mcq_compl_pending_transfer(). When force_compl is true, run
blk_mq_tagset_busy_iter() afterward to complete residual in-flight
requests with DID_REQUEUE, and remove the now-unused
ufshcd_mcq_compl_one() callback.
Fixes: ab248643d3 ("scsi: ufs: core: Add error handling for MCQ mode")
Cc: stable@vger.kernel.org
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Stanley Jhu <stanleyjhu@google.com>
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Link: https://patch.msgid.link/20260928035816.1294326-3-stanleyjhu@google.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
During MCQ host reset, ufshcd_host_reset_and_restore() stops the host
controller via ufshcd_hba_stop() (HCE = 0) before calling
ufshcd_complete_requests(hba, true) ->
ufshcd_mcq_compl_pending_transfer(hba, true) ->
ufshcd_mcq_force_compl_one() -> ufshcd_mcq_compl_all_cqes_lock(). Because
ufshcd_mcq_force_compl_one() is its sole caller,
ufshcd_mcq_compl_all_cqes_lock() always runs with HCE = 0.
Despite the comment above ufshcd_mcq_compl_all_cqes_lock() stating that
reading CQTPy may not be safe with the controller disabled, the function
still calls ufshcd_mcq_update_cq_tail_slot() at the end of its sweep:
1. Unsafe CQTPy MMIO read:
Calling ufshcd_mcq_update_cq_tail_slot() at the end of the sweep reads
CQTPy over MMIO while HCE = 0, directly contradicting the function's
documented contract (commit 1373df88d5 ("scsi: ufs: core: Add a
comment block above ufshcd_mcq_compl_all_cqes_lock()")) that reading
CQTPy may not be safe with the controller disabled.
2. Spurious error logs on empty slots:
Sweeping all max_entries slots visits empty entries where
command_desc_base_addr is 0, causing ufshcd_mcq_process_cqe() to log
unguarded dev_err(hba->dev, "Abnormal CQ entry!\n") messages.
Fix both issues in ufshcd_mcq_compl_all_cqes_lock():
- Remove the ufshcd_mcq_update_cq_tail_slot() call and the redundant
hwq->cq_head_slot = hwq->cq_tail_slot assignment without replacement.
The two indices are already equal after the sweep: they are equal when
the sweep starts, since ufshcd_mcq_poll_cqe_lock() consumes entries
until cq_head_slot reaches cq_tail_slot, and the sweep advances
cq_head_slot by exactly one full ring. Both indices are also
reinitialized before the queue is reused.
- Extract ufshcd_mcq_compl_cqe() and invoke it only on non-empty slots
during full-ring sweeps, keeping "Abnormal CQ entry!" logging strictly
for unexpected empty entries in ufshcd_mcq_poll_cqe_lock().
Fixes: ab248643d3 ("scsi: ufs: core: Add error handling for MCQ mode")
Cc: stable@vger.kernel.org
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Signed-off-by: Stanley Jhu <stanleyjhu@google.com>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Link: https://patch.msgid.link/20260928035816.1294326-2-stanleyjhu@google.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
ch_readconfig() looks up the scsi_device of every data transfer element
whose SCSI id the changer reports in READ ELEMENT STATUS, and stores it in
ch->dt[]. scsi_device_lookup() takes a reference, and nothing ever drops
it: ch_destroy() frees the array with kfree(). ch->dt[] is read nowhere
else - it only supplies the vendor, model and revision printed in the same
loop.
Once such a drive is removed, its scsi_device can never be released. It
stays on the host's device list at its address, so a new device there is
refused by anything that walks the list - target_core_pscsi reports
"scsi_device_get() failed for H:C:T:L" - and the low-level driver's module
can no longer be unloaded. Only a reboot recovers.
It shows with any changer that reports its drives' ids; with the mhvtl
virtual library (IBM 3573-TL personality), each create and remove of a
library with four drives leaves four references behind, counted by the
module's use count in lsmod. With ch not bound the count is unchanged, and
with this patch applied it is unchanged too.
Drop the reference as soon as the name has been printed, and remove the now
unused dt[] array. That also removes the array leaked when ch_probe() fails
after ch_readconfig().
The same leak was reported with an RFC patch in 2022, which was not merged.
Fixes: daa6eda65a ("[SCSI] add scsi changer driver")
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/linux-scsi/20220719075442.6215-1-yanghao_ht@163.com/
Signed-off-by: Ahmed Abdelhaleem Ahmed <ahmedhal@gmail.com>
Reviewed-by: Laurence Oberman <loberman@redhat.com>
Fixes: daa6eda65a ("[SCSI] add scsi changer driver")
Link: https://patch.msgid.link/20260929-ch-dt-leak-v2-1-ddda8d635dca@gmail.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
The MediaTek helper enables VA09 before powering on the mPHY, but ignores
the PHY result. A failure can leave VA09 enabled and publish
mphy_powered_on as true, so a later power-on attempt is skipped.
Check phy_power_on(), attempt to unwind VA09 on failure, and leave the
state flag unchanged. Propagate the helper result from host initialization
as well as its existing resume caller. Keep the original PHY error if the
supply rollback also fails, and report that rollback separately.
The issue was found by our static-analysis tool.
Fixes: 561e3a8726 ("scsi: ufs-mediatek: Fix unbalanced clock on/off")
Fixes: cf137b3ea4 ("scsi: ufs-mediatek: Support VA09 regulator operations")
Assisted-by: gpt 5
Signed-off-by: Pengpeng Hou <hppiscas@163.com>
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Reviewed-by: Stanley Jhu <stanleyjhu@google.com>
Link: https://patch.msgid.link/20260920034953.19535-1-hppiscas@163.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
This reverts commit 232d49dd4b.
Anirudh reports a regression from this change.
It is not appropriate for net this late in the release cycle
in the first place, so let's revert and revisit in net-next.
Reported-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
Link: https://lore.kernel.org/CAEev2e8+fr1tJnSErD+2TtLDw5fGJbQOMcM5eefMnLyFUR+m7w@mail.gmail.com
Fixes: 232d49dd4b ("net: stmmac: propagate PTP addend and system time programming errors")
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
The aligned scan boundary is derived from the last valid byte,
(s + count - 1). When count is huge (e.g. SIZE_MAX, which FORTIFY
strcat/strlcat pass when the destination size is not known at compile
time), s + count wraps around and the boundary lands before s, so the
ZBB path returns a bogus length. The original implementation
(5ba15d419f) had the same wrap-around in its (s + count) & ~7
boundary computation; after 5d588c6848 the wrapped boundary is caught
by the pre-loop guard "bgeu t0, t4, 2f", which then always exits for
aligned strings of 8 or more characters and strnlen() returns 8
instead of the real length.
This silently truncates strings built by fortified strcat: the dm
sysfs name attribute shows "live-bas" instead of "live-base", the
truncated name pollutes the udev database, and blivet/anaconda (as
well as LVM/dm-crypt/multipath userspace) break on RISC-V systems.
Detect the wrap-around and saturate the boundary to the top of the
address space, making the scan equivalent to strlen(). The saturation
clamps the increment to ~s, so it stays branchless and wrap-free:
s + min(count - 1, ~s) == saturating_add(s, count - 1)
Normal counts are unaffected.
Fixes: 5ba15d419f ("riscv: lib: add strnlen() implementation")
Cc: stable@vger.kernel.org
Suggested-by: David Laight <david.laight.linux@gmail.com>
Suggested-by: Qingfang Deng <qingfang.deng@linux.dev>
Signed-off-by: Shao Mingyin <shao.mingyin@zte.com.cn>
Acked-by: Michael Neuling <mikey@neuling.org>
Tested-by: Troy Mitchell <troy.mitchell@linux.dev>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Link: https://patch.msgid.link/20260915152656708z04s4oSYY2BGj34F36RZa@zte.com.cn
Signed-off-by: Paul Walmsley <pjw@kernel.org>