mirror of
https://github.com/torvalds/linux.git
synced 2026-10-12 21:31:03 +02:00
362bd5bce2
1481688 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
362bd5bce2 |
wifi: mac80211: don't offload TC setup on AP_VLAN interfaces
AP_VLAN interfaces are purely virtual, so don't try to offload
TC setup to drivers. We can't really use the AP interface either
since we may not know it all the time, and it could technically
even change.
Just reject the TC offload so things get done in software.
Assisted-by: LLM
Fixes:
|
||
|
|
a7491b7efb |
wifi: mac80211: don't warn when an IBSS has no channel to scan
ieee80211_request_ibss_scan() warns when regulatory leaves no
allowed channel, but that can happen as the regdomain can change
while IBSS is operating, and it can continue to operate briefly
during the 60s grace period until it's shut down.
Just remove the warning in this case.
Assisted-by: LLM
Fixes:
|
||
|
|
733f0fde95 |
wifi: mac80211: don't start a ROC while scanning
The ROC work can be pending when a scan starts (which requires
ROC list to be empty, but that's possible), and then a new ROC
can be added to the list and the work will pick it up.
Avoid starting that ROC if a scan made it between things, as
otherwise we'll hit a warning later:
WARNING: net/mac80211/offchannel.c:404 at ieee80211_start_next_roc+0x256/0x2d0
Workqueue: events_unbound cfg80211_wiphy_work
Call Trace:
__ieee80211_scan_completed+0x4fd/0xe40 net/mac80211/scan.c:537
ieee80211_scan_work+0x472/0x1ff0 net/mac80211/scan.c:1193
cfg80211_wiphy_work+0x410/0x570 net/wireless/core.c:513
Assisted-by: LLM
Fixes:
|
||
|
|
23c68b4aaf |
wifi: mac80211: don't drop scan probe requests for lack of peer rates
While software scanning, ieee80211_tx_h_rate_ctrl() warns and drops the frame if the target station has no usable bitrate on the band that's currently being scanned. But that's really meant for data frames, not if we happen to scan for the BSSID on the wrong band, which can be constructed easily. Skip the check for IEEE80211_TX_CTRL_DONT_USE_RATE_MASK, the previous commit also ignored the station rate mask for such frames as well. Assisted-by: LLM Reported-by: syzbot+0d516b33238bd97ee864@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=0d516b33238bd97ee864 Link: https://patch.msgid.link/20260904165722.b57ea4ab82d3.Id6c9c42d5cef5901bfac88853647b03ba4077b3e@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com> |
||
|
|
f5dd0626d2 |
wifi: mac80211: don't apply peer rates to off-channel frames
All the off-channel frames (including scan) aren't really part of the connection, so don't apply the station rates even if they're being sent to the station in question (e.g. by accident). They don't use the rate mask via IEEE80211_TX_CTRL_DONT_USE_RATE_MASK, but the station might not have rates of them either, hitting the warning found by syzbot. Assisted-by: LLM Reported-by: syzbot+34463a129786910405dd@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=34463a129786910405dd Link: https://patch.msgid.link/20260904165722.ade6b07421b8.I59b7ea810eb021a7a68b3090828a757b6dd85e57@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com> |
||
|
|
f4e72e3758 |
wifi: cfg80211: reduce RTNL holding in regulatory enforcement
Regulatory enforcement in reg_check_chans_work() does all work with the RTNL held, which can block the RTNL for a long time, which syzbot can hit and report hung tasks. Except for NAN, we don't need the RTNL for the enforcement, and the list iteration can be done with RCU instead. Split the enforcement off into new work structs: for NAN, we have to have the RTNL to close dependent NAN_DATA interfaces, everything else can use cfg80211_leave_locked() in a wiphy work. It'd be doable to use just a single work with RTNL, but then the RTNL would end up being used all the time, and really it only needs to be used for NAN. Assisted-by: LLM Reported-by: syzbot+adeb8550754921fece20@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=adeb8550754921fece20 Reported-by: syzbot+101224300649c3eb8af4@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=101224300649c3eb8af4 Link: https://patch.msgid.link/20260904165614.f65bd4d9fa35.I82dac71371d87f39e459fce931b0e5321e4f9767@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com> |
||
|
|
17a5f8571d |
wifi: cfg80211: fix NAN regulatory enforcement
reg_wdev_chan_valid() returns early for any wdev that has no netdev,
which is fine for P2P originally (and later PD still), but NAN has
no netdev and yet enforcement code was added and is needed, but is
dead code right now.
Use wdev_running() instead so that netdev-less wdevs aren't skipped.
P2P/PD don't do anything in the later switch, but NAN code can now
be reached.
Assisted-by: LLM
Fixes:
|
||
|
|
708f9d43d6 |
wifi: cfg80211: ibss: ref BSS entry for joined event
When the IBSS is joined, we only record the BSSID/channel in the event
and look up the BSS entry when processing it. However, that's racy,
e.g. a new scan with NL80211_SCAN_FLAG_FLUSH can remove it, causing a
warning in the event work:
!bss
WARNING: net/wireless/ibss.c:37 at __cfg80211_ibss_joined+0x3d3/0x440
Workqueue: cfg80211 cfg80211_event_work
cfg80211_process_wdev_events+0x39f/0x5b0 net/wireless/util.c:1144
cfg80211_process_rdev_events+0xa1/0x110 net/wireless/util.c:1179
cfg80211_event_work+0x2f/0x40 net/wireless/core.c:393
Do the lookup early (the driver is expected to only join an IBSS that
has a BSS entry) and keep a reference to it.
Assisted-by: LLM
Fixes:
|
||
|
|
b377e1000d |
wifi: cfg80211: don't filter by BSS type when removing stale entries
When an assoc AP switches to a channel that already has a BSS entry,
cfg80211_update_assoc_bss_entry() removes that entry before rehashing
the real one, since the two would otherwise collide in the BSS rbtree.
The lookup for that entry also required it to match the connection's BSS
type, so an entry advertising e.g. the IBSS capability bit was left in
place, and the following cfg80211_rehash_bss() then ran into it:
WARN_ON(!cmp)
Changing the type shouldn't really happen, but can be triggered by a
rogue AP/device, so drop the check and remove any entries matching
the comparison.
Assisted-by: LLM
Fixes:
|
||
|
|
068843ed09 |
wifi: cfg80211: only group hidden BSSes with beacon entries
When a probe response for an unknown BSS comes in, __cfg80211_bss_update()
looks for an existing entry with the same BSSID and a hidden (zero-length
or NUL-filled) SSID, and if it finds one it groups them, using the beacon
IEs from the existing entry.
But that could find another entry without a beacon, if it was also from a
probe response (with SSID), so there's a group without beacon elements.
If a beacon with a hidden SSID for that BSSID arrives later,
cfg80211_combine_bsses() goes looking for the probe response entries that
belong to it - i.e. entries with the same BSSID and channel that have no
beacon IEs - and finds those two. They are already grouped with each
other, so it hits its
WARN_ON_ONCE(bss->pub.hidden_beacon_bss)
WARN_ON_ONCE(!list_empty(&bss->hidden_list))
which are there because an entry without beacon elements is not supposed
to be part of a group yet.
Only combine entries when a beacon was already received, ones that are
kept separate will be combined when a beacon arrives.
Assisted-by: LLM
Fixes:
|
||
|
|
dab68a74e9 |
wifi: cfg80211: don't free driver-owned scan requests
When an interface goes down while a scan is running, cfg80211 completes
the scan towards userspace and frees the scan request. However, the
driver can be convinced that it owns the request, since the cancellation
is (intended to be) asynchronous.
The WARN_ON() in the netdev notifier was meant to catch this, but it's
not actually avoidable, so it triggers and we get a UAF in scan_done().
There doesn't seem to be a great way around it, so just track that the
driver is still convinced it owns the request, and then just free it on
completion if it was already cancelled. Also remove the warnings since
they can trigger in the intended architecture.
Assisted-by: LLM
Fixes:
|
||
|
|
48b2c5c628 |
wifi: cfg80211: check IP header size in cfg80211_classify8021d()
A frame that looks like IP can be transmitted, but be too short, so
the DS field is read incorrectly:
BUG: KMSAN: uninit-value in cfg80211_classify8021d+0x99d/0x12b0 net/wireless/util.c:1027
cfg80211_classify8021d+0x99d/0x12b0 net/wireless/util.c:1027
ieee80211_select_queue+0x37a/0x9e0 net/mac80211/wme.c:180
__ieee80211_subif_start_xmit+0x60f/0x1d90 net/mac80211/tx.c:4304
ieee80211_subif_start_xmit+0xa8/0x6d0 net/mac80211/tx.c:4538
...
packet_sendmsg+0x9173/0xa2a0 net/packet/af_packet.c:3108
Use skb_header_pointer() like the MPLS case.
Assisted-by: LLM
Fixes:
|
||
|
|
a7783e5853 |
wifi: cfg80211: don't get the radio mask for netdev-less wdevs
cfg80211_calculate_bi_data() calls rdev_get_radio_mask() with
wdev->netdev, which can be NULL and then crashes in mac80211.
To avoid that, invert the order of checks since wdev->netdev
is always valid for beaconing interfaces.
Assisted-by: LLM
Fixes:
|
||
|
|
ad7265b299 |
.get_maintainer.ignore: add myself
Since I've touched so many things all over I get CC'ed on far too many things - add myself here to avoid that. I'm also listed in MAINTAINERS for the right things. Signed-off-by: Johannes Berg <johannes.berg@intel.com> |
||
|
|
da2ca406f4 |
wifi: mac80211: avoid WARN in set_bitrate_mask when sdata not in driver
ieee80211_set_bitrate_mask() checks if the interface is running via
ieee80211_sdata_running(), but it does not check if the interface is
still present in the driver.
When sdata is running but IEEE80211_SDATA_IN_DRIVER is not set, the
call reaches drv_set_bitrate_mask() in driver-ops.h which hits
wlan1: Failed check-sdata-in-driver check, flags: 0x0
WARNING: net/mac80211/driver-ops.h:884 at drv_set_bitrate_mask
Syzkaller triggers this via wext SIOCSIWRATE ioctl. The Call Trace shows
wext_ioctl_dispatch() in wext-core.c dispatching the ioctl, calling
ioctl_standard_call() for SIOCSIWRATE, which calls cfg80211_wext_siwrate()
in wext-compat.c. That builds a bitrate mask and calls
rdev_set_bitrate_mask() which ends up in ieee80211_set_bitrate_mask() in
cfg.c. The interface is marked running via SDATA_STATE_RUNNING but
flags is 0, so check_sdata_in_driver() fails.
When the interface is being torn down, or when wext ioctl is issued
during interface bringup before drv_add_interface() sets IN_DRIVER, the
running check passes while IN_DRIVER is clear.
Check IEEE80211_SDATA_IN_DRIVER in ieee80211_set_bitrate_mask() before
calling the driver, returning -ENETDOWN. This avoids the WARN_ONCE in
driver-ops.h and matches other cfg.c operations that bail early when not
in driver.
This change should be safe because wiphy mutex is held in
cfg80211_wext_siwrate() via guard(wiphy), and IN_DRIVER is set/cleared
under RTNL and wiphy paths in drv_add_interface() and
drv_remove_interface() in driver-ops.c, so the check is race-free
against driver add/remove. Returning -ENETDOWN is the same error other
not-running paths use and does not introduce new locking.
Reported-by: syzbot+af177aa139efdd13a9da@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=af177aa139efdd13a9da
Link: https://lore.kernel.org/all/6a75205c.59b6c763.2bba34.00c3.GAE@google.com/
Fixes:
|
||
|
|
d8efd84f49 |
wifi: p54: require a full exp_if record in PDR_INTERFACE_LIST
The PDR_INTERFACE_LIST loop only checks that the record start is within
the entry before reading an entire struct exp_if from it. A truncated
trailing record makes the if_id/variant reads cross the entry boundary
into the heap beyond the EEPROM buffer (verified with a KASAN
reproducer of the loop). The variant also feeds the synth front-end
selection, so this is not only a leak.
Advance only while a full record still fits in the entry.
Fixes:
|
||
|
|
ce858fa6b8 |
wifi: p54: validate curve data length in the calibration curve converters
p54_convert_rev0() and p54_convert_rev1() read calibration curve
data from the device-supplied EEPROM entry using channel and
points-per-channel counts taken verbatim from that same entry, so
an entry that declares more data than it carries drives an
out-of-bounds read past the EEPROM buffer (verified with a KASAN
reproducer of the conversion loop). The sibling converters
p54_convert_output_limits() and p54_convert_db() already validate
their counts against the entry length; this path was missed.
Reject the entry when the counts do not fit in the entry data.
Fixes:
|
||
|
|
c46cfaf8db |
wifi: ipw2x00: bound management frame length to the receive buffer
Both management receive paths establish a lower bound on the frame length and no upper bound, even though the length originates from the device. ipw2100_corruption_check() returns 0 without inspecting frame_size for management frames, and __ipw2100_rx_process() only rejects a frame smaller than the three-address header, so any reported size up to the u32 limit reaches libipw_rx_mgt() against a receive allocation of IPW_RX_NIC_BUFFER_LENGTH bytes. Check frame_size itself rather than stats.len, which is a u16: a size of 65566 truncates to 30 on assignment and would pass a check made afterwards. ipw_rx() likewise only rejects a frame shorter than the header length. Bound it against the DMA mapped receive buffer. The size passed to alloc_skb() is rounded up by the allocator, so skb_tailroom() can exceed IPW_RX_BUF_SIZE and is not a usable bound here; the existing uses of that idiom in the data paths are too permissive for the same reason. libipw then hands the remainder to libipw_parse_info_param(), which walks information elements for as long as the length allows, so an over-long reported length reads past the receive buffer without any wraparound being involved. The length is device-reported, so per Documentation/process/threat-model.rst this is a robustness fix rather than a vulnerability. Found by an AI-assisted review of length arithmetic in management frame parsers. Compile-tested only for these two hunks; I do not have the hardware, so they are not tested on a real device. Assisted-by: Claude:claude-opus-5 Signed-off-by: Shmulik Cohen <anuk909@gmail.com> Link: https://patch.msgid.link/20260812190412.18333-4-anuk909@gmail.com Signed-off-by: Johannes Berg <johannes.berg@intel.com> |
||
|
|
adb7118b7d |
wifi: libipw: reject too-short association responses
libipw_handle_assoc_resp() reads the capability, status and aid fields
of the 30-byte association response prefix and then computes the
information element length as
stats->len - sizeof(*frame)
stats->len is a u16 and sizeof() has type size_t, so the subtraction is
evaluated as size_t and wraps instead of going negative. Truncating
that to the u16 length parameter of libipw_parse_info_param() turns a
frame shorter than the fixed fields into a length near 64 KiB, and the
parser then reads past the receive buffer.
Both the ipw2100 and ipw2200 management receive paths reach this
function having established only that the frame carries the generic
24-byte three-address header.
Reject the frame before any fixed field is touched.
Found by an AI-assisted review of length arithmetic in management frame
parsers. Verified with a KUnit case under Generic KASAN on arm64 under
QEMU; I do not have the hardware, so it is not tested on a real device.
Fixes:
|
||
|
|
5ce5721e8c |
wifi: libipw: reject too-short beacon and probe responses
libipw_process_probe_response() and the libipw_network_init() call it
makes assume the frame contains the full 36-byte beacon and probe
response prefix, but the ipw2100 and ipw2200 receive paths only
establish that a management frame carries the generic 24-byte
three-address header.
libipw_network_init() then computes the information element length as
stats->len - sizeof(*beacon)
stats->len is a u16 and sizeof() has type size_t, so the subtraction is
evaluated as size_t and wraps instead of going negative. Truncating
that to the u16 length parameter of libipw_parse_info_param() yields
65524 for a 24-byte beacon, and the parser then walks the receive
buffer as if it held almost 64 KiB of information elements, reading
past the allocation.
Reject the frame before any fixed field is touched.
Found by an AI-assisted review of length arithmetic in management frame
parsers. Verified with a KUnit case under Generic KASAN on arm64 under
QEMU; I do not have the hardware, so it is not tested on a real device.
Fixes:
|
||
|
|
3687d7d480 |
wifi: mwifiex: validate scan response extents
mwifiex_ret_802_11_scan() subtracts the fixed response fields and the
firmware-provided BSS length from resp->size without first proving that
either extent fits. A short response or oversized BSS length can
therefore underflow tlv_buf_size and make the TLV parser walk beyond the
command response.
Compute the fixed extent from the selected normal or background scan
response. Validate that the fixed fields and BSS data fit before deriving
the TLV extent and entering the parser.
Fixes:
|
||
|
|
1c25bfad93 |
wifi: mwifiex: validate action frame fixed fields
mwifiex_process_mgmt_packet() accepts an rx_pkt_length as small as a
four-address struct ieee80211_hdr plus the two-byte firmware length prefix.
After stripping the prefix, mwifiex_parse_mgmt_packet() can receive a
frame equal to sizeof(struct ieee80211_hdr).
For action frames, the parser reads the category byte immediately after
that header and, for a public action frame, reads the following action
code byte without verifying that either field is present. A truncated frame
can therefore make the parser consume up to two bytes past the
firmware-declared frame length. If those bytes look like a TDLS discovery
response, the malformed frame can spuriously update peer signal state.
Require the category and public action-code fields before reading them.
Use sizeof(*ieee_hdr) so the checks and field accesses directly match the
firmware four-address layout being parsed before address4 is removed.
Suggested-by: Johannes Berg <johannes@sipsolutions.net>
Suggested-by: Brian Norris <briannorris@chromium.org>
Fixes:
|
||
|
|
e667aee1c1 |
wifi: mwifiex: bound the pairwise-cipher OUI walk to the IE length
mwifiex_search_oui_in_ie() reads a pairwise-cipher (PTK) count from a
beacon/probe-response RSN or WPA information element and then walks that
many 4-byte OUIs, comparing each with memcmp(). The count comes straight
from the (attacker-supplied) IE and is never checked against the
element's own length, and the callers admit the element on element_id
alone (has_ieee_hdr() / has_vendor_hdr(), no length check). A crafted
RSN/WPA IE with a large pairwise count therefore makes the walk read up
to 255 * 4 bytes past the element -- an out-of-bounds read of the
kmemdup()'d beacon buffer, reachable from any AP whose beacon/probe
response is processed during scan-result parsing.
Pass the number of IE bytes available at the OUI list and bound the walk
to the element. Keep the length signed and reject a negative value
before any unsigned arithmetic, so a small or zero IE length cannot
underflow to a large size_t and defeat the bound.
Found by 0sec automated security-research tooling (https://0sec.ai).
Fixes:
|
||
|
|
e2de8d5eb2 |
wifi: brcmfmac: cyw: pass PMKID to firmware if present
Zero out auth_status on initialization. Otherwise, garbage will
leak from the stack to the firmware (when ssid is less than 32 bytes
and/or when params->pmkid is set). Then, pass the params->pmkid to the
firmware (without it, the firmware caches a garbage PMKID on successful
authentication and denies a subsequent association request that includes
the PMKID).
Fixes:
|
||
|
|
fa00193eb9 |
wifi: mwifiex: prevent authentication frame length truncation
mwifiex_cfg80211_authenticate() derives the authentication frame length
from req->ie_len and req->auth_data_len, both of type size_t, but stores
it in a u16.
NL80211_ATTR_AUTH_DATA only has a minimum length policy. Since nla_len is
a u16, a single attribute can carry up to 65531 bytes of payload, so the
sum can exceed U16_MAX before it is assigned to pkt_len. The truncated
pkt_len determines the skb frame area, while the copy length remains
req->auth_data_len - 4, resulting in a heap buffer overflow.
For example, with auth_data_len equal to 65510 and no IEs, the sum is
65546. It is truncated to 10 and then reduced by four to 6. The driver
appends only six bytes to the skb with skb_put(), but then copies 65506
user-provided bytes into the authentication body.
Reaching this path requires CAP_NET_ADMIN in the user namespace owning
the network namespace, an up station netdev, and a suitable BSS/SAE
authentication request.
Compute the length in size_t, reject values that cannot be represented by
the firmware's u16 frame length field, and only then assign it to pkt_len.
Fixes:
|
||
|
|
a3d722190c |
wifi: mwifiex: fix IRQ leak using wrong index in MSI-X error path
mwifiex_pcie_request_irq() registers each MSI-X vector with a per-index
dev_id (&card->msix_ctx[i]). On a request_irq() failure the cleanup loop
"for (j = 0; j < i; j++)" frees msix_entries[j].vector but passes the
failed index's &card->msix_ctx[i] as the dev_id. free_irq() matches on
(irq, dev_id), so it fails to find the action registered with
&card->msix_ctx[j]: the already-requested IRQ j is not freed (leaked) and
free_irq() warns about freeing a non-existent IRQ. Use &card->msix_ctx[j].
Fixes:
|
||
|
|
bbb9a0ab96 |
wifi: libertas_tf: fix UAF in lbtf_free_adapter()
lbtf_free_adapter() calls lbtf_free_cmd_buffer() to free the command
buffers before calling timer_delete_sync() to wait for the command
timer callback. If the timer callback (command_timer_fn) is already
running when lbtf_free_cmd_buffer() frees the command array, the
callback dereferences priv->cur_cmd->cmdbuf which points to freed
memory.
Swap the order so that timer_delete_sync() runs first, ensuring any
in-flight callback has completed before the command buffers are freed.
Fixes:
|
||
|
|
f9edf7cf63 |
wifi: virt_wifi: free skb when disconnected
When the simulated link is disconnected, virt_wifi_start_xmit() returns
NET_XMIT_DROP without freeing the skb. dev_hard_start_xmit() treats this
return value as consumed, so every packet sent while disconnected leaks its
skb.
Free the skb before returning the drop status.
Fixes:
|
||
|
|
ba6cb7c086 |
wifi: wilc1000: fix out-of-bounds read in P2P public action frames
wilc_wfi_p2p_rx() and mgmt_tx() start parsing a frame once
ieee80211_is_public_action() returns true. That helper only verifies the
frame is long enough for the action category field, that is
offsetofend(struct ieee80211_mgmt, u.action.category), 25 bytes. Both
functions then read the P2P public action header up to oui_subtype at
offset 30 and pass "size - ie_offset" to cfg80211_find_vendor_ie(), where
ie_offset is offsetof(struct ieee80211_mgmt, u) + sizeof(*d), i.e. 32.
A public action frame of 25 to 31 bytes passes the check but is shorter
than that 32 byte header, so oui_subtype can be read out of bounds, and
because the length is unsigned, "size - ie_offset" underflows to a value
close to 4 GiB. cfg80211_find_vendor_ie() takes an unsigned int length,
so even the size_t subtraction in mgmt_tx() is truncated to the same
value. It then walks far past the buffer searching for a vendor element
until it reaches unmapped memory.
In the receive path the frame arrives over the air and needs no
association, so a nearby unauthenticated device can crash the host while
it is in P2P listen. Reject frames shorter than the P2P public action
header in both paths before dereferencing it.
Fixes:
|
||
|
|
8a1f3cf89d |
wifi: wlcore: release runtime PM ref on regdomain config failure
wlcore_regdomain_config() gets a runtime PM reference before sending
the regulatory-domain command. When
wlcore_cmd_regdomain_config_locked() fails, the function queues recovery
and returns without dropping that reference.
Release the reference after handling the command result so both success
and failure paths balance the preceding
pm_runtime_resume_and_get(). The recovery worker takes a separate
runtime PM reference and cannot release the reference held here.
Fixes:
|
||
|
|
b5526b780f |
wifi: iwlegacy: fix broadcast stations deallocation
On the error path of __il4965_up(), il_dealloc_bcast_stations() clears only IL_STA_UCODE_ACTIVE, leaving IL_STA_BCAST set. This causes the same broadcast stations to be deallocated again by __il4965_down(). This can occur when RF_KILL is toggled during driver startup. To fix clear the entire 'used' field, since we will not do any other operations on the station. Reported-and-tested-by: Martin-Éric Racine <martin-eric.racine+kernel-bugzilla@iki.fi> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221733 Fixes: |
||
|
|
e6031f0226 |
wifi: mac80211: avoid out-of-bounds read for empty PREQ elements
ieee80211_mesh_preq_size_ok() derives the location of the PREQ bottom
fields before checking whether the element contains even the fixed
header. ieee80211_mesh_hwmp_preq_get_bottom() reads the flags byte to
account for the optional Address Extension field. Consequently, an
empty PREQ element causes a one-byte read beyond its declared payload.
Move the helper call after both size checks, so the bottom fields are
only accessed when they are present.
Fixes:
|
||
|
|
af72b5946d |
wifi: mac80211: include TIM bitmap control for buffered S1G mcast traffic
Currently when building the S1G TIM element, we only build the bitmap
control if we have buffered unicast traffic. Since AID 0 sits within
the bitmap control if we have buffered multicast traffic with no
buffered unicast traffic the bitmap control won't be emitted and
dozing stations will be unaware of buffered multicast.
To fix, only exclude the bitmap control byte when we don't have
both buffered unicast and multicast traffic.
Fixes:
|
||
|
|
adf50c47a4 |
Including fixes from bluetooth.
Previous releases - regressions:
- page_pool: keep frag_offset aligned for odd-sized requests
- sched: fix u32 duplicate handle when node ID pool is exhausted
- udp: create exceptions before socket matching
- igmp: convert struct ip_sf_list to RCU
- ip6_gre: check tunnel info before xmit in ip6gre_tunnel_xmit
- rds: acquire the fastpath locks in rds_conn_shutdown()
- tipc:
- protect node reset trace dump with node lock
- fix NULL deref in tipc_named_node_up() on empty publication list
- bluetooth:
L2CAP: fix out-of-bounds write in l2cap_ecred_connect
hci_core: fix race condition during device registration
- eth: mlx5e: prevent stale XSK buffer release on refill retries
- eth: bridge: don't truncate the port group walk on teardown
Previous releases - always broken:
- gro: fix nesting of TCP GSO SKBs in skb_gro_receive_list()
- sched: fix skb sizing and action leak on reoffload delete
- tcp: fix use-after-free in do_tcp_getsockopt()
- af_packet: don't cast tpacket_hdr.tp_len to int in tpacket_parse_header().
- sctp: fix soft lockup from unpadded ASCONF-ACK parameter iteration
- iptunnel: fix stale transport header during tunnel decapsulation
- eth: vxlan: fix use-after-free in vxlan_mdb_remote_src_del()
- eth: bonding: fix uninitialized transport header access in alb_determine_nd()
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-----BEGIN PGP SIGNATURE-----
iQJGBAABCgAwFiEEg1AjqC77wbdLX2LbKSR5jcyPE6QFAmqZp4kSHHBhYmVuaUBy
ZWRoYXQuY29tAAoJECkkeY3MjxOkEjkQALMGg903vZ4TfGlzKayFzyhcd5ZC8G4F
R4M+UgTGRfNuas/1YwjpyOpvOYyFgGZ9xBmYNFdsW0YCzZwu8PxpXgu6WTZ+F4gu
sDtWoAbN5V6CfY3fdC7IbXTp8t4CX+shQAsVvEp39Y8SJF4AZeMn8N0+Lnu4DlD3
DAPo/lYSSfvv7RK/5Jvr9FWo7vyoEylfG+LekzGASmWGwhC3h7kWGB4RB4PhJmyq
vRIj2ZjnzdDxu4N7ZGh+EEu5SBCcLP0e/dIMCDg++HAghDqPJ+7pzbWC1kFtQ0ss
qOSyws/xMW3D0Rb68tkiikYWRwgvXUsfEL7Jdf2lhC1xDI8ZpxrrnPYYSZS4rsjb
hjeBwtzRZhv5R0PnNlaZyNpFICIW3XwqP0bYqH/Z/CgwwkKYd+Rp6Tm7hkLpafNx
Py607x2Ff/L2Aydp8csJEyqFP33QOHAfeW+X/YCo4jTc0zBTMSsOblG/EsPPBdNX
fvhVkx4NdqAvIdLYm65cdvhe5dZtIhOAhwAMcrGiMIia4vCIsXq3fWbAe6Phtu8T
KHpQ7Esg/if6blNPpflBuVPsoU+5N6mL7a+zsurqvilJBC5DgYaxwbMlgRSUmJzg
2rR6IlrOsb0FFITNUv+xgPEGzMGV1rL4wnaMSmVN0tjmFQvcu24XQ17D+ug27+eG
rD+E2lrX5rNn
=0sv8
-----END PGP SIGNATURE-----
Merge tag 'net-7.3-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Pull networking fixes from Paolo Abeni:
"Including fixes from bluetooth.
Previous releases - regressions:
- page_pool: keep frag_offset aligned for odd-sized requests
- sched: fix u32 duplicate handle when node ID pool is exhausted
- udp: create exceptions before socket matching
- igmp: convert struct ip_sf_list to RCU
- ip6_gre: check tunnel info before xmit in ip6gre_tunnel_xmit
- rds: acquire the fastpath locks in rds_conn_shutdown()
- tipc:
- protect node reset trace dump with node lock
- fix NULL deref in tipc_named_node_up() on empty publication
list
- bluetooth:
- L2CAP: fix out-of-bounds write in l2cap_ecred_connect
- hci_core: fix race condition during device registration
- eth:
- mlx5e: prevent stale XSK buffer release on refill retries
- bridge: don't truncate the port group walk on teardown
Previous releases - always broken:
- gro: fix nesting of TCP GSO SKBs in skb_gro_receive_list()
- sched: fix skb sizing and action leak on reoffload delete
- tcp: fix use-after-free in do_tcp_getsockopt()
- af_packet: don't cast tpacket_hdr.tp_len to int in
tpacket_parse_header()
- sctp: fix soft lockup from unpadded ASCONF-ACK parameter iteration
- iptunnel: fix stale transport header during tunnel decapsulation
- eth:
- vxlan: fix use-after-free in vxlan_mdb_remote_src_del()
- bonding: fix uninitialized transport header access in
alb_determine_nd()"
* tag 'net-7.3-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (83 commits)
net: gro: Fix nesting of TCP GSO SKBs in skb_gro_receive_list()
net: stmmac: reconfigure RX packet parser table in stmmac_hw_setup() after reset
net: airoha: enable RX_DONE interrupt for RX queue 31
net/rds: don't let rds_conn_shutdown() consume a concurrent drop
net/rds: acquire the fastpath locks in rds_conn_shutdown()
net/rds: acquire RDS_IN_XMIT in rds_tcp_reset_callbacks()
net/rds: tcp: don't force RDS_CONN_RESETTING over a concurrent shutdown
net/rds: clear cp_flags bits individually in rds_conn_path_reset()
net/rds: use clear_bit_unlock() in release_refill()
net/rds: use wq_has_sleeper() in release_in_xmit()
net: usb: qmi_wwan: add Compal EXM-G1x support
net: macb: exclude software FCS from TX byte statistics
net: Remove conflicting altnames for dying netns in __dev_change_net_namespace().
net: bridge: mcast: don't truncate the port group walk on teardown
bonding: do not clear curr_active_slave prematurely when releasing all slaves
net: qrtr: Send HELLO message on endpoint register
octeontx2-af: Fix limiting SRIOV VF count logic
bonding: alb: fix uninitialized transport header access in alb_determine_nd()
s390/ctcm: Prevent XID null dereference
net: psp: do not inherit the Rx association on clone
...
|
||
|
|
8ab1afb2eb |
- dm-crypt: fix a race condition that could make errors not being reported
- dm-cache: fix rwsem being locked and unlocked from different processes
- dm-integrity: set the 'stable writes' flag
- dm-integrity: fix a buffer overflow introduced in this merge window
- dm-integrity: fix an infinite loop if tag size is greater than 64
- dm-cache: fix demotion statistics
- dm-integrity: fix NULL pointer dereference in the data-recovery mode
- dm-ebs: remove a bogus restriction on the starting sector offset
-----BEGIN PGP SIGNATURE-----
iIoEABYIADIWIQRnH8MwLyZDhyYfesYTAyx9YGnhbQUCapmHXxQcbXBhdG9ja2FA
cmVkaGF0LmNvbQAKCRATAyx9YGnhbXwlAP9TGvtNybtjhdQJmo3t528XRdwYrYuJ
TZTRcQ+KMXEAkgEAxG1l4vvECTwSkUhZXub2own7+IypiY8N5cFOWCkdVwc=
=hVzb
-----END PGP SIGNATURE-----
Merge tag 'for-7.3/dm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm
Pull device mapper fixes from Mikulas Patocka:
- fix a dm-crypt race condition that could make errors not being reported
- dm-cache:
- fix rwsem being locked and unlocked from different processes
- fix demotion statistics
- dm-integrity:
- set the 'stable writes' flag
- fix a buffer overflow introduced in this merge window
- fix an infinite loop if tag size is greater than 64
- fix NULL pointer dereference in dm-integrity data-recovery mode
- remove a bogus restriction on the dm-ebs starting sector offset
* tag 'for-7.3/dm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm:
dm-ebs: fix incorrect device offset check in ebs_ctr()
dm-integrity: fix NULL pointer dereference when the 'R' flag is used
dm cache: fix demotion stats in passthrough mode
dm-integrity: fix infinite loop on discard with large tag size
dm-integrity: fix buffer overflow with keyed discard
dm-integrity: require stable writes for internal hash modes
dm cache: fix issue with background work locking
dm-crypt: fix a tiny race condition in crypt_dec_pending
|
||
|
|
97be98b94d |
- Serialize truncate, fallocate, and mmap fault paths with
invalidate_lock, avoiding mmap failures during concurrent size changes
and exposure of uninitialized data during allocation.
- Correct fallocate signal and zeroing error handling.
- Fix FITRIM range alignment to prevent discard requests from extending
into allocated clusters.
- Fix free-cluster accounting when cluster-freeing rollback or bitmap
clearing fails.
- Keep volumes marked dirty when ntfs errors have been recorded.
- Compute bi_sector in 512-byte units, preventing silent corruption on
4Kn devices.
- Validate sectors_per_cluster values and prevent undefined shifts when
parsing MFT and index record sizes.
- Bound $AttrDef traversal to the loaded table size.
- Fix MFT record resizing, memmove overlap, and kmap_local cleanup issues.
- Improve error propagation across attribute, EA, and reparse operations,
including returning -ERANGE for undersized xattr buffers.
- Avoid modifying the HasEA flag when setxattr fails and return
DT_UNKNOWN when directory inode lookup fails.
- Reduce contention in WOF decompression by performing block reads outside
the decompression lock.
-----BEGIN PGP SIGNATURE-----
iQJKBAABCgA0FiEE6NzKS6Uv/XAAGHgyZwv7A1FEIQgFAmqZGasWHGxpbmtpbmpl
b25Aa2VybmVsLm9yZwAKCRBnC/sDUUQhCIdnD/9OEohX3GvIqwHT90GubLIGunJr
S2D1MSJz0AwNF0sNQhTawAc3fbjwI77B2H3mI/Xghkd4IvgtzcY/L/jYfaZ3M7sn
Grctto0BypHI5DuBbArfjTQdW/NkPR0IpXGyBLQ8sO6aYVUPGAG0lvL9tT1Zm52N
JQU1mtjEihE5ZpD79gx8PexuDJHIg0uuok4EANk9Vu+Ub68bDBsnl/Zyxm4spIEA
976QAdboGDvo+71IdpPSaMuSAMytOf7LDJqxECqZXN5aUOoz9wrJnjELVg+xRE6c
AFM9hHZ4tZ0zs5A0EpR835URaB/bxGWpbGdkCyDDBm+QMHiTGNp5nGFl/Sd/NO5B
NcSaj0Tc2+7DbcTLU2hk1FhUsEk8eTwBZK05gxE6OajAIfAyXqxTNeB1th5smLKG
PjKWjQh9F2okIB71D6jkdntAs/0RPyuu37bTl0EtJeuRoWYZooHkgeA+tV350BQz
vjOwQuVUnDoNRQ0z1egrqAZalgjoNG7xLu0fI+n7eXZ5a4XZvQpYlKWKsodXYVwX
TBwnQhst8zEx49fe5dIBGnLiZhhQMe2zxmh7lxAOu6VcVPE4Xv6jSwzcilyiPtQF
YrdZGOEgtByOLsD+m1PRYZvukvQDDpn+NX6w4dJ+YL3MjGB7X1e2c7imqonJJYM1
0hByGPAn3g+5XdGSig==
=gAcy
-----END PGP SIGNATURE-----
Merge tag 'ntfs-for-7.3-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/ntfs
Pull ntfs fixes from Namjae Jeon:
- Serialize truncate, fallocate, and mmap fault paths with
invalidate_lock, avoiding mmap failures during concurrent size
changes and exposure of uninitialized data during allocation
- Correct fallocate signal and zeroing error handling
- Fix FITRIM range alignment to prevent discard requests from extending
into allocated clusters
- Fix free-cluster accounting when cluster-freeing rollback or bitmap
clearing fails
- Keep volumes marked dirty when ntfs errors have been recorded
- Compute bi_sector in 512-byte units, preventing silent corruption on
4Kn devices
- Validate sectors_per_cluster values and prevent undefined shifts when
parsing MFT and index record sizes
- Bound $AttrDef traversal to the loaded table size
- Fix MFT record resizing, memmove overlap, and kmap_local cleanup
issues
- Improve error propagation across attribute, EA, and reparse
operations, including returning -ERANGE for undersized xattr buffers
- Avoid modifying the HasEA flag when setxattr fails and return
DT_UNKNOWN when directory inode lookup fails
- Reduce contention in WOF decompression by performing block reads
outside the decompression lock
* tag 'ntfs-for-7.3-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/ntfs: (23 commits)
ntfs: take invalidate_lock in ntfs_filemap_page_mkwrite()
ntfs: take invalidate_lock in ntfs_setattr_size()
ntfs: handle signal interruption in fallocate
ntfs: fix FITRIM range alignment
ntfs: read WOF chunks outside the decompression lock
ntfs: leave HasEA flag untouched on setxattr failure
ntfs: fix race between fallocate and mmap reads
ntfs: fix memmove overlap in ntfs_new_attr_flags
ntfs: compute bi_sector in 512-byte units
ntfs: reject invalid sectors_per_cluster in the boot sector
ntfs: bound $AttrDef table walk to the loaded table size
ntfs: fix undefined behavior in mft/index record size calculation
ntfs: treat any nonzero dio zero-range return as an error
ntfs: fix incorrect MFT record pointer passed to ntfs_attr_record_resize
ntfs: do not mark the volume clean in sync_fs when errors were recorded
ntfs: skip free cluster decrement when rollback fails
ntfs: only count successfully cleared runs when freeing clusters
ntfs: fix kmap_local leak in write_mft_record_nolock() error paths
ntfs: return real error from ntfs_non_resident_attr_record_add()
ntfs: preserve error code in ntfs_resident_attr_record_add()
...
|
||
|
|
66817a9794 |
net: gro: Fix nesting of TCP GSO SKBs in skb_gro_receive_list()
Fraglist GRO and hardware GRO can create an fraglist of
HW-GRO packets. This cannot be segmented back into
the original form on TCP tethering scenario.
Avoid constructing such a GSO packet, by flushing an already
built fraglist GRO packet if a hardware GRO packet arrives.
Scenario (Tethering/Forwarding):
1.Driver submits a single TCP packet, P1. P1 is kept in the
gro_list as the first packet.
2. The driver submits a TCP GSO skb, P2. P2 has already aggregated
multiple TCP packets by HW_GRO, and its non-linear data is stored in
frags[].
3. P1 and P2 match the GRO rules, and since there is no local socket,
they are aggregated by skb_gro_receive_list(). The resulting skb,
P3, has a frag_list entry that still contains frags[]:
P3: [ Linear Data ] -> frag_list -> [ Linear Data ]
[ frag[1] ]
[ frag[2] ]
...
4. Later, tcp4_gso_segment() or tcp6_gso_segment() calls
skb_segment_list() to segment P3. However, skb_segment_list() only
segments the entries in frag_list. It does not segment the frags[]
inside P2, so P3 is not restored to the original packets, which leads
to IP fragmentation or packet drop in the following path.
Check skb_is_gso(skb) and current GRO method, make sure fraglist GRO
applies to consecutive non-GSO skb, others adopt regular GRO path.
Fixes:
|
||
|
|
6b8fed2675 |
net: stmmac: reconfigure RX packet parser table in stmmac_hw_setup() after reset
The core software reset issued in stmmac_init_dma_engine() during
ndo_open() callback clears the MTL RX packet parser registers, but
stmmac_rxp_config() is only invoked from the cls_u32 add/delete paths.
After an ifdown/ifup cycle the hardware therefore runs with the default
all-pass table while priv->tc_entries still reports the filters as
installed. Re-apply the RX packet parser table from priv->tc_entries in
stmmac_hw_setup(), right after the software reset, so the filters are
restored when the interface is brought up again.
Fixes:
|
||
|
|
7db28abbea |
net: airoha: enable RX_DONE interrupt for RX queue 31
RX queue 31 has always been allocated and filled by airoha_qdma_init_rx()
since RX_DONE_INT_MASK spans queues 0-31, but none of the RX_IRQ*
_BANK_PIN_MASK values covered BIT(31). As a consequence the RX_DONE
interrupt for queue 31 was never enabled, airoha_qdma_rx_process() never
ran on that queue and its buffers were never reaped.
Route RX queue 31's RX_DONE interrupt to IRQ bank 1 so that the queue
is drained and its buffers returned to the page pool.
Fixes:
|
||
|
|
2f38e26a57 |
Merge branch 'net-rds-own-the-fastpath-locks-across-connection-teardown'
Allison Henderson says:
====================
net/rds: own the fastpath locks across connection teardown
This is v5 of the follow-up set to "net/rds: Bug fix ports, part 2"
[1] (v1 at [2], v2 at [3], v3 at [4], v4 at [5]). During review of part 2,
the later half of that series needed more work than a respin, so it was
split off into this set together with the companion fixes identified
along the way. As discussed on the v2 thread, it is targeted at net.
RDS connection teardown quiesces the transmit and receive-refill fast
paths by waiting for the RDS_IN_XMIT/RDS_RECV_REFILL bits to be
sampled clear. Sampling a bit clear is not owning it: the fast path
can re-take its bit right after the wait returns and then run
concurrently with the transport shutdown and the send-state reset.
Oracle UEK closed this by making teardown acquire the bits as locks
("rds: Make sure transmit path and connection tear-down does not run
concurrently"); patches 5 and 6 do the same for the two
rds_send_path_reset() call sites upstream.
Making teardown block on the bits as locks promotes several latent
ordering bugs from rare to load-bearing, so they are fixed first:
Patches 1 and 2 fix the release side of the two bit locks.
release_in_xmit() and release_refill() both clear their bit and then
test for waiters, but the barrier is on the wrong side of the clear
to order the critical section's stores before the release, and the
waiter check does not order against the clear. Once teardown blocks
on these bits as locks (uninterruptible and untimed), a lost wake-up
or a store observed out of order stops mattering only in theory.
Use clear_bit_unlock() and wq_has_sleeper(), the pattern already
half-present in release_in_xmit().
Patch 3: rds_conn_path_reset() wipes the whole cp_flags word with a
plain store. Once teardown owns bits in that word across the reset,
a blanket store would end lock ownership early - and it already
races atomic RMWs on the same word today. Clear the bits the reset
is responsible for individually, as Oracle UEK also does.
Patch 4: rds_tcp_reset_callbacks() stores RDS_CONN_RESETTING
unconditionally, which can overwrite the RDS_CONN_ERROR or
RDS_CONN_DISCONNECTING of a shutdown already in progress on the same
path and send that shutdown through an extra drop cycle. Once the
accept path can park for the duration of a teardown (patch 6) that
window widens, so make the transition conditional first, as Oracle
UEK does.
With those in place, patch 5 converts rds_tcp_reset_callbacks() from
waiting on RDS_IN_XMIT to acquiring it, holding it across the socket
swap and rds_send_path_reset(), and patch 6 has rds_conn_shutdown()
hold both bit locks across the transport shutdown and path reset.
Patch 7 fixes a pre-existing teardown-state hole that this series
makes easier to hit but did not introduce. Since commit
|
||
|
|
260c6308fe |
net/rds: don't let rds_conn_shutdown() consume a concurrent drop
rds_conn_shutdown() finishes by moving the path from
RDS_CONN_DISCONNECTING to RDS_CONN_DOWN, and also accepts
RDS_CONN_ERROR as the starting state of that final transition, so that
a FIN processed in softirq context during the teardown does not derail
the shutdown into a noisy error path.
But consuming that RDS_CONN_ERROR also consumes the shutdown pass that
came with it: rds_conn_path_drop() sets RDS_CONN_ERROR and then queues
cp_down_w, and a pass that starts on a path already in RDS_CONN_DOWN
is a no-op. For the FIN case that is harmless - the socket the FIN
arrived on is the very socket the teardown just released. It is not
harmless for a dropper that attached something to the path first.
rds_tcp_accept_one() is such a dropper. Its path claim in
rds_tcp_accept_one_path() transitions RDS_CONN_DOWN ->
RDS_CONN_CONNECTING, and a concurrent drop - a FIN on a previous
socket in softirq context, an administrative reset - can put the path
into RDS_CONN_ERROR between that claim and the state check that
follows, which accepts RDS_CONN_ERROR. The accept then installs the
freshly accepted socket with rds_tcp_set_callbacks() while the queued
teardown - which sampled tc->t_sock before this socket existed - is
still running. rds_connect_path_complete() fails its transition to
RDS_CONN_UP and drops the path again, queueing the pass that should
reap the socket it just installed. If the in-flight shutdown's final
transition consumes that drop's RDS_CONN_ERROR, the queued pass finds
the path in RDS_CONN_DOWN and does nothing. The installed socket is
never torn down: it sits established with its callbacks armed and its
rds_tcp_connection on rds_tcp_tc_list, the peer sees a connection that
nothing ever reads, and the path is wedged in RDS_CONN_DOWN until some
later event drops it again. Reproduced with widened race windows as
an ever-growing receive queue on a socket owned by a path stuck in
RDS_CONN_DOWN, with the peer's send path wedged behind it.
Make the final transition only DISCONNECTING -> DOWN. If it fails
because the path is in RDS_CONN_ERROR, a drop raced the teardown:
cancel the reconnect timer and clear RDS_RECONNECT_PENDING - the one
piece of the skipped tail that must not be left behind - and return,
letting the pass the drop queued finish the job: it tears down
whatever attached to the path in the meantime, completes the
transition to RDS_CONN_DOWN, and re-arms the reconnect from its own
tail.
The timer quiesce in that branch matters because the racing drop does
not always queue that pass: rds_conn_path_drop() returns without
queueing when a destroy is pending - exactly the situation during a
netns teardown or module unload, when a FIN on the dying socket is
processed while rds_conn_path_destroy() flushes cp_down_w. If the
flushed pass is the one that takes this return, no later pass exists,
and rds_conn_path_destroy() would find cp_conn_w still armed
(WARN_ON) and then free a path whose reconnect timer can still fire.
With the cancel in the branch, every exit of a shutdown pass leaves
the timer quiesced no matter which pass completes the transition.
The FIN case keeps making progress, one pass later and still without
noisy logging. Any other state keeps today's rds_conn_path_error()
handling; no current cp_state writer can leave a DISCONNECTING path
in anything but RDS_CONN_ERROR (every other writer is a cmpxchg from
a non-DISCONNECTING state), so that branch is defensive.
On kernels without the preceding patches the same hazard exists with
the sample-based quiesce; the fix applies there equally.
Fixes:
|
||
|
|
813f3582ac |
net/rds: acquire the fastpath locks in rds_conn_shutdown()
rds_conn_shutdown() quiesces the transmit and receive-refill paths by
waiting for RDS_IN_XMIT and RDS_RECV_REFILL to be sampled clear, and
then runs the transport shutdown and rds_conn_path_reset(). Sampling
the bits clear is not the same as owning them: the moment after the
wait_event() returns, rds_send_xmit() can re-acquire RDS_IN_XMIT (or
rds_ib_recv_refill() can re-acquire RDS_RECV_REFILL) and run
concurrently with the teardown.
The sender does recheck the connection state after taking the lock,
but that recheck is a classic store-buffering pattern: teardown writes
the state and reads the bit while the sender writes the bit and reads
the state. acquire_in_xmit() is only an acquire operation, so on
weakly ordered architectures both sides can miss each other's write,
and the transmit path then runs while the transport zeroes its rings
(e.g. rds_ib_ring_init()) and rds_send_path_reset() rewrites the
transmit state under it.
Oracle UEK fixed the same class of crashes - a 14-year tail of
BUG_ON()s in rds_ib_sub_signaled(), unexpected op-codes and NULL
dereferences in rds_ib_send_cqe_handler() during failover testing -
by making the teardown path *acquire* the fastpath bit locks instead
of testing them ("rds: Make sure transmit path and connection
tear-down does not run concurrently"). Ownership of a single word is
decided by RMW atomicity, so no cross-variable ordering is needed.
Do the same here: take both locks before calling the transport
shutdown, hold them across rds_conn_path_reset(), and release them
explicitly with a wake-up afterwards. Both are released with
clear_bit_unlock(), so that the ring re-initialization done by the
transport shutdown and the transmit state rewritten by
rds_send_path_reset() are ordered before either bit is seen clear by
the next acquire_in_xmit() or acquire_refill().
The fastpath users of these bits - rds_send_xmit() and
rds_ib_recv_refill() - are trylock style and back off while teardown
owns the locks, so no new lock dependency is introduced for them.
rds_tcp_reset_callbacks() is different: since the previous patch it
acquires RDS_IN_XMIT as well, and it blocks doing so, so its wait now
spans the teardown instead of at most one send batch. That waiter
runs from rds_tcp_accept_one() on the single-threaded krdsd workqueue
and holds rds_tcp_accept_lock and t_conn_path_lock while it waits, so
a duelling SYN accepted while its path is being torn down parks
accept processing for the duration of the teardown - for TCP bounded
by the (up to 5 s) drain loop in rds_tcp_conn_path_shutdown(). An IB
path's drain in rds_ib_conn_path_shutdown() has no round cap, but no
blocking waiter either: rds_tcp_reset_callbacks() is the only blocking
acquirer of these bits and waits only on its own TCP path, and the
fastpaths are trylock-and-back-off on both transports, so a long IB
drain lengthens only that path's own quiesce. The
window is narrow: the accept-side state check has to pass before the
teardown moves the path to RDS_CONN_DISCONNECTING.
Because krdsd is a single global workqueue, everything else queued
there - accept processing for other connections and network
namespaces, and the flush_workqueue(rds_wq) in rds_tcp_listen_stop()
during namespace teardown - waits behind the parked accept worker for
that time. It cannot deadlock, although the waits do point at each
other: the teardown blocks until the bit's holder releases it, and
the holder may be that krdsd accept worker. The holder finishes
without needing anything the teardown owns: the sync cancels
rds_tcp_reset_callbacks() issues target cp_send_w and cp_recv_w on
the path's ordered cp_wq, whose only execution slot is occupied by
the blocked cp_down_w itself, so they are pending at most and cancel
without flushing - a reliance on cp_wq being ordered that is now
noted next to those cancels (on the allocation-failure fallback where
a path shares rds_wq, the work items simply serialize).
Nor is the blocking wait itself new: rds_tcp_reset_callbacks() has
waited on RDS_IN_XMIT from the krdsd work item since
commit
|
||
|
|
02c5f9dc2e |
net/rds: acquire RDS_IN_XMIT in rds_tcp_reset_callbacks()
rds_tcp_reset_callbacks() quiesces the transmit path by setting the
path state to RDS_CONN_RESETTING and then waiting for RDS_IN_XMIT to
be sampled clear before swapping the underlying socket and calling
rds_send_path_reset().
Sampling the bit clear is not the same as owning it: rds_send_xmit()
can re-acquire RDS_IN_XMIT right after the wait_event() returns. Its
state recheck after taking the lock is a store-buffering pattern (the
resetter writes the state and reads the bit, the sender writes the
bit and reads the state) and acquire_in_xmit() is only an acquire
operation, so on weakly ordered architectures both sides can miss
each other's write and the transmit path then runs concurrently with
rds_send_path_reset() rewriting cp_xmit_* state - which is exactly
what the comment above rds_send_path_reset() tells its callers to
prevent.
Take the lock instead, hold it across the socket swap and
rds_send_path_reset(), and release it with a wake-up at the end. The
lock-ordering constraint documented above the wait still holds: the
lock is acquired before lock_sock(), so a sender inside tcp_sendmsg()
can never be waited on while we hold the socket lock.
Two details of the old code go away with the same change:
- t_sock is now read only after the lock is acquired. The old code
cached it before waiting; the teardown in rds_conn_shutdown()
releases that socket and clears t_sock, so a pointer cached before
the wait can be stale by the time the accept path resumes. Reading
it under RDS_IN_XMIT is what makes the exclusion complete once the
teardown owns the same lock, which the next patch arranges; until
then the teardown still only samples the bit, and the two paths
remain as exposed to each other as they are today.
- The old !osock early path called rds_send_path_reset() with no
serialization at all. It now runs under the lock like the normal
path. The conditional RDS_CONN_RESETTING transition of the
previous patch happens before the socket check either way: a path
found without a socket is either still connecting (its reconnect
worker blocked on t_conn_path_lock) and legitimately goes
RESETTING -> UP on the new socket, or it has been torn down
meanwhile and is dropped.
The in-function comment describing the old wait-based quiesce is
rewritten to describe the lock-based one, and the stale block comment
above the function (which still described a return value and an
incomplete list of t_sock writers) is refreshed to name all four
writers - the connect, accept, teardown and swap paths - and what
serializes each of them.
Fixes:
|
||
|
|
e8e60d74fe |
net/rds: tcp: don't force RDS_CONN_RESETTING over a concurrent shutdown
rds_tcp_reset_callbacks() resolves a duelling SYN by storing RDS_CONN_RESETTING into cp_state unconditionally. Nothing serializes that store against the shutdown path: rds_tcp_accept_one() checks for RDS_CONN_CONNECTING or RDS_CONN_ERROR under t_conn_path_lock, but neither rds_conn_path_drop(), which forces RDS_CONN_ERROR, nor rds_conn_shutdown(), which moves the path to RDS_CONN_DISCONNECTING under cp_cm_lock, takes that lock. The store can therefore land on top of a shutdown that is already in progress, or that gets queued right after the accept-side check. When it does, the shutdown worker's final DISCONNECTING -> DOWN transition fails and the path goes through rds_conn_path_error() and a second drop/shutdown cycle instead of a clean reconnect, tearing down the socket the accept path has just installed. Before commit |
||
|
|
103c4b13c4 |
net/rds: clear cp_flags bits individually in rds_conn_path_reset()
rds_conn_path_reset() wipes the whole flag word with a plain
cp->cp_flags = 0 store. Every other accessor of that word uses
atomic bitops, and some of them can run concurrently with the reset:
RDS_LL_SEND_FULL is set from rds_send_xmit() and cleared from the
transport completion paths, neither of which holds anything that
excludes the shutdown worker. A plain store racing an atomic
read-modify-write on the same word is a data race, and whichever
side loses has its update silently discarded.
Clear the two bits the reset is actually responsible for instead.
RDS_IN_XMIT and RDS_RECV_REFILL need no store at all here: they
belong to the caller, rds_conn_shutdown(), which waits for both to be
clear before calling the transport shutdown and this reset.
This also gives every bit in cp_flags a single well-defined writer
discipline, which the following patches rely on when they turn
RDS_IN_XMIT and RDS_RECV_REFILL into bit locks held across the
teardown: a blanket store mid-teardown would destroy lock ownership
that an atomic clear preserves.
Oracle UEK carries the same conversion ("net/rds: Preserve essential
connection state flags"), motivated by its asynchronous shutdown
state machine, whose progress and destroy flags must survive the
reset. UEK's variant also clears RDS_IN_XMIT and RDS_RECV_REFILL
because there the reset runs as the final step of a teardown that
owns both bits, making those clears its unlock. Upstream that
release belongs in rds_conn_shutdown(): once a later patch in this
series turns the two bits into locks held across the teardown, ending
ownership needs release semantics and a wake-up that a plain clear
inside the reset would not provide.
Based on Oracle UEK commit "net/rds: Preserve essential connection
state flags" by Gerd Rausch.
Fixes:
|
||
|
|
17c4476dbb |
net/rds: use clear_bit_unlock() in release_refill()
release_refill() drops the RDS_RECV_REFILL bit with a plain
clear_bit(). clear_bit() has no ordering semantics, and the
smp_mb__after_atomic() that follows it sits on the wrong side for a
lock release: it orders the clear against the waitqueue_active() load
below it, but does nothing to order the refill critical section's ring
and descriptor stores before the clear itself.
That matters once connection teardown owns RDS_RECV_REFILL as a lock
across the transport shutdown and path reset, rather than sampling it
clear, which "net/rds: acquire the fastpath locks in
rds_conn_shutdown()" later in this series arranges: on a weakly
ordered architecture the teardown can win the bit and start the
shutdown and reset while some of the refill's stores are not yet
visible to it. The same gap existed under the sample-based scheme - a
waiter that saw the bit clear had no guarantee it also observed the
refill's stores - but taking the bit as a lock makes the missing
release pairing load-bearing.
Switch to clear_bit_unlock(), which orders the critical section before
the release, and replace the open-coded barrier-plus-waitqueue_active()
with wq_has_sleeper(), whose internal full barrier keeps the
store-buffering guarantee between clearing the bit and checking for
sleepers. This mirrors what "net/rds: use wq_has_sleeper() in
release_in_xmit()" does for RDS_IN_XMIT.
The fast-path acquire side, acquire_refill(), uses test_and_set_bit(),
a full-barrier RMW that pairs with this release. The teardown at this
point in the series still samples the bit, so on its own this change
is release-side hardening; the shutdown-conversion patch named above
makes the teardown acquire the bit with the same RMW, completing the
pairing at the end of the series.
Fixes:
|
||
|
|
6d0c8b7073 |
net/rds: use wq_has_sleeper() in release_in_xmit()
release_in_xmit() clears RDS_IN_XMIT with clear_bit_unlock() and then checks waitqueue_active() to decide whether anyone needs waking. clear_bit_unlock() is only a release operation: it orders the critical section before the bit clear, but does not order the subsequent plain load of the wait queue head after it. The waiter side does the mirror image - it adds itself to the wait queue and then tests the bit. That is the classic store-buffering pattern: the releasing CPU can read the wait queue as empty while the waiting CPU still reads the bit as set, so the sleeper is never woken. The waiters are rds_conn_shutdown() and rds_tcp_reset_callbacks(), both in uninterruptible wait_event() with no timeout. A lost wake-up strands the shutdown worker on its single-threaded workqueue until some other sender releases the bit again - and on a connection that is being torn down precisely because it failed, there may never be another sender. The barrier used to be there: release_in_xmit() did clear_bit() followed by smp_mb__after_atomic() until commit |
||
|
|
08710f033e |
net: usb: qmi_wwan: add Compal EXM-G1x support
The Compal EXM-G1x is a Qualcomm SDX12-based LTE modem. Add support for its QMI WWAN interface 8 using the DTR quirk. Tested on a Compal EXM-G1x modem. Signed-off-by: Ian Lin <jisayme@gmail.com> Link: https://patch.msgid.link/20260831084124.65074-1-jisayme@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> |
||
|
|
d85f521a9a |
net: macb: exclude software FCS from TX byte statistics
Frames for which macb_pad_and_fcs() supplies the FCS have four FCS
bytes appended, and TX completion then accounts the grown skb->len.
tx_bytes is defined to exclude the FCS, so these frames are reported
four bytes too large.
Track only the number of FCS bytes appended in software, 0 or
ETH_FCS_LEN, and subtract that from skb->len at completion. skb->len
already reflects the padded length by then, so there is nothing else
to store. macb_pad_and_fcs() already returns 0 on every non-error
path. Return the FCS length from there instead, rather than
recomputing the same check in the caller. BQL stays on the padded
skb->len that netdev_tx_sent_queue() saw.
Fixes:
|
||
|
|
debac3a20d |
net: Remove conflicting altnames for dying netns in __dev_change_net_namespace().
syzbot reported the warning in cfg80211_pernet_exit(). [0] The repro does the following: 1. create two device in root netns and non-root netns 2. assign the same altname for the two devices 3. remove the non-root netns Since commit |