mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-09-22 09:34:56 +02:00
66817a9794263cd2a5dc4e99bf8e5fcc5ff7181e
1481047
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
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 |
||
|
|
5a3f7a683a |
net: bridge: mcast: don't truncate the port group walk on teardown
__br_multicast_disable_port_ctx() and br_multicast_del_port() walk
port->mglist with hlist_for_each_entry_safe(). However,
br_multicast_find_del_pg() can also delete other entries from the same
list through br_multicast_fwd_src_remove() or __fwd_del_star_excl().
If such an entry is the iterator's saved next node, hlist_del_init()
clears its ->next and terminates the walk early. The reproducer triggers
this in both teardown walks, leaving port groups in the bridge mdb with
a dangling ->key.port after del_nbp() frees the port:
BUG: KASAN: slab-use-after-free in __mdb_fill_info+0x1191/0x1320
__mdb_fill_info+0x1191/0x1320
br_mdb_dump+0x594/0xe40
rtnl_mdb_dump+0x1cf/0x5d0
Use hlist_del_init_rcu() to unlink the group while preserving ->next.
br_multicast_del_pg() and the teardown walks run under
br->multicast_lock. The GC worker must acquire the same lock before
detaching the group for destruction, so the node remains alive while
the walk uses the preserved pointer.
Preserving ->next means a walk can now reach a group that an earlier
iteration already deleted as a side effect. That group is off mp->ports,
so br_multicast_find_del_pg() would fall through its port scan and hit
the trailing WARN_ON(1). Skip such groups at the top of that helper: a
port group is put on port->mglist when it is created and only unlinked
when it is deleted, so hlist_unhashed() identifies exactly this case.
Fixes:
|
||
|
|
af602c7aa5 |
bonding: do not clear curr_active_slave prematurely when releasing all slaves
When releasing all slaves during bond destruction (all == true),
__bond_release_one() unconditionally clears bond->curr_active_slave to
NULL in every iteration.
If a backup slave is released before the active slave,
bond_alb_deinit_slave() triggers rlb_teach_disabled_mac_on_primary(),
which increments the active slave dev promiscuity counter and sets
bond_info->primary_is_promisc = 1.
Because bond->curr_active_slave was prematurely cleared to NULL when
releasing the backup slave, the subsequent iteration releasing the active
slave evaluates oldcurrent as NULL, so bond_change_active_slave(bond, NULL)
is skipped. Consequently, bond_alb_handle_active_change() is never called
to decrement the promiscuity counter, permanently leaking promiscuous
mode on the physical device after bond teardown.
When oldcurrent == slave, bond_change_active_slave(bond, NULL) already sets
bond->curr_active_slave to NULL. We only need to avoid selecting a new
active slave when all == true. Replace the if (all) branch with
if (!all && oldcurrent == slave).
Fixes:
|
||
|
|
544d85de4d |
net: qrtr: Send HELLO message on endpoint register
HELLO is currently handled entirely by the name server (NS): it is sent once as a broadcast when the NS initializes, and again as a reply whenever the NS receives an inbound HELLO from a remote. Some remote QRTR endpoints (e.g. an external WLAN chipset attached over MHI) operate in a slave role: they only ever send a HELLO in response to one they receive, and never initiate. Since the host cannot tell in advance which remotes behave this way, if the host also only replies, both sides wait on the other to speak first and no HELLO is ever exchanged, stalling further communication. To fix this: - Transfer HELLO handshake ownership to the core layer. A HELLO is now sent once, per endpoint, at registration time. - Schedule a delayed work item on endpoint registration to send a HELLO once the name server is bound. The work reschedules itself with a 100ms backoff if the name server socket is not yet bound or if allocating the control packet fails, so a transient startup condition does not abandon the handshake permanently. - Enforce HELLO-first ordering by dropping non-HELLO packets and returning -EAGAIN until the HELLO is confirmed sent, using bool hello_sent guarded by ep_lock to make the gate check atomic with xmit(). - Skip nodes with nid == QRTR_EP_NID_AUTO in bcast_enqueue(), to avoid broadcasting control packets with QRTR_EP_NID_AUTO as the destination node ID. - Remove say_hello() from the name server's ctrl_cmd_hello() handler and from qrtr_ns_init(); the core layer is now the sole sender of the outbound HELLO. This removes the NS's reply-on-receive behaviour without a replacement. Signed-off-by: Chris Lew <christopher.lew@oss.qualcomm.com> Co-developed-by: Deepak Kumar Singh <deepak.singh@oss.qualcomm.com> Signed-off-by: Deepak Kumar Singh <deepak.singh@oss.qualcomm.com> Co-developed-by: Pranav Mahesh Phansalkar <pranav.phansalkar@oss.qualcomm.com> Signed-off-by: Pranav Mahesh Phansalkar <pranav.phansalkar@oss.qualcomm.com> Signed-off-by: David S. Miller <davem@davemloft.net> |
||
|
|
f695390ea6 |
octeontx2-af: Fix limiting SRIOV VF count logic
When RVU PF0/AF's VFs are SDP instead of LBK, limiting the VF count
based on the LBK channel count is incorrect.
Apply LBK channel-based VF limits only when the VF device ID matches
the LBK RVU AFVF device.
Fixes:
|
||
|
|
70f3995830 |
bonding: alb: fix uninitialized transport header access in alb_determine_nd()
alb_determine_nd() uses icmp6_hdr(skb) to inspect ICMPv6 headers.
However, in xmit paths (e.g. packets sent via AF_PACKET / raw sockets
or forwarded packets), skb->transport_header is not guaranteed to be
initialized. While pskb_network_may_pull() ensures the packet data is
linear starting from the network header, it does not set or adjust the
transport header offset.
Dereferencing icmp6_hdr(skb) can therefore access out-of-bounds memory.
Fetch the icmp6hdr directly after ipv6hdr following pskb_network_may_pull(),
and reload ipv6hdr in case pskb_may_pull() reallocated skb->head.
Also remove the unused bond argument from alb_determine_nd().
Fixes:
|
||
|
|
b264d84227 |
s390/ctcm: Prevent XID null dereference
The mpc_validate_xid() function sets grp->saved_xid2->xid2_flag2 to 0x40
to signal XID validation error. If peer XID is NULL or r/w channel
pairing mismatch happens, grp->saved_xid2 is never initialized. An
attempt to set the flag in such case leads to NULL dereference.
Fix this by using the always available priv->xid->xid2_flag2 instead of
grp->saved_xid2->xid2_flag2 for validation errors.
Fixes:
|
||
|
|
1d2929d085 |
net: psp: do not inherit the Rx association on clone
sk->psp_assoc sits past sk_dontcopy_end, so sock_copy() copies it into
every socket accepted from a listener without taking a reference, while
inet_sock_destruct() puts for every inet socket. psp_twsk_init() does
refcount_inc() for the timewait socket, so a child closing through
TIME_WAIT cancels its own put and leaves the association with one
reference and N timewait sockets holding the same pointer. Closing the
listener frees it, and the timewait timers then put freed memory.
Rejecting the association on a listening socket is not sufficient: a socket
can acquire one while established and then be turned back into a listener,
because tcp_disconnect() leaves sk->psp_assoc in place.
BUG: KASAN: slab-use-after-free in psp_twsk_assoc_free+0x6f/0xf0
Write of size 4 at addr ffff888110f9255c by task swapper/7/0
psp_twsk_assoc_free+0x6f/0xf0
inet_twsk_put+0xda/0x1b0
call_timer_fn+0x53/0x2e0
__run_timers+0x764/0xa80
Freed by task 99:
kfree+0x1a7/0x500
process_one_work+0x7ec/0x1100
An association carries a per-connection SPI and key, so a child must not
inherit the parent's. Clear it on clone.
Fixes:
|
||
|
|
bc93419130 |
net: bonding: annotate lockless writes with WRITE_ONCE()
Several fields in bonding are read locklessly using READ_ONCE() (or ACCESS_ONCE() previously) but have corresponding writes that do not use WRITE_ONCE(). Add WRITE_ONCE() annotations to: - bond->send_peer_notif decrements in bond_peer_notify_may_events() and reset in bond_close(). - bond->slave_cnt increments and decrements in bond_enslave() and __bond_release_one(). - bond->recv_probe updates in bond_open(), bond_option_arp_interval_set() and rlb_initialize(). - slaves->count decrement in bond_skip_slave(). Fixes: |
||
|
|
c037915f80 |
mac802154: fix data race and NULL deref on local->assoc_dev
local->assoc_dev is shared between the association path and the
association-response worker without common synchronization.
mac802154_perform_association() stores the coordinator pointer and waits
for a response. Its timeout and error paths clear the pointer and return
to mac802154_associate(), which may then free the coordinator object.
Meanwhile, mac802154_rx_mac_cmd_worker() may observe the associating bit
and enter mac802154_process_association_resp(), which dereferences
assoc_dev.
The worker's bit test and the handler's pointer dereference are not
atomic with respect to cleanup. Cleanup can clear assoc_dev between them,
causing a NULL dereference, or free the coordinator while the response
handler still uses the pointer.
The recorded result is exposed to the same window. assoc_status and
assoc_addr are written by the handler but read by the association path
while the associating bit is still set, so a second response for the same
request - a malicious one, for instance - can replace them between those
reads and leave the caller with an incoherent status and address pair.
The response handler only needs the coordinator extended address.
Replace assoc_dev with a cached address, removing the pointer lifetime
dependency. Protect the cached address and the associating bit with a
dedicated spinlock. A READ_ONCE()/WRITE_ONCE() pair would not guarantee
an atomic __le64 access on all 32-bit architectures.
wpan_dev->association_lock cannot be reused here: nl802154_associate()
holds it across rdev_associate(), hence for the whole of
mac802154_perform_association() including the wait for the response.
A response handler taking that lock would only get it once the
association has already given up.
Reset the completion, publish the cached address, and set the associating
bit while holding the lock. The response handler takes the lock, rechecks
the bit and the cached address, records the response, clears the bit, and
only then completes the waiter. Thus cleanup cannot pass the handler
between its state check and completion, and the cached 64-bit value
cannot tear.
The handler clears the bit before completing, not the woken waiter:
otherwise complete() is issued under the lock and a second (e.g.
malicious) response can reacquire it before the waiter and replace the
result. So a wait that returns success implies the bit is already clear,
and the success and negative-response paths return directly. The
transmit-error and timeout paths still clear it under assoc_lock, which
serializes any racing response against the cleanup while the call returns
the error it already selected. Both paths snapshot assoc_status and
assoc_addr under the same lock.
Both users run in process context, so a plain spinlock is sufficient.
The lock is not held while waiting for the completion.
Suggested-by: Miquel Raynal <miquel.raynal@bootlin.com>
Suggested-by: Xuanqiang Luo <xuanqiang.luo@linux.dev>
Fixes:
|
||
|
|
73e594c19b |
af_packet: Don't cast tpacket_hdr.tp_len to int in tpacket_parse_header().
syzbot reported BUG() in sock_sendmsg_nosec(). [0]
The problem is that tpacket_parse_header() casts user-provided
tpacket_hdr.tp_len, which is u32, to int.
If the length is larger than INT_MAX, the following condition
in tpacket_parse_header() passes,
if (unlikely(tp_len > size_max))
and any negative value can be returned to the caller, up to
sock_sendmsg_nosec().
The repro set tpacket_hdr.tp_len to 0xfffffdef, which is cast
to -EIOCBQUEUED (-529), triggering BUG() in sock_sendmsg_nosec().
*(uint64_t*)0x200000000008 = 0xfffffdef;
...
syscall(__NR_write, /*fd=*/r[0], /*buf=*/0x200000000000ul, /*count=*/1ul);
Let's define the local tp_len as u32 in tpacket_parse_header().
[0]:
kernel BUG at net/socket.c:803!
Oops: invalid opcode: 0000 [#1] SMP KASAN PTI
CPU: 0 UID: 0 PID: 5628 Comm: syz-executor176 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/24/2026
RIP: 0010:sock_sendmsg_nosec+0x145/0x180 net/socket.c:803
Code: 06 67 48 0f b9 3a eb 95 e8 e8 3a 22 f8 48 89 df 4c 89 f6 4c 89 e2 4d 89 fb 2e e8 32 a5 5c 16 e9 51 ff ff ff e8 cc 3a 22 f8 90 <0f> 0b e8 c4 3a 22 f8 48 83 c3 18 48 89 d8 48 c1 e8 03 42 80 3c 28
RSP: 0018:ffffc90003aefb48 EFLAGS: 00010293
RAX: ffffffff89a578d4 RBX: ffff8880764c67c0 RCX: ffff88807fb23e80
RDX: 0000000000000000 RSI: 00000000fffffdef RDI: 00000000fffffdef
RBP: 00000000fffffdef R08: ffffc90003aef747 R09: 1ffff9200075dee8
R10: dffffc0000000000 R11: fffff5200075dee9 R12: 0000000000000001
R13: dffffc0000000000 R14: ffffc90003aefbc0 R15: ffffffff8aac4310
FS: 000055559101b400(0000) GS:ffff888124ce0000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000200000000210 CR3: 0000000073dca000 CR4: 00000000003526f0
Call Trace:
<TASK>
__sock_sendmsg net/socket.c:815 [inline]
sock_write_iter+0x2de/0x3e0 net/socket.c:1266
new_sync_write fs/read_write.c:595 [inline]
vfs_write+0x612/0xba0 fs/read_write.c:687
ksys_write+0x150/0x270 fs/read_write.c:739
do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
do_syscall_64+0x166/0x520 arch/x86/entry/syscall_64.c:84
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f173130ecb9
Code: c0 79 93 eb d5 48 8d 7c 1d 00 eb 99 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 d8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007ffd67e44248 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
RAX: ffffffffffffffda RBX: 0000200000000000 RCX: 00007f173130ecb9
RDX: 0000000000000001 RSI: 0000200000000000 RDI: 0000000000000003
RBP: 0000000000000001 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 00007ffd67e44388
R13: 0000000000000002 R14: 00002000000000c0 R15: 0000000000000002
</TASK>
Fixes:
|
||
|
|
545b63503c |
net: ntb_netdev: Fix statistics races
ntb_netdev updates shared net_device stats from per-QP RX and TX
callbacks. Once multiple queues are enabled, concurrent updates can be
lost.
Use per-CPU tstats for packet and byte counters and DEV_STATS_INC() for
less frequent drop and error counters. Callbacks can run synchronously
in the xmit path or asynchronously from a tasklet or the memcpy kthread.
Pin TX updates against migration in the kthread path. Use the IRQ-safe
u64_stats helpers because netpoll can invoke the synchronous path with
IRQs disabled.
Let the core manage tstats while keeping transport teardown after
unregister_netdev(), outside RTNL. RCU lets unregister wait for TX
completions already updating stats, while later completions only consume
the skb and skip accounting and queue wake.
Fixes:
|
||
|
|
975b5b067f |
ipv6: sr: restore network header before routing and forwarding
ipv6_srh_rcv() runs with skb->data at the Segment Routing Header (SRH)
while skb_network_header() points at the IPv6 header.
When segments_left > 0, ipv6_srh_rcv() previously restored the skb->data
position by pushing sizeof(struct ipv6hdr), assuming the SRH immediately
followed the fixed IPv6 header. If another extension header (such as a
Hop-by-Hop options header) precedes the SRH, skb_network_offset()
remained negative.
This led to two problems:
1. During ip6_route_input(), fib6_rules_early_flow_dissect() invokes
__skb_flow_dissect() which passes the negative skb_network_offset()
to flow dissection, breaking BPF and C flow dissector logic.
2. If forwarded via ip6_forward() or redirected via act_mirred, downstream
handlers (like sch_fragment() or neighbour output) pass the negative
offset as an unsigned length, triggering OOB memcpy or buffer overflows.
Fix this by pushing -skb_network_offset(skb) before routing, ensuring
skb_network_offset(skb) is 0 for route lookup / flow dissection as well as
downstream forwarding. On the loopback path, pull skb_transport_offset(skb)
to restore skb->data to the SRH before looping back.
Fixes:
|
||
|
|
81c600c263 |
tipc: Dont send random pad bytes in RESET/ACTIVATE messages
The interface name is passed in a fixed length (TIPC_MAX_IF_NAME) buffer.
Replace the strcpy(data, l->if_name) with memcpy() so that the
pad bytes are actually written (l->if_name[] is zero padded)
rather than sending random bytes from the skb to the remote system.
Replace two other strcpy() with strscpy().
Fixes:
|
||
|
|
b3b76e9f4f |
tipc: fix NULL deref in tipc_named_node_up() on empty publication list
User-space applications can bind a large number of service addresses to
one or more sockets. Each binding of a local-scope service address inserts
one entry (publication) into the TIPC name table. If the number of these
publications exceeds TIPC_MAX_PUBL (65535), protocol service types
(such as node state and link state) are no longer inserted into the name
table. This causes two issues:
1. User-space applications subscribing to node or link up/down events
stop receiving notifications.
2. A NULL pointer dereference can occur:
BUG: kernel NULL pointer dereference, address: 00000000000000d0
...
CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 7.2.0-rc4-default+ #5 PREEMPT(full)
...
RIP: 0010:tipc_named_node_up (./include/linux/skbuff.h:2251 net/tipc/name_distr.c:195 net/tipc/name_distr.c:221)
...
Call Trace:
<IRQ>
tipc_node_write_unlock (net/tipc/node.c:428)
tipc_rcv (net/tipc/node.c:934 net/tipc/node.c:2189)
tipc_udp_recv (net/tipc/udp_media.c:389)
Thread 1 (tipc_net_finalize) | Thread 2 (named_distribute)
-----------------------------|-----------------------------
| ...
| list_for_each_entry(publ, pls, binding_node) {
| ...
| __skb_queue_tail(list, skb);
| ...
| }
| ...
| hdr = buf_msg(skb_peek_tail(list));
... |
tipc_nametbl_publish(); |
If 'tipc_nametbl_publish()' (Thread 1) fails because the number of
local publications reaches TIPC_MAX_PUBL, list (Thread 2) will be empty. As a
result, NULL is passed to 'buf_msg()', leading to a NULL pointer dereference.
Fix these issues by allowing protocol service types (node state, link state,
and topology server) to be inserted into the name table unconditionally.
This ensures that users subscribing to these types always receive
notifications. In addition, the maximum number of local user publications is
reduced to (TIPC_MAX_PUBL - 1). This ensures that the maximum bulk size
calculated in tipc_link_set_queue_limits() remains valid.
Fixes:
|
||
|
|
f88bbbbe96 |
Merge branch 'mitigate-a-side-channel-in-routing-exception-caches'
Ido Schimmel says: ==================== Mitigate a side channel in routing exception caches When an ICMP error that quotes a UDP packet is locally delivered, the kernel only creates a routing exception if the quoted packet matches a socket. This allows an off-path attacker to conduct a side-channel attack on the routing exception caches in order to discover the ephemeral ports used by connected UDP sockets. Previous mitigations tried to make it harder for attackers to find hash collisions in these caches and make the eviction of exceptions less predictable. Amit Klein and Noam Caspi demonstrated that both of these mitigations can be bypassed. This patchset tries to mitigate such attacks by always creating an exception, even before trying to find a matching socket. The exception is created by the same helpers that are used when the quoted packet did not originate from a socket, so that guesses (right or wrong) from an off-path attacker always result in an exception being created or updated in the cache that the attacker can observe. Note that this mitigation does not make it easier for attackers to fill these caches, since they can already create exceptions with little to no validation. For example, by sending an ICMP error that quotes an ICMP Echo Reply or one that quotes a UDP source port that matches a wildcard socket. In the good case (matched socket) this comes at the cost of an extra route lookup, as the exception is created before the one performed by the socket path. When the two lookups resolve to different nexthops, an exception is created in the cache of each. Patch #1 fixes a pre-existing bug in the handling of ICMPv6 Redirect Message packets. Discovered while writing the selftest. Patch #2 creates an exception from the IPv4 UDP code even before socket matching. Other socket types do not need this: raw sockets have no ports, and for TCP the ICMP error is discarded unless the quoted sequence number is in window. Patch #3 does the same for IPv6. Patch #4 adds a selftest. v1: https://lore.kernel.org/netdev/20260826143735.1819315-1-idosch@nvidia.com/ ==================== Link: https://patch.msgid.link/20260828192344.2596928-1-idosch@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> |
||
|
|
c923c14942 |
selftests: net: Add exception cache tests
Add a test for the IPv4 and IPv6 exception caches, covering the
exceptions that are created in response to ICMP errors quoting a UDP
packet.
The topology consists of a host (h1) that reaches a remote host (h2)
via a router (r1), with a second router (r2) attached to the segment
shared by h1 and r1. UDP packets are injected using a packet socket, so
that an ICMP error quoting them is only matched to a socket when one was
opened separately with the same source port. PMTU errors are provoked by
lowering the MTU of the far end of the path and redirects by pointing
r1's route towards h2 back over the segment it received the packet from.
The following is tested for both address families and for both PMTU and
redirect exceptions:
* An error that is not matched to a socket creates an exception that
carries the new MTU or gateway.
* An error that is matched to a socket creates the same exception.
The PMTU tests further verify that a lower PMTU replaces the one stored
in the exception whereas a higher one does not, and that a socket which
disabled PMTU discovery using IP{,V6}_PMTUDISC_OMIT gets the same
exception as the other cases.
Without "ipv4: udp: Create exceptions before socket matching" and "ipv6:
udp: Create exceptions before socket matching", the tests that do not
open a socket fail:
# ./exception_cache.sh
TEST: IPv4: PMTU: exception without a matching socket [FAIL]
No socket: exception does not carry an MTU of 1400
TEST: IPv6: PMTU: exception without a matching socket [FAIL]
No socket: exception does not carry an MTU of 1400
TEST: IPv4: PMTU: exception with a matching socket [ OK ]
TEST: IPv6: PMTU: exception with a matching socket [ OK ]
TEST: IPv4: PMTU: exception with a socket ignoring it [FAIL]
PMTU discovery disabled: exception does not carry an MTU of 1400
TEST: IPv6: PMTU: exception with a socket ignoring it [FAIL]
PMTU discovery disabled: exception does not carry an MTU of 1400
TEST: IPv4: Redirect: exception without a matching socket [FAIL]
No socket: exception does not carry the new gateway
TEST: IPv6: Redirect: exception without a matching socket [FAIL]
No socket: exception does not carry the new gateway
TEST: IPv4: Redirect: exception with a matching socket [ OK ]
TEST: IPv6: Redirect: exception with a matching socket [ OK ]
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260828192344.2596928-5-idosch@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||
|
|
ac76cab50e |
ipv6: udp: Create exceptions before socket matching
Currently, when ICMPv6 Packet Too Big and Redirect Message packets are locally delivered and quote a UDP packet, an exception is only created in the IPv6 exception cache if the kernel can match the UDP packet to an existing socket. This behavior allows off-path attackers to conduct a side-channel attack on the exception cache in order to discover the ephemeral port used by a connected UDP socket. Commit |
||
|
|
4c3499f79f |
ipv4: udp: Create exceptions before socket matching
Currently, when ICMP Fragmentation Needed and Redirect Message packets are locally delivered and quote a UDP packet, a FIB nexthop exception (FNHE) is only created if the kernel can match the UDP packet to an existing socket. This behavior allows off-path attackers to conduct a side-channel attack on the FNHE cache in order to discover the ephemeral port used by a connected UDP socket. Commit |
||
|
|
cd51b74bdd |
ipv6: Fix redirect exception creation for UDP/RAW sockets
When an ICMP Redirect Message is matched to a socket, both IPv4 and IPv6
verify that the source IP of the ICMP packet is the current gateway for
the quoted packet. Both also pass the socket's bound device as the
expected nexthop device.
The difference is that IPv4 treats "oif=0" as "any", whereas IPv6 always
requires an exact match (see ip6_redirect_nh_match()), since the gateway
address is usually a link-local address.
Therefore, when an IPv6 UDP/RAW socket is not bound to a device, the
above verification fails and an exception is not created. This also
happens when the socket is bound to a VRF, as l3mdev_update_flow()
resets the oif to 0.
Fix this by passing the ifindex of the ingress device as the expected
nexthop device. This is consistent with the existing callers of
ip6_redirect(). Note that for ICMPv6 Redirect Message packets the VRF
driver does not reset skb->dev to the VRF device, so skb->dev is
correct, even when it is a VRF port.
Fixes:
|
||
|
|
97cc84dad1 |
ip6_gre: check tunnel info before xmit in ip6gre_tunnel_xmit
Shuangpeng Bai reported a KASAN slab-use-after-free in ip6gre_tunnel_xmit(). The precise KASAN bug was caused by ip6_tnl_xmit() consuming the skb during headroom expansion and returning an error, while ip6gre_tunnel_xmit() still held the stale pointer and called skb_tunnel_info_txcheck(skb) at tx_err. That specific bug was fixed by commit |
||
|
|
ec12bdd568 |
Merge branch 'ipv6-mcast-rcu-and-timer-fixes'
Eric Dumazet says: ==================== ipv6: mcast: RCU and timer fixes This series addresses several RCU synchronization and timer calculation issues identified in IPv6 multicast (MLD) handling within net/ipv6/mcast.c while I was working on fixing a syzbot report in net/ipv4/icmp.c. Patch 1 fixes an RCU reader diversion in ip6_mc_del1_src() where mutating psf->sf_next to insert an unlinked source node into the tombstone list diverted concurrent lockless readers (e.g. ipv6_chk_mcast_addr()) into pmc->mca_tomb, causing them to miss remaining active sources. Patch 2 converts ip6_mc_source() to use copy-on-write RCU updates. Previously, source additions and deletions modified the socket's psl->sl_addr array in-place, causing concurrent lockless readers in inet6_mc_check() (UDP/RAW receive path) to observe torn 16-byte IPv6 addresses or duplicated/missed sources. Patch 3 fixes delay calculation in igmp6_join_group() when canceling an existing delayed work, preventing unsigned jiffies underflows when the timer has already expired and clamping the delay to the unsolicited report interval. Patch 4 ensures rcu_assign_pointer() is consistently used for __rcu list updates in __ipv6_dev_mc_dec(), ipv6_sock_mc_drop(), __ipv6_sock_mc_close(), and related helpers. Patch 5 switches igmp6_mc_seq_show() to use jiffies_delta_to_clock_t() with a signed long delta, preventing underflows in /proc/net/igmp6 timer duration reporting. ==================== Link: https://patch.msgid.link/20260828084531.1826790-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> |
||
|
|
b4cf4a092a |
ipv6: mcast: use jiffies_delta_to_clock_t() in igmp6_mc_seq_show()
If a multicast group timer has expired but the delayed work has not yet run to clear MAF_TIMER_RUNNING, expires - jiffies produces a negative value. Because unsigned arithmetic was used with jiffies_to_clock_t(), expires - jiffies underflows to a huge value and reports invalid timer durations in /proc/net/igmp6. Use jiffies_delta_to_clock_t() with a signed long delta to properly cap expired deltas to 0, matching IPv4 igmp_mc_seq_show() and commit |
||
|
|
0c8f56c583 |
ipv6: mcast: use rcu_assign_pointer() for __rcu list updates
Several places in net/ipv6/mcast.c update RCU-protected lists
(np->ipv6_mc_list, idev->mc_list, idev->mc_tomb) using direct pointer
assignments instead of rcu_assign_pointer():
1. In __ipv6_dev_mc_dec(), unlinking a group from idev->mc_list did:
*map = ma->next;
without rcu_assign_pointer() while concurrent readers traverse
idev->mc_list locklessly under rcu_read_lock().
2. In ipv6_sock_mc_drop() and __ipv6_sock_mc_close(), unlinking a group
from np->ipv6_mc_list directly assigned *lnk = mc_lst->next and
np->ipv6_mc_list = mc_lst->next without rcu_assign_pointer(), racing
with lockless readers in inet6_mc_check().
3. In __ipv6_sock_mc_join(), mc_lst->next was initialized to
np->ipv6_mc_list via raw assignment before publishing mc_lst.
4. In mld_del_delrec() and __ipv6_dev_mc_inc(), __rcu source pointers
passed into rcu_assign_pointer() lacked explicit dereference helpers.
Fix these by consistently using rcu_assign_pointer() along with
mc_dereference() / sock_dereference().
Fixes:
|
||
|
|
75fa9caeb8 |
ipv6: mcast: fix delay calculation in igmp6_join_group()
When joining a multicast group, if a report work is already pending
(e.g. scheduled by a query or a previous join), igmp6_join_group()
cancels the delayed work and recalculates the delay:
if (cancel_delayed_work(&ma->mca_work)) {
refcount_dec(&ma->mca_refcnt);
delay = ma->mca_work.timer.expires - jiffies;
}
Unlike igmp6_group_queried(), igmp6_join_group() did not check
if delay >= interval. This leads to two issues:
1. If the timer has already expired (timer.expires <= jiffies), the
stale expiry is reused by mod_delayed_work(), causing the second
unsolicited report to fire on the very next tick without a
randomized delay.
2. If the timer was originally armed by a query with a large
maximum response delay, delay could exceed
unsolicited_report_interval(ma->idev).
Fix this by initializing delay to unsolicited_report_interval(ma->idev)
and re-randomizing it with get_random_u32_below(interval) when
delay >= interval, mirroring the logic in igmp6_group_queried().
Fixes:
|
||
|
|
c073d1b070 |
ipv6: mcast: use copy-on-write RCU updates in ip6_mc_source()
pmc->sflist is read locklessly under rcu_read_lock() by
inet6_mc_check() during packet reception in the UDP and RAW
multicast receive paths.
ip6_mc_source() mutated psl->sl_addr and psl->sl_count in-place
when adding or removing a source filter. Additionally, when expanding
the filter buffer, newpsl was published via rcu_assign_pointer()
before writing the new source into the array.
Because 16-byte struct in6_addr writes are not atomic and array
shifting is not synchronized with RCU readers, concurrent readers in
inet6_mc_check() could read torn IPv6 addresses or observe
duplicated/missed source entries.
Fix this by switching ip6_mc_source() to copy-on-write RCU updates:
allocate and fully populate newpsl before publishing it via
rcu_assign_pointer(), and reclaim the old filter via kfree_rcu(),
matching ip6_mc_msfilter().
Also remove the now unused IP6_SFBLOCK macro.
Fixes:
|
||
|
|
93b4923984 |
ipv6: mcast: fix RCU list diversion in ip6_mc_del1_src()
When removing a source filter whose count reaches zero, ip6_mc_del1_src()
unlinks psf from pmc->mca_sources. If the filter was previously active,
the code moved psf directly into pmc->mca_tomb by updating psf->sf_next.
Because pmc->mca_sources is traversed locklessly under RCU (e.g. by
ipv6_chk_mcast_addr()), mutating psf->sf_next before a grace period
elapses diverts concurrent readers to the tombstone list. Consequently,
readers miss remaining active sources in pmc->mca_sources and improperly
examine deleted tombstone entries.
Fix this by allocating a new tombstone node for pmc->mca_tomb (as done
in sf_setstate()) and retiring the original psf via kfree_rcu().
Fixes:
|
||
|
|
d8d4d1cf40 |
ppp: ppp_synctty: simplify tty disc_data access
Apply the same simplification as the preceding ppp_async change.
Fixes:
|
||
|
|
9feb069e5e |
ppp: ppp_async: simplify tty disc_data access
tty_ldisc_hangup() invokes the hangup callback while holding only a read lock on tty->ldisc_sem, so it can run concurrently with other line discipline callbacks. This currently forces async PPP to maintain separate lifetime protection around tty->disc_data. Line discipline close is called under the write lock during hangup processing. Remove the hangup callback and rely on close for teardown, as done for SLIP by commit |
||
|
|
2987ee196c |
igmp: convert struct ip_sf_list to RCU
Commit |
||
|
|
1ea9fff22b |
Merge tag 'for-net-2026-08-31' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth
Luiz Augusto von Dentz says: ==================== bluetooth pull request for net: Core: - hci_core: Fix race condition during device registration - L2CAP: fix chan mode for LE_CONN_REQ + EXT_FLOWCTL pchan - L2CAP: fix out-of-bounds write in l2cap_ecred_connect - L2CAP: clear FLAG_DEFER_SETUP only for same PID/PSM Drivers: - hci_mrvl: Fix wrong return value check of wait_on_bit_timeout() - btintel_pcie: Clear automask on spurious interrupts - btintel: validate version TLV value lengths - btintel: bound firmware ID by TLV length - btintel: propagate version TLV parsing errors * tag 'for-net-2026-08-31' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth: Bluetooth: hci_mrvl: Fix wrong return value check of wait_on_bit_timeout() Bluetooth: L2CAP: clear FLAG_DEFER_SETUP only for same PID/PSM Bluetooth: L2CAP: fix out-of-bounds write in l2cap_ecred_connect Bluetooth: L2CAP: fix chan mode for LE_CONN_REQ + EXT_FLOWCTL pchan Bluetooth: hci_core: Fix race condition during device registration Bluetooth: btintel: propagate version TLV parsing errors Bluetooth: btintel: bound firmware ID by TLV length Bluetooth: btintel: validate version TLV value lengths Bluetooth: btintel_pcie: Clear automask on spurious interrupts ==================== Link: https://patch.msgid.link/20260831181837.946230-1-luiz.dentz@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> |
||
|
|
fee1065570 |
net/sched: cls_flower: validate mask pointer after nla_next()
fl_set_enc_opt() iterates the key's nested tunnel-option attributes with nla_for_each_attr() while advancing a single mask pointer via nla_next() at the bottom of each loop, so the mask cursor is driven by the number of key attributes rather than by the mask's own attributes. The nla_ok() added by commit |
||
|
|
9d0f206eb3 |
Merge branch 'vsock-validate-packet-sources-after-bound-lookup-fallback'
Daehyeon Ko says: ==================== vsock: validate packet sources after bound lookup fallback Both virtio and VMCI look up connected sockets by the full tuple before falling back to a destination-only bound lookup. The fallback can select a non-listening socket without validating the packet source. V2 covered only the virtio path. Following Stefano's review, this series moves the source and transport validation into a documented AF_VSOCK helper and uses it for both virtio and VMCI. The VMCI patch checks both its bottom-half and deferred workqueue receive paths. V4 preserves VMCI's existing RST behavior when source validation fails. The reset is addressed from the received packet so that a bound but non-listening or concurrently closed socket still notifies the sender, without directing the reset to a connected socket's stored peer. The v3 regression was reproduced in three x86_64 KASAN boots: a REQUEST to a bound but non-listening socket returned VMCI_ERROR_NO_ACCESS but no RST arrived within one second. With v4, the sending context received the expected RST in all three boots. The original VMCI source-validation oracle also passed in three v4 boots: a matched RST reset the pending socket while a mismatched-context RST left it pending. No KASAN report occurred. Patch 1 is unchanged from v3 (identical stable patch-id) and carries Bobby's Reviewed-by for that revision. Its v3 validation covered the cross-UID injection oracle, local CID aliases, selected VSOCK selftests, and W=1 changed-object builds under allmodconfig and allyesconfig. The current-tree guest-CID vhost probe could not be rerun because the test user lacks access to /dev/vhost-vsock. ==================== Link: https://patch.msgid.link/20260826003929.966160-1-4ncienth@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> |
||
|
|
ad9a7da3fa |
vsock/vmci: validate packet source for connected sockets
vmci_transport_recv_stream_cb() looks up sockets first by the full source
and destination tuple, then by destination only in the bound table. The
fallback can select a non-listening socket without checking whether the
packet came from its stored peer.
This was reproduced with two VMCI contexts. A RST from the context not
stored in a TCP_SYN_SENT socket reset that socket after it was selected by
the destination-only lookup.
VMCI can process notification packets in bottom-half context when the
socket is not owned by user context, or defer packets to a workqueue. Use
vsock_check_source() after taking the socket lock in the bottom-half path,
and recheck after lock_sock() in the workqueue path. Listening sockets
continue to accept packets from any source.
Reply with a RST addressed from the received packet before dropping a
source that fails validation. This preserves the existing reset behavior
for bound non-listening and concurrently closed sockets without directing
the reset to a connected socket's stored peer.
Fixes:
|
||
|
|
dee44f41f2 |
vsock/virtio: validate packet source for connected sockets
virtio_transport_recv_pkt() looks up sockets first by the full source and
destination tuple, then by destination only in the bound table. The
fallback is needed for listening and connecting sockets, but sockets remain
in the bound table after connect(), so it can also return a non-listening
socket.
The fallback does not validate the source address. In TCP_SYN_SENT, a
RESPONSE from an unrelated source can transition the victim socket to
TCP_ESTABLISHED while its stored remote address remains unchanged.
Subsequent RW packets from that source are delivered through the same
destination-only fallback.
This was reproduced with capability-empty processes under different UIDs.
The attacker discovered the target tuple through unprivileged AF_VSOCK
sock_diag and caused the victim socket to read 16 attacker-chosen bytes;
the intended peer-side socket read 0 of those 16 bytes.
Add vsock_check_source() to validate the transport, source port and source
CID against the peer stored in a non-listening socket. The local transport
is the CID exception because its packets are generated internally with
VMADDR_CID_LOCAL as their source, including connections using CID aliases.
Use the helper after lock_sock() in the virtio receive path.
Fixes:
|
||
|
|
dc0df5a0c6 |
page_pool: keep frag_offset aligned for odd-sized requests
page_pool_alloc_frag_netmem() rounds the requested fragment size with
size = ALIGN(size, dma_get_cache_alignment());
dma_get_cache_alignment() returns 1 unless the architecture defines
ARCH_DMA_MINALIGN, which DMA-coherent architectures such as x86 do not.
There the ALIGN() is a no-op and pool->frag_offset advances by the raw,
unrounded size.
A single caller asking for an odd size then leaves frag_offset misaligned
for every fragment carved out of that page afterwards. The pool is shared,
so the damage is not confined to the caller that caused it.
The per-cpu system_page_pool used by generic XDP hits this.
skb_pp_cow_data() allocates its fragments with the raw packet length:
size = min_t(u32, len, PAGE_SIZE);
truesize = size;
page = page_pool_dev_alloc(pool, &page_off, &truesize);
leaving frag_offset odd for whatever is carved out of that page next. Its
own head allocation is already aligned -- SKB_HEAD_ALIGN(size) plus the
XDP_PACKET_HEADROOM its callers pass -- so it is a later user of the shared
pool that pays: page_pool_dev_alloc_va() returns a misaligned buffer,
napi_build_skb() installs it as skb->head, and skb_shinfo(skb) ==
skb->head + skb->end is misaligned with it.
skb_shinfo()->dataref is a 4-byte atomic_t at offset 0x20, so the
atomic_inc() in __skb_clone() straddles a cache line. On x86 with split
lock detection -- fatal for kernel split locks by default -- this panics
the machine:
Oops: Split lock detected
RIP: 0010:skb_clone+0x154/0x1e0
Call Trace:
<IRQ>
raw_local_deliver+0x1ed/0x2c0
ip_protocol_deliver_rcu+0x54/0x1c0
ip_local_deliver_finish+0x85/0x100
ip_local_deliver+0x67/0x100
__netif_receive_skb_one_core+0x85/0xa0
process_backlog+0x87/0x130
Reproduced by attaching any generic-mode XDP program to loopback and
opening a RAW IPPROTO_UDP socket, which makes raw_local_deliver() clone
every locally delivered UDP packet; ordinary DNS traffic then triggers it,
roughly once per 2500 clones. Observed on 6.12.101 and 7.1.8.
Tracing page_pool_alloc_frag_netmem() over one such run shows the
amplification -- two odd-sized requests, nine misaligned offsets:
requested size & 7: 0: 17035 5: 1 7: 1
frag_offset & 7: 0: 17028 3: 1 4: 1 5: 1 6: 1 7: 5
and skb_pp_cow_data() returning heads that were aligned on entry:
head 0xffff8f4c86aeac00 -> 0xffff8f4c53a9a9c4 (&7=4)
head 0xffff8f4d6a8a42c0 -> 0xffff8f4c4f7b7a45 (&7=5)
Round the fragment size up to at least the alignment struct skb_shared_info
requires, so fragments are always suitably aligned for the objects callers
build on them. Architectures needing a larger DMA alignment keep it.
This also makes the remainder computed in page_pool_alloc_netmem(),
*size = max_size - *offset;
aligned, since max_size is a power of two -- which fixes the matching
misalignment of skb->end.
Verified with a controlled A/B under QEMU/KVM: same tree, same config,
same compiler, same rootfs and identical traffic, differing only by this
patch. A SEC("xdp.frags") XDP_PASS program on lo plus UDP datagrams
larger than max_head_size drives skb_pp_cow_data()'s fragment loop, which
passes raw packet lengths to the pool. Measured at the return of
skb_pp_cow_data():
unpatched patched
skb_pp_cow_data calls 40800 40800
misaligned skb->head 1120 0
dataref at line offset >60 80 0
The last row counts the accesses that actually fault:
skb_shinfo()->dataref sits at head+end+0x20 and is a 4-byte atomic, so
`lock incl` splits a 64-byte cache line only when that address lands at
offset 61..63. All 80 occurrences were at offset 61; the panic reported
above was at offset 62. Eliminating the misalignment removes every one
of them.
Same class of bug as commit
|
||
|
|
7b120a7719 |
selftests: tc-testing: add u32 node ID pool exhaustion test
Add a tdc test case that fills the u32 node ID space with 4095 auto-generated handles, then attempts to add a 4096th. On the fixed kernel the 4096th filter is rejected with ENOSPC (exit 2). On the unfixed kernel it silently succeeds with a duplicate handle. The setup pipes the 4095 add commands directly into `tc -b -` inside a single bash -c (matching the existing test id 1234 pattern), avoiding any temp file. Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com> Link: https://patch.msgid.link/20260825081052.133898-2-jhs@mojatatu.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> |