| Age | Commit message (Collapse) | Author |
|
git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next
Pull networking updates from Paolo Abeni:
"This includes a significant number of low-priority fixes - especially
in the NIC drivers area - that we deferred from the last few RCs in
the previous cycle, which can't be easily outlined in the synopsis
below.
Core & protocols:
- Continue the work on removing rtnl_lock dependencies:
- per-netns ARP and ND neighbour tables, with the default settings
now configurable per netns (inheritance from init_net is
controlled by the new net.core.neigh_inherit_init_net sysctl)
- RCU-protected configuration and rtnl_lock-less fill_info() for
hsr, netkit, sit, vlan and vxlan devices
- per-netns device unregistration for ip tunnel and gre devices
- use the netdev instance lock instead of rtnl_lock when reading
speed and duplex via sysfs
- batch the flushing of uncached routes at device unregistration
time, relieving rtnl_lock contention on netns dismantle.
- Add hardware pacing offload support, admin-controlled via a new
rtnetlink attribute, with sch_fq integration (implemented in idpf).
- Re-segment BIG TCP GSO packets into GSO packets fitting the egress
device limits instead of plain MSS-sized segments, improving
throughput for mixed BIG TCP / non-BIG TCP paths by up to 70%.
- Generate RSS keys that spread flows over all the RX queues; the
previous random keys could leave some queues unused.
- Optimize the bridge VLAN forwarding paths: cache the port-VLAN in
fdb entries and consider only VLAN members when flooding, for ~10%
more Mpps in the fdb forwarding path.
- A few TCP/IP performance improvements aimed at efficient cache
usage and reducing contention.
- Add the TCP ROCCET congestion control, a CUBIC variant aimed at
avoiding bufferbloat in cellular networks.
- Continue the conversion of getsockopt callbacks to sockopt_t.
- Add an ethtool command to list the front-facing ports of an
interface, including SFP cages and modules, using the phy_port
representation.
- Enable BIG TCP support for bareudp tunnels.
- Remove the IPV6_ADDRFORM socket option and disallow buggy TCP state
transitions (listen() + shutdown() + connect() and connect() +
connect(AF_UNSPEC) + listen()).
- Remove most BUG_ON()s from core packet processing, replacing them
with error paths.
Wireless:
- Latency improvements, including lockless station get/dump and
beacon updates, plus RTNL reduction and locking cleanups.
- Infrastructure for non-station TX/RX with MLO.
- NAN (Wi-Fi Aware) Instant Communication support and other NAN
improvements.
- Control frame Integrity Protocol (CIP) and protected TWT support.
- Improvements for AP regulatory checks.
Netfilter:
- Disable br_netfilter in user namespaces and schedule it for removal
in 2027.
- Restrict the raw table in nft_compat to the specific family, hook
and priority.
- Prepare the flowtable for mixed IPv4-over-IPv6 tunneling (and vice
versa).
- Use GFP_KERNEL_ACCOUNT for most netfilter allocations, for better
integration with memcg.
- Allow discovering conntrack zone filtering support in ctnetlink
dumps, and fix nfnetlink_hook handling of large dumps.
Deletions:
- Move the LLC type 2 sockets out of tree. There are no known users
and the code attracts a never-ending stream of LLM-driven fixes.
Device drivers:
- New drivers:
- Meta Platforms NIC (mpnic), the second-generation NIC from Meta
- initial skeleton of the Nebula-matrix NICs driver (nbl)
- X-Powers AC200/AC300 Fast Ethernet PHYs
- Ethernet high-speed NICs:
- Intel:
- i40e: XDP metadata support for RX hash and VLAN tag
- ice: expose the E825 TSPLL state via the DPLL subsystem
- nVidia/Mellanox:
- move the data direct infrastructure from IB to core, in
preparation for netdev support.
- reduce the memory used per offloaded TC rule
- Meta (fbnic):
- support large io_uring zero-copy RX buffers
- Microsoft vNIC (mana):
- add BQL support
- Ethernet NICs consumer, and embedded:
- Airoha:
- LRO offload support
- Cadence (macb):
- context swapping for ringparam and MTU changes, avoiding
buffer loss under memory pressure
- Mucse (rnpgbe):
- TX/RX and link status support
- NXP (enetc):
- SR-IOV improvements and VF support for ENETC v4
- Qualcomm (ppe):
- IPQ5424 support
- Realtek PCI (r8169):
- phylink support
- RSS support for RTL8127
- Renesas (ravb):
- gPTP support for R-Car Gen4
- Synopsys (stmmac):
- XDP multi-buffer support on the TX side
- tc mqprio hw queue priority offload
- support for RK3568 SGMII, Allwinner H616 EMAC1, UltraRISC
DP1000 and Qualcomm sa8255p
- Ethernet switches:
- Mediatek (mt7530):
- fast age and change conduit support
- Microchip (ksz):
- support for KSZ8995XA/KS8995XA
- Microchip (lan966x):
- PCIe FDMA support, ~20x throughput increase in PCIe endpoint
- Microchip (sparx5):
- Time Aware Shaper (taprio) offload
- Motorcomm (yt921x):
- LED and SerDes PCS support
- Realtek (rtl8365mb):
- EEE support
- Ethernet PHYs:
- Broadcom:
- enable jumbo frames on BCM54xx
- Realtek:
- support for RTL8261CE_CG and RTL8261D_VM
- MDIO support for RTL838x and RTL839x
- WiFi drivers:
- Broadcom (brcmfmac):
- FT/OKC roaming offload
- Intel (iwlwifi):
- UHR sniffer support
- support for newer UEFI/BIOS tables
- MediaTek (mt76):
- mt7925 NAN improvements
- offchannel/scan improvements and MLO fixes
- Morse Micro (mm81x):
- monitor mode support
- Qualcomm (ath12k):
- IPQ5332 platform infrastructure
- Realtek (rtw88):
- RTL8723BS support
- SDIO TX performance improvements
- Realtek (rtw89):
- P2P_DEVICE support
- BT-coex updates for RTL8922D
- Bluetooth:
- move H:4 reassembly into the Bluetooth core
- add generic support for vendor packets
- MGMT: add security level changed event
- Bluetooth drivers:
- btusb: support Bulk Serialization Mode
- Intel: support Draco and Titan Lake, allow unsigned firmware
- Mediatek: MT7928 support
- Qualcomm: QCC2072 support
- Broadcom: Synaptics 4384 support"
* tag 'net-next-7.4' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next: (2126 commits)
Bluetooth: btusb: disable by default Qualcomm multi-subsystem
tipc: fix broadcast sender hang on last acker departure
tipc: fix use-after-free of broadcast reception link at node release
r8169: clear TX LPI on RTL8168h at link up after phylink conversion
tun: Require CAP_NET_ADMIN to attach to an ownerless device
net/sched/sch_cake: drop dead nla_nest_end() error check
net/sched/sch_cake: widen buffer_used to u64
net/sched/sch_cake: reduce parent backlog when clearing a tin
net/sched/sch_cake: serialize reconfiguration with the datapath
tg3: Add Datto SIRIS 5 1U Server to restart AER quirk table
net/mlx5e: Stop asserting for RTNL when closing channels
net: shrink the payload-only part of skb dataref to one bit
net: wwan: iosm: validate msg_head before indexing msg_ring
net: bgmac: rate limit RX error messages
selftests: net: veth: test XDP_TX to a peer with GRO enabled
veth: schedule the peer's NAPI after XDP_TX when only GRO is enabled
pppoe: delete session hash entries by pointer match
net: lan969x: don't disable hardirqs in fdma tx clear
net: sparx5/lan969x: do not clobber the PSFP cycle timer update period
net: lan969x: fix DSM calendar for empty taxis
...
|
|
Merge in late fixes in preparation for the net-next PR.
Conflicts:
net/netfilter/nf_conntrack_netlink.c
cd37ab22a74e0 ("netfilter: nf_conntrack_netlink: fix inverted IPv6 tuple filter")
1ae2d094b0200 ("netfilter: ctnetlink: fix inverted IPv6 address match in dump filter")
Adjacent changes:
drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
8830e65ed46de ("net: use assign_bit() where applicable")
07bd391eb957 ("octeontx2-af: Fix CQ enable state tracking after AQ writes")
net/core/sock.c
31c5ea8a3296 ("ipv6: Remove IPV6_ADDRFORM.")
31b564f70d88 ("net: use the full socket in sk_mc_loop()")
net/mptcp/protocol.h
0cb6910130a3 ("mptcp: remove thmac from subflow ctx")
7538fa33bb2f ("mptcp: fix subflow bitfield misuse")
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|
TIPC group broadcast senders are blocked while a replicast still has
outstanding member acks: tipc_group_bc_cong() returns true as long as
grp->bc_ackers is non-zero, and clears *grp->open, which is what
tipc_poll() uses to report EPOLLOUT (via tsk->group_is_open).
When the last outstanding acker departs before acking,
tipc_group_delete_member() decrements grp->bc_ackers to zero but
never restores *grp->open. As a result poll(EPOLLOUT) never fires
again. A writer blocked in sendmsg() is only released if some other
wakeup happens after the deletion: with TIPC_GROUP_MEMBER_EVTS the
leave event delivery calls sk_data_ready() and wakes it, but without
member events nothing does and it sleeps indefinitely, since the
default send timeout is MAX_SCHEDULE_TIMEOUT.
Commit 99cc2a62e07a ("tipc: reject invalid and unexpected
GRP_ACK_MSG to prevent bc_ackers underflow") already calls this out
in its changelog as a pre-existing issue.
Restore the open state exactly on the 1->0 transition in the delete
path, mirroring the GRP_ACK_MSG completion path, and invoke
sk->sk_write_space() from tipc_sk_filter_rcv() when the group just
became writable again.
Also make the ack accounting precise. The delete path used to test
less(m->bc_acked, grp->bc_snd_nxt - 1), which also matches members
that were never counted for the current replicast (JOINING/LEAVING
members keep a stale bc_acked), and the GRP_ACK_MSG handler accepted
an ack from any member whose bc_acked differed from the expected
value. Either could zero bc_ackers on behalf of a member that owes
nothing and silently void an ack still owed by a real acker. Track
whether a member owes an ack for the current replicast in a new
per-member bc_pending flag, set when the member is counted and
cleared when its ack arrives, and use it both to accept an ack and
to decide on deletion. bc_acked has no remaining user and is
removed. Suggested by Tung Quang Nguyen.
This issue was discovered by Tencent CodeBuddy Security.
Cc: stable@vger.kernel.org
Fixes: 2f487712b893 ("tipc: guarantee that group broadcast doesn't bypass group unicast")
Signed-off-by: Henry Martin <bsdhenrymartin@gmail.com>
Reviewed-by: Tung Nguyen <tung.quang.nguyen@est.tech>
Link: https://patch.msgid.link/20261019115859.3471295-1-bsdhenrymartin@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|
When the last reference to a tipc_node is dropped, the node itself is
deferred to the RCU callback tipc_node_free(), but the nested broadcast
reception link, n->bc_entry.link, is kfree()d synchronously in
tipc_node_kref_release(), before call_rcu(), and the pointer is never
cleared. Readers that obtained the node from node_list and then
dereference bc_entry.link deep into the link (tipc_link_name() in
tipc_nl_node_reset_link_stats(), bcl->name/stats in
tipc_nl_add_bc_link() on the link dump path) therefore touch freed
memory although the enclosing node stays alive for a full grace period.
The sibling per-bearer links get "kfree + NULL" under the node write
lock in tipc_node_clear_links(); the broadcast entry was missed.
The race is reachable through the node cleanup timer: once a peer has
been unreachable for NODE_CLEANUP_AFTER (300 s), tipc_node_timeout() ->
tipc_node_cleanup() unlinks the node under the write lock, and the
final tipc_node_put() at the caller runs outside node_list_lock, so the
kfree executes in timer softirq context, concurrently with genl dump/
reset walkers that hold only rcu_read_lock(). (A netlink "peer remove"
cannot race those walkers itself: tipc_genl_family has no parallel_ops,
so all doit/dumpit calls serialize on the global genl lock.)
Reproduced in a QEMU/KVM guest running v7.3.0 with KASAN and
PREEMPT(full): 10 TIPC peer namespaces on veth bearers, bearer removal
staggered so the 300 s node cleanup timers expire while other tasks
loop link dumps with the broadcast filter and reset-link-stats lookups.
KASAN hit within two cleanup cycles:
BUG: KASAN: slab-use-after-free in strlen+0x85/0xa0
Read of size 1 at addr ffff88800b54a004 by task poc_eth/371
strlen+0x85/0xa0
tipc_nl_add_bc_link+0x2f9/0xd40
__tipc_nl_add_node_links+0x10c/0x140
tipc_nl_node_dump_link+0x8d5/0xd50
Freed by task 0:
kfree+0x121/0x380
tipc_node_timeout+0xa33/0xcf0
run_timer_softirq+0x144/0x250
sysvec_apic_timer_interrupt
with the freed object being the kmalloc-1k tipc_link allocated by
tipc_link_bc_create() during peer discovery. The same defect fires in
strcmp() called from tipc_nl_node_reset_link_stats().
Move the kfree of n->bc_entry.link into the tipc_node_free() RCU
callback so the broadcast link lives exactly as long as the enclosing
node. All readers are covered: the netlink walkers are inside
rcu_read_lock(), and the packet reception path reaches the node via
tipc_node_find(), whose kref defers kref_release itself.
Found during a static-analysis-assisted audit: candidate sites were
surfaced by a Coccinelle rule, and the reader/writer paths were
confirmed by LLM-assisted (GLM-5.3) code inspection.
Fixes: d25a01257e42 ("tipc: fix crash during node removal")
Assisted-by: GLM-5.3 coccinelle
Signed-off-by: Binbin Deng <18983559317@163.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Reviewed-by: Tung Nguyen <tung.quang.nguyen@est.tech>
Link: https://patch.msgid.link/20261019104352.488347-1-18983559317@163.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|
cake_dump_class_stats() closes the TCA_STATS_APP nest with
if (nla_nest_end(d->skb, stats) < 0)
return -1;
nla_nest_end() never returns a negative value: it has a single
`return skb->len;` and no error path (that is why the overflow-aware
nla_nest_end_safe() helper was later added). The '< 0' test can never
be true, so the 'return -1' is unreachable dead code.
Drop the check and close the nest with the bare statement, matching the
sibling cake nests in the same file.
This issue was discovered while fixing a bug on the gate action, see:
https://lore.kernel.org/netdev/QDISC-H19Z.v1.20261001053234@mojatatu.com/
Conditions to recreate the bug:
- not runtime observable: the issue is found by inspection.
Link: https://lore.kernel.org/netdev/87v77csd5q.fsf@toke.dk/
Reviewed-by: Victor Nogueira <victor@mojatatu.com>
Acked-by: Toke Høiland-Jørgensen <toke@toke.dk>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/QDISC-5RTM.v3.r0.20261020053711-4@mojatatu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
This is a follow-up to commit 4c660ee8c809 ("net: sched: fix 32-bit
backlog wrap in gred, bfifo and plug enqueue"), which promoted the
backlog + length admission sums in gred, bfifo and plug to u64. CAKE's
own memory accounting has the same 32-bit wrap.
The issue:
cake_sched_data.buffer_used accumulates skb->truesize and is compared
against memory_limit:
q->buffer_used += skb->truesize;
if (q->buffer_used <= q->buffer_limit)
return NET_XMIT_SUCCESS;
while (q->buffer_used > q->buffer_limit)
drop...
buffer_used is u32, so once the resident truesize passes 2^32 it wraps to
a small value, the <= test passes and the drop loop is skipped even
though far more than the configured limit is queued. memory_limit is a
u32 attribute (TCA_CAKE_MEMORY), so buffer_limit can be as large as
U32_MAX and never caps buffer_used below the wrap point; with a large
memory_limit the queue then grows until the machine is out of memory.
The fix:
Widen buffer_used and buffer_max_used to u64, the same shape as the
gred/bfifo/plug fix. buffer_limit stays u32; the comparison promotes it
to u64, so the bounded queue stops at the configured limit below 2^32 and
the counter can no longer wrap. buffer_used is subtracted on dequeue and
drop, so the widened type flows through unchanged. The ACK-filter
replacement applied the net delta as one expression,
q->buffer_used += skb->truesize - ack->truesize. Both operands are
unsigned int, so the subtraction is evaluated at u32 and a larger removed
ACK wraps the delta; the old u32 accumulator folded that back to the
correct net value, but the widened u64 accumulator would persist it as a
roughly 4 GiB over-count. Apply the replacement as two exact operations
on the widened counter instead; the queue already accounts ack->truesize,
so the subtraction cannot underflow.
Widening the counters alone is incomplete because cake_dump_stats() still
exports buffer_max_used through PUT_STAT_U32(MEMORY_USED, ...), and
tc.yaml declares memory-used as u32. buffer_max_used only ever rises, so
once the widened counter passes 2^32 the export reports peak - 2^32 for
the rest of the qdisc's life. Clamp the exported value to U32_MAX; the
counter itself is unaffected.
The dump path runs without the qdisc lock: tc_fill_qdisc() passes NULL to
gnet_stats_start_copy_compat(), so the reader races with the enqueue-side
update. READ_ONCE() is not an atomic 64-bit load on 32-bit CPUs, so a
reader can observe a torn high-water mark and report a bogus MEMORY_USED.
Publish the counter as u64_stats_t under the qdisc lock, which the enqueue
path already holds, and take a seqcount-protected snapshot in the dump.
The counter stays u64; only the exported value is bounded.
Conditions to recreate the bug:
CAP_NET_ADMIN (root or a user namespace, the qdisc attach is gated by
netlink_net_capable(CAP_NET_ADMIN)).
A TUN device is needed so the root qdisc can park packets instead of
dropping them. Open /dev/net/tun, request TUNSETIFF with
IFF_TUN | IFF_NO_PI | IFF_BACKPRESSURE and keep the fd open without
reading it (run it in the background and stop it at teardown): with
IFF_BACKPRESSURE the full tx ring calls netif_tx_stop_queue() rather than
dropping, so the queue behind the qdisc can grow past 4 GiB of resident
truesize. A plain 'ip tuntap add' attaches no fd and does not request
IFF_BACKPRESSURE, so it cannot park the queue this way.
ip link set tun0 txqueuelen 32 up
ip addr add 10.99.0.1/24 dev tun0
tc qdisc add dev tun0 root handle 1: cake memlimit 4294967295
# Then push more than 4 GiB of resident truesize through the qdisc: six
# UDP senders using large SO_SNDBUFFORCE buffers send 1400-byte
# datagrams (the reported OOM witness used 6 workers for 100 s on a
# 12 GiB guest). On the unfixed kernel buffer_used wraps, the admission
# test passes, the drop loop is bypassed and the guest runs out of
# memory; with the fix the counter passes the limit without wrapping and
# the excess is dropped.
# The ACK-filter over-count is a separate corner: it needs ack-filter
# enabled and a queued pure ACK whose truesize is larger than the
# replacement ACK. Use a fresh interface (or 'tc qdisc change') rather
# than a second root 'tc qdisc add' on an interface that already has a
# qdisc:
tc qdisc change dev tun0 root cake ack-filter
CONFIG_NET_SCH_CAKE=y and CONFIG_TUN=y are required, and the
memory-residency recipe needs a root-run sender envelope with enough
guest RAM to hold the queued data.
Reported-by: Sashiko (gemini) <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260818095927.15901-1-jhs@mojatatu.com
Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260818095927.15901-1-jhs@mojatatu.com
Link: https://lore.kernel.org/netdev/20260818095927.15901-1-jhs@mojatatu.com/
Reviewed-by: Victor Nogueira <victor@mojatatu.com>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Acked-by: Toke Høiland-Jørgensen <toke@toke.dk>
Link: https://patch.msgid.link/QDISC-5RTM.v3.r0.20261020053711-3@mojatatu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
The issue:
CAKE has purged unused tins on DiffServ reconfiguration since commit
83f8fd69af4f ("sch_cake: Add DiffServ handling") without propagating the
resulting backlog reduction to classful parents. The issue was noticed
while reviewing 7cbfb180945c, but predates that change.
cake_clear_tin() drops every packet from a tin with
kfree_skb_reason() but never calls qdisc_tree_reduce_backlog(), so a
CAKE qdisc under a classful parent (e.g. HTB) leaves the dropped packets
in the parent qdisc's and class's qlen/backlog accounting forever. The
normal dequeue path does reduce the parent; only the live reconfigure
purge misses it.
The fix:
Tins are cleared from cake_reset() and, on reconfigure, from
cake_configure_rates(). The qdisc core already owns the parent delta for
the reset path: qdisc_purge_queue() snapshots qlen/backlog, runs
qdisc_reset(), then reduces the tree, so propagating the reduction from
cake_clear_tin() itself would subtract the same backlog twice. Snapshot
CAKE's qlen/backlog around only the reconfiguration purge in
cake_configure_rates() and reduce the parent once afterwards, matching
the delta pattern already used by cake_enqueue().
Conditions to recreate the bug:
put CAKE (diffserv8) under an HTB class, flood DSCP-classified traffic
into a high tin so it backlogs, then change CAKE to diffserv3. The HTB
parent keeps the purged packets in its qlen and backlog; a kernel with
the fix shows the parent at the leaf's backlog (426b/5p) instead of
retaining the purged packets.
Reported-by: Sashiko (gemini) <sashiko-bot@kernel.org>
Link: https://sashiko.dev/#/patchset/20260816012109.2865223-1-ooonea@gmail.com
Link: https://lore.kernel.org/netdev/20260816012109.2865223-1-ooonea@gmail.com/
Link: https://lore.kernel.org/netdev/8733ugtry8.fsf@toke.dk/
Reviewed-by: Victor Nogueira <victor@mojatatu.com>
Acked-by: Toke Høiland-Jørgensen <toke@toke.dk>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/QDISC-5RTM.v3.r0.20261020053711-2@mojatatu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
This is a follow-up to commit 7cbfb180945c ("net/sched: sch_cake: fix
autorate reconfiguration throttling"). That change only stored
last_reconfig_time; it did not address the concurrency between the
autorate rate update in cake_enqueue() and the netlink reconfiguration
path, which the original review flagged.
The issue:
cake_change() -> cake_config_change() updates the fields of the shared
struct cake_sched_config under RTNL but not under the qdisc lock: it only
took sch_tree_lock() later, around cake_reconfigure(). The datapath in
turn serializes cake_enqueue() with itself under the qdisc lock, and its
autorate-ingress path stores the estimated rate into
q->config->rate_bps. Two writers therefore update the same rate with no
common lock:
CPU0: cake_enqueue() sees CAKE_FLAG_AUTORATE_INGRESS, computes an
estimate, and is about to store it.
CPU1: 'tc qdisc change ... bandwidth X' clears autorate in its local
rate_flags, writes rate_bps = X, publishes the cleared flag, and
waits in sch_tree_lock().
CPU0: stores the estimate, calls cake_reconfigure(), and unlocks.
CPU1: reconfigures from the estimate and returns.
The qdisc is left with autorate disabled but with the estimate installed
instead of X.
The fix:
Commit the parsed configuration and reconfigure while holding the same
qdisc lock that serializes the datapath, so the netlink writer and the
autorate writer can no longer interleave. rate_bps needs no atomic: it is
only ever loaded and stored, so plain READ_ONCE()/WRITE_ONCE() annotations
are enough for the accesses that run outside the lock. The lockless
paths read the rate once into a local and reuse that value, so a single
coherent snapshot is used per operation.
The annotations do not make a 64-bit access single-copy atomic on 32-bit:
READ_ONCE()/WRITE_ONCE() are still two 32-bit accesses there. The lockless
readers -- cake_config_dump() and the cake_mq children, which observe the
shared config under a different child's lock -- can therefore still see a
torn rate on 32-bit. That rate is an advisory shaper value and is accepted
as best-effort; the state that must be consistent (the configured rate and
the autorate flag) is written under the qdisc lock.
Conditions to recreate the bug:
The lost update (a) needs no sanitizer. Put cake in autorate-ingress on a
device, drive bursty traffic with gaps so the 250 ms autorate reconfiguration
fires, and concurrently loop 'tc qdisc change ... cake bandwidth <N>kbit'
without autorate-ingress (specifying a bandwidth clears the flag).
If the autorate store lands after the change wrote its rate but before the
change reconfigures, the qdisc ends up with autorate disabled and the estimate
installed instead of <N>; reading the rate back then shows the estimate, which
an unfixed kernel can do and a fixed one cannot.
(b) The unsynchronized access is reported by KCSAN: build with CONFIG_KCSAN=y
and run the same trigger with the change loop keeping autorate-ingress set;
KCSAN reports a data race in cake_config_change / cake_enqueue.
The non-atomic 64-bit store only shows up as tearing on a 32-bit machine;
on 64-bit the store is atomic and KCSAN flags the access discipline instead.
Reported-by: Sashiko (gemini) <sashiko-bot@kernel.org>
Link: https://sashiko.dev/#/patchset/20260816012109.2865223-1-ooonea@gmail.com
Link: https://lore.kernel.org/netdev/20260816012109.2865223-1-ooonea@gmail.com/
Link: https://lore.kernel.org/netdev/875wzctsky.fsf@toke.dk/
Link: https://lore.kernel.org/netdev/87ld7t3kl3.fsf@all.your.base.are.belong.to.us/
Reviewed-by: Victor Nogueira <victor@mojatatu.com>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Acked-by: Toke Høiland-Jørgensen <toke@toke.dk>
Link: https://patch.msgid.link/QDISC-5RTM.v3.r0.20261020053711-1@mojatatu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
Follow the object_action() naming convention for netmem non-page_pool
reference helpers by renaming get_netmem() and put_netmem() to
netmem_inc_ref() and netmem_dec_ref().
Use netmem_inc_ref() and netmem_dec_ref() rather than netmem_ref() and
netmem_unref() because netmem_ref is already a typedef (typedef unsigned
long __bitwise netmem_ref).
Suggested-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Mina Almasry <almasrymina@google.com>
Link: https://patch.msgid.link/20261021015558.4124825-3-almasrymina@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
Follow the object_action() naming convention for net_iov non-page_pool
reference helpers by renaming get_net_iov() and put_net_iov() to
net_iov_inc_ref() and net_iov_dec_ref(), and renaming
net_devmem_get_net_iov() and net_devmem_put_net_iov() to
net_devmem_net_iov_inc_ref() and net_devmem_net_iov_dec_ref().
Use *_inc_ref() and *_dec_ref() rather than *_ref() and *_unref() to
pair symmetrically with netmem_inc_ref() and netmem_dec_ref() (since
netmem_ref is already the typedef for the generic network memory
handle).
Suggested-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Mina Almasry <almasrymina@google.com>
Link: https://patch.msgid.link/20261021015558.4124825-2-almasrymina@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
Expose the phy_port information to userspace, so that we can know how
many ports are available on a given interface, as well as their
capabilities. For MDI ports, we report the list of supported linkmodes
based on what the PHY that drives this port says.
For MII ports, i.e. empty SFP cages, we report the MII linkmodes that we
can output on this port.
Tested-by: Aleksei Sviridkin <f@lex.la>
Reviewed-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
Tested-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Link: https://patch.msgid.link/20261016133107.54054-10-maxime.chevallier@bootlin.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
phy_port is aimed at representing the various physical interfaces of a
net_device. They can be controlled by various components in the link,
such as the Ethernet PHY, the Ethernet MAC, and SFP module, etc.
Let's therefore make so we keep track of all the ports connected to a
netdev in phy_link_topology. The only ports added for now are phy-driven
ports.
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Tested-by: Aleksei Sviridkin <f@lex.la>
Reviewed-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
Tested-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Link: https://patch.msgid.link/20261016133107.54054-3-maxime.chevallier@bootlin.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer core updates from Thomas Gleixner:
"Updates for the core timekeeping and timers subsystem:
- Futher cleanups for the POSIX timer exit/exec related code to
simplify the code flow and to make it more robust against future
changes.
- Prevent tearing of timekeeper::ktime_sec which can be accessed
without the sequence count protection.
The timekeeper is updated by memcpy() with an uneven sequence count
to force readers into the retry path. On 64-bit machine the
ktime_sec member can be accessed atomically without the sequence
count protection. That is only correct when the update side
memcpy() guarantees atomicity at the 64-bit granularity. That's not
guaranteed due to debug options, compilers and instruction
availability. If the memcpy() does not provide the atomicity then
the unprotected readers can observe store tearing.
To prevent this write the ktime_sec member before the memcpy() so
that a non-atomic memcpy() will write the same data. A similar fix
has been done for the xtime_sec member, but the ktime_sec
equivalent was missed.
- Prevent time64_to_tm() day truncation on 32-bit kernels
The function receives a 64-bit seconds value but stores the
quotient of the computation in a long, which truncates the result
for large input values. Cure this by using div_s64_rem() which
stores the quotient in s64 and only leaves the seconds-within-day
reminder in a long, which is guaranteed to fit. This fix comes with
a corresponding kunit test to prevent further mishaps.
- Mark data-racy accesses to the hrtimer_sleeper::task member.
The recent updates to KCSAN flagged these benign races. Annotate
them with new helper functions, convert all existing usage sites
and mark the task member private after that so that future users
which fail to use the helpers can be detected automatically.
- Address similar benign KCSAN flagged issues in the hrtimer, timer
and timer migration code.
- Fixes for a few selftest issues"
* tag 'timers-core-2026-10-20' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (26 commits)
selftests/timers: clocksource-switch: Fix unchecked open()/read()
selftests: timers: Measure the CPU timers on the clock they count
selftests: timers: Count what tick is worth in the drift estimate
time/kunit: Add time64_to_tm() case beyond 32-bit day count
time: Prevent time64_to_tm() day truncation on 32-bit
timekeeping: Use READ_ONCE/WRITE_ONCE() for ktime_sec to prevent tearing
timers/migration: Mark racy updates to tmigr_event::ignore field
timers: Mark racy updates to hlist_node::pprev field
hrtimer: Apply READ_ONCE() to lockless base->running loads
hrtimer: Mark the hrtimer_sleeper structure's ->task field __private
hrtimer: Update hrtimer_resolution only if value changes
futex: Use accessor for hrtimer_sleeper ->task field in requeue
rtmutex: Use accessor for hrtimer_sleeper ->task field
net: pktgen: Use accessor for hrtimer_sleeper ->task field
timers: Use accessor for hrtimer_sleeper ->task field in sleep_timeout.c
futex: Use accessor for hrtimer_sleeper ->task field in waitwake.c
io-uring/rw: Use accessor for hrtimer_sleeper ->task field
wait: Use accessor for hrtimer_sleeper ->task field
aio: Use accessor for hrtimer_sleeper ->task field
hrtimer: Mark data-racy accesses to hrtimer_sleeper ->task field
...
|
|
This is long over-due: the __get_user() and __put_user() functions are
entirely historical, and are never the rigth thing to use any more. And
when mis-used (read: every case) they are not only slower than the right
thing, but also insecure because they don't check the user address
range.
Most of the usage sites have been converted long ago, but various
left-overs remained. So this started out as a single patch that I wrote
as a "show people how to convert __{get,put}_user() to modern code".
In particular, Thomas last year implemented the very nice new scoped
user access region helpers (see commit e497310b4ffb: "uaccess: Provide
scoped user access regions") that makes the modern interfaces
particularly easy to use and really removes any excuse for the old
horrors.
That small example patch then grew to this, partly using Claude as a
glorified coccinelle script to apply the pattern to other places.
There were a few different reasons for using __put_user() and
__get_user() rather than the alternatives, but the original historical
one was performance: when doing multiple accesses off the same base
pointer, doing a single range check followed by multiple non-checked
accesses used to create smaller and faster code.
The keyword here is "used to". It hasn't been true for years, because
the range check isn't actually the real cost these days. The real cost
of user accesses on modern hardware is turning the user accesses on and
off in the first place (on x86, using the STAC/CLAC instructions).
Those sequences get turned into 'scoped_user_read_access() { }' blocks,
see for example that first patch in the series: "signal: use scoped user
access for old-style sigaction".
Another, historical reason for using __get_user() and friends is that
you actually want to do a kernel pointer access, but the pointer might
not be entirely reliable (typically during fault handling), so you want
to have exception handling for the kernel access.
The modern way to do that kind of non-faulting kernel access is using
"get_kernel_nofault()", but some code predates that helper existing at
all, and used __get_user() as a way to just get a memory access with
exception handling. For that pattern, see for example "alpha: use
get_kernel_nofault() in dik_show_code()"
A third bad reason for using __get_user() and friends was that the
proper get_user() had a "might_fault()" in it, and code that ran in
atomic regions but hadn't disabled page faults would result in a
warning. That kind of code needs to explicitly disable page faults,
because "atomic region" is not well defined at run-time and can be
invisible (eg a preempt-off region in a non-preemptible kernel).
See "vdpa_sim: disable page faults around vringh_need_notify_iotlb()"
for an example of that pattern, where the local_bh_disable() now also
grows a pagefault_disable(), which makes the normal get_user() no longer
warn about the user access in non-process context, because it can see
that the potential page fault will not cause problems.
And finally, the really nasty reason to use __get_user() and friends:
pointers that can be either kernel pointers or user pointers. We've
gotten rid of almost all such cases, but a couple remained. See for
example "x86/sev: Use explicit user-or-kernel accessors for #VC memory
operands".
NOTE! This series removes all __get/put_user() calls from generic code
but only does the final removal of the whole interface on x86. Other
architectures have not been entirely converted, for a variety of reasons:
- arm64 makes __{get,put}_user() be exactly the same as
{get,put}_user() so it's harmless and didn't have the dangers of the
legacy use cases.
- any architecture that uses <asm-generic/uaccess.h> will still use
__{get,put}_user as the underlying helper function name
- several architectures had some legacy uses that weren't entirely
trivial and I didn't want to extend this patch series to things that
I don't know and that don't really matter.
but I did do a couple of the obvious "follows the exact same pattern"
just because it could be done mindlessly and automatically.
Let's see if I broke anything, but we should have done this years ago.
* uaccess-cleanups: (48 commits)
drm/i915/gem: ignore errors on presumed_offset write-back
powerpc/align: use get_user_instr() for a user-mode instruction
powerpc/signal64: use scoped user access in setup_trampoline()
powerpc/signal64: use get_user() for the single context reads
powerpc/signal32: use get_user() for the single context reads
KVM: PPC: Book3S HV: use get_user()/put_user() for the HPT fd
powerpc/powernv: use get_user()/put_user() in the LPC debugfs files
s390: use get_user()/put_user() instead of the unchecked variants
ARM: OABI: use scoped user access in epoll_put_uevent()
ARM: signal: stop using __put_user() for the signal frame
ARM: signal: check the FDPIC function descriptor address
alpha: split the prefetch check in do_page_fault() by mode
openrisc: use get_kernel_nofault() in show_registers()
alpha: use get_kernel_nofault() in dik_show_code()
nios2: use scoped user access for the signal frame
nios2: check the signal frame address before writing to it
hexagon: use scoped user access for the signal frame
alpha: use scoped user access when setting up signal frames
alpha: use scoped user access in the sigreturn path
alpha: use scoped user access in osf_sigaction()
...
|
|
SO_INQ makes recvmsg() return the bytes left in the receive queue in an
SCM_INQ cmsg, saving a SIOCINQ call per receive. AF_UNIX stream sockets
support it, AF_VSOCK fails with ENOPROTOOPT.
Add it for SOCK_STREAM, reusing the hint already computed for io_uring.
As with TCP_INQ, 1 is reported once the stream is finished so the caller
reads again and sees EOF, and accepted sockets inherit the setting from
the listener. No cmsg is sent when the transport cannot report the queue
length.
SOCK_SEQPACKET is refused, as on AF_UNIX: its transport callback counts
messages, not bytes.
Signed-off-by: David Carlier <devnexen@gmail.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Link: https://patch.msgid.link/20261016132716.272018-3-devnexen@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|
SO_ZEROCOPY is handled inline in vsock_connectible_setsockopt(). Move it
to a helper with a switch on optname, so other SOL_SOCKET options can be
added as new cases. The value parsing goes to its own helper too, so each
option can do its own checks before it.
No functional change.
Signed-off-by: David Carlier <devnexen@gmail.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Link: https://patch.msgid.link/20261016132716.272018-2-devnexen@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|
RTM_GETMULTICAST dumps IPv4 and IPv6 multicast group memberships, but
the device multicast list (dev->mc) is only available through
/proc/net/dev_mcast, so "ip maddr show" still has to parse procfs for
its link-layer entries.
Handle RTM_GETMULTICAST dumps with ifa_family set to AF_PACKET next to
the dev->mc helpers in dev_addr_lists.c and report every entry of
dev->mc in the existing ifaddrmsg format:
- IFA_MULTICAST carries the raw link-layer address
- IFA_MC_USERS carries the entry reference count
- IFA_F_GLOBAL in IFA_FLAGS reports netdev_hw_addr::global_use, set
by dev_mc_add_global() (SIOCADDMULTI) and dev_mc_add_excl()
("bridge fdb add ... self"), i.e. entries added explicitly rather
than by a protocol join. This is the static column of
/proc/net/dev_mcast
- ifa_scope is RT_SCOPE_LINK
This covers every column of /proc/net/dev_mcast. AF_PACKET is the
family iproute2 already uses for link-layer addresses ("ip -0").
The default FDB dump also walks dev->mc, but only for Ethernet devices
and only if the driver uses it, vxlan for example does not, and it has
no users count or global_use bit. Extending it would change "bridge fdb
show" output and add NDA_* attributes.
Requests are always validated, there are no legacy users: prefixlen,
flags and scope must be zero, ifa_index selects one device and
IFA_TARGET_NETNSID is the only attribute accepted. The dump runs under
RCU and netif_addr_lock_bh() without RTNL. cb->seq is set from the
dev->mc generation counter and dev_base_seq before each round and
checked after it, so an entry added or removed since the previous
round sets NLM_F_DUMP_INTR. A round without a message skips the check
and cb->seq is set once more after the round, so the NLMSG_DONE check
reports a change made during the last round or before an empty one.
Signed-off-by: Yuyang Huang <sigefriedhyy@gmail.com>
Reviewed-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Link: https://patch.msgid.link/20261012011707.3378-5-sigefriedhyy@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|
A multi-part RTM_GETMULTICAST dump of dev->mc resumes by position, so
entries added or removed between two dump rounds can be skipped or
repeated. The IPv4 and IPv6 dumps report that with NLM_F_DUMP_INTR by
stamping cb->seq from a per netns generation counter combined with
dev_base_seq, see inet_base_seq().
Add the equivalent for the device multicast lists: a per netns counter
bumped whenever an entry is added to or removed from any dev->mc. The
list helpers do not know which device a list belongs to, so give
netdev_hw_addr_list an mc_dev pointer, set for dev->mc only, and bump
the counter of dev_net(mc_dev) from the count helpers. That covers the
dev_mc_* helpers, both lists of a sync, the hardware sync helpers
drivers call from their rx mode callbacks or their own workers and the
reconciliation after an asynchronous rx mode update. It is atomic
since the writers only hold the address lock of their own device.
Used by the following patch for the AF_PACKET multicast dump.
Signed-off-by: Yuyang Huang <sigefriedhyy@gmail.com>
Reviewed-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Link: https://patch.msgid.link/20261012011707.3378-4-sigefriedhyy@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|
The count of a netdev_hw_addr_list is changed in several places of
dev_addr_lists.c and a few drivers read it directly. The next patch
needs to account every change of the count of dev->mc.
Add __hw_addr_count_add(), __hw_addr_count_inc(), __hw_addr_count_dec()
and __hw_addr_count_reset(), use them for every change of the count
and rename the field to _count so that a direct write stands out.
Readers keep using netdev_hw_addr_list_count() and the netdev_uc_count()
and netdev_mc_count() helpers, the few that read the field directly
are converted. No functional change.
Signed-off-by: Yuyang Huang <sigefriedhyy@gmail.com>
Reviewed-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Link: https://patch.msgid.link/20261012011707.3378-3-sigefriedhyy@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|
In tcp_bpf_sendmsg(), the value returned by sk_msg_memcopy_from_iter()
is checked for error but not propagated to 'out_err' label, so error
handling may not work as expected. Fix this by assigning error value
to 'err', thus making sure that error won't be silently ignored.
Reported-by: Sashiko <shodan.ai@mcst.ru>
Fixes: 5153a75ef34b ("tcp_bpf: Fix copied value in tcp_bpf_sendmsg")
Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Jason Xing <kerneljasonxing@gmail.com>
Reviewed-by: Eric Dumazet <edumazet@kernel.org>
Link: https://patch.msgid.link/20261019082214.102398-1-dmantipov@yandex.ru
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf
Pablo Neira Ayuso says:
====================
Netfilter/IPVS fixes for net
The following patchset contains Netfilter/IPVS for net:
1) Fix IPv6 nexthdr offset truncation in fragment reassembly,
this has been uncovered by LLM, from Jeremy Jean.
2) Restrict checksums in nfqueue to known protocols and offset,
after this patch the plan is to re-enable nfqueue in userns,
this came via LLM report. from Florian Westhphal.
3) Fix races when handling overload flag in IPVS, this patch
is not perfect but Julian considers this improves the situation.
This was uncovered by LLM. From Julian Anastasov.
4) Error handling for IPVS sync_threshold sysctl, from Joel Granados.
5) Use skb_vlan_tag_get_id() to retrieve the VLAN id, discard tci
bits, when handling VLAN in the flowtable, from Shuangfeng He.
6) Initialize IPCB for inet/ingress reject, uncovered by LLM.
7) Restrict completion of binary search array to anonymous set.
8) Restrict DCCP option matching to avoid out-of-bound read,
from Sung Byeongchan.
9) Reset transport header offset in flowtable after tunnel
decapsulation to fix issue with qdisc xmit path,
from Lorenzo Bianconi.
10) Fix inverted matching in ctnetlink dump filtering,
from Liu Chao.
* tag 'nf-26-10-19' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf:
netfilter: nf_conntrack_netlink: fix inverted IPv6 tuple filter
netfilter: flowtable: reset transport header after nf_flow_encap_pop()
netfilter: xt_dccp: handle reserved options as single-byte
netfilter: nft_set_rbtree: narrow down range completion to anonymous sets
netfilter: nf_reject: initialize IPCB at inet ingress
netfilter: flowtable: use the vlan id, not the full tci, in the tuple key
ipvs: skip committing sync_threshold when proc_dointvec fails
ipvs: fix more races around the overload flag
netfilter: nft_payload: restrict checksum offsets to known values
netfilter: nf_conntrack: avoid truncating IPv6 nexthdr offset
====================
Link: https://patch.msgid.link/20261019150249.1879516-1-pablo@netfilter.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
Commit 68822bdf76f1 ("net: generalize skb freeing deferral to
per-cpu lists") added alloc_cpu to struct sk_buff and placed it in the
headers group copied by __copy_skb_header().
This is wrong for newly allocated skbs. For example, skb_segment()
allocates a new skb and records the current CPU in alloc_cpu, but
__copy_skb_header() overwrites it with the value from the original skb.
If the original skb was allocated on another CPU, the segment may later
be treated as remotely allocated and unnecessarily deferred there when
it is freed.
Move alloc_cpu out of the headers group so it is preserved across
header copies. Copy it explicitly in skb_clone(), which allocates
the skb object directly instead of going through __alloc_skb().
This was discovered while investigating a throughput regression with
software IPsec. The load used 512 IPsec tunnels carrying traffic over
VXLAN, with 512 parallel iperf3 flows and an MTU of 4500.
Before the fix:
16.09% queued_spin_lock_slowpath
|
--15.90%--_raw_spin_lock_irqsave
|
--9.37%--__slab_free
kfree
skb_release_data
napi_consume_skb
mlx5e_poll_tx_cq
After the fix:
6.84% queued_spin_lock_slowpath
|
--6.57%--_raw_spin_lock_irqsave
|
--5.00%--__slab_free
kfree
skb_release_data
napi_consume_skb
mlx5e_poll_tx_cq
Fixes: 68822bdf76f1 ("net: generalize skb freeing deferral to per-cpu lists")
Signed-off-by: Carolina Jubran <cjubran@nvidia.com>
Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
Reviewed-by: Björn Töpel <bjorn@kernel.org>
Reviewed-by: Jason Xing <kerneljasonxing@gmail.com>
Reviewed-by: Eric Dumazet <edumazet@kernel.org>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20261019174152.2932829-1-cjubran@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
When a send wraps the end of the send buffer, smc_tx_sendmsg() copies
the data in two chunks. If memcpy_from_msg() faults on the second one,
smc_tx_sendmsg() returns send_done, which already counts the first
chunk, but leaves tx_curs_prep and sndbuf_space as they were. send()
reports bytes the peer never receives, and the next send() overwrites
them. Any caller can hit this on its own stream with a buffer whose
tail is unreadable.
On a fault in the second chunk, queue the first one. The next pass
retries the rest and returns send_done if it faults again, so send()
reports only what it queued, as TCP does.
Fixes: e6727f39004b ("smc: send data (through RDMA)")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Link: https://patch.msgid.link/20261013-b4-disp-872a3689-v1-1-2a4c63b04761@proton.me
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
fib6_info_hw_flags_set() is called by drivers from process context
without RTNL or RCU. When the route uses a nexthop object,
rt6_nlmsg_size() and rt6_fill_node() access the nexthop's RCU protected
nexthop info and group pointers via rcu_dereference_rtnl(), resulting in
suspicious RCU usage splats [1].
Fix by holding RCU while sizing and filling the notification, like
fib_alias_hw_flags_set() already does. Switch to GFP_ATOMIC for the skb
allocation accordingly.
Reproducer:
# echo "10 0" > /sys/bus/netdevsim/new_device
# sysctl -wq net.ipv6.fib_notify_on_flag_change=1
# sysctl -wq net.ipv4.nexthop_compat_mode=1
# ip -6 nexthop add id 1 blackhole
# ip -6 route add 2001:db8:1::1/128 nhid 1
[1]
WARNING: suspicious RCU usage
7.3.0-rc7-virtme-g191aa41548b2 #38 Not tainted
net/ipv4/nexthop.c:1539 suspicious rcu_dereference_check() usage!
[...]
Workqueue: events nsim_fib_event_work
Call Trace:
<TASK>
dump_stack_lvl (lib/dump_stack.c:94 lib/dump_stack.c:120)
lockdep_rcu_suspicious.cold (kernel/locking/lockdep.c:6972)
nexthop_for_each_fib6_nh (net/ipv4/nexthop.c:1539 (discriminator 16))
rt6_nlmsg_size (net/ipv6/route.c:5728)
fib6_info_hw_flags_set (net/ipv6/route.c:6503)
nsim_fib6_rt_add (drivers/net/netdevsim/fib.c:671 drivers/net/netdevsim/fib.c:694)
nsim_fib6_rt_insert (drivers/net/netdevsim/fib.c:759)
nsim_fib_event_work (drivers/net/netdevsim/fib.c:856 drivers/net/netdevsim/fib.c:889 drivers/net/netdevsim/fib.c:1493)
process_one_work (kernel/workqueue.c:3396)
worker_thread (kernel/workqueue.c:3479 kernel/workqueue.c:3560)
kthread (kernel/kthread.c:436)
ret_from_fork (arch/x86/kernel/process.c:158)
ret_from_fork_asm (arch/x86/entry/entry_64.S:245)
</TASK>
Fixes: 907eea486888 ("net: ipv6: Emit notification when fib hardware flags are changed")
Reported-by: Sashiko <netdev-bot+sashiko@kernel.org>
Closes: https://lore.kernel.org/netdev/179152182668.434549.18232968419539498055@kernel.org/
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Eric Dumazet <edumazet@kernel.org>
Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://patch.msgid.link/20261019140337.2886875-2-idosch@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
net.unix.max_dgram_qlen is parsed as a signed int and copied to the u32
sock::sk_max_ack_backlog when an AF_UNIX socket is created. Consequently,
a negative value such as -1 is accepted and converted to UINT_MAX. Since
the receive queue length is also u32, its fullness check cannot become true
for that limit.
max_dgram_qlen has no documented negative sentinel. Its existing signed
interface represents nonnegative values only through INT_MAX; negative bit
patterns are not a supported encoding for the upper half of the u32
consumer range.
Switch to proc_dointvec_minmax and make the established 0..INT_MAX input
range explicit. This rejects negative values without adding new accepted
values or changing the default and zero-value behavior. Very large valid
values can still make the queue limit impractical to reach; this change
corrects the input domain rather than imposing a new resource ceiling.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Yingjie Wang <1075151112@qq.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/tencent_A643419B56079E9A448D97922763FF069F08@qq.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
reg_vif_xmit() hands the skb to ip6mr_cache_report() as an
MRT6MSG_WHOLEPKT report. skb_realloc_headroom() copies skb->cb[]
into the report, which is queued to the mroute socket, where
rawv6_recvmsg() reads it as IP6CB.
By the time the pim6reg device transmits the packet, skb->cb[] is
not IP6CB anymore: qdisc_pkt_len_init() overwrites iif and ra,
and any qdisc installed on the device (fq, fq_codel, pie, cake...)
or a tc BPF program writing skb->cb[] fills the area holding
dst0, srcrt, dst1, lastopt and flags.
Since commit dd433671fef3 ("ipv6: validate extension header length
before copying to cmsg") these stale offsets can no longer cause
out-of-bounds reads, but the mroute socket can still receive bogus
IPV6_PKTINFO ifindex and extension header ancillary data.
Clear IP6CB before building the report. The skb is freed right
after, so nothing else depends on its control block.
Fixes: 14fb64e1f449 ("[IPV6] MROUTE: Support PIM-SM (SSM).")
Signed-off-by: Eric Dumazet <edumazet@kernel.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
__rds_conn_create() calls trans->conn_free() with rds_conn_lock held
and IRQs disabled when it loses the race to insert a connection.
rds_ib_conn_free() takes the device list lock with spin_lock_irq() and
releases it with spin_unlock_irq(), so IRQs are turned on while
rds_conn_lock is still held:
raw_local_irq_restore() called with IRQs enabled
WARNING: kernel/locking/irqflag-debug.c:10 at warn_bogus_irq_restore+0xc/0x20
_raw_spin_unlock_irqrestore+0x67/0x80
__rds_conn_create+0x1de5/0x2290
rds_conn_create_outgoing+0x43/0x60
rds_sendmsg+0xfca/0x20e0
__sys_sendto+0x408/0x5a0
It needs an RDS socket bound to an address on an RDMA device (e.g. rxe)
and two concurrent sendto() calls to the same new destination.
The TCP and loopback ->conn_free() callbacks already use irqsave, so
do the same here.
Fixes: 745cbccac3fe ("RDS: Rewrite connection cleanup, fixing oops on rmmod")
Reported-by: syzbot+c3741bb338b5c6d6a4aa@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=c3741bb338b5c6d6a4aa
Cc: stable@vger.kernel.org
Signed-off-by: Nguyen Ngoc Thang <ngocthang2710.1999@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next
Pablo Neira Ayuso says:
====================
Netfilter updates for net-next
The following patchset contains Netfilter/IPVS updates for net-next:
1) Disable br_netfilter in userns and schedule it for removal in 2027,
from Florian Westphal.
2) Update selftest nft_queue.sh to make it more stable on debug
kernels, from Jakub Kicinski.
3) Fix a overflow in IPVS sync messages which can only happen in very
old 2.6 kernels, from Julian Anastasov.
4) Finer grain packet drop in nfnetlink_queue when dependency objects
are going away, from Antonio Ojea.
5) Add a selftest for the nfnetlink_queue packet drop case, also
from Antonio Ojea.
6) Flush conntrack gc worker when existing netns to address a unlikely
UaF, from Florian Westphal.
7) Switch nf_tables chain types to use rcu, otherwise module removal
can trigger UaF, also from Florian.
8) Remove redundant parsing in nft_exthdr for the tcp options case,
from Fernando F. Mancera.
9) Remove redundant skb_header_pointer() calls in nft_exthdr for tcp
options, from Fernando F. Mancera.
10) Fix conntrack_vrf.sh selftest return value in zone subtest,
from Florian Westphal.
11) Restrict raw table in nft_compat to specific family, hook and
priority, from Florian Westphal.
Prepare the flowtable to support for IPv4 over IPv6 tunneling and
vice-versa, this includes 4 patches from Lorenzo Bianconi.
12) Explicitly set inner protocol when popping header, this is not
needed for the existing IPIP and IP6IP6 case because skb->protocol
remains the same.
13) Simplify tuple tunnel information fill up when parsing outer
tunnel IP headers.
14) Add a new encap_proto which determines the outer tunnel protocol
family.
15) Prepare flowtable forwarding path to deal with mixed IPv4-IPv6
tunnels.
* tag 'nf-next-26-10-18' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next:
netfilter: flowtable: unify tunnel push for IPv4 and IPv6
netfilter: flowtable: add encap_proto to flow_offload_tunnel
netfilter: flowtable: populate tunnel tuple regardless of inner protocol
netfilter: flowtable: set inner protocol when popping tunnel header
netfilter: nft_compat: restrict raw table targets/matches
selftests: netfilter: fix return value in zone subtest
netfilter: nft_exthdr: avoid 60 bytes stack buffer in TCP option mangling
netfilter: nft_exthdr: remove redundant op parsing in tcp_set_init
netfilter: nf_tables: switch chain_types array to rcu
netfilter: conntrack: fix unlikely UaF in gc worker
selftests: netfilter: nft_queue: check the scope of the hook drop flush
netfilter: nf_queue: limit the hook drop flush to the unregistered hook point
ipvs: fix buffer overflow when sending sync messages
selftests: netfilter: nft_queue.sh: only queue icmp echo request/reply
netfilter: disable br_netfilter in user namespaces
====================
Link: https://patch.msgid.link/20261018005638.1776148-1-pablo@netfilter.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
The old test_bpf module is going away, therefore port the two test
cases which were added in 76db8087c4c9 ("net: bpf: add a test for
skb_segment in test_bpf module") as well as cf204a718357 ("bpf,
testing: Introduce 'gso_linear_no_head_frag' skb_segment test")
into the net_test.c to retain coverage. With it in place:
# Subtest: gso_test_func
ok 1 no_gso
ok 2 linear
ok 3 frags
ok 4 frags_pure
ok 5 gso_partial
ok 6 frag_list
ok 7 frag_list_pure
ok 8 frag_list_non_uniform
ok 9 frag_list_head_frag
ok 10 frag_list_no_head_frag
ok 11 gso_by_frags
ok 12 resegment
ok 13 resegment_multi
ok 14 resegment_tail
ok 15 resegment_one_mss
# gso_test_func: pass:15 fail:0 skip:0 total:15
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Cc: Willem de Bruijn <willemb@google.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20261015151033.591439-1-daniel@iogearbox.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
rt6_insert_exception() and rt6_remove_exception() update
rt6_stats->fib_rt_cache of dev_net(rt6i->dst.dev), but the device of an
exception dst can move to another netns while the exception is still in
its bucket.
This happens when the bucket is flushed from an RCU callback, for
instance from nexthop_free_rcu() for the nh_info of a replaced nexthop,
whose exceptions still point to live routes. If the device moves to
another netns before that callback runs, the decrement hits the other
netns, whose u32 counter underflows in /proc/net/rt6_stats, while the
counter of the original netns never goes back down.
Account exceptions to the netns their dst was allocated in, derived from
dst->ops as ip6_dst_gc() already does, which does not depend on the
device. The dst already relies on that netns' ip6_dst_ops being alive
when it is destroyed, which happens after the exception is removed.
Fixes: 81eb8447daae ("ipv6: take care of rt6_stats")
Signed-off-by: Eric Dumazet <edumazet@kernel.org>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20261016091556.2750902-1-edumazet@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
net_devmem_bind_dmabuf() uses dma_buf_attach(), a static attachment
with peer2peer false. Exporters must then keep the buffer reachable
without P2P; amdgpu does so by placing it in GTT (system memory), so a
device memory binding silently ends up in host memory.
Use dma_buf_dynamic_attach() with allow_peer2peer set, so an exporter
that can do P2P to the device keeps the buffer in device memory.
Dynamic attachments are not pinned on map, and devmem cannot handle the
buffer moving, so:
- pin it with dma_buf_pin() before mapping, which keeps it in place for
the lifetime of the binding, as before;
- wait for the exporter's kernel fences after mapping, interruptibly,
as the core does for static attachments.
This follows the pinned RDMA umem path, including its limits: the
binding cannot be revoked by the exporter, and once a P2P binding has
pinned a buffer in device memory, a later attachment to the same buffer
that cannot do P2P may fail to pin it. Exporters that cannot do P2P to
the device place the buffer as before. RX and TX bindings both go
through this function.
Signed-off-by: Erfan Sharafzadeh <erfansh@meta.com>
Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Link: https://patch.msgid.link/20261013210954.2170175-1-erfansh@meta.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
When a port group cannot be created for a new group, the MDB entry that
was created for it is left with no ports and is not joined by the host.
Its timer is never armed, so the entry is never deleted, but it is
counted towards mcast_hash_max. When this maximum is reached, the bridge
disables multicast snooping.
Since commit b57e8d870d52 ("net: bridge: Maintain number of MDB entries
in net_bridge_mcast_port"), port group creation also fails when the port
reached its mcast_max_groups limit. A host behind such a port can
therefore disable snooping by sending reports for new groups, which is
what the limit is meant to prevent. The RTM_NEWMDB path has the same
problem.
Fix by deleting the entry after a failure if it is unused. Delete it
immediately rather than arming its timer, so that it stops counting
towards the maximum right away.
Fixes: b57e8d870d52 ("net: bridge: Maintain number of MDB entries in net_bridge_mcast_port")
Reported-by: Yunlong Ma <yunlong_ma@buaa.edu.cn>
Closes: https://lore.kernel.org/netdev/2f5b61e2.1e71a.1a11fcb3809.Coremail.yunlong_ma@buaa.edu.cn/
Acked-by: Nikolay Aleksandrov <nikolay@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Tested-by: Gabriel Goller <g.goller@proxmox.com>
Reviewed-by: Gabriel Goller <g.goller@proxmox.com>
Link: https://patch.msgid.link/20261016101407.2030133-2-idosch@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
truncating it
The issue:
tcf_dump_walker() trims the half-built nest and returns the number of
actions dumped so far as soon as one action does not fit. When the action
at the current index cannot be serialized even into an *empty* dump skb,
that count is zero, so tc_dump_action() returns skb->len (zero) and
netlink sends NLMSG_DONE with no error: "tc actions ls" silently drops
that action and every action after it.
That case is reachable inside the gate entry cap this series adds: a gate
entry serializes to 36 bytes (40 with the gate-open flag) while a dump skb
is clamped to SKB_WITH_OVERHEAD(32768) by netlink_recvmsg()/netlink_dump(),
so the top of the range the cap admits installs but cannot be dumped -
and, before this change, fails silently.
The Fix:
tcf_dump_walker() already has to distinguish the two cases: a walk that
filled the skb before completing the current action must keep returning a
positive count so netlink retries that action in a fresh skb, while an
action that cannot be serialized even into an empty skb must return
-EMSGSIZE. So return n_i when anything was dumped and -EMSGSIZE (with an
extack) when nothing was, and let tc_dump_action() propagate the walker's
error code instead of overwriting it with skb->len. That mirrors
tc_dump_tfilter(), which returns the walker error when a retry made no
progress (if (skb->len == 0 && err) return err;), and tc_dump_chain()
carries the same idiom. This is netlink's documented contract: -EMSGSIZE
with data in the skb means "more to dump", -EMSGSIZE with an empty skb is
delivered to user space.
Context note:
The shared nla_put_failure label stamps -EMSGSIZE for any inner
tcf_action_dump_1()/terse failure, not only a size failure, consistent
with how every other nla_put_failure label in the file reports; the
-EMSGSIZE the action dump now returns is therefore not a strict size
assertion.
The cap stays a memory bound; this only makes an action the cap admits but
the dump buffer cannot carry fail loudly instead of silently truncating
the list. This is a long-standing silent failure, not a regression, so it
is net-next hardening.
Reported-by: Paul Moses <p@1g4.org>
Closes: https://lore.kernel.org/netdev/vPFrhbkwAui8zFPcGQTUDazQfsFDlr5GYuaYQ5BxJcrDiT6x1EljEze4cYadHqbeUW2ivLdpa8eC_cXC6ceACswgb-lW47aSVkHvHjhn_X8=@1g4.org/
Suggested-by: Paul Moses <p@1g4.org>
Reviewed-by: Victor Nogueira <victor@mojatatu.com>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/QDISC-H19Z.v3.r0.20261012193813-5@mojatatu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
parse_sched_list() accepts _any number_ of TCA_TAPRIO_SCHED_ENTRY
elements. The only bound is the enclosing nlattr u16 nla_len. A minimal
accepted entry is 12 bytes (the entry nest plus
TCA_TAPRIO_SCHED_ENTRY_INTERVAL), so that u16 admits roughly 5460
entries - protocol-bounded amplification, not truly unbounded, but far
past any hardware schedule.
The bug:
Each entry is a separate sched_entry allocation (368 bytes, rounded up
to the kmalloc-512 bucket) and, in full offload, is also composed into a
per-entry offload array, so the largest representable minimal list pins
roughly 2.7 MiB for the lifetime of the schedule.
Some context:
The schedule list is not dumped the way the gate action list is: a
taprio dump is bounded by the carrying skb (the 32K dump skb, and
NLMSG_GOODSIZE for notify and unicast get), which keeps the plain
nla_nest_end() closes from ever seeing a wrapped length. But the
input-side amplification is the same class as the act_gate entry list,
and the offload interface composes every supplied entry into the
hardware schedule table without a capacity check.
The top of the accepted band cannot be read back: a schedule above
roughly 900 entries does not fit the 32K dump skb, so "tc qdisc show"
fails loudly with -EMSGSIZE for it (as the action-dump patch does). The
pre-existing silent gaps - no change notification above about 100
entries, and no unicast get reply - are tracked separately.
The Cap:
Cap the list at 1024 entries. This matches the SJA1105 schedule-table
capacity (SJA1110 provides 4096) and the act_gate entry cap, and keeps
the list inside the current 16-bit TLV format.
This is an operational cap on a configuration the uAPI accepted before,
so it is net-next hardening; a stable backport would start rejecting
taprio configurations that install today.
Conditions to recreate the bug:
CAP_NET_ADMIN with CONFIG_NET_SCH_TAPRIO=y. Install a taprio qdisc with
more than 1024 minimal TCA_TAPRIO_SCHED_ENTRY elements over a raw
netlink RTM_NEWQDISC request. The cap rejects the list with -E2BIG and
an extack naming the limit; 1024 entries install.
Reviewed-by: Victor Nogueira <victor@mojatatu.com>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/QDISC-H19Z.v3.r0.20261012193813-4@mojatatu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
parse_gate_list() accepts _any number_ of TCA_GATE_ONE_ENTRY elements.
The only bound/cap is the enclosing nlattr u16 nla_len (~5460
minimal 12-byte entries). Each entry is a separate GFP_ATOMIC
allocation, and the dump of a large list grows one action's reply well
past NLMSG_GOODSIZE.
The bugs:
1. A single gate can make tcf_dump_walker() silently truncate
"tc actions ls" ("net/sched: act_api: report an oversized action dump
instead of silently truncating it" makes such an action report -EMSGSIZE
instead of dropping the rest of the list).
2. Lack of capping pins memory for as long as the action lives: the
largest representable minimal list is roughly 5460 entries, each a
separate GFP_ATOMIC allocation, with a per-entry offload array on top in
full offload. The held-reply RTM_GETACTION amplification demonstrated in
the original posting of this series (Link below) is a generic netlink
property this cap does not remove; the bound added here is the install-side
pin.
So we need to provide an upper bound cap of TCA_GATE_ONE_ENTRY elements.
Some context:
The gate action offloads through FLOW_ACTION_GATE. The offload
interface passes the priority, base time, cycle time, cycle-time
extension, the complete entry count and an array holding each entry's
gate state, interval, IPV and maximum-octet value. The in-tree SJA1105
DSA driver forwards that complete list to sja1105_vl_gate() without any
entry cap check, and composes every supplied entry into the hardware
schedule table.
Act gate challenges:
SJA1105 and SJA1110 are two device families in the one sja1105 driver.
They expose different schedule-table capacities: SJA1105 provides up to
1024 schedule entries and SJA1110 up to 4096. These are total table
capacities shared with other schedules, so they are upper bounds, not a
guaranteed per-action budget. Software gate actions with _a lot more_
entries install and serialize today, so a low cap would reject working
configurations and would look like a UAPI breakage; but an infinite size
of entries is a bogus choice; a 65-entry configuration was verified
during this work to install and dump well-formed.
Netlink Challenges:
Netlink attributes record their total size, including the four-byte
header, in a 16-bit nla_len, so a nested attribute can describe at most
65532 bytes. A minimal accepted input entry is 12 bytes, which puts the
max we can fit at roughly 5460 entries; a dumped entry occupies 36 bytes,
or 40 bytes when it carries the gate-open flag.
1024 entries therefore serialize to 36868-40964 bytes, which fits
inside one nested attribute, while a 4096-entry schedule would need
roughly 144-160 KiB which _cannot fit_ at the moment due to the 16bit
length.
Note: This represents challenges primarily with netlink.
The Cap:
Cap the list at 1024 entries. This value is based on the existing
SJA1105 schedule-table capacity and preserves the verified 65-entry
configuration while providing a substantial headroom, and keeps the
complete gate list inside the current 16-bit TLV format. It
deliberately declines to expose SJA1110's 1025-4096 range through
an interface that cannot serialize it, and deliberately rejects
software-only schedules above 1024.
Why 1024 despite the dump budget:
1024 is a SJA1105 schedule-table capacity, not a dump-budget value. The
kernel clamps a dump skb to SKB_WITH_OVERHEAD(32768), so only ~800-890
entries of this list fit "tc actions ls"; the top of the admitted band
therefore installs but is not listed. That is accepted deliberately:
a unicast RTM_GETACTION reply is pre-sized from the action's advertised
size (budgeted per entry since the parent fix), so "tc actions get"
enumerates the whole band, and "net/sched: act_api: report an oversized
action dump instead of silently truncating it" makes the list view fail
loudly with -EMSGSIZE and an extack rather than silently truncating. A
filter whose action list contains such a gate also stops "tc filter show"
for that chain with -EMSGSIZE (loud), through tc_dump_tfilter()'s
no-progress path.
This is an operational cap on a configuration the uAPI accepted before,
so it is net-next hardening; if we made this a stable backport then
it would start rejecting gate configurations that install today (even
though those settings would be totally bogus).
Conditions to recreate the bug:
CAP_NET_ADMIN with CONFIG_NET_ACT_GATE=y. Install a gate
action with 1025 or more minimal TCA_GATE_ONE_ENTRY elements over a raw
netlink RTM_NEWACTION request. The cap rejects the list with -E2BIG and
an extack naming the limit; 1024 entries install and an indexed
RTM_GETACTION returns a well-formed reply.
Link: https://lore.kernel.org/netdev/QDISC-H19Z.v1.20261001053234@mojatatu.com/
Reviewed-by: Victor Nogueira <victor@mojatatu.com>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/QDISC-H19Z.v3.r0.20261012193813-3@mojatatu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
Spotted while fixing the dump sizing reported by Sashiko. This references
commit cfa165cbfbed ("net/sched: act_gate: budget the per-entry list in
get_fill_size"), which is only one way to trigger the issue.
The issue:
tcf_action_add() returns the result of tcf_add_notify(), so an
RTM_NEWACTION is reported back to user space as a failure when the event
notification cannot be built, even though tcf_action_init() has already
inserted the actions into the idr. The realistic trigger is an action
list whose TCA_ACT_TAB exceeds a u16 nest (the notification can never be
built), or a memory-pressure -ENOBUFS from the notification's alloc_skb().
The Fix:
Drop the notification failure on the add path: the created actions
stay installed and the add reports success, with an extack noting that
the event notification could not be sent. The extack is set on a
successful ack, so iproute2 reports it as a warning; it replaces any
warning tcf_action_init() left there. This needs no idr/refcount
audit - tca_put_bound_many() already runs unconditionally after the
notification, so this path releases exactly what the success path does
and only the returned result changes. A create that ignores a
notification failure is already the filter-side norm: tc_new_tfilter()
does not look at tfilter_notify()'s result.
This is net-next hardening: it corrects the reported result of an add
that already took effect, not a regression.
Conditions to recreate the bug:
CONFIG_NET_CLS_ACT=y; CONFIG_NET_ACT_GATE=y. Send an RTM_NEWACTION whose
actions create an aggregate TCA_ACT_TAB larger than a u16 nest, so the
notification cannot be built; before this change the add reports -EINVAL
although the actions were installed, after it the add reports success and
the actions are present.
Reported-by: Sashiko (nipa) <sashiko-bot@kernel.org>
Closes: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260824153903.4143642-1-victor@mojatatu.com
Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/QDISC-H19Z.v2.20261007062551%40mojatatu.com
Reviewed-by: Victor Nogueira <victor@mojatatu.com>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/QDISC-H19Z.v3.r0.20261012193813-2@mojatatu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
This is a followup of commit cfa165cbfbed ("net/sched: act_gate: budget
the per-entry list in get_fill_size") as reported by Sashiko.
The issue:
An action dump is carried inside nested netlink attributes whose lengths
are u16. A gate action with enough schedule entries produces a dump
larger than U16_MAX, and the plain nla_nest_end() closes by writing a
wrapped length: the reply is structurally corrupt. On a CONFIG_DEBUG_NET
kernel a plain nla_nest_end() also warns (DEBUG_NET_WARN_ON_ONCE warns
once per call site), which an unprivileged RTM_GETACTION or
RTM_GETTFILTER can reach once the action or filter exists.
The oversized dump also reaches the filter notification path through
tcf_fill_node(), which reports the failure as -EMSGSIZE.
tfilter_notify_prep() treats that as socket-buffer exhaustion and
retries with an ever larger alloc_skb(); a dump that does not fit a u16
nest cannot be built at any skb size, so the loop only spins until the
allocation itself fails.
The Fix:
Close every wrap-capable nest an action dump travels in with
nla_nest_end_safe(), which reports -EMSGSIZE before writing a wrapped
length: TCA_GATE_ENTRY_LIST, TCA_ACT_OPTIONS, the per-action nest and
TCA_ACT_TAB; the shared action and police containers in
tcf_exts_dump()/tcf_exts_terse_dump(); and the caller-owned TCA_OPTIONS
of every action-capable classifier (flower, matchall, basic, bpf,
cgroup, flow, fw, route4, u32). The output is byte identical for every
message that serializes. Bound the tfilter_notify_prep() retry once the
skb is already larger than any valid message, while a regular dump that
only needs a bigger skb still retries.
The retry bound and the checked closes are one change: it is
nla_nest_end_safe() that turns an unrepresentable dump into -EMSGSIZE,
so a backport has to take both together if either is taken.
Context note:
A delete notification that cannot be built must not veto the state
change the caller asked for. Two delete paths built the notification
before the state change and propagated the build failure.
tfilter_del_notify() builds the filter's delete notification before
calling ->delete(), so a filter whose dump cannot be represented in a u16
nest could be created but never removed by "tc filter del ... handle H" -
and only when a notification was actually needed (rtnl_notify_needed():
an RTNLGRP_TC listener or NLM_F_ECHO), which made it intermittent.
tcf_del_notify() has the same shape for RTM_DELACTION: it builds the
notification before tcf_action_delete(), so an action list whose
TCA_ACT_TAB exceeds a u16 nest could not be deleted either. In both cases
drop the unbuildable notification instead: on -EMSGSIZE the delete
proceeds. This needs tca_get_fill() and tcf_del_notify_msg() to pass
-EMSGSIZE up instead of collapsing it to -1/-EINVAL, and tca_get_fill()
reports any inner tcf_action_dump() failure as -EMSGSIZE too
(tcf_gate_dump() and tcf_action_dump_1() return plain -1 after one of
their checked closes fails), so a single oversized action's delete is not
vetoed either. On the delete paths the rule is scoped to notification
BUILD failures: a
delivery failure after the state change (rtnetlink_send() failing once
->delete() has already committed) still reports an error to the caller,
as it did before this series. The extack that notes a dropped filter
event is set only after ->delete() has returned 0.
-EMSGSIZE here is the general tcf_fill_node() outcome for any ->dump()
that does not fit, not only a u16 nest overflow; the effect of the new
branch is limited to dropping a best-effort notification.
why net-next?
This is hardening rather than a regression fix: the enclosing action and
filter-path nests have wrapped since the actions and classifiers allowed
large entry lists - TCA_ACT_TAB is core act_api and the filter-side
container predates the act_gate sizing change. A plain nla_nest_end()
has always written the wrapped length at U16_MAX; this stops the
corruption at the abstraction boundary instead of imposing a new policy
limit on accepted gate schedules. A separate patch caps the entry list
itself.
Conditions to recreate the bug:
CONFIG_NET_CLS_ACT=y; CONFIG_NET_ACT_GATE=y;
CONFIG_NET_CLS_MATCHALL=y and/or CONFIG_NET_CLS_BASIC=y. Create a
matchall or basic filter on an ingress/clsact qdisc whose action list
holds two gate actions of 1024 minimal TCA_GATE_ONE_ENTRY elements
each (TCA_ACT_MAX_PRIO admits up to 32 actions); the aggregate
TCA_ACT_TAB nest is ~74.3 KiB > 65532 and wraps, then RTM_GETTFILTER
it (or trigger the notify with NLM_F_ECHO).
The same shape as two standalone gate actions is hit on the action path
by RTM_DELACTION with NLM_F_ECHO; before this change the fill fails and
the delete is refused, after it the actions are removed and only the
notification is dropped.
For a single action the outermost TCA_ACT_TAB wraps from 1815 entries
(1821 for the innermost TCA_GATE_ENTRY_LIST); on the filter path the
outermost wrap-capable nest is the classifier's TCA_OPTIONS. Installing
needs CAP_NET_ADMIN in a user namespace; the RTM_GETTFILTER trigger needs
no capability once it exists. The two-action shape survives the
per-action cap added by "net/sched: act_gate: cap the number of scheduling
entries": the enclosing nests overflow from aggregate action size, which
no per-action cap can bound.
Reported-by: Sashiko (nipa) <sashiko-bot@kernel.org>
Closes: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260824153903.4143642-1-victor@mojatatu.com
Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/QDISC-H19Z.v2.20261007062551%40mojatatu.com
Link: https://lore.kernel.org/netdev/QDISC-H19Z.v2.20261007062551@mojatatu.com/
Link: https://lore.kernel.org/netdev/QDISC-H19Z.v1.20261001053234@mojatatu.com/
Link: https://lore.kernel.org/netdev/179111893181.434549.13449660670267048994@kernel.org/
Reviewed-by: Victor Nogueira <victor@mojatatu.com>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/QDISC-H19Z.v3.r0.20261012193813-1@mojatatu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
tls_device_rx_resync_new_rec() can run in process context with the
socket lock held, but without an RCU read lock: from the strparser work
item (tls_strp_work()) and from the receive paths (tls_rx_rec_wait(),
tls_rx_rec_done()). The resync_async pointer belongs to the driver RX
context, which tls_device_down() tears down from the netdev notifier
without taking the socket lock; only the softirq entry to the parser is
implicitly inside an RCU section.
If the parser passes the TLS_RX_DEV_DEGRADED check before device-down
sets it, tls_device_down() can complete synchronize_net() and delete the
driver context before the parser accesses resync_async->req or its
record log. In the asynchronous stage the parser also writes the record
log, so this is a write to freed memory, not only a stale read. The RCU
section in tls_device_resync_rx() starts after those accesses and
therefore does not prevent the use-after-free.
Found by code inspection; not reproduced. Hitting the window requires
the parser to be preempted between the DEGRADED check and the
resync_async access across the device-down grace period and the
driver's teardown.
Fixes: ed9b7646b06a ("net/tls: Add asynchronous resync")
Signed-off-by: Rishikesh Jethwani <rjethwani@purestorage.com>
Link: https://patch.msgid.link/20261013213517.2219663-1-rjethwani@purestorage.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
tcp_get_metrics(), __tcp_get_metrics_req() and tcpm_new() look up and
create metrics entries in the netns of the cached dst device rather than
in the netns of the socket.
These usually match, but not after the device has been moved to another
netns or unregistered: a socket can keep a stale dst in sk_dst_cache
until it is checked again, and tcp_update_metrics() reads it with
__sk_dst_get() without any dst_check(). Once dst_dev_put() has run, the
dst device is blackhole_netdev and the entry is created in init_net.
Before that, for instance for routes through nexthop objects whose
cached dsts are released from a nested RCU callback, it is the netns the
device has just been moved to.
A TCP socket of netns A that enters TIME_WAIT in that window then
creates or updates an entry carrying A's addresses and RTT in another
netns, where TCP_METRICS_CMD_GET can dump it and where new connections
to the same peer inherit those metrics.
The metrics belong to the netns of the socket, so use sock_net() for
full sockets and request sockets, and pass it to tcpm_new().
Kernel sockets that do not hold a netns reference can still reach
tcp_time_wait() after tcp_net_metrics_exit_batch() has flushed the
entries of their dismantling netns, and an entry created then would
never be flushed and would keep a dangling tcpm_net. Make tcpm_new()
refuse to create entries when check_net() fails. Its callers are in
an RCU read-side section, and cleanup_net() waits for a grace period
between the refcount reaching zero and the flush, so an entry added
after a successful check is always seen by the flush.
Fixes: 51c5d0c4b169 ("tcp: Maintain dynamic metrics in local cache.")
Signed-off-by: Eric Dumazet <edumazet@kernel.org>
Cc: Qiliang Yuan <odys.yuan@gmail.com>
Reviewed-by: Neal Cardwell <ncardwell@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20261016084802.2725187-1-edumazet@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
addrconf_dad_failure() can create a stable-privacy replacement without
RTNL. After ipv6_add_addr() publishes it, addrconf_ifdown() can mark the
new ifaddr DEAD, clear its route, and unlink it before the recovery path
takes ifp2->lock.
The recovery path then unconditionally changes the state back to PREDAD
and queues delayed DAD work. The MTU teardown path can leave IF_READY
set. For an optimistic address, addrconf_dad_begin() can consequently
pass the cleared NULL route to ip6_ins_rt().
This follow-on was found by source review and was not separately
triggered at runtime.
The new ifaddr is already initialized in PREDAD. Under ifp2->lock, record
the retry and queue DAD only if teardown has not changed the state to
DEAD. If teardown wins after this check, the work observes DEAD and exits
without reviving the address.
This complements the existing lock_errdad check that preserves the original
ifaddr's DEAD state after the same function reacquires its lock.
Fixes: 5f40ef77adb2 ("ipv6: do retries on stable privacy addresses")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <netdev-bot+sashiko@kernel.org>
Closes: https://lore.kernel.org/r/179161099408.434549.14449036924552933828@kernel.org
Link: https://lore.kernel.org/r/20260513025509.3776405-1-lilinmao@kylinos.cn
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20261015050651.1841557-5-4ncienth@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
ipv6_create_tempaddr() holds a reference to the public ifaddr, publishes
the new temporary address through ipv6_add_addr(), and only then stores
the reference and final timestamps.
addrconf_ifdown() can remove the temporary address before ifpub is
stored, leaking the public ifaddr reference. Publishing ifpub alone is
insufficient: manage_tempaddrs() can then find the object before cstamp
and tstamp are final, update its lifetimes, and have the constructor
overwrite its timestamp with an older value.
This follow-on was found by source review and was not separately
triggered at runtime.
Pass the public ifaddr and both timestamps in ifa6_config. Initialize all
three fields before adding the temporary address to either the hash or
per-device lists. On success the existing public-ifaddr reference
transfers to the temporary object. On error it remains owned and released
by ipv6_create_tempaddr().
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <netdev-bot+sashiko@kernel.org>
Closes: https://lore.kernel.org/r/179122559913.434549.12720841717630168470@kernel.org
Link: https://lore.kernel.org/r/179161099665.434549.5858601179492551889@kernel.org
Link: https://lore.kernel.org/r/20261007164548.GA1153540@shredder
Link: https://lore.kernel.org/r/20261012145240.GA779501@shredder
Suggested-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20261015050651.1841557-4-4ncienth@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
ipv6_add_addr() checks idev state before allocating an ifaddr, but
publishes the object later. addrconf_ifdown() can mark and detach the
idev between the check and publication.
This happens when a non-loopback device MTU falls below IPV6_MIN_MTU. A
forced interleaving published an address on a dead idev, and
ipv6_get_ifaddr() still returned it after teardown. Later device deletion
remained blocked with:
unregister_netdevice: waiting for ac0 to become free. Usage count = 3
Protect the dead indication with idev->lock and keep that lock across
both hash and device-list publication. Recheck dead before publishing;
if teardown wins the lock, reject the unpublished object.
Non-unregister teardown does not set dead. The preceding change covers an
add that misses the initial hash scan but reaches the per-device list
snapshot. Both changes are required when backporting this fix.
Fixes: 8814c4b53381 ("[IPV6] ADDRCONF: Convert addrconf_lock to RCU.")
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/179161099408.434549.14449036924552933828@kernel.org
Link: https://lore.kernel.org/r/20261012145306.GB779501@shredder
Suggested-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20261015050651.1841557-3-4ncienth@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
addrconf_ifdown() clears the address hash before snapshotting the
per-device address list. A concurrent ipv6_add_addr() can publish an
address after the hash scan and before the list snapshot.
The ifdown path then removes the address from the device list and drops
the list-owned reference while it is still linked in the hash. Once the
remaining references are released, inet6_ifa_finish_destroy() warns, but
a DEAD address continues to kfree_rcu(). The hash therefore points to
freed memory that later RCU walkers can dereference.
This follow-on was found by source review and was not separately
triggered at runtime.
Remove each non-kept address from the hash immediately before removing
it from the per-device list. Keeping it hashed through the delete
notification blocks same-address publication until NETDEV_DOWN has been
delivered. hlist_del_init_rcu() is safe when the earlier hash scan
already removed the address.
This handles a late publisher captured by the list snapshot. The next
change serializes publication with teardown so an add cannot miss both
observations. Both changes are required when backporting the complete fix.
Fixes: 73a8bd74e261 ("ipv6: Revert 'administrative down' address handling changes.")
Cc: stable@vger.kernel.org
Reported-by: Ido Schimmel <idosch@nvidia.com>
Link: https://lore.kernel.org/r/20261004135117.GA206930@shredder
Link: https://lore.kernel.org/r/179161099539.434549.2238120015372268173@kernel.org
Suggested-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20261015050651.1841557-2-4ncienth@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
neigh_periodic_work() reschedules tbl->gc_work with a delay of
BASE_REACHABLE_TIME >> 1.
neigh_table is now per-netns, and a user could hog CPU by setting
BASE_REACHABLE_TIME to a small value.
Unlike INTERVAL_PROBE_TIME_MS, BASE_REACHABLE_TIME is also used to
compute reachable_time for NUD_REACHABLE entries.
Let's floor only the GC interval at 1 second.
Suggested-by: Ido Schimmel <idosch@nvidia.com>
Link: https://lore.kernel.org/netdev/20260902143023.GA3966681@shredder/
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20261013205816.1642597-6-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
Previously, neigh_managed_work() was not rescheduled within
1s since commit ed6cd6a17896 ("net, neigh: Set lower cap for
neigh_managed_work rearming").
Later, commit 211da42eaa45 ("net, neigh: introduce
interval_probe_time_ms for periodic probe") added
INTERVAL_PROBE_TIME_MS and changed the limit to 1ms.
The limit actually did not work but was fixed with
netlink_range_validation by commit 6d79b223ec44 ("neighbour:
Enforce min/max to NDTPA_INTERVAL_PROBE_TIME_MS.").
neigh_table is now per-netns, and a user could hog CPU by setting
INTERVAL_PROBE_TIME_MS to a small value.
Let's floor the value at 1 second.
This is a user-visible change, but given we had the 1s floor before
and the default is 5s, it is unlikely that anyone but syzbot is
setting it below 1s and affected by this change.
Suggested-by: Ido Schimmel <idosch@nvidia.com>
Link: https://lore.kernel.org/netdev/20260902143023.GA3966681@shredder/
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20261013205816.1642597-5-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
neigh_table is now per-netns.
tbl->managed_work is scheduled when netns is created and runs
periodically even though the netns does not have any NTF_MANAGED
entries.
Let's delay scheduling the work for the first NTF_MANAGED entry
and stop rescheduling if tbl->managed_list is empty.
Suggested-by: Ido Schimmel <idosch@nvidia.com>
Link: https://lore.kernel.org/netdev/20260902143023.GA3966681@shredder/
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20261013205816.1642597-4-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
The SCTP checksum is a CRC32c over the whole SCTP packet. set_sctp()
updates it as old_csum ^ old_correct_csum ^ new_csum, with the two CRCs
computed over the bytes of the current skb only. That is correct only
when the skb holds the whole SCTP packet. For a first fragment, and for
a later fragment, it holds just a part of it, and the CRC delta of a
change at the start of the packet depends on how many bytes follow, so
the checksum written is wrong. The receiver drops the reassembled
packet.
validate_set() accepts SCTP set action for any flow with ip.proto set to
SCTP, regardless of the fragmentation bits, as it only receives the
masked key. As the checksum cannot be fixed up without the whole
datagram, fail the action for packets that are IP fragments of either
family, so the packet is dropped with OVS_DROP_ACTION_ERROR instead of
being forwarded with modified ports and an invalid checksum.
Link: https://lore.kernel.org/netdev/d4fc14f3-4308-4560-9012-43c09c1b3845@ovn.org/
Fixes: a175a723301a ("openvswitch: Add SCTP support")
Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
Reviewed-by: Ilya Maximets <i.maximets@ovn.org>
Link: https://patch.msgid.link/20261015124749.4694-2-fmancera@suse.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
An IPv4 later fragment carries no L4 header, but key extraction leaves
ip.proto set to the real protocol and the flow may wildcard the frag
field, so validate_set() accepts such packets. set_tcp() and set_udp()
then treat the first bytes of the fragment payload as an L4 header,
rewrite them as ports and patch the bytes at the checksum offset,
corrupting the packet.
Skip these actions for OVS_FRAG_TYPE_LATER. IPv6 later fragments are not
affected, since their ip.proto is NEXTHDR_FRAGMENT and validate_set()
rejects L4 set actions for them.
Fixes: ccb1352e76cf ("net: Add Open vSwitch kernel components.")
Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
Reviewed-by: Ilya Maximets <i.maximets@ovn.org>
Link: https://patch.msgid.link/20261015124749.4694-1-fmancera@suse.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
skb_unshare() only copies cloned skbs. A shared skb that is not a clone
comes back unchanged, which the name doesn't suggest. The loopback
selftest hooks got caught by this and hit BUG_ON(skb_shared()).
Rename it to skb_unclone_full(). Like skb_unclone() it only acts on
clones, but it copies the whole skb, not just the head.
Suggested-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>
Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com> # dpaa2
Link: https://patch.msgid.link/20261015-nb-skb-unclone-full-v1-1-0dfbf01f60f2@tipi-net.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
rtnl_unregister_all() and rtnl_af_unregister() wait for RCU readers
before tearing down what those readers use, but do not say which
readers they are waiting for.
A missing wait is then easy to overlook: rtnl_link_unregister() lacked
its synchronize_rcu() until commit 3b70edea393d ("rtnetlink: wait for
RCU readers in rtnl_link_unregister()"). Add a comment to both waits,
naming the readers each one waits for.
Suggested-by: Eric Dumazet <edumazet@kernel.org>
Link: https://lore.kernel.org/CAL4WiioFMQN4troVjQjCmE6Z9kwwb95SnoEupjD=PPSK6Q5f6w@mail.gmail.com
Assisted-by: LLM
Signed-off-by: Andrea Parri <parri.andrea@gmail.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20261015081723.404990-1-parri.andrea@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|