From: Eric Dumazet <edumazet@kernel.org>
To: "David S . Miller" <davem@davemloft.net>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>
Cc: Willem de Bruijn <willemb@google.com>,
Mahesh Bandewar <maheshb@google.com>,
Kuniyuki Iwashima <kuniyu@google.com>,
Simon Horman <horms@kernel.org>,
netdev@vger.kernel.org, Kyle Zeng <kylebot@openai.com>,
Eric Dumazet <edumazet@kernel.org>
Subject: [PATCH net] ipvlan: make outbound skb headers writable
Date: Wed, 4 Nov 2026 12:35:30 +0100 [thread overview]
Message-ID: <20261104113530.986664-1-edumazet@kernel.org> (raw)
From: Kyle Zeng <kylebot@openai.com>
In L3 and L3S modes, ipvlan_process_v4_outbound() and
ipvlan_process_v6_outbound() hand the skb to ip_local_out() and
ip6_local_out(). The IP output path assumes it owns the network header:
__ip_local_out() rewrites tot_len and the header checksum, and
transport-mode XFRM can memmove the network header into the headroom
when xfrm_skb_check_space() finds enough room, without copying.
The skb reaching ipvlan can have its header shared with another skb,
for example after an AF_PACKET tap on the ipvlan device or a tc mirred
mirror action. pskb_network_may_pull() only makes the header linear;
it does not unshare an already linear head. The writes above then
modify the other skb. If that skb is on the receive path and its IPv4
header was already validated, IPv4 option processing can use the
modified header, write past the linear data, and corrupt
skb_shared_info.
Use skb_cow_head() before taking header pointers and entering the local
IP output path, like ip_forward() does with skb_cow() before it touches
the header. Only checking skb_header_cloned() is enough here: skbs that
TCP transmits are clones of the write-queue skb, whose header area has
been released with __skb_header_release(). Their headers are private,
so they are not copied, which avoids a reallocation for every TCP
segment sent through an ipvlan slave.
If the allocation fails, the existing error accounting and drop paths
are used. L2 mode is unaffected.
Fixes: 2ad7bf363841 ("ipvlan: Initial check-in of the IPVLAN driver.")
Signed-off-by: Kyle Zeng <kylebot@openai.com>
[edumazet: use skb_cow_head() instead of skb_unclone() to avoid
copying every TCP segment, reword changelog]
Signed-off-by: Eric Dumazet <edumazet@kernel.org>
---
drivers/net/ipvlan/ipvlan_core.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c
index 7ad12dc7845c836bdd04395f153b2b4b397797d6..d2afc2ec896e039d174e2b0ecfd4c9ff6634cfaa 100644
--- a/drivers/net/ipvlan/ipvlan_core.c
+++ b/drivers/net/ipvlan/ipvlan_core.c
@@ -438,7 +438,8 @@ static noinline_for_stack int ipvlan_process_v4_outbound(struct sk_buff *skb)
.flowi4_mark = skb->mark,
};
- if (!pskb_network_may_pull(skb, sizeof(struct iphdr)))
+ if (!pskb_network_may_pull(skb, sizeof(struct iphdr)) ||
+ skb_cow_head(skb, 0))
goto err;
ip4h = ip_hdr(skb);
@@ -504,7 +505,8 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb)
struct net_device *dev = skb->dev;
int err, ret = NET_XMIT_DROP;
- if (!pskb_network_may_pull(skb, sizeof(struct ipv6hdr))) {
+ if (!pskb_network_may_pull(skb, sizeof(struct ipv6hdr)) ||
+ skb_cow_head(skb, 0)) {
DEV_STATS_INC(dev, tx_errors);
kfree_skb(skb);
return ret;
--
2.53.0
next reply other threads:[~2026-11-04 11:35 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-04 11:35 Eric Dumazet [this message]
2026-11-04 11:39 ` [PATCH net] ipvlan: make outbound skb headers writable netdev-bot+sinfo
2026-11-04 11:48 ` Eric Dumazet
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261104113530.986664-1-edumazet@kernel.org \
--to=edumazet@kernel.org \
--cc=davem@davemloft.net \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=kuniyu@google.com \
--cc=kylebot@openai.com \
--cc=maheshb@google.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=willemb@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox