* [PATCH net v2] vxlan: fix NULL vn6_sock dereference in vxlan_igmp_join() and vxlan_igmp_leave()
From: Weiming Shi @ 2026-04-18 11:41 UTC (permalink / raw)
To: Andrew Lunn, David S . Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: Roopa Prabhu, netdev, Xiang Mei, Weiming Shi
vxlan_sock_add() tolerates IPv6 socket creation failure with
-EAFNOSUPPORT (e.g. ipv6.disable=1), leaving vn6_sock as NULL while
successfully creating vn4_sock. vxlan_igmp_join() and
vxlan_igmp_leave() then crash when they dereference the NULL vn6_sock
for VNI filter entries with IPv6 multicast groups:
Oops: general protection fault, probably for non-canonical address
0xdffffc0000000002: 0000 [#1] SMP KASAN NOPTI
KASAN: null-ptr-deref in range [0x0000000000000010-0x0000000000000017]
RIP: 0010:vxlan_igmp_join (drivers/net/vxlan/vxlan_multicast.c:40)
Call Trace:
vxlan_multicast_join (drivers/net/vxlan/vxlan_multicast.c:195)
vxlan_open (drivers/net/vxlan/vxlan_core.c:2965)
__dev_open (net/core/dev.c:1704)
__dev_change_flags (net/core/dev.c:9781)
do_setlink.isra.0 (net/core/rtnetlink.c:3180)
rtnl_newlink (net/core/rtnetlink.c:4238)
rtnetlink_rcv_msg (net/core/rtnetlink.c:6921)
Skip the IPv6 multicast join/leave when vn6_sock is NULL, consistent
with how vxlan_sock_add() tolerates missing IPv6 support.
Fixes: f9c4bb0b245c ("vxlan: vni filtering support on collect metadata device")
Reported-by: Xiang Mei <xmei5@asu.edu>
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
---
v2:
- drop sock4 NULL checks
drivers/net/vxlan/vxlan_multicast.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/net/vxlan/vxlan_multicast.c b/drivers/net/vxlan/vxlan_multicast.c
index a7f2d67dc61b..e6aa5ab1c939 100644
--- a/drivers/net/vxlan/vxlan_multicast.c
+++ b/drivers/net/vxlan/vxlan_multicast.c
@@ -37,6 +37,9 @@ int vxlan_igmp_join(struct vxlan_dev *vxlan, union vxlan_addr *rip,
} else {
struct vxlan_sock *sock6 = rtnl_dereference(vxlan->vn6_sock);
+ if (!sock6)
+ return 0;
+
sk = sock6->sock->sk;
lock_sock(sk);
ret = ipv6_stub->ipv6_sock_mc_join(sk, ifindex,
@@ -71,6 +74,9 @@ int vxlan_igmp_leave(struct vxlan_dev *vxlan, union vxlan_addr *rip,
} else {
struct vxlan_sock *sock6 = rtnl_dereference(vxlan->vn6_sock);
+ if (!sock6)
+ return 0;
+
sk = sock6->sock->sk;
lock_sock(sk);
ret = ipv6_stub->ipv6_sock_mc_drop(sk, ifindex,
--
2.43.0
^ permalink raw reply related
* Re: [RFC PATCH v4 01/19] landlock: Support socket access-control
From: Mikhail Ivanov @ 2026-04-18 11:29 UTC (permalink / raw)
To: Günther Noack
Cc: mic, gnoack, willemdebruijn.kernel, matthieu,
linux-security-module, netdev, netfilter-devel, yusongping,
artem.kuzin, konstantin.meskhidze
In-Reply-To: <af464773-b01b-f3a4-474d-0efb2cfae142@huawei-partners.com>
On 11/22/2025 2:13 PM, Mikhail Ivanov wrote:
> On 11/22/2025 1:49 PM, Günther Noack wrote:
>> On Tue, Nov 18, 2025 at 09:46:21PM +0800, Mikhail Ivanov wrote:
>>> +/**
>>> + * struct landlock_socket_attr - Socket protocol definition
>>> + *
>>> + * Argument of sys_landlock_add_rule().
>>> + */
>>> +struct landlock_socket_attr {
>>> + /**
>>> + * @allowed_access: Bitmask of allowed access for a socket protocol
>>> + * (cf. `Socket flags`_).
>>> + */
>>> + __u64 allowed_access;
>>> + /**
>>> + * @family: Protocol family used for communication
>>> + * (cf. include/linux/socket.h).
>>> + */
>>> + __s32 family;
>>> + /**
>>> + * @type: Socket type (cf. include/linux/net.h)
>>> + */
>>> + __s32 type;
>>> + /**
>>> + * @protocol: Communication protocol specific to protocol family
>>> set in
>>> + * @family field.
>>
>> This is specific to both the @family and the @type, not just the @family.
>>
>>> From socket(2):
>>
>> Normally only a single protocol exists to support a particular
>> socket type within a given protocol family.
>>
>> For instance, in your commit message above the protocol in the example
>> is IPPROTO_TCP, which would imply the type SOCK_STREAM, but not work
>> with SOCK_DGRAM.
>
> You're right.
>
I revised the socket(2) semantics and this part is about that kernel
maps (family, type, 0) to the default protocol of given family and type.
Eg. (AF_INET, SOCK_STREAM, 0) is mapped to (AF_INET, SOCK_STREAM,
IPPROTO_TCP). I would like to clarify that such mapping is taking place
in landlock_socket_attr.protocol field doc.
There should be list of protocols defined per protocol family. From
socket(2):
The domain argument specifies a communication domain.
...
The protocol number to use is specific to the “communication
domain” in which communication is to take place.
Such mapping allows to define strange socket rules if setting @type=-1.
For example:
struct landlock_socket_attr attr = {
.family = AF_INET,
.type = -1,
.protocol = 0,
};
This definition corresponds to (AF_INET, SOCK_STREAM, 0->IPPROTO_TCP)
and to (AF_INET, SOCK_DGRAM, 0->IPPROTO_UDP).
I don't see this as a bad thing as far as there is proper documentation
for landlock_socket_attr.
^ permalink raw reply
* [PATCH net] net/packet: fix TOCTOU race on mmap'd vnet_hdr in tpacket_snd()
From: Bingquan Chen @ 2026-04-18 11:20 UTC (permalink / raw)
To: Willem de Bruijn, Greg KH
Cc: Stephen Hemminger, security, David S . Miller, Jakub Kicinski,
Eric Dumazet, netdev, Bingquan Chen
In-Reply-To: <2026041858-estimator-shower-0f16@gregkh>
In tpacket_snd(), when PACKET_VNET_HDR is enabled, vnet_hdr points
directly into the mmap'd TX ring buffer shared with userspace. The
kernel validates the header via __packet_snd_vnet_parse() but then
re-reads all fields later in virtio_net_hdr_to_skb(). A concurrent
userspace thread can modify the vnet_hdr fields between validation
and use, bypassing all safety checks.
The non-TPACKET path (packet_snd()) already correctly copies vnet_hdr
to a stack-local variable. All other vnet_hdr consumers in the kernel
(tun.c, tap.c, virtio_net.c) also use stack copies. The TPACKET TX
path is the only caller of virtio_net_hdr_to_skb() that reads directly
from user-controlled shared memory.
Fix this by copying vnet_hdr from the mmap'd ring buffer to a
stack-local variable before validation and use, consistent with the
approach used in packet_snd() and all other callers.
Fixes: 1d036d25e560 ("packet: tpacket_snd gso and checksum offload")
Signed-off-by: Bingquan Chen <patzilla007@gmail.com>
---
net/packet/af_packet.c | 21 +++++++++++++--------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 4b043241fd56..8e6f3a734ba0 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -2718,7 +2718,8 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
{
struct sk_buff *skb = NULL;
struct net_device *dev;
- struct virtio_net_hdr *vnet_hdr = NULL;
+ struct virtio_net_hdr vnet_hdr;
+ bool has_vnet_hdr = false;
struct sockcm_cookie sockc;
__be16 proto;
int err, reserve = 0;
@@ -2819,16 +2820,20 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
hlen = LL_RESERVED_SPACE(dev);
tlen = dev->needed_tailroom;
if (vnet_hdr_sz) {
- vnet_hdr = data;
data += vnet_hdr_sz;
tp_len -= vnet_hdr_sz;
- if (tp_len < 0 ||
- __packet_snd_vnet_parse(vnet_hdr, tp_len)) {
+ if (tp_len < 0) {
+ tp_len = -EINVAL;
+ goto tpacket_error;
+ }
+ memcpy(&vnet_hdr, data - vnet_hdr_sz, sizeof(vnet_hdr));
+ if (__packet_snd_vnet_parse(&vnet_hdr, tp_len)) {
tp_len = -EINVAL;
goto tpacket_error;
}
copylen = __virtio16_to_cpu(vio_le(),
- vnet_hdr->hdr_len);
+ vnet_hdr.hdr_len);
+ has_vnet_hdr = true;
}
copylen = max_t(int, copylen, dev->hard_header_len);
skb = sock_alloc_send_skb(&po->sk,
@@ -2865,12 +2870,12 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
}
}
- if (vnet_hdr_sz) {
- if (virtio_net_hdr_to_skb(skb, vnet_hdr, vio_le())) {
+ if (has_vnet_hdr) {
+ if (virtio_net_hdr_to_skb(skb, &vnet_hdr, vio_le())) {
tp_len = -EINVAL;
goto tpacket_error;
}
- virtio_net_hdr_set_proto(skb, vnet_hdr);
+ virtio_net_hdr_set_proto(skb, &vnet_hdr);
}
skb->destructor = tpacket_destruct_skb;
--
2.53.0
^ permalink raw reply related
* Re: [PATCH net] ipv6: Apply max_dst_opts_cnt to ip6_tnl_parse_tlv_enc_lim
From: Justin Iurman @ 2026-04-18 10:59 UTC (permalink / raw)
To: Daniel Borkmann, kuba
Cc: edumazet, dsahern, tom, willemdebruijn.kernel, idosch, pabeni,
netdev
In-Reply-To: <20260417220358.693101-1-daniel@iogearbox.net>
On 4/18/26 00:03, Daniel Borkmann wrote:
> Commit 47d3d7ac656a ("ipv6: Implement limits on Hop-by-Hop and
> Destination options") added net.ipv6.max_{hbh,dst}_opts_{cnt,len}
> and applied them in ip6_parse_tlv(), the generic TLV walker
> invoked from ipv6_destopt_rcv() and ipv6_parse_hopopts().
>
> ip6_tnl_parse_tlv_enc_lim() does not go through ip6_parse_tlv();
> it has its own hand-rolled TLV scanner inside its NEXTHDR_DEST
> branch which looks for IPV6_TLV_TNL_ENCAP_LIMIT. That inner
> loop is bounded only by optlen, which can be up to 2048 bytes.
> Stuffing the Destination Options header with 2046 Pad1 (type=0)
> entries advances the scanner a single byte at a time, yielding
> ~2000 TLV iterations per extension header.
>
> Reuse max_dst_opts_cnt to bound the TLV iterations, matching
> the semantics from 47d3d7ac656a.
>
> Fixes: 47d3d7ac656a ("ipv6: Implement limits on Hop-by-Hop and Destination options")
> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
> ---
> net/ipv6/ip6_tunnel.c | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
> index 907c6a2af331..0ab76f93c136 100644
> --- a/net/ipv6/ip6_tunnel.c
> +++ b/net/ipv6/ip6_tunnel.c
> @@ -430,11 +430,16 @@ __u16 ip6_tnl_parse_tlv_enc_lim(struct sk_buff *skb, __u8 *raw)
> break;
> }
> if (nexthdr == NEXTHDR_DEST) {
> + int tlv_max = READ_ONCE(init_net.ipv6.sysctl.max_dst_opts_cnt);
> + int tlv_cnt = 0;
> u16 i = 2;
>
> while (1) {
> struct ipv6_tlv_tnl_enc_lim *tel;
>
> + if (unlikely(tlv_cnt++ >= tlv_max))
> + break;
> +
> /* No more room for encapsulation limit */
> if (i + sizeof(*tel) > optlen)
> break;
Good point on reusing max_dst_opts_cnt in ip6_tnl_parse_tlv_enc_lim(),
but this patch is not ready yet.
We need to be careful: max_dst_opts_cnt can be negative. If this is the
case, ip6_tnl_parse_tlv_enc_lim() would probably return 0, which is not
what we want here. From the doc:
max_dst_opts_number - INTEGER
Maximum number of non-padding TLVs allowed in a Destination
options extension header. If this value is less than zero
then unknown options are disallowed and the number of known
TLVs allowed is the absolute value of this number.
Default: 8
Since ip6_tnl_parse_tlv_enc_lim() does not check for specific option
types (e.g., Pad1, PadN, you-name-it) and does not differentiate known
from unknown options during parsing, I would simply use the absolute
value of max_dst_opts_cnt by default.
Also, I wouldn't use unlikely() because it could harm us more than it
helps in this specific context (consistent with ip6_parse_tlv()).
^ permalink raw reply
* Re: [PATCH 1/4 nf] netfilter: nft_exthdr: skip SCTP chunk evaluation for non-first fragments
From: Fernando Fernandez Mancera @ 2026-04-18 9:51 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel, netdev, coreteam, fw, phil
In-Reply-To: <aeM3gmXM43beA3ot@chamomile>
On 4/18/26 9:49 AM, Pablo Neira Ayuso wrote:
> Hi Fernando,
>
> On Fri, Apr 17, 2026 at 08:34:30PM +0200, Fernando Fernandez Mancera wrote:
>> The SCTP chunk matching logic in nft_exthdr relies on SCTP common header
>> being present at the transport header offset. For fragmented packets at
>> IP level, only the first fragment would match this condition.
>>
>> The nft_exthdr could be used in a PREROUTING chain with a priority lower
>> than -400. This would bypass defragmentation. In addition, it can be use
>> in stateless environments so it should work on a environment where
>> defragmentation is not being performed at all.
>
> Yes, and stateless filtering is still a valid configuration, ie.
> nf_conntrack is not loaded.
>
>> Add a check for pkt->fragoff to ensure exthdr SCTP only evaluates
>> unfragmented packets or the first fragment in the stream.
>
> I would suggest to squash the three small patches to check for
> pkt->fragoff in one patch. The three expressions have been already
> around for a while (backporting the combo patch that makes the same
> logical change should be easy) and it is basically the same logical
> change.
>
Hi Pablo,
Thanks for the review! I am not sure about squashing them as they all
have different blamed commits. I find accurate fixes tag quite useful
when handling backports and I guess others do too (also for stable
kernels). Is that convincing?
Anyway, not a big deal if there is a strong preference I will squash them.
Thanks,
Fernando.
> Thanks!
>
>> Fixes: 133dc203d77d ("netfilter: nft_exthdr: Support SCTP chunks")
>> Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
>> ---
>> net/netfilter/nft_exthdr.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c
>> index 7eedf4e3ae9c..8eb708bb8cff 100644
>> --- a/net/netfilter/nft_exthdr.c
>> +++ b/net/netfilter/nft_exthdr.c
>> @@ -376,7 +376,7 @@ static void nft_exthdr_sctp_eval(const struct nft_expr *expr,
>> const struct sctp_chunkhdr *sch;
>> struct sctp_chunkhdr _sch;
>>
>> - if (pkt->tprot != IPPROTO_SCTP)
>> + if (pkt->tprot != IPPROTO_SCTP || pkt->fragoff)
>> goto err;
>>
>> do {
>> --
>> 2.53.0
>>
^ permalink raw reply
* [RFC PATCH net] mptcp: pm: fix ADD_ADDR timer infinite retry on option space insufficient
From: Li Xiasong @ 2026-04-18 10:00 UTC (permalink / raw)
To: Matthieu Baerts, Mat Martineau, Geliang Tang, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman
Cc: netdev, mptcp, linux-kernel, yuehaibing, zhangchangzhong,
weiyongjun1
When TCP option space is insufficient (e.g., IPv6 with tcp_timestamps
enabled), the original code jumped to out_unlock without clearing the
addr_signal flag. This caused mptcp_pm_add_timer to keep rescheduling
indefinitely without sending ADD_ADDR, preventing the endpoint list from
being traversed.
In a pure ACK scenario (indicated by drop_other_suboptions=true), if
the option space is insufficient to carry the ADD_ADDR suboption, it
is appropriate to drop this address signal to allow the timer handler
to move on to other addresses.
Fixes: 00cfd77b9063 ("mptcp: retransmit ADD_ADDR when timeout")
Signed-off-by: Li Xiasong <lixiasong1@huawei.com>
---
Seeking feedback on:
When announcing addresses to the peer, MPTCP sends a pure ACK packet
to carry MPTCP options (ADD_ADDR). In this scenario, if the option space
is insufficient for ADD_ADDR, clearing addr_signal would:
- Prevent the timer from retrying infinitely
- Allow the timer to continue traversing and processing other addresses
- Not block other subflow creation or address announcement operations
Is there any scenario where we should retry later instead of clearing
the address signal/echo flag? However, if a pure ACK doesn't have
enough space for the flag, subsequent packets won't either.
---
net/mptcp/pm.c | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
index 57a456690406..1d49779c6a1f 100644
--- a/net/mptcp/pm.c
+++ b/net/mptcp/pm.c
@@ -881,19 +881,18 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, const struct sk_buff *skb,
}
*echo = mptcp_pm_should_add_signal_echo(msk);
+ add_addr = msk->pm.addr_signal &
+ ~(*echo ? BIT(MPTCP_ADD_ADDR_ECHO) : BIT(MPTCP_ADD_ADDR_SIGNAL));
port = !!(*echo ? msk->pm.remote.port : msk->pm.local.port);
-
family = *echo ? msk->pm.remote.family : msk->pm.local.family;
- if (remaining < mptcp_add_addr_len(family, *echo, port))
- goto out_unlock;
- if (*echo) {
- *addr = msk->pm.remote;
- add_addr = msk->pm.addr_signal & ~BIT(MPTCP_ADD_ADDR_ECHO);
- } else {
- *addr = msk->pm.local;
- add_addr = msk->pm.addr_signal & ~BIT(MPTCP_ADD_ADDR_SIGNAL);
+ if (remaining < mptcp_add_addr_len(family, *echo, port)) {
+ if (*drop_other_suboptions)
+ WRITE_ONCE(msk->pm.addr_signal, add_addr);
+ goto out_unlock;
}
+
+ *addr = *echo ? msk->pm.remote : msk->pm.local;
WRITE_ONCE(msk->pm.addr_signal, add_addr);
ret = true;
--
2.34.1
^ permalink raw reply related
* pre-boot plugged SFP autoneg advertisement
From: markus.stockhausen @ 2026-04-18 9:27 UTC (permalink / raw)
To: linux, andrew, hkallweit1, netdev; +Cc: 'Jonas Jelonek', jan
Hi,
I'm currently analyzing an issue where a pre-boot-plugged SFP module
comes up with autoneg=no advertisement during boot. After an
unplug/replug autoneg=yes advertisement is chosen.
The following addition in phylink_start() just before the call to
phylink_mac_initial_config() mitigiates this.
+ /* If an SFP module was already present before phylink_start() was
+ * called, phylink_sfp_set_config() was unable to call
+ * phylink_mac_initial_config() as phylink was not yet started.
+ * Ensure the SFP capabilities are reflected in advertising.
+ */
+ if (pl->sfp_bus && !linkmode_empty(pl->sfp_support))
+ linkmode_copy(pl->link_config.advertising, pl->sfp_support);
Remark! This is about the OpenWrt Realtek Switch ecosystem with
kernel 6.18 where we are working hard to get hardware up and
running. We still rely heavily on pcs/dsa downstream drivers. So
I'm unsure if my observation/idea regarding upstream phylink is
right.
Thanks for your feedback in advance.
Markus
^ permalink raw reply
* [PATCH iwl-net v1] ice: fix UAF/NULL deref when VSI rebuild and XDP attach race
From: Kohei Enju @ 2026-04-18 9:01 UTC (permalink / raw)
To: intel-wired-lan, netdev
Cc: Tony Nguyen, Przemek Kitszel, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Wojciech Drewek,
Jacob Keller, Larysa Zaremba, Maciej Fijalkowski, Kohei Enju
ice_xdp_setup_prog() unconditionally hot-swaps xdp_prog when
ICE_VSI_REBUILD_PENDING is set. In the attach path, this can publish a
new rx_ring->xdp_prog before rx_ring->xdp_ring becomes valid while the
rebuild is pending. As a result, ice_clean_rx_irq() may dereference
rx_ring->xdp_ring too early.
With high-volume RX packets, running these commands in parallel
triggered a KASAN splat [1].
# ethtool --reset $DEV irq dma filter offload
# ip link set dev $DEV xdp {obj $OBJ sec xdp,off}
Fix this by rejecting XDP attach while rebuild is pending.
Keep XDP detach allowed in this window. Detach clears rx_ring->xdp_prog,
so the RX path will not attempt to access rx_ring->xdp_ring.
[1]
BUG: KASAN: slab-use-after-free in ice_napi_poll+0x3921/0x41a0
Read of size 2 at addr ffff88812475b880 by task ksoftirqd/1/23
[...]
Call Trace:
<TASK>
ice_napi_poll+0x3921/0x41a0
__napi_poll+0x98/0x520
net_rx_action+0x8f2/0xfa0
handle_softirqs+0x1cb/0x7f0
[...]
</TASK>
Allocated by task 7246:
ice_prepare_xdp_rings+0x3de/0x12d0
ice_xdp+0x61c/0xef0
dev_xdp_install+0x3c4/0x840
dev_xdp_attach+0x50a/0x10a0
dev_change_xdp_fd+0x175/0x210
[...]
Freed by task 7251:
__rcu_free_sheaf_prepare+0x5f/0x230
rcu_free_sheaf+0x1a/0xf0
rcu_core+0x567/0x1d80
handle_softirqs+0x1cb/0x7f0
Fixes: 2504b8405768 ("ice: protect XDP configuration with a mutex")
Signed-off-by: Kohei Enju <kohei@enjuk.jp>
---
drivers/net/ethernet/intel/ice/ice_main.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index d1f628f1c8ac..4681cbe193f6 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -2912,12 +2912,21 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog,
}
/* hot swap progs and avoid toggling link */
- if (ice_is_xdp_ena_vsi(vsi) == !!prog ||
- test_bit(ICE_VSI_REBUILD_PENDING, vsi->state)) {
+ if (ice_is_xdp_ena_vsi(vsi) == !!prog) {
ice_vsi_assign_bpf_prog(vsi, prog);
return 0;
}
+ if (test_bit(ICE_VSI_REBUILD_PENDING, vsi->state)) {
+ if (prog) {
+ NL_SET_ERR_MSG_MOD(extack, "VSI rebuild is pending");
+ return -EAGAIN;
+ }
+
+ ice_vsi_assign_bpf_prog(vsi, NULL);
+ return 0;
+ }
+
if_running = netif_running(vsi->netdev) &&
!test_and_set_bit(ICE_VSI_DOWN, vsi->state);
--
2.51.0
^ permalink raw reply related
* Re: [PATCH net-deletions] caif: remove CAIF NETWORK LAYER
From: Greg KH @ 2026-04-18 8:48 UTC (permalink / raw)
To: Jakub Kicinski
Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms, corbet,
skhan, alexs, si.yanteng, dzm91, linux, mst, jasowang, xuanzhuo,
eperezma, xu.xin16, wang.yaxin, jiang.kun2, linusw,
jihed.chaibi.dev, arnd, tytso, jiayuan.chen
In-Reply-To: <20260416182829.1440262-1-kuba@kernel.org>
On Thu, Apr 16, 2026 at 11:28:28AM -0700, Jakub Kicinski wrote:
> Remove CAIF (Communication CPU to Application CPU Interface), the
> ST-Ericsson modem protocol. The subsystem has been orphaned since 2013.
> The last meaningful changes from the maintainers were in March 2013:
> a8c7687bf216 ("caif_virtio: Check that vringh_config is not null")
> b2273be8d2df ("caif_virtio: Use vringh_notify_enable correctly")
> 0d2e1a2926b1 ("caif_virtio: Introduce caif over virtio")
>
> Not-so-coincidentally, according to "the Internet" ST-Ericsson officially
> shut down its modem joint venture in Aug 2013.
>
> If anyone is using this code please yell!
>
> In the 13 years since, the code has accumulated 200 non-merge commits,
> of which 71 were cross-tree API changes, 21 carried Fixes: tags, and
> the remaining ~110 were cleanups, doc conversions, treewide refactors,
> and one partial removal (caif_hsi, ca75bcf0a83b).
>
> We are still getting fixes to this code, in the last 10 days there were
> 3 reports on security@ about CAIF that I have been CCed on.
>
> UAPI constants (AF_CAIF, ARPHRD_CAIF, N_CAIF, VIRTIO_ID_CAIF) and the
> SELinux classmap entry are intentionally kept for ABI stability.
>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> ---
> I think we should accumulate such patches over the coming days on a separate
> branch. CAIF is a no-brainer IMO but other removals may be more controversial.
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
^ permalink raw reply
* Re: [PATCH 1/2 nf] netfilter: nfnetlink_osf: fix out-of-bounds read on option matching
From: Pablo Neira Ayuso @ 2026-04-18 7:57 UTC (permalink / raw)
To: Fernando Fernandez Mancera; +Cc: netfilter-devel, netdev, coreteam, fw, phil
In-Reply-To: <20260417162057.3732-1-fmancera@suse.de>
On Fri, Apr 17, 2026 at 06:20:56PM +0200, Fernando Fernandez Mancera wrote:
> In nf_osf_match(), the nf_osf_hdr_ctx structure is initialized once
> and passed by reference to nf_osf_match_one() for each fingerprint
> checked. During TCP option parsing, nf_osf_match_one() advances the
> shared ctx->optp pointer.
>
> If a fingerprint perfectly matches, the function returns early without
> restoring ctx->optp to its initial state. If the user has configured
> NF_OSF_LOGLEVEL_ALL, the loop continues to the next fingerprint.
> However, because ctx->optp was not restored, the next call to
> nf_osf_match_one() starts parsing from the end of the options buffer.
> This causes subsequent matches to read garbage data and fail
> immediately, making it impossible to log more than one match or logging
> incorrect matches.
>
> Instead of using a shared ctx->optp pointer, pass the context as a
> constant pointer and use a local pointer (optp) for TCP option
> traversal. This makes nf_osf_match_one() strictly stateless from the
> caller's perspective, ensuring every fingerprint check starts at the
> correct option offset.
>
> Fixes: 1a6a0951fc00 ("netfilter: nfnetlink_osf: add missing fmatch check")
> Suggested-by: Florian Westphal <fw@strlen.de>
> Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
^ permalink raw reply
* Re: [PATCH 2/2 nf] netfilter: nfnetlink_osf: fix potential NULL dereference in ttl check
From: Pablo Neira Ayuso @ 2026-04-18 7:53 UTC (permalink / raw)
To: Fernando Fernandez Mancera
Cc: netfilter-devel, netdev, coreteam, fw, phil, Kito Xu (veritas501)
In-Reply-To: <20260417162057.3732-2-fmancera@suse.de>
On Fri, Apr 17, 2026 at 06:20:57PM +0200, Fernando Fernandez Mancera wrote:
> The nf_osf_ttl() function accessed skb->dev to perform a local interface
> address lookup without verifying that the device pointer was valid.
>
> Additionally, the implementation utilized an in_dev_for_each_ifa_rcu
> loop to match the packet source address against local interface
> addresses. It assumed that packets from the same subnet should not see a
> decrement on the initial TTL. A packet might appear it is from the same
> subnet but it actually isn't especially in modern environments with
> containers and virtual switching.
>
> Remove the device dereference and interface loop. Replace the logic with
> a switch statement that evaluates the TTL according to the ttl_check.
>
> Fixes: 11eeef41d5f6 ("netfilter: passive OS fingerprint xtables match")
> Reported-by: Kito Xu (veritas501) <hxzene@gmail.com>
> Closes: https://lore.kernel.org/netfilter-devel/20260414074556.2512750-1-hxzene@gmail.com/
> Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
> ---
> Note: if some help is needed during the backport I can assist.
> ---
> net/netfilter/nfnetlink_osf.c | 22 +++++++---------------
> 1 file changed, 7 insertions(+), 15 deletions(-)
>
> diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c
> index f58267986453..f0d1e596e146 100644
> --- a/net/netfilter/nfnetlink_osf.c
> +++ b/net/netfilter/nfnetlink_osf.c
> @@ -31,26 +31,18 @@ EXPORT_SYMBOL_GPL(nf_osf_fingers);
> static inline int nf_osf_ttl(const struct sk_buff *skb,
> int ttl_check, unsigned char f_ttl)
> {
> - struct in_device *in_dev = __in_dev_get_rcu(skb->dev);
> const struct iphdr *ip = ip_hdr(skb);
> - const struct in_ifaddr *ifa;
> - int ret = 0;
>
> - if (ttl_check == NF_OSF_TTL_TRUE)
> + switch (ttl_check) {
> + case NF_OSF_TTL_TRUE:
> return ip->ttl == f_ttl;
> - if (ttl_check == NF_OSF_TTL_NOCHECK)
> - return 1;
> - else if (ip->ttl <= f_ttl)
> + break;
> + case NF_OSF_TTL_NOCHECK:
> return 1;
> -
> - in_dev_for_each_ifa_rcu(ifa, in_dev) {
> - if (inet_ifa_match(ip->saddr, ifa)) {
> - ret = (ip->ttl == f_ttl);
> - break;
> - }
> + case NF_OSF_TTL_LESS:
> + default:
> + return ip->ttl <= f_ttl;
> }
> -
> - return ret;
> }
>
> struct nf_osf_hdr_ctx {
> --
> 2.53.0
>
^ permalink raw reply
* Re: [PATCH 4/4 nf] netfilter: xtables: fix L4 header parsing for non-first fragments
From: Pablo Neira Ayuso @ 2026-04-18 7:51 UTC (permalink / raw)
To: Fernando Fernandez Mancera; +Cc: netfilter-devel, netdev, coreteam, fw, phil
In-Reply-To: <20260417183433.4739-6-fmancera@suse.de>
On Fri, Apr 17, 2026 at 08:34:35PM +0200, Fernando Fernandez Mancera wrote:
> The TPROXY target and osf match relies on L4 header to operate. For
> fragmented packets, every fragment carries the transport protocol
> identifier, but only the first fragment contains the L4 header.
>
> As the 'raw' table can be configured to run at priority -450 (before
> defragmentation at -400), the target/match can be reached before
> reassembly. In this case, non-first fragments have their payload
> incorrectly parsed as a TCP/UDP header.
I see, this refers to a misconfiguration scenario.
> Add a fragment check to ensure TPROXY/osf only evaluates unfragmented
> packets or the first fragment in the stream.
LGTM this combo patch for osf and TPROXY in xtables.
Thanks.
> Fixes: 902d6a4c2a4f ("netfilter: nf_defrag: Skip defrag if NOTRACK is set")
> Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
> ---
> net/netfilter/xt_TPROXY.c | 8 ++++++--
> net/netfilter/xt_osf.c | 3 +++
> 2 files changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/net/netfilter/xt_TPROXY.c b/net/netfilter/xt_TPROXY.c
> index e4bea1d346cf..ac4b011ce48c 100644
> --- a/net/netfilter/xt_TPROXY.c
> +++ b/net/netfilter/xt_TPROXY.c
> @@ -40,6 +40,9 @@ tproxy_tg4(struct net *net, struct sk_buff *skb, __be32 laddr, __be16 lport,
> struct udphdr _hdr, *hp;
> struct sock *sk;
>
> + if (ip_is_fragment(iph))
> + return NF_DROP;
> +
> hp = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_hdr), &_hdr);
> if (hp == NULL)
> return NF_DROP;
> @@ -106,6 +109,7 @@ tproxy_tg6_v1(struct sk_buff *skb, const struct xt_action_param *par)
> {
> const struct ipv6hdr *iph = ipv6_hdr(skb);
> const struct xt_tproxy_target_info_v1 *tgi = par->targinfo;
> + unsigned short fragoff = 0;
> struct udphdr _hdr, *hp;
> struct sock *sk;
> const struct in6_addr *laddr;
> @@ -113,8 +117,8 @@ tproxy_tg6_v1(struct sk_buff *skb, const struct xt_action_param *par)
> int thoff = 0;
> int tproto;
>
> - tproto = ipv6_find_hdr(skb, &thoff, -1, NULL, NULL);
> - if (tproto < 0)
> + tproto = ipv6_find_hdr(skb, &thoff, -1, &fragoff, NULL);
> + if (tproto < 0 || fragoff)
> return NF_DROP;
>
> hp = skb_header_pointer(skb, thoff, sizeof(_hdr), &_hdr);
> diff --git a/net/netfilter/xt_osf.c b/net/netfilter/xt_osf.c
> index dc9485854002..889dff4daff0 100644
> --- a/net/netfilter/xt_osf.c
> +++ b/net/netfilter/xt_osf.c
> @@ -27,6 +27,9 @@
> static bool
> xt_osf_match_packet(const struct sk_buff *skb, struct xt_action_param *p)
> {
> + if (ip_is_fragment(ip_hdr(skb)))
> + return false;
> +
> return nf_osf_match(skb, xt_family(p), xt_hooknum(p), xt_in(p),
> xt_out(p), p->matchinfo, xt_net(p), nf_osf_fingers);
> }
> --
> 2.53.0
>
^ permalink raw reply
* Re: [PATCH 1/4 nf] netfilter: nft_exthdr: skip SCTP chunk evaluation for non-first fragments
From: Pablo Neira Ayuso @ 2026-04-18 7:49 UTC (permalink / raw)
To: Fernando Fernandez Mancera; +Cc: netfilter-devel, netdev, coreteam, fw, phil
In-Reply-To: <20260417183433.4739-1-fmancera@suse.de>
Hi Fernando,
On Fri, Apr 17, 2026 at 08:34:30PM +0200, Fernando Fernandez Mancera wrote:
> The SCTP chunk matching logic in nft_exthdr relies on SCTP common header
> being present at the transport header offset. For fragmented packets at
> IP level, only the first fragment would match this condition.
>
> The nft_exthdr could be used in a PREROUTING chain with a priority lower
> than -400. This would bypass defragmentation. In addition, it can be use
> in stateless environments so it should work on a environment where
> defragmentation is not being performed at all.
Yes, and stateless filtering is still a valid configuration, ie.
nf_conntrack is not loaded.
> Add a check for pkt->fragoff to ensure exthdr SCTP only evaluates
> unfragmented packets or the first fragment in the stream.
I would suggest to squash the three small patches to check for
pkt->fragoff in one patch. The three expressions have been already
around for a while (backporting the combo patch that makes the same
logical change should be easy) and it is basically the same logical
change.
Thanks!
> Fixes: 133dc203d77d ("netfilter: nft_exthdr: Support SCTP chunks")
> Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
> ---
> net/netfilter/nft_exthdr.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c
> index 7eedf4e3ae9c..8eb708bb8cff 100644
> --- a/net/netfilter/nft_exthdr.c
> +++ b/net/netfilter/nft_exthdr.c
> @@ -376,7 +376,7 @@ static void nft_exthdr_sctp_eval(const struct nft_expr *expr,
> const struct sctp_chunkhdr *sch;
> struct sctp_chunkhdr _sch;
>
> - if (pkt->tprot != IPPROTO_SCTP)
> + if (pkt->tprot != IPPROTO_SCTP || pkt->fragoff)
> goto err;
>
> do {
> --
> 2.53.0
>
^ permalink raw reply
* Re: [PATCH net-next] r8169: report per-queue statistics through netdev qstats
From: Eric Dumazet @ 2026-04-18 6:27 UTC (permalink / raw)
To: Gustavo Arantes
Cc: Heiner Kallweit, nic_swsd, Andrew Lunn, David S . Miller,
Jakub Kicinski, Paolo Abeni, netdev, linux-kernel
In-Reply-To: <20260418021232.5425-1-dev.gustavoa@gmail.com>
On Fri, Apr 17, 2026 at 7:12 PM Gustavo Arantes <dev.gustavoa@gmail.com> wrote:
>
> r8169 maintains synchronized per-CPU software counters for packet and byte
> accounting, but does not expose them through the netdev qstats interface.
>
> Add netdev_stat_ops callbacks and report the existing software counters
> through queue 0 for both Rx and Tx. Provide zero base stats so device-scope
> qstats report the packet and byte counters as supported and match the
> existing RTNL statistics.
>
> Signed-off-by: Gustavo Arantes <dev.gustavoa@gmail.com>
## Form letter - net-next-closed
Please repost when net-next reopens after Apr 27th.
RFC patches sent for review only are obviously welcome at any time.
See:
https://www.kernel.org/doc/html/next/process/maintainer-netdev.html#development-cycle
pw-bot: cr
^ permalink raw reply
* Re: [PATCH net 1/2] tcp: call sk_data_ready() after listener migration
From: Eric Dumazet @ 2026-04-18 6:02 UTC (permalink / raw)
To: Zhenzhong Wu
Cc: netdev, ncardwell, kuniyu, davem, dsahern, kuba, pabeni, horms,
shuah, tamird, linux-kernel, linux-kselftest, stable
In-Reply-To: <20260418041633.691435-2-jt26wzz@gmail.com>
On Fri, Apr 17, 2026 at 9:17 PM Zhenzhong Wu <jt26wzz@gmail.com> wrote:
>
> When inet_csk_listen_stop() migrates an established child socket from
> a closing listener to another socket in the same SO_REUSEPORT group,
> the target listener gets a new accept-queue entry via
> inet_csk_reqsk_queue_add(), but that path never notifies the target
> listener's waiters.
>
> As a result, a nonblocking accept() still succeeds because it checks
> the accept queue directly, but waiters that sleep for listener
> readiness can remain asleep until another connection generates a
> wakeup. This affects poll()/epoll_wait()-based waiters, and can also
> leave a blocking accept() asleep after migration even though the
> child is already in the target listener's accept queue.
>
> This was observed in a local test where listener A completed the
> handshake, queued the child, and was closed before userspace called
> accept(). The child was migrated to listener B, but listener B never
> received a wakeup for the migrated accept-queue entry.
>
> Call READ_ONCE(nsk->sk_data_ready)(nsk) after a successful migration
> in inet_csk_listen_stop().
>
> The reqsk_timer_handler() path does not need the same change:
> half-open requests only become readable to userspace when the final
> ACK completes the handshake, and tcp_child_process() already wakes
> the listener in that case.
>
> Fixes: 54b92e841937 ("tcp: Migrate TCP_ESTABLISHED/TCP_SYN_RECV sockets in accept queues.")
> Cc: stable@vger.kernel.org
> Signed-off-by: Zhenzhong Wu <jt26wzz@gmail.com>
> ---
> net/ipv4/inet_connection_sock.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
> index 4ac3ae1bc..da1ce082f 100644
> --- a/net/ipv4/inet_connection_sock.c
> +++ b/net/ipv4/inet_connection_sock.c
> @@ -1483,6 +1483,7 @@ void inet_csk_listen_stop(struct sock *sk)
> __NET_INC_STATS(sock_net(nsk),
> LINUX_MIB_TCPMIGRATEREQSUCCESS);
> reqsk_migrate_reset(req);
> + READ_ONCE(nsk->sk_data_ready)(nsk);
I think this is adding a potential UAF (Use Afte Free).
@nsk might have been freed already by another thread/cpu.
Note the existing code already has similar issues.
Untested patch:
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 4ac3ae1bc1afc3a39f2790e39b4dda877dc3272b..287b6e01c4f71bfec3dd2a708f316224d9eb4a64
100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -1479,6 +1479,7 @@ void inet_csk_listen_stop(struct sock *sk)
if (nreq) {
refcount_set(&nreq->rsk_refcnt, 1);
+ rcu_read_lock();
if (inet_csk_reqsk_queue_add(nsk,
nreq, child)) {
__NET_INC_STATS(sock_net(nsk),
LINUX_MIB_TCPMIGRATEREQSUCCESS);
@@ -1489,7 +1490,7 @@ void inet_csk_listen_stop(struct sock *sk)
reqsk_migrate_reset(nreq);
__reqsk_free(nreq);
}
-
+ rcu_read_unlock();
/* inet_csk_reqsk_queue_add() has already
* called inet_child_forget() on failure case.
*/
^ permalink raw reply
* Re: [PATCH v1 net] tcp: Disable usec TS for SYN Cookie.
From: Eric Dumazet @ 2026-04-18 5:49 UTC (permalink / raw)
To: Kuniyuki Iwashima
Cc: Neal Cardwell, David S. Miller, Jakub Kicinski, Paolo Abeni,
Simon Horman, Kuniyuki Iwashima, netdev
In-Reply-To: <CAAVpQUA8+eibr_0CcdKEWUhzyn6SNE8MA5uzYCJhNmWstq2OAQ@mail.gmail.com>
On Fri, Apr 17, 2026 at 10:33 PM Kuniyuki Iwashima <kuniyu@google.com> wrote:
>
> On Fri, Apr 17, 2026 at 9:59 PM Eric Dumazet <edumazet@google.com> wrote:
> >
> > On Fri, Apr 17, 2026 at 7:50 PM Kuniyuki Iwashima <kuniyu@google.com> wrote:
> > >
> > > cookie_tcp_reqsk_alloc() sets tcp_rsk(req)->req_usec_ts to false
> > > unconditionally.
> > >
> > > If want_cookie is true in tcp_conn_request(), we should not set
> > > tcp_rsk(req)->req_usec_ts.
> > >
> > > Let's not call dst_tcp_usec_ts() for SYN Cookie.
> >
> > May I ask why ?
>
> Sorry, I missed tcp_skb_timestamp_ts() properly restores the
> cookie TS generated by cookie_init_timestamp() to ms unit.
>
> Still we don't need to call dst_tcp_usec_ts() for SYN cookie,
> but this was more like a cleanup patch.
Okay, but consider the standard path (or fast path) has to call it.
dst_tcp_usec_ts() is a mere dst_feature(dst,
RTAX_FEATURE_TCP_USEC_TS), which is pretty fast.
Adding a conditional branch won't help.
^ permalink raw reply
* [PATCH 2/2] Bluetooth: ISO: Fix data-race on iso_pi(sk) in socket and HCI event paths
From: SeungJu Cheon @ 2026-04-18 5:34 UTC (permalink / raw)
To: luiz.dentz, marcel
Cc: linux-bluetooth, netdev, linux-kernel, me, skhan,
linux-kernel-mentees, SeungJu Cheon
In-Reply-To: <20260418053401.128483-1-suunj1331@gmail.com>
Several iso_pi(sk) fields (qos, qos_user_set, bc_sid, base, base_len,
sync_handle, bc_num_bis) are written under lock_sock in
iso_sock_setsockopt() and iso_sock_bind(), but read and written under
hci_dev_lock only in two other paths:
- iso_connect_bis() / iso_connect_cis(), invoked from connect(2),
read qos/base/bc_sid and reset qos to default_qos on the
qos_user_set validation failure -- all without lock_sock.
- iso_connect_ind(), invoked from hci_rx_work, writes sync_handle,
bc_sid, qos.bcast.encryption, bc_num_bis, base and base_len on
PA_SYNC_ESTABLISHED / PAST_RECEIVED / BIG_INFO_ADV_REPORT /
PER_ADV_REPORT events. The BIG_INFO handler additionally passes
&iso_pi(sk)->qos together with sync_handle / bc_num_bis / bc_bis
to hci_conn_big_create_sync() while setsockopt may be mutating
them.
Acquire lock_sock around the affected accesses in both paths.
The locking order hci_dev_lock -> lock_sock matches the existing
iso_conn_big_sync() precedent, whose comment documents the same
requirement for hci_conn_big_create_sync(). The HCI connect/bind
helpers do not wait for command completion -- they enqueue work via
hci_cmd_sync_queue{,_once}() / hci_le_create_cis_pending() and
return -- so the added hold time is comparable to iso_conn_big_sync().
KCSAN report:
BUG: KCSAN: data-race in iso_connect_cis / iso_sock_setsockopt
read to 0xffffa3ae8ce3cdc8 of 1 bytes by task 335 on cpu 0:
iso_connect_cis+0x49f/0xa20
iso_sock_connect+0x60e/0xb40
__sys_connect_file+0xbd/0xe0
__sys_connect+0xe0/0x110
__x64_sys_connect+0x40/0x50
x64_sys_call+0xcad/0x1c60
do_syscall_64+0x133/0x590
entry_SYSCALL_64_after_hwframe+0x77/0x7f
write to 0xffffa3ae8ce3cdc8 of 60 bytes by task 334 on cpu 1:
iso_sock_setsockopt+0x69a/0x930
do_sock_setsockopt+0xc3/0x170
__sys_setsockopt+0xd1/0x130
__x64_sys_setsockopt+0x64/0x80
x64_sys_call+0x1547/0x1c60
do_syscall_64+0x133/0x590
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Reported by Kernel Concurrency Sanitizer on:
CPU: 1 UID: 0 PID: 334 Comm: iso_setup_race Not tainted 7.0.0-10949-g8541d8f725c6 #44 PREEMPT(lazy)
The iso_connect_ind() races were found by inspection.
Fixes: ccf74f2390d6 ("Bluetooth: Add BTPROTO_ISO socket type")
Signed-off-by: SeungJu Cheon <suunj1331@gmail.com>
---
net/bluetooth/iso.c | 54 +++++++++++++++++++++++++--------------------
1 file changed, 30 insertions(+), 24 deletions(-)
diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
index 14963ba68597..3ba13769be3a 100644
--- a/net/bluetooth/iso.c
+++ b/net/bluetooth/iso.c
@@ -347,6 +347,7 @@ static int iso_connect_bis(struct sock *sk)
return -EHOSTUNREACH;
hci_dev_lock(hdev);
+ lock_sock(sk);
if (!bis_capable(hdev)) {
err = -EOPNOTSUPP;
@@ -399,13 +400,9 @@ static int iso_connect_bis(struct sock *sk)
goto unlock;
}
- lock_sock(sk);
-
err = iso_chan_add(conn, sk, NULL);
- if (err) {
- release_sock(sk);
+ if (err)
goto unlock;
- }
/* Update source addr of the socket */
bacpy(&iso_pi(sk)->src, &hcon->src);
@@ -421,9 +418,8 @@ static int iso_connect_bis(struct sock *sk)
iso_sock_set_timer(sk, READ_ONCE(sk->sk_sndtimeo));
}
- release_sock(sk);
-
unlock:
+ release_sock(sk);
hci_dev_unlock(hdev);
hci_dev_put(hdev);
return err;
@@ -444,6 +440,7 @@ static int iso_connect_cis(struct sock *sk)
return -EHOSTUNREACH;
hci_dev_lock(hdev);
+ lock_sock(sk);
if (!cis_central_capable(hdev)) {
err = -EOPNOTSUPP;
@@ -498,13 +495,9 @@ static int iso_connect_cis(struct sock *sk)
goto unlock;
}
- lock_sock(sk);
-
err = iso_chan_add(conn, sk, NULL);
- if (err) {
- release_sock(sk);
+ if (err)
goto unlock;
- }
/* Update source addr of the socket */
bacpy(&iso_pi(sk)->src, &hcon->src);
@@ -520,9 +513,8 @@ static int iso_connect_cis(struct sock *sk)
iso_sock_set_timer(sk, READ_ONCE(sk->sk_sndtimeo));
}
- release_sock(sk);
-
unlock:
+ release_sock(sk);
hci_dev_unlock(hdev);
hci_dev_put(hdev);
return err;
@@ -2259,8 +2251,10 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
sk = iso_get_sock(hdev, &hdev->bdaddr, bdaddr, BT_LISTEN,
iso_match_sid, ev1);
if (sk && !ev1->status) {
+ lock_sock(sk);
iso_pi(sk)->sync_handle = le16_to_cpu(ev1->handle);
iso_pi(sk)->bc_sid = ev1->sid;
+ release_sock(sk);
}
goto done;
@@ -2271,8 +2265,10 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
sk = iso_get_sock(hdev, &hdev->bdaddr, bdaddr, BT_LISTEN,
iso_match_sid_past, ev1a);
if (sk && !ev1a->status) {
+ lock_sock(sk);
iso_pi(sk)->sync_handle = le16_to_cpu(ev1a->sync_handle);
iso_pi(sk)->bc_sid = ev1a->sid;
+ release_sock(sk);
}
goto done;
@@ -2299,27 +2295,35 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
ev2);
if (sk) {
- int err;
- struct hci_conn *hcon = iso_pi(sk)->conn->hcon;
+ int err = 0;
+ bool big_sync;
+ struct hci_conn *hcon;
+ lock_sock(sk);
+
+ hcon = iso_pi(sk)->conn->hcon;
iso_pi(sk)->qos.bcast.encryption = ev2->encryption;
if (ev2->num_bis < iso_pi(sk)->bc_num_bis)
iso_pi(sk)->bc_num_bis = ev2->num_bis;
- if (!test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags) &&
- !test_and_set_bit(BT_SK_BIG_SYNC, &iso_pi(sk)->flags)) {
+ big_sync = !test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags) &&
+ !test_and_set_bit(BT_SK_BIG_SYNC, &iso_pi(sk)->flags);
+
+ if (big_sync)
err = hci_conn_big_create_sync(hdev, hcon,
&iso_pi(sk)->qos,
iso_pi(sk)->sync_handle,
iso_pi(sk)->bc_num_bis,
iso_pi(sk)->bc_bis);
- if (err) {
- bt_dev_err(hdev, "hci_le_big_create_sync: %d",
- err);
- sock_put(sk);
- sk = NULL;
- }
+
+ release_sock(sk);
+
+ if (big_sync && err) {
+ bt_dev_err(hdev, "hci_le_big_create_sync: %d",
+ err);
+ sock_put(sk);
+ sk = NULL;
}
}
@@ -2373,8 +2377,10 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
if (!base || base_len > BASE_MAX_LENGTH)
goto done;
+ lock_sock(sk);
memcpy(iso_pi(sk)->base, base, base_len);
iso_pi(sk)->base_len = base_len;
+ release_sock(sk);
} else {
/* This is a PA data fragment. Keep pa_data_len set to 0
* until all data has been reassembled.
--
2.52.0
^ permalink raw reply related
* [PATCH 1/2] Bluetooth: ISO: Fix data-race on dst in iso_sock_connect()
From: SeungJu Cheon @ 2026-04-18 5:34 UTC (permalink / raw)
To: luiz.dentz, marcel
Cc: linux-bluetooth, netdev, linux-kernel, me, skhan,
linux-kernel-mentees, SeungJu Cheon
In-Reply-To: <20260418053401.128483-1-suunj1331@gmail.com>
iso_sock_connect() copies the destination address into
iso_pi(sk)->dst under lock_sock, then releases the lock and reads
it back with bacmp() to decide between the CIS and BIS connect
paths:
lock_sock(sk);
bacpy(&iso_pi(sk)->dst, &sa->iso_bdaddr);
iso_pi(sk)->dst_type = sa->iso_bdaddr_type;
release_sock(sk);
if (bacmp(&iso_pi(sk)->dst, BDADDR_ANY)) // <- no lock held
This read after release_sock() races with any concurrent write to
iso_pi(sk)->dst on the same socket.
Fix by performing the bacmp() inside the lock_sock critical section
and caching the result in a local variable.
This patch addresses only the bacmp() race in iso_sock_connect();
other unprotected iso_pi(sk) accesses are fixed separately in the
next patch.
KCSAN report:
BUG: KCSAN: data-race in memcmp+0x39/0xb0
race at unknown origin, with read to 0xffff8f96ea66dde3 of 1 bytes by task 549 on cpu 1:
memcmp+0x39/0xb0
iso_sock_connect+0x275/0xb40
__sys_connect_file+0xbd/0xe0
__sys_connect+0xe0/0x110
__x64_sys_connect+0x40/0x50
x64_sys_call+0xcad/0x1c60
do_syscall_64+0x133/0x590
entry_SYSCALL_64_after_hwframe+0x77/0x7f
value changed: 0x00 -> 0xee
Reported by Kernel Concurrency Sanitizer on:
CPU: 1 UID: 0 PID: 549 Comm: iso_race_combin Not tainted 7.0.0-08391-g1d51b370a0f8 #40 PREEMPT(lazy)
Fixes: ccf74f2390d6 ("Bluetooth: Add BTPROTO_ISO socket type")
Signed-off-by: SeungJu Cheon <suunj1331@gmail.com>
---
net/bluetooth/iso.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
index be145e2736b7..14963ba68597 100644
--- a/net/bluetooth/iso.c
+++ b/net/bluetooth/iso.c
@@ -1169,6 +1169,7 @@ static int iso_sock_connect(struct socket *sock, struct sockaddr_unsized *addr,
struct sockaddr_iso *sa = (struct sockaddr_iso *)addr;
struct sock *sk = sock->sk;
int err;
+ bool bcast;
BT_DBG("sk %p", sk);
@@ -1191,9 +1192,11 @@ static int iso_sock_connect(struct socket *sock, struct sockaddr_unsized *addr,
bacpy(&iso_pi(sk)->dst, &sa->iso_bdaddr);
iso_pi(sk)->dst_type = sa->iso_bdaddr_type;
+ bcast = !bacmp(&iso_pi(sk)->dst, BDADDR_ANY);
+
release_sock(sk);
- if (bacmp(&iso_pi(sk)->dst, BDADDR_ANY))
+ if (!bcast)
err = iso_connect_cis(sk);
else
err = iso_connect_bis(sk);
--
2.52.0
^ permalink raw reply related
* [PATCH 0/2] Bluetooth: ISO: Fix KCSAN data-races on iso_pi(sk)
From: SeungJu Cheon @ 2026-04-18 5:33 UTC (permalink / raw)
To: luiz.dentz, marcel
Cc: linux-bluetooth, netdev, linux-kernel, me, skhan,
linux-kernel-mentees, SeungJu Cheon
Found while auditing iso_pi(sk) field accesses after a KCSAN report.
Patch 1/2 is the reported race on iso_pi(sk)->dst in iso_sock_connect();
patch 2/2 covers related races on other iso_pi(sk) fields accessed in
iso_connect_{bis,cis}() and iso_connect_ind() that were found by
inspection during the same audit.
SeungJu Cheon (2):
Bluetooth: ISO: Fix data-race on dst in iso_sock_connect()
Bluetooth: ISO: Fix data-race on iso_pi(sk) in socket and HCI event
paths
net/bluetooth/iso.c | 59 ++++++++++++++++++++++++++-------------------
1 file changed, 34 insertions(+), 25 deletions(-)
--
2.52.0
^ permalink raw reply
* Re: [PATCH v1 net] tcp: Disable usec TS for SYN Cookie.
From: Kuniyuki Iwashima @ 2026-04-18 5:32 UTC (permalink / raw)
To: Eric Dumazet
Cc: Neal Cardwell, David S. Miller, Jakub Kicinski, Paolo Abeni,
Simon Horman, Kuniyuki Iwashima, netdev
In-Reply-To: <CANn89iLL0iWoU-jh=Nk+0fsGWNOeuwQ8DP=dVUT=LjBGHR_2FA@mail.gmail.com>
On Fri, Apr 17, 2026 at 9:59 PM Eric Dumazet <edumazet@google.com> wrote:
>
> On Fri, Apr 17, 2026 at 7:50 PM Kuniyuki Iwashima <kuniyu@google.com> wrote:
> >
> > cookie_tcp_reqsk_alloc() sets tcp_rsk(req)->req_usec_ts to false
> > unconditionally.
> >
> > If want_cookie is true in tcp_conn_request(), we should not set
> > tcp_rsk(req)->req_usec_ts.
> >
> > Let's not call dst_tcp_usec_ts() for SYN Cookie.
>
> May I ask why ?
Sorry, I missed tcp_skb_timestamp_ts() properly restores the
cookie TS generated by cookie_init_timestamp() to ms unit.
Still we don't need to call dst_tcp_usec_ts() for SYN cookie,
but this was more like a cleanup patch.
>
> TCP usec TS are based on routing. this feature is not part of SYN
> and/or SYNACK options.
>
> Both side must have:
>
> ip route ... feature tcp_usec_ts
>
> syncookies are orthogonal to this constraint, so TCP flows can use
> usec TS just fine.
>
> pw-bot: cr
^ permalink raw reply
* [syzbot] [net?] possible deadlock in br_forward_delay_timer_expired (5)
From: syzbot @ 2026-04-18 5:30 UTC (permalink / raw)
To: andrew+netdev, davem, edumazet, jv, kuba, linux-kernel, netdev,
pabeni, syzkaller-bugs
Hello,
syzbot found the following issue on:
HEAD commit: 43cfbdda5af6 Merge tag 'for-linus-iommufd' of git://git.ke..
git tree: upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=100a4702580000
kernel config: https://syzkaller.appspot.com/x/.config?x=8195c5b22e79c2cf
dashboard link: https://syzkaller.appspot.com/bug?extid=a7f25fd06ad99e9379e4
compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
Unfortunately, I don't have any reproducer for this issue yet.
Downloadable assets:
disk image: https://storage.googleapis.com/syzbot-assets/848e46852283/disk-43cfbdda.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/24283dbdc318/vmlinux-43cfbdda.xz
kernel image: https://storage.googleapis.com/syzbot-assets/f91b3fadd31d/bzImage-43cfbdda.xz
IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+a7f25fd06ad99e9379e4@syzkaller.appspotmail.com
netlink: 16 bytes leftover after parsing attributes in process `syz.3.6945'.
=====================================================
WARNING: SOFTIRQ-safe -> SOFTIRQ-unsafe lock order detected
syzkaller #0 Tainted: G L
-----------------------------------------------------
syz.3.6945/21491 [HC0[0]:SC0[2]:HE1:SE0] is trying to acquire:
ffff888035200e98 (&bond->stats_lock/2){+.+.}-{3:3}, at: bond_get_stats+0x458/0x740 drivers/net/bonding/bond_main.c:4514
and this task is already holding:
ffff888036758e18 (&br->lock){+.-.}-{3:3}, at: spin_lock_bh include/linux/spinlock.h:348 [inline]
ffff888036758e18 (&br->lock){+.-.}-{3:3}, at: br_port_slave_changelink+0x3d/0x150 net/bridge/br_netlink.c:1212
which would create a new lock dependency:
(&br->lock){+.-.}-{3:3} -> (&bond->stats_lock/2){+.+.}-{3:3}
but this new dependency connects a SOFTIRQ-irq-safe lock:
(&br->lock){+.-.}-{3:3}
... which became SOFTIRQ-irq-safe at:
lock_acquire+0x106/0x350 kernel/locking/lockdep.c:5868
__raw_spin_lock include/linux/spinlock_api_smp.h:158 [inline]
_raw_spin_lock+0x2e/0x40 kernel/locking/spinlock.c:158
spin_lock include/linux/spinlock.h:342 [inline]
br_forward_delay_timer_expired+0x4f/0x460 net/bridge/br_stp_timer.c:88
call_timer_fn+0x192/0x5e0 kernel/time/timer.c:1748
expire_timers kernel/time/timer.c:1799 [inline]
__run_timers kernel/time/timer.c:2374 [inline]
__run_timer_base+0x652/0x8b0 kernel/time/timer.c:2386
run_timer_base kernel/time/timer.c:2395 [inline]
run_timer_softirq+0xb7/0x170 kernel/time/timer.c:2405
handle_softirqs+0x22a/0x840 kernel/softirq.c:622
__do_softirq kernel/softirq.c:656 [inline]
invoke_softirq kernel/softirq.c:496 [inline]
__irq_exit_rcu+0xca/0x220 kernel/softirq.c:735
irq_exit_rcu+0x9/0x30 kernel/softirq.c:752
common_interrupt+0xbb/0xe0 arch/x86/kernel/irq.c:326
asm_common_interrupt+0x26/0x40 arch/x86/include/asm/idtentry.h:688
finish_task_switch+0x427/0xbe0 kernel/sched/core.c:5244
context_switch kernel/sched/core.c:5390 [inline]
__schedule+0x17bc/0x5680 kernel/sched/core.c:7188
__schedule_loop kernel/sched/core.c:7267 [inline]
schedule+0x164/0x360 kernel/sched/core.c:7282
smpboot_thread_fn+0x5bc/0xa50 kernel/smpboot.c:156
kthread+0x388/0x470 kernel/kthread.c:436
ret_from_fork+0x514/0xb70 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
to a SOFTIRQ-irq-unsafe lock:
(&bond->stats_lock/2){+.+.}-{3:3}
... which became SOFTIRQ-irq-unsafe at:
...
lock_acquire+0x106/0x350 kernel/locking/lockdep.c:5868
_raw_spin_lock_nested+0x32/0x50 kernel/locking/spinlock.c:382
bond_get_stats+0x458/0x740 drivers/net/bonding/bond_main.c:4514
dev_get_stats+0xb4/0xa50 net/core/dev.c:11916
rtnl_fill_stats+0x47/0x8c0 net/core/rtnetlink.c:1506
rtnl_fill_ifinfo+0x1840/0x20f0 net/core/rtnetlink.c:2155
rtmsg_ifinfo_build_skb+0x17d/0x260 net/core/rtnetlink.c:4452
rtmsg_ifinfo_event net/core/rtnetlink.c:4485 [inline]
rtnetlink_event+0x1b7/0x270 net/core/rtnetlink.c:7054
notifier_call_chain+0x1ad/0x3d0 kernel/notifier.c:85
call_netdevice_notifiers_extack net/core/dev.c:2287 [inline]
call_netdevice_notifiers net/core/dev.c:2301 [inline]
netdev_features_change net/core/dev.c:1590 [inline]
netdev_change_features net/core/dev.c:11155 [inline]
netdev_compute_master_upper_features+0x91e/0xac0 net/core/dev.c:12913
bond_enslave+0x21cc/0x3c10 drivers/net/bonding/bond_main.c:2276
do_set_master+0x533/0x6d0 net/core/rtnetlink.c:2985
do_setlink+0x1018/0x4590 net/core/rtnetlink.c:3187
rtnl_changelink net/core/rtnetlink.c:3798 [inline]
__rtnl_newlink net/core/rtnetlink.c:3971 [inline]
rtnl_newlink+0x15ad/0x1bb0 net/core/rtnetlink.c:4108
rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6994
netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
netlink_unicast+0x75c/0x8e0 net/netlink/af_netlink.c:1344
netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
sock_sendmsg_nosec net/socket.c:787 [inline]
__sock_sendmsg net/socket.c:802 [inline]
____sys_sendmsg+0x972/0x9f0 net/socket.c:2698
___sys_sendmsg+0x2a5/0x360 net/socket.c:2752
__sys_sendmsg net/socket.c:2784 [inline]
__do_sys_sendmsg net/socket.c:2789 [inline]
__se_sys_sendmsg net/socket.c:2787 [inline]
__x64_sys_sendmsg+0x1bd/0x2a0 net/socket.c:2787
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x15f/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
other info that might help us debug this:
Possible interrupt unsafe locking scenario:
CPU0 CPU1
---- ----
lock(&bond->stats_lock/2);
local_irq_disable();
lock(&br->lock);
lock(&bond->stats_lock/2);
<Interrupt>
lock(&br->lock);
*** DEADLOCK ***
3 locks held by syz.3.6945/21491:
#0: ffffffff8fdddc80 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_lock net/core/rtnetlink.c:80 [inline]
#0: ffffffff8fdddc80 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_nets_lock net/core/rtnetlink.c:341 [inline]
#0: ffffffff8fdddc80 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_newlink+0x883/0x1bb0 net/core/rtnetlink.c:4107
#1: ffff888036758e18 (&br->lock){+.-.}-{3:3}, at: spin_lock_bh include/linux/spinlock.h:348 [inline]
#1: ffff888036758e18 (&br->lock){+.-.}-{3:3}, at: br_port_slave_changelink+0x3d/0x150 net/bridge/br_netlink.c:1212
#2: ffffffff8e95cb20 (rcu_read_lock){....}-{1:3}, at: rcu_lock_acquire include/linux/rcupdate.h:300 [inline]
#2: ffffffff8e95cb20 (rcu_read_lock){....}-{1:3}, at: rcu_read_lock include/linux/rcupdate.h:838 [inline]
#2: ffffffff8e95cb20 (rcu_read_lock){....}-{1:3}, at: bond_get_stats+0x11a/0x740 drivers/net/bonding/bond_main.c:4509
the dependencies between SOFTIRQ-irq-safe lock and the holding lock:
-> (&br->lock){+.-.}-{3:3} {
HARDIRQ-ON-W at:
lock_acquire+0x106/0x350 kernel/locking/lockdep.c:5868
__raw_spin_lock_bh include/linux/spinlock_api_smp.h:150 [inline]
_raw_spin_lock_bh+0x36/0x50 kernel/locking/spinlock.c:182
spin_lock_bh include/linux/spinlock.h:348 [inline]
br_add_if+0xa99/0xeb0 net/bridge/br_if.c:668
do_set_master+0x533/0x6d0 net/core/rtnetlink.c:2985
do_setlink+0x1018/0x4590 net/core/rtnetlink.c:3187
rtnl_changelink net/core/rtnetlink.c:3798 [inline]
__rtnl_newlink net/core/rtnetlink.c:3971 [inline]
rtnl_newlink+0x15ad/0x1bb0 net/core/rtnetlink.c:4108
rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6994
netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
netlink_unicast+0x75c/0x8e0 net/netlink/af_netlink.c:1344
netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
sock_sendmsg_nosec net/socket.c:787 [inline]
__sock_sendmsg net/socket.c:802 [inline]
__sys_sendto+0x672/0x710 net/socket.c:2265
__do_sys_sendto net/socket.c:2272 [inline]
__se_sys_sendto net/socket.c:2268 [inline]
__x64_sys_sendto+0xde/0x100 net/socket.c:2268
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x15f/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
IN-SOFTIRQ-W at:
lock_acquire+0x106/0x350 kernel/locking/lockdep.c:5868
__raw_spin_lock include/linux/spinlock_api_smp.h:158 [inline]
_raw_spin_lock+0x2e/0x40 kernel/locking/spinlock.c:158
spin_lock include/linux/spinlock.h:342 [inline]
br_forward_delay_timer_expired+0x4f/0x460 net/bridge/br_stp_timer.c:88
call_timer_fn+0x192/0x5e0 kernel/time/timer.c:1748
expire_timers kernel/time/timer.c:1799 [inline]
__run_timers kernel/time/timer.c:2374 [inline]
__run_timer_base+0x652/0x8b0 kernel/time/timer.c:2386
run_timer_base kernel/time/timer.c:2395 [inline]
run_timer_softirq+0xb7/0x170 kernel/time/timer.c:2405
handle_softirqs+0x22a/0x840 kernel/softirq.c:622
__do_softirq kernel/softirq.c:656 [inline]
invoke_softirq kernel/softirq.c:496 [inline]
__irq_exit_rcu+0xca/0x220 kernel/softirq.c:735
irq_exit_rcu+0x9/0x30 kernel/softirq.c:752
common_interrupt+0xbb/0xe0 arch/x86/kernel/irq.c:326
asm_common_interrupt+0x26/0x40 arch/x86/include/asm/idtentry.h:688
finish_task_switch+0x427/0xbe0 kernel/sched/core.c:5244
context_switch kernel/sched/core.c:5390 [inline]
__schedule+0x17bc/0x5680 kernel/sched/core.c:7188
__schedule_loop kernel/sched/core.c:7267 [inline]
schedule+0x164/0x360 kernel/sched/core.c:7282
smpboot_thread_fn+0x5bc/0xa50 kernel/smpboot.c:156
kthread+0x388/0x470 kernel/kthread.c:436
ret_from_fork+0x514/0xb70 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
INITIAL USE at:
lock_acquire+0x106/0x350 kernel/locking/lockdep.c:5868
__raw_spin_lock_bh include/linux/spinlock_api_smp.h:150 [inline]
_raw_spin_lock_bh+0x36/0x50 kernel/locking/spinlock.c:182
spin_lock_bh include/linux/spinlock.h:348 [inline]
br_add_if+0xa99/0xeb0 net/bridge/br_if.c:668
do_set_master+0x533/0x6d0 net/core/rtnetlink.c:2985
do_setlink+0x1018/0x4590 net/core/rtnetlink.c:3187
rtnl_changelink net/core/rtnetlink.c:3798 [inline]
__rtnl_newlink net/core/rtnetlink.c:3971 [inline]
rtnl_newlink+0x15ad/0x1bb0 net/core/rtnetlink.c:4108
rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6994
netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
netlink_unicast+0x75c/0x8e0 net/netlink/af_netlink.c:1344
netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
sock_sendmsg_nosec net/socket.c:787 [inline]
__sock_sendmsg net/socket.c:802 [inline]
__sys_sendto+0x672/0x710 net/socket.c:2265
__do_sys_sendto net/socket.c:2272 [inline]
__se_sys_sendto net/socket.c:2268 [inline]
__x64_sys_sendto+0xde/0x100 net/socket.c:2268
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x15f/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
}
... key at: [<ffffffff9aa0b240>] br_dev_setup.__key+0x0/0x20
the dependencies between the lock to be acquired
and SOFTIRQ-irq-unsafe lock:
-> (&bond->stats_lock/2){+.+.}-{3:3} {
HARDIRQ-ON-W at:
lock_acquire+0x106/0x350 kernel/locking/lockdep.c:5868
_raw_spin_lock_nested+0x32/0x50 kernel/locking/spinlock.c:382
bond_get_stats+0x458/0x740 drivers/net/bonding/bond_main.c:4514
dev_get_stats+0xb4/0xa50 net/core/dev.c:11916
rtnl_fill_stats+0x47/0x8c0 net/core/rtnetlink.c:1506
rtnl_fill_ifinfo+0x1840/0x20f0 net/core/rtnetlink.c:2155
rtmsg_ifinfo_build_skb+0x17d/0x260 net/core/rtnetlink.c:4452
rtmsg_ifinfo_event net/core/rtnetlink.c:4485 [inline]
rtnetlink_event+0x1b7/0x270 net/core/rtnetlink.c:7054
notifier_call_chain+0x1ad/0x3d0 kernel/notifier.c:85
call_netdevice_notifiers_extack net/core/dev.c:2287 [inline]
call_netdevice_notifiers net/core/dev.c:2301 [inline]
netdev_features_change net/core/dev.c:1590 [inline]
netdev_change_features net/core/dev.c:11155 [inline]
netdev_compute_master_upper_features+0x91e/0xac0 net/core/dev.c:12913
bond_enslave+0x21cc/0x3c10 drivers/net/bonding/bond_main.c:2276
do_set_master+0x533/0x6d0 net/core/rtnetlink.c:2985
do_setlink+0x1018/0x4590 net/core/rtnetlink.c:3187
rtnl_changelink net/core/rtnetlink.c:3798 [inline]
__rtnl_newlink net/core/rtnetlink.c:3971 [inline]
rtnl_newlink+0x15ad/0x1bb0 net/core/rtnetlink.c:4108
rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6994
netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
netlink_unicast+0x75c/0x8e0 net/netlink/af_netlink.c:1344
netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
sock_sendmsg_nosec net/socket.c:787 [inline]
__sock_sendmsg net/socket.c:802 [inline]
____sys_sendmsg+0x972/0x9f0 net/socket.c:2698
___sys_sendmsg+0x2a5/0x360 net/socket.c:2752
__sys_sendmsg net/socket.c:2784 [inline]
__do_sys_sendmsg net/socket.c:2789 [inline]
__se_sys_sendmsg net/socket.c:2787 [inline]
__x64_sys_sendmsg+0x1bd/0x2a0 net/socket.c:2787
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x15f/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
SOFTIRQ-ON-W at:
lock_acquire+0x106/0x350 kernel/locking/lockdep.c:5868
_raw_spin_lock_nested+0x32/0x50 kernel/locking/spinlock.c:382
bond_get_stats+0x458/0x740 drivers/net/bonding/bond_main.c:4514
dev_get_stats+0xb4/0xa50 net/core/dev.c:11916
rtnl_fill_stats+0x47/0x8c0 net/core/rtnetlink.c:1506
rtnl_fill_ifinfo+0x1840/0x20f0 net/core/rtnetlink.c:2155
rtmsg_ifinfo_build_skb+0x17d/0x260 net/core/rtnetlink.c:4452
rtmsg_ifinfo_event net/core/rtnetlink.c:4485 [inline]
rtnetlink_event+0x1b7/0x270 net/core/rtnetlink.c:7054
notifier_call_chain+0x1ad/0x3d0 kernel/notifier.c:85
call_netdevice_notifiers_extack net/core/dev.c:2287 [inline]
call_netdevice_notifiers net/core/dev.c:2301 [inline]
netdev_features_change net/core/dev.c:1590 [inline]
netdev_change_features net/core/dev.c:11155 [inline]
netdev_compute_master_upper_features+0x91e/0xac0 net/core/dev.c:12913
bond_enslave+0x21cc/0x3c10 drivers/net/bonding/bond_main.c:2276
do_set_master+0x533/0x6d0 net/core/rtnetlink.c:2985
do_setlink+0x1018/0x4590 net/core/rtnetlink.c:3187
rtnl_changelink net/core/rtnetlink.c:3798 [inline]
__rtnl_newlink net/core/rtnetlink.c:3971 [inline]
rtnl_newlink+0x15ad/0x1bb0 net/core/rtnetlink.c:4108
rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6994
netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
netlink_unicast+0x75c/0x8e0 net/netlink/af_netlink.c:1344
netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
sock_sendmsg_nosec net/socket.c:787 [inline]
__sock_sendmsg net/socket.c:802 [inline]
____sys_sendmsg+0x972/0x9f0 net/socket.c:2698
___sys_sendmsg+0x2a5/0x360 net/socket.c:2752
__sys_sendmsg net/socket.c:2784 [inline]
__do_sys_sendmsg net/socket.c:2789 [inline]
__se_sys_sendmsg net/socket.c:2787 [inline]
__x64_sys_sendmsg+0x1bd/0x2a0 net/socket.c:2787
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x15f/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
INITIAL USE at:
lock_acquire+0x106/0x350 kernel/locking/lockdep.c:5868
_raw_spin_lock_nested+0x32/0x50 kernel/locking/spinlock.c:382
bond_get_stats+0x458/0x740 drivers/net/bonding/bond_main.c:4514
dev_get_stats+0xb4/0xa50 net/core/dev.c:11916
rtnl_fill_stats+0x47/0x8c0 net/core/rtnetlink.c:1506
rtnl_fill_ifinfo+0x1840/0x20f0 net/core/rtnetlink.c:2155
rtmsg_ifinfo_build_skb+0x17d/0x260 net/core/rtnetlink.c:4452
rtmsg_ifinfo_event net/core/rtnetlink.c:4485 [inline]
rtnetlink_event+0x1b7/0x270 net/core/rtnetlink.c:7054
notifier_call_chain+0x1ad/0x3d0 kernel/notifier.c:85
call_netdevice_notifiers_extack net/core/dev.c:2287 [inline]
call_netdevice_notifiers net/core/dev.c:2301 [inline]
netdev_features_change net/core/dev.c:1590 [inline]
netdev_change_features net/core/dev.c:11155 [inline]
netdev_compute_master_upper_features+0x91e/0xac0 net/core/dev.c:12913
bond_enslave+0x21cc/0x3c10 drivers/net/bonding/bond_main.c:2276
do_set_master+0x533/0x6d0 net/core/rtnetlink.c:2985
do_setlink+0x1018/0x4590 net/core/rtnetlink.c:3187
rtnl_changelink net/core/rtnetlink.c:3798 [inline]
__rtnl_newlink net/core/rtnetlink.c:3971 [inline]
rtnl_newlink+0x15ad/0x1bb0 net/core/rtnetlink.c:4108
rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6994
netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
netlink_unicast+0x75c/0x8e0 net/netlink/af_netlink.c:1344
netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
sock_sendmsg_nosec net/socket.c:787 [inline]
__sock_sendmsg net/socket.c:802 [inline]
____sys_sendmsg+0x972/0x9f0 net/socket.c:2698
___sys_sendmsg+0x2a5/0x360 net/socket.c:2752
__sys_sendmsg net/socket.c:2784 [inline]
__do_sys_sendmsg net/socket.c:2789 [inline]
__se_sys_sendmsg net/socket.c:2787 [inline]
__x64_sys_sendmsg+0x1bd/0x2a0 net/socket.c:2787
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x15f/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
}
... key at: [<ffffffff9a825582>] bond_init.__key+0x2/0x20
... acquired at:
_raw_spin_lock_nested+0x32/0x50 kernel/locking/spinlock.c:382
bond_get_stats+0x458/0x740 drivers/net/bonding/bond_main.c:4514
dev_get_stats+0xb4/0xa50 net/core/dev.c:11916
rtnl_fill_stats+0x47/0x8c0 net/core/rtnetlink.c:1506
rtnl_fill_ifinfo+0x1840/0x20f0 net/core/rtnetlink.c:2155
rtmsg_ifinfo_build_skb+0x17d/0x260 net/core/rtnetlink.c:4452
rtmsg_ifinfo_event net/core/rtnetlink.c:4485 [inline]
rtmsg_ifinfo+0x8c/0x1a0 net/core/rtnetlink.c:4494
__dev_notify_flags+0xf2/0x310 net/core/dev.c:9845
__dev_set_promiscuity+0x27f/0x710 net/core/dev.c:9647
netif_set_promiscuity+0x50/0xe0 net/core/dev.c:9657
dev_set_promiscuity+0x126/0x260 net/core/dev_api.c:287
br_port_clear_promisc net/bridge/br_if.c:135 [inline]
br_manage_promisc+0x4db/0x560 net/bridge/br_if.c:172
nbp_update_port_count net/bridge/br_if.c:242 [inline]
br_port_flags_change+0x160/0x1f0 net/bridge/br_if.c:747
br_setport+0xc0a/0x1680 net/bridge/br_netlink.c:1000
br_port_slave_changelink+0x12f/0x150 net/bridge/br_netlink.c:1213
rtnl_changelink net/core/rtnetlink.c:3791 [inline]
__rtnl_newlink net/core/rtnetlink.c:3971 [inline]
rtnl_newlink+0x191b/0x1bb0 net/core/rtnetlink.c:4108
rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6994
netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
netlink_unicast+0x75c/0x8e0 net/netlink/af_netlink.c:1344
netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
sock_sendmsg_nosec net/socket.c:787 [inline]
__sock_sendmsg net/socket.c:802 [inline]
____sys_sendmsg+0x972/0x9f0 net/socket.c:2698
___sys_sendmsg+0x2a5/0x360 net/socket.c:2752
__sys_sendmsg net/socket.c:2784 [inline]
__do_sys_sendmsg net/socket.c:2789 [inline]
__se_sys_sendmsg net/socket.c:2787 [inline]
__x64_sys_sendmsg+0x1bd/0x2a0 net/socket.c:2787
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x15f/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
stack backtrace:
CPU: 0 UID: 0 PID: 21491 Comm: syz.3.6945 Tainted: G L syzkaller #0 PREEMPT(full)
Tainted: [L]=SOFTLOCKUP
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 03/18/2026
Call Trace:
<TASK>
dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120
print_bad_irq_dependency kernel/locking/lockdep.c:2616 [inline]
check_irq_usage kernel/locking/lockdep.c:2857 [inline]
check_prev_add kernel/locking/lockdep.c:3169 [inline]
check_prevs_add kernel/locking/lockdep.c:3284 [inline]
validate_chain kernel/locking/lockdep.c:3908 [inline]
__lock_acquire+0x2a94/0x2cf0 kernel/locking/lockdep.c:5237
lock_acquire+0x106/0x350 kernel/locking/lockdep.c:5868
_raw_spin_lock_nested+0x32/0x50 kernel/locking/spinlock.c:382
bond_get_stats+0x458/0x740 drivers/net/bonding/bond_main.c:4514
dev_get_stats+0xb4/0xa50 net/core/dev.c:11916
rtnl_fill_stats+0x47/0x8c0 net/core/rtnetlink.c:1506
rtnl_fill_ifinfo+0x1840/0x20f0 net/core/rtnetlink.c:2155
rtmsg_ifinfo_build_skb+0x17d/0x260 net/core/rtnetlink.c:4452
rtmsg_ifinfo_event net/core/rtnetlink.c:4485 [inline]
rtmsg_ifinfo+0x8c/0x1a0 net/core/rtnetlink.c:4494
__dev_notify_flags+0xf2/0x310 net/core/dev.c:9845
__dev_set_promiscuity+0x27f/0x710 net/core/dev.c:9647
netif_set_promiscuity+0x50/0xe0 net/core/dev.c:9657
dev_set_promiscuity+0x126/0x260 net/core/dev_api.c:287
br_port_clear_promisc net/bridge/br_if.c:135 [inline]
br_manage_promisc+0x4db/0x560 net/bridge/br_if.c:172
nbp_update_port_count net/bridge/br_if.c:242 [inline]
br_port_flags_change+0x160/0x1f0 net/bridge/br_if.c:747
br_setport+0xc0a/0x1680 net/bridge/br_netlink.c:1000
br_port_slave_changelink+0x12f/0x150 net/bridge/br_netlink.c:1213
rtnl_changelink net/core/rtnetlink.c:3791 [inline]
__rtnl_newlink net/core/rtnetlink.c:3971 [inline]
rtnl_newlink+0x191b/0x1bb0 net/core/rtnetlink.c:4108
rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6994
netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
netlink_unicast+0x75c/0x8e0 net/netlink/af_netlink.c:1344
netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
sock_sendmsg_nosec net/socket.c:787 [inline]
__sock_sendmsg net/socket.c:802 [inline]
____sys_sendmsg+0x972/0x9f0 net/socket.c:2698
___sys_sendmsg+0x2a5/0x360 net/socket.c:2752
__sys_sendmsg net/socket.c:2784 [inline]
__do_sys_sendmsg net/socket.c:2789 [inline]
__se_sys_sendmsg net/socket.c:2787 [inline]
__x64_sys_sendmsg+0x1bd/0x2a0 net/socket.c:2787
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x15f/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f779019c819
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f7791124028 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
RAX: ffffffffffffffda RBX: 00007f7790415fa0 RCX: 00007f779019c819
RDX: 0000000000008002 RSI: 0000200000000340 RDI: 0000000000000003
RBP: 00007f7790232c91 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007f7790416038 R14: 00007f7790415fa0 R15: 00007f779053fa48
</TASK>
---
This report is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.
syzbot will keep track of this issue. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.
If the report is already addressed, let syzbot know by replying with:
#syz fix: exact-commit-title
If you want to overwrite report's subsystems, reply with:
#syz set subsystems: new-subsystem
(See the list of subsystem names on the web dashboard)
If the report is a duplicate of another one, reply with:
#syz dup: exact-subject-of-another-report
If you want to undo deduplication, reply with:
#syz undup
^ permalink raw reply
* Re: [PATCH v1 net] tcp: Disable usec TS for SYN Cookie.
From: Eric Dumazet @ 2026-04-18 4:59 UTC (permalink / raw)
To: Kuniyuki Iwashima
Cc: Neal Cardwell, David S. Miller, Jakub Kicinski, Paolo Abeni,
Simon Horman, Kuniyuki Iwashima, netdev
In-Reply-To: <20260418024957.2669737-1-kuniyu@google.com>
On Fri, Apr 17, 2026 at 7:50 PM Kuniyuki Iwashima <kuniyu@google.com> wrote:
>
> cookie_tcp_reqsk_alloc() sets tcp_rsk(req)->req_usec_ts to false
> unconditionally.
>
> If want_cookie is true in tcp_conn_request(), we should not set
> tcp_rsk(req)->req_usec_ts.
>
> Let's not call dst_tcp_usec_ts() for SYN Cookie.
May I ask why ?
TCP usec TS are based on routing. this feature is not part of SYN
and/or SYNACK options.
Both side must have:
ip route ... feature tcp_usec_ts
syncookies are orthogonal to this constraint, so TCP flows can use
usec TS just fine.
pw-bot: cr
^ permalink raw reply
* [PATCH net 4/4] xsk: fix use-after-free of xs->skb in xsk_build_skb() free_err path
From: Jason Xing @ 2026-04-18 4:56 UTC (permalink / raw)
To: davem, edumazet, kuba, pabeni, bjorn, magnus.karlsson,
maciej.fijalkowski, jonathan.lemon, sdf, ast, daniel, hawk,
john.fastabend, horms, andrew+netdev
Cc: bpf, netdev, Jason Xing
In-Reply-To: <20260418045644.28612-1-kerneljasonxing@gmail.com>
From: Jason Xing <kernelxing@tencent.com>
When xsk_build_skb() processes multi-buffer packets in copy mode, the
first descriptor stores data into the skb linear area without adding
any frags, so nr_frags stays at 0. The caller then sets xs->skb = skb
to accumulate subsequent descriptors.
If a continuation descriptor fails (e.g. alloc_page returns NULL with
-EAGAIN), we jump to free_err where the condition:
if (skb && !skb_shinfo(skb)->nr_frags)
kfree_skb(skb);
evaluates to true because nr_frags is still 0 (the first descriptor
used the linear area, not frags). This frees the skb while xs->skb
still points to it, creating a dangling pointer. On the next transmit
attempt or socket close, xs->skb is dereferenced, causing a
use-after-free or double-free.
Fix by adding a !xs->skb check to the condition, ensuring we only free
skbs that were freshly allocated in this call (xs->skb is NULL) and
never free an in-progress multi-buffer skb that the caller still
references.
Closes: https://lore.kernel.org/all/20260415082654.21026-4-kerneljasonxing@gmail.com/
Fixes: 6b9c129c2f93 ("xsk: remove @first_frag from xsk_build_skb()")
Signed-off-by: Jason Xing <kernelxing@tencent.com>
---
net/xdp/xsk.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
index 2918b773aa84..22c7a92e0734 100644
--- a/net/xdp/xsk.c
+++ b/net/xdp/xsk.c
@@ -894,7 +894,7 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
return skb;
free_err:
- if (skb && !skb_shinfo(skb)->nr_frags)
+ if (skb && !xs->skb && !skb_shinfo(skb)->nr_frags)
kfree_skb(skb);
if (err == -EOVERFLOW) {
--
2.41.3
^ permalink raw reply related
* [PATCH net 3/4] xsk: handle NULL dereference of the skb without frags issue
From: Jason Xing @ 2026-04-18 4:56 UTC (permalink / raw)
To: davem, edumazet, kuba, pabeni, bjorn, magnus.karlsson,
maciej.fijalkowski, jonathan.lemon, sdf, ast, daniel, hawk,
john.fastabend, horms, andrew+netdev
Cc: bpf, netdev, Jason Xing
In-Reply-To: <20260418045644.28612-1-kerneljasonxing@gmail.com>
From: Jason Xing <kernelxing@tencent.com>
When a first descriptor (xs->skb == NULL) triggers -EOVERFLOW in
xsk_build_skb_zerocopy (e.g., MAX_SKB_FRAGS exceeded), the free_err
EOVERFLOW handler unconditionally dereferences xs->skb via
xsk_inc_num_desc(xs->skb) and xsk_drop_skb(xs->skb), causing a NULL
pointer dereference.
In the patch 2/4, the skb is already freed by kfree_skb() inside
xsk_build_skb_zerocopy for the first-descriptor case, so we only need
to do the bookkeeping: cancel the one reserved CQ slot and account for
the single invalid descriptor.
Guard the existing xsk_inc_num_desc/xsk_drop_skb calls with an
xs->skb check (for the continuation case), and add an else branch
for the first-descriptor case that manually cancels the CQ slot and
increments invalid_descs by one.
Fixes: cf24f5a5feea ("xsk: add support for AF_XDP multi-buffer on Tx path")
Signed-off-by: Jason Xing <kernelxing@tencent.com>
---
net/xdp/xsk.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
index 5d3dbb118730..2918b773aa84 100644
--- a/net/xdp/xsk.c
+++ b/net/xdp/xsk.c
@@ -898,9 +898,14 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
kfree_skb(skb);
if (err == -EOVERFLOW) {
- /* Drop the packet */
- xsk_inc_num_desc(xs->skb);
- xsk_drop_skb(xs->skb);
+ if (xs->skb) {
+ /* Drop the packet */
+ xsk_inc_num_desc(xs->skb);
+ xsk_drop_skb(xs->skb);
+ } else {
+ xsk_cq_cancel_locked(xs->pool, 1);
+ xs->tx->invalid_descs++;
+ }
xskq_cons_release(xs->tx);
} else {
/* Let application retry */
--
2.41.3
^ permalink raw reply related
* [PATCH net 2/4] xsk: free the skb when hitting the upper bound MAX_SKB_FRAGS
From: Jason Xing @ 2026-04-18 4:56 UTC (permalink / raw)
To: davem, edumazet, kuba, pabeni, bjorn, magnus.karlsson,
maciej.fijalkowski, jonathan.lemon, sdf, ast, daniel, hawk,
john.fastabend, horms, andrew+netdev
Cc: bpf, netdev, Jason Xing
In-Reply-To: <20260418045644.28612-1-kerneljasonxing@gmail.com>
From: Jason Xing <kernelxing@tencent.com>
Fix it by explicitly adding kfree_skb() before returning back to its
caller.
How to reproduce it in virtio_net:
1. the current skb is the first one (which means xs->skb is NULL) and
hit the limit MAX_SKB_FRAGS.
2. xsk_build_skb_zerocopy() returns -EOVERFLOW.
3. the caller xsk_build_skb() clears skb by using 'skb = NULL;'. This
is why bug can be triggered.
4. there is no chance to free this skb anymore.
Note that if in this case the xs->skb is not NULL, xsk_build_skb() will
call xsk_drop_skb(xs->skb) to do the right thing.
Fixes: cf24f5a5feea ("xsk: add support for AF_XDP multi-buffer on Tx path")
Signed-off-by: Jason Xing <kernelxing@tencent.com>
---
net/xdp/xsk.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
index 8fcde34aec7b..5d3dbb118730 100644
--- a/net/xdp/xsk.c
+++ b/net/xdp/xsk.c
@@ -778,8 +778,11 @@ static struct sk_buff *xsk_build_skb_zerocopy(struct xdp_sock *xs,
addr = buffer - pool->addrs;
for (copied = 0, i = skb_shinfo(skb)->nr_frags; copied < len; i++) {
- if (unlikely(i >= MAX_SKB_FRAGS))
+ if (unlikely(i >= MAX_SKB_FRAGS)) {
+ if (!xs->skb)
+ kfree_skb(skb);
return ERR_PTR(-EOVERFLOW);
+ }
page = pool->umem->pgs[addr >> PAGE_SHIFT];
get_page(page);
--
2.41.3
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox