* [PATCH bpf v4 0/3] bpf, sockmap: reject a packet-modifying SK_SKB stream parser
@ 2026-06-19 6:29 Sechang Lim
2026-06-19 6:29 ` [PATCH bpf v4 1/3] selftests/bpf: don't modify the skb in the strparser parser prog Sechang Lim
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Sechang Lim @ 2026-06-19 6:29 UTC (permalink / raw)
To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
Eduard Zingerman, Kumar Kartikeya Dwivedi, John Fastabend,
Jakub Sitnicki, David S . Miller, Jakub Kicinski, Eric Dumazet,
Paolo Abeni, Kuniyuki Iwashima, Willem de Bruijn, Shuah Khan
Cc: Jiri Olsa, Martin KaFai Lau, Song Liu, Yonghong Song,
Simon Horman, Bobby Eshleman, Jiayuan Chen, bpf, netdev,
linux-kernel, linux-kselftest
A BPF_PROG_TYPE_SK_SKB stream parser runs on strparser's message head,
which can chain skbs through frag_list. A parser that resizes the skb
frees the frag_list segments that strparser still tracks through
skb_nextp, leading to a use-after-free.
A stream parser is only meant to measure the next message, not to modify
the packet, so reject a packet-modifying parser at attach time.
v4:
- drop the Fixes tag (Jiayuan Chen)
- drop the unsafe skb modification from the test prog (John Fastabend)
v3:
- https://lore.kernel.org/all/20260618102718.2331468-1-rhkrqnwk98@gmail.com/
v2:
- https://lore.kernel.org/all/20260612123553.2724240-1-rhkrqnwk98@gmail.com/
v1:
- https://lore.kernel.org/all/20260609112316.3685738-1-rhkrqnwk98@gmail.com/
Sechang Lim (3):
selftests/bpf: don't modify the skb in the strparser parser prog
bpf, sockmap: reject a packet-modifying SK_SKB stream parser
selftests/bpf: test rejection of a packet-modifying SK_SKB stream
parser
net/core/sock_map.c | 20 ++++++++++++
.../selftests/bpf/prog_tests/sockmap_strp.c | 31 +++++++++++++++++++
.../selftests/bpf/progs/sockmap_parse_prog.c | 22 -------------
.../selftests/bpf/progs/test_sockmap_strp.c | 7 +++++
4 files changed, 58 insertions(+), 22 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH bpf v4 1/3] selftests/bpf: don't modify the skb in the strparser parser prog
2026-06-19 6:29 [PATCH bpf v4 0/3] bpf, sockmap: reject a packet-modifying SK_SKB stream parser Sechang Lim
@ 2026-06-19 6:29 ` Sechang Lim
2026-06-19 6:35 ` Jiayuan Chen
2026-06-19 7:08 ` bot+bpf-ci
2026-06-19 6:29 ` [PATCH bpf v4 2/3] bpf, sockmap: reject a packet-modifying SK_SKB stream parser Sechang Lim
2026-06-19 6:29 ` [PATCH bpf v4 3/3] selftests/bpf: test rejection of " Sechang Lim
2 siblings, 2 replies; 10+ messages in thread
From: Sechang Lim @ 2026-06-19 6:29 UTC (permalink / raw)
To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
Eduard Zingerman, Kumar Kartikeya Dwivedi, John Fastabend,
Jakub Sitnicki, David S . Miller, Jakub Kicinski, Eric Dumazet,
Paolo Abeni, Kuniyuki Iwashima, Willem de Bruijn, Shuah Khan
Cc: Jiri Olsa, Martin KaFai Lau, Song Liu, Yonghong Song,
Simon Horman, Bobby Eshleman, Jiayuan Chen, bpf, netdev,
linux-kernel, linux-kselftest
sockmap_parse_prog.c is attached as an SK_SKB stream parser and modifies
the skb. It calls bpf_skb_pull_data() and writes a byte into the packet.
A stream parser runs on strparser's message head and must not modify it.
A resize frees the frag_list segments strparser still tracks, leading to
a use-after-free.
Make the parser read-only. It only needs to return the message length,
which keeps it attaching once packet-modifying parsers are rejected.
Signed-off-by: Sechang Lim <rhkrqnwk98@gmail.com>
---
.../selftests/bpf/progs/sockmap_parse_prog.c | 22 -------------------
1 file changed, 22 deletions(-)
diff --git a/tools/testing/selftests/bpf/progs/sockmap_parse_prog.c b/tools/testing/selftests/bpf/progs/sockmap_parse_prog.c
index c9abfe3a11af..56e9aebf05f2 100644
--- a/tools/testing/selftests/bpf/progs/sockmap_parse_prog.c
+++ b/tools/testing/selftests/bpf/progs/sockmap_parse_prog.c
@@ -5,28 +5,6 @@
SEC("sk_skb1")
int bpf_prog1(struct __sk_buff *skb)
{
- void *data_end = (void *)(long) skb->data_end;
- void *data = (void *)(long) skb->data;
- __u8 *d = data;
- int err;
-
- if (data + 10 > data_end) {
- err = bpf_skb_pull_data(skb, 10);
- if (err)
- return SK_DROP;
-
- data_end = (void *)(long)skb->data_end;
- data = (void *)(long)skb->data;
- if (data + 10 > data_end)
- return SK_DROP;
- }
-
- /* This write/read is a bit pointless but tests the verifier and
- * strparser handler for read/write pkt data and access into sk
- * fields.
- */
- d = data;
- d[7] = 1;
return skb->len;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH bpf v4 2/3] bpf, sockmap: reject a packet-modifying SK_SKB stream parser
2026-06-19 6:29 [PATCH bpf v4 0/3] bpf, sockmap: reject a packet-modifying SK_SKB stream parser Sechang Lim
2026-06-19 6:29 ` [PATCH bpf v4 1/3] selftests/bpf: don't modify the skb in the strparser parser prog Sechang Lim
@ 2026-06-19 6:29 ` Sechang Lim
2026-06-19 6:35 ` Jiayuan Chen
2026-06-19 6:51 ` sashiko-bot
2026-06-19 6:29 ` [PATCH bpf v4 3/3] selftests/bpf: test rejection of " Sechang Lim
2 siblings, 2 replies; 10+ messages in thread
From: Sechang Lim @ 2026-06-19 6:29 UTC (permalink / raw)
To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
Eduard Zingerman, Kumar Kartikeya Dwivedi, John Fastabend,
Jakub Sitnicki, David S . Miller, Jakub Kicinski, Eric Dumazet,
Paolo Abeni, Kuniyuki Iwashima, Willem de Bruijn, Shuah Khan
Cc: Jiri Olsa, Martin KaFai Lau, Song Liu, Yonghong Song,
Simon Horman, Bobby Eshleman, Jiayuan Chen, bpf, netdev,
linux-kernel, linux-kselftest
sk_psock_strp_parse() runs the BPF_PROG_TYPE_SK_SKB stream-parser program
to find the length of the next message. strparser assembles a message out
of several received skbs by chaining them onto the head's frag_list and
recording where to append the next one in strp->skb_nextp:
*strp->skb_nextp = skb;
strp->skb_nextp = &skb->next;
and then calls the parser on the head:
len = (*strp->cb.parse_msg)(strp, head);
The parser is only meant to inspect the skb, but the program may call
bpf_skb_change_tail() -- or the sibling bpf_skb_pull_data(),
bpf_skb_change_head(), bpf_skb_adjust_room(), all allowed for SK_SKB.
Once the head carries a frag_list these go
... -> skb_ensure_writable -> pskb_may_pull -> __pskb_pull_tail
and __pskb_pull_tail() frees the frag_list skbs that strparser still
tracks through skb_nextp:
while ((list = skb_shinfo(skb)->frag_list) != insp) {
skb_shinfo(skb)->frag_list = list->next;
consume_skb(list);
}
strp->skb_nextp now points into a freed sk_buff. The next segment of
the same message arrives in __strp_recv(), which links it with
*strp->skb_nextp = skb, an 8-byte write into the freed skb. The free
and the write happen in different __strp_recv() calls, so the message
has to span at least three segments before it triggers.
BUG: KASAN: slab-use-after-free in __strp_recv+0x447/0xda0
Write of size 8 at addr ffff88810db86140 by task repro/349
Call Trace:
<IRQ>
__strp_recv+0x447/0xda0
__tcp_read_sock+0x13d/0x590
tcp_bpf_strp_read_sock+0x195/0x320
strp_data_ready+0x267/0x340
sk_psock_strp_data_ready+0x1ce/0x350
tcp_data_queue+0x1364/0x2fd0
tcp_rcv_established+0xe07/0x1640
[...]
Allocated by task 349:
skb_clone+0x17b/0x210
__strp_recv+0x2c3/0xda0
__tcp_read_sock+0x13d/0x590
[...]
Freed by task 349:
kmem_cache_free+0x150/0x570
__pskb_pull_tail+0x57b/0xc20
skb_ensure_writable+0x236/0x260
__bpf_skb_change_tail+0x1d4/0x590
sk_skb_change_tail+0x2a/0x40
bpf_prog_1b285dcd6c41373e+0x27/0x30
bpf_prog_run_pin_on_cpu+0xf3/0x260
sk_psock_strp_parse+0x118/0x1e0
__strp_recv+0x4f6/0xda0
[...]
The same resize also leaves the head's length inconsistent with its
frags, so a later __pskb_pull_tail() can instead hit the
BUG_ON(skb_copy_bits(...)) in net/core/skbuff.c.
A stream parser is only meant to measure the next message, not to modify
the packet. Reject a parser whose program can change packet data
(prog->aux->changes_pkt_data) at attach time. The check is shared by
sock_map_prog_update() and sock_map_link_update_prog(), which between them
cover prog attach, link create and link update. Verdict programs are
unaffected and may still modify the skb.
Signed-off-by: Sechang Lim <rhkrqnwk98@gmail.com>
---
net/core/sock_map.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/net/core/sock_map.c b/net/core/sock_map.c
index 99e3789492a0..c60ba6d292f9 100644
--- a/net/core/sock_map.c
+++ b/net/core/sock_map.c
@@ -1515,6 +1515,17 @@ static int sock_map_prog_link_lookup(struct bpf_map *map, struct bpf_prog ***ppr
return 0;
}
+static int sock_map_prog_attach_check(enum bpf_attach_type attach_type,
+ struct bpf_prog *prog)
+{
+ /* A stream parser must not modify the skb, only measure it. */
+ if (prog && attach_type == BPF_SK_SKB_STREAM_PARSER &&
+ prog->aux->changes_pkt_data)
+ return -EINVAL;
+
+ return 0;
+}
+
/* Handle the following four cases:
* prog_attach: prog != NULL, old == NULL, link == NULL
* prog_detach: prog == NULL, old != NULL, link == NULL
@@ -1533,6 +1544,10 @@ static int sock_map_prog_update(struct bpf_map *map, struct bpf_prog *prog,
if (ret)
return ret;
+ ret = sock_map_prog_attach_check(which, prog);
+ if (ret)
+ return ret;
+
/* for prog_attach/prog_detach/link_attach, return error if a bpf_link
* exists for that prog.
*/
@@ -1776,6 +1791,11 @@ static int sock_map_link_update_prog(struct bpf_link *link,
ret = -EINVAL;
goto out;
}
+
+ ret = sock_map_prog_attach_check(link->attach_type, prog);
+ if (ret)
+ goto out;
+
if (!sockmap_link->map) {
ret = -ENOLINK;
goto out;
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH bpf v4 3/3] selftests/bpf: test rejection of a packet-modifying SK_SKB stream parser
2026-06-19 6:29 [PATCH bpf v4 0/3] bpf, sockmap: reject a packet-modifying SK_SKB stream parser Sechang Lim
2026-06-19 6:29 ` [PATCH bpf v4 1/3] selftests/bpf: don't modify the skb in the strparser parser prog Sechang Lim
2026-06-19 6:29 ` [PATCH bpf v4 2/3] bpf, sockmap: reject a packet-modifying SK_SKB stream parser Sechang Lim
@ 2026-06-19 6:29 ` Sechang Lim
2026-06-19 6:35 ` Jiayuan Chen
2026-06-19 7:08 ` bot+bpf-ci
2 siblings, 2 replies; 10+ messages in thread
From: Sechang Lim @ 2026-06-19 6:29 UTC (permalink / raw)
To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
Eduard Zingerman, Kumar Kartikeya Dwivedi, John Fastabend,
Jakub Sitnicki, David S . Miller, Jakub Kicinski, Eric Dumazet,
Paolo Abeni, Kuniyuki Iwashima, Willem de Bruijn, Shuah Khan
Cc: Jiri Olsa, Martin KaFai Lau, Song Liu, Yonghong Song,
Simon Horman, Bobby Eshleman, Jiayuan Chen, bpf, netdev,
linux-kernel, linux-kselftest
Verify that attaching an SK_SKB stream parser that can modify the packet
is rejected, while a read-only parser still attaches.
Signed-off-by: Sechang Lim <rhkrqnwk98@gmail.com>
---
.../selftests/bpf/prog_tests/sockmap_strp.c | 31 +++++++++++++++++++
.../selftests/bpf/progs/test_sockmap_strp.c | 7 +++++
2 files changed, 38 insertions(+)
diff --git a/tools/testing/selftests/bpf/prog_tests/sockmap_strp.c b/tools/testing/selftests/bpf/prog_tests/sockmap_strp.c
index 621b3b71888e..1d7231728eaf 100644
--- a/tools/testing/selftests/bpf/prog_tests/sockmap_strp.c
+++ b/tools/testing/selftests/bpf/prog_tests/sockmap_strp.c
@@ -431,6 +431,35 @@ static void test_sockmap_strp_verdict(int family, int sotype)
test_sockmap_strp__destroy(strp);
}
+static void test_sockmap_strp_parser_reject(void)
+{
+ struct test_sockmap_strp *strp = NULL;
+ int parser_mod, parser_ro, link;
+ int err, map;
+
+ strp = test_sockmap_strp__open_and_load();
+ if (!ASSERT_OK_PTR(strp, "test_sockmap_strp__open_and_load"))
+ return;
+
+ map = bpf_map__fd(strp->maps.sock_map);
+ parser_mod = bpf_program__fd(strp->progs.prog_skb_parser_resize);
+ parser_ro = bpf_program__fd(strp->progs.prog_skb_parser);
+
+ err = bpf_prog_attach(parser_mod, map, BPF_SK_SKB_STREAM_PARSER, 0);
+ ASSERT_ERR(err, "bpf_prog_attach parser_mod");
+
+ link = bpf_link_create(parser_ro, map, BPF_SK_SKB_STREAM_PARSER, NULL);
+ if (!ASSERT_GE(link, 0, "bpf_link_create parser_ro"))
+ goto out;
+
+ err = bpf_link_update(link, parser_mod, NULL);
+ ASSERT_ERR(err, "bpf_link_update parser_mod");
+out:
+ if (link >= 0)
+ close(link);
+ test_sockmap_strp__destroy(strp);
+}
+
void test_sockmap_strp(void)
{
if (test__start_subtest("sockmap strp tcp pass"))
@@ -451,4 +480,6 @@ void test_sockmap_strp(void)
test_sockmap_strp_multiple_pkt(AF_INET, SOCK_STREAM);
if (test__start_subtest("sockmap strp tcp dispatch"))
test_sockmap_strp_dispatch_pkt(AF_INET, SOCK_STREAM);
+ if (test__start_subtest("sockmap strp parser reject pkt mod"))
+ test_sockmap_strp_parser_reject();
}
diff --git a/tools/testing/selftests/bpf/progs/test_sockmap_strp.c b/tools/testing/selftests/bpf/progs/test_sockmap_strp.c
index dde3d5bec515..fe88fa6d40bc 100644
--- a/tools/testing/selftests/bpf/progs/test_sockmap_strp.c
+++ b/tools/testing/selftests/bpf/progs/test_sockmap_strp.c
@@ -50,4 +50,11 @@ int prog_skb_parser_partial(struct __sk_buff *skb)
return 10;
}
+SEC("sk_skb/stream_parser")
+int prog_skb_parser_resize(struct __sk_buff *skb)
+{
+ bpf_skb_change_tail(skb, skb->len, 0);
+ return skb->len;
+}
+
char _license[] SEC("license") = "GPL";
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH bpf v4 1/3] selftests/bpf: don't modify the skb in the strparser parser prog
2026-06-19 6:29 ` [PATCH bpf v4 1/3] selftests/bpf: don't modify the skb in the strparser parser prog Sechang Lim
@ 2026-06-19 6:35 ` Jiayuan Chen
2026-06-19 7:08 ` bot+bpf-ci
1 sibling, 0 replies; 10+ messages in thread
From: Jiayuan Chen @ 2026-06-19 6:35 UTC (permalink / raw)
To: Sechang Lim, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
Eduard Zingerman, Kumar Kartikeya Dwivedi, John Fastabend,
Jakub Sitnicki, David S . Miller, Jakub Kicinski, Eric Dumazet,
Paolo Abeni, Kuniyuki Iwashima, Willem de Bruijn, Shuah Khan
Cc: Jiri Olsa, Martin KaFai Lau, Song Liu, Yonghong Song,
Simon Horman, Bobby Eshleman, Jiayuan Chen, bpf, netdev,
linux-kernel, linux-kselftest
On 6/19/26 2:29 PM, Sechang Lim wrote:
> sockmap_parse_prog.c is attached as an SK_SKB stream parser and modifies
> the skb. It calls bpf_skb_pull_data() and writes a byte into the packet.
> A stream parser runs on strparser's message head and must not modify it.
> A resize frees the frag_list segments strparser still tracks, leading to
> a use-after-free.
>
> Make the parser read-only. It only needs to return the message length,
> which keeps it attaching once packet-modifying parsers are rejected.
>
> Signed-off-by: Sechang Lim <rhkrqnwk98@gmail.com>
This series should target bpf-next.
Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH bpf v4 2/3] bpf, sockmap: reject a packet-modifying SK_SKB stream parser
2026-06-19 6:29 ` [PATCH bpf v4 2/3] bpf, sockmap: reject a packet-modifying SK_SKB stream parser Sechang Lim
@ 2026-06-19 6:35 ` Jiayuan Chen
2026-06-19 6:51 ` sashiko-bot
1 sibling, 0 replies; 10+ messages in thread
From: Jiayuan Chen @ 2026-06-19 6:35 UTC (permalink / raw)
To: Sechang Lim, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
Eduard Zingerman, Kumar Kartikeya Dwivedi, John Fastabend,
Jakub Sitnicki, David S . Miller, Jakub Kicinski, Eric Dumazet,
Paolo Abeni, Kuniyuki Iwashima, Willem de Bruijn, Shuah Khan
Cc: Jiri Olsa, Martin KaFai Lau, Song Liu, Yonghong Song,
Simon Horman, Bobby Eshleman, Jiayuan Chen, bpf, netdev,
linux-kernel, linux-kselftest
On 6/19/26 2:29 PM, Sechang Lim wrote:
> sk_psock_strp_parse() runs the BPF_PROG_TYPE_SK_SKB stream-parser program
> to find the length of the next message. strparser assembles a message out
> of several received skbs by chaining them onto the head's frag_list and
> recording where to append the next one in strp->skb_nextp:
>
> *strp->skb_nextp = skb;
> strp->skb_nextp = &skb->next;
>
> and then calls the parser on the head:
>
> len = (*strp->cb.parse_msg)(strp, head);
>
> The parser is only meant to inspect the skb, but the program may call
> bpf_skb_change_tail() -- or the sibling bpf_skb_pull_data(),
> bpf_skb_change_head(), bpf_skb_adjust_room(), all allowed for SK_SKB.
> Once the head carries a frag_list these go
>
> ... -> skb_ensure_writable -> pskb_may_pull -> __pskb_pull_tail
>
> and __pskb_pull_tail() frees the frag_list skbs that strparser still
> tracks through skb_nextp:
>
> while ((list = skb_shinfo(skb)->frag_list) != insp) {
> skb_shinfo(skb)->frag_list = list->next;
> consume_skb(list);
> }
>
> strp->skb_nextp now points into a freed sk_buff. The next segment of
> the same message arrives in __strp_recv(), which links it with
> *strp->skb_nextp = skb, an 8-byte write into the freed skb. The free
> and the write happen in different __strp_recv() calls, so the message
> has to span at least three segments before it triggers.
>
> BUG: KASAN: slab-use-after-free in __strp_recv+0x447/0xda0
> Write of size 8 at addr ffff88810db86140 by task repro/349
>
> Call Trace:
> <IRQ>
> __strp_recv+0x447/0xda0
> __tcp_read_sock+0x13d/0x590
> tcp_bpf_strp_read_sock+0x195/0x320
> strp_data_ready+0x267/0x340
> sk_psock_strp_data_ready+0x1ce/0x350
> tcp_data_queue+0x1364/0x2fd0
> tcp_rcv_established+0xe07/0x1640
> [...]
>
> Allocated by task 349:
> skb_clone+0x17b/0x210
> __strp_recv+0x2c3/0xda0
> __tcp_read_sock+0x13d/0x590
> [...]
>
> Freed by task 349:
> kmem_cache_free+0x150/0x570
> __pskb_pull_tail+0x57b/0xc20
> skb_ensure_writable+0x236/0x260
> __bpf_skb_change_tail+0x1d4/0x590
> sk_skb_change_tail+0x2a/0x40
> bpf_prog_1b285dcd6c41373e+0x27/0x30
> bpf_prog_run_pin_on_cpu+0xf3/0x260
> sk_psock_strp_parse+0x118/0x1e0
> __strp_recv+0x4f6/0xda0
> [...]
>
> The same resize also leaves the head's length inconsistent with its
> frags, so a later __pskb_pull_tail() can instead hit the
> BUG_ON(skb_copy_bits(...)) in net/core/skbuff.c.
>
> A stream parser is only meant to measure the next message, not to modify
> the packet. Reject a parser whose program can change packet data
> (prog->aux->changes_pkt_data) at attach time. The check is shared by
> sock_map_prog_update() and sock_map_link_update_prog(), which between them
> cover prog attach, link create and link update. Verdict programs are
> unaffected and may still modify the skb.
>
> Signed-off-by: Sechang Lim <rhkrqnwk98@gmail.com>
Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH bpf v4 3/3] selftests/bpf: test rejection of a packet-modifying SK_SKB stream parser
2026-06-19 6:29 ` [PATCH bpf v4 3/3] selftests/bpf: test rejection of " Sechang Lim
@ 2026-06-19 6:35 ` Jiayuan Chen
2026-06-19 7:08 ` bot+bpf-ci
1 sibling, 0 replies; 10+ messages in thread
From: Jiayuan Chen @ 2026-06-19 6:35 UTC (permalink / raw)
To: Sechang Lim, Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
Eduard Zingerman, Kumar Kartikeya Dwivedi, John Fastabend,
Jakub Sitnicki, David S . Miller, Jakub Kicinski, Eric Dumazet,
Paolo Abeni, Kuniyuki Iwashima, Willem de Bruijn, Shuah Khan
Cc: Jiri Olsa, Martin KaFai Lau, Song Liu, Yonghong Song,
Simon Horman, Bobby Eshleman, Jiayuan Chen, bpf, netdev,
linux-kernel, linux-kselftest
On 6/19/26 2:29 PM, Sechang Lim wrote:
> Verify that attaching an SK_SKB stream parser that can modify the packet
> is rejected, while a read-only parser still attaches.
>
> Signed-off-by: Sechang Lim <rhkrqnwk98@gmail.com>
Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH bpf v4 2/3] bpf, sockmap: reject a packet-modifying SK_SKB stream parser
2026-06-19 6:29 ` [PATCH bpf v4 2/3] bpf, sockmap: reject a packet-modifying SK_SKB stream parser Sechang Lim
2026-06-19 6:35 ` Jiayuan Chen
@ 2026-06-19 6:51 ` sashiko-bot
1 sibling, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-06-19 6:51 UTC (permalink / raw)
To: Sechang Lim; +Cc: bpf
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Incomplete mitigation for a Use-After-Free in the stream parser. The newly added attach-time check can be bypassed using `bpf_dynptr_write()`.
--
commit 045eed2578465803e8813874d62e6ec53c4a01de
Author: Sechang Lim <rhkrqnwk98@gmail.com>
bpf, sockmap: reject a packet-modifying SK_SKB stream parser
sk_psock_strp_parse() runs the BPF_PROG_TYPE_SK_SKB stream-parser program
to find the length of the next message. strparser assembles a message out
of several received skbs by chaining them onto the head's frag_list and
recording where to append the next one in strp->skb_nextp. A stream parser
is only meant to measure the next message, so this patch rejects a parser
whose program can change packet data at attach time.
> diff --git a/net/core/sock_map.c b/net/core/sock_map.c
> index 99e3789492a09..c60ba6d292f9a 100644
> --- a/net/core/sock_map.c
> +++ b/net/core/sock_map.c
[ ... ]
> @@ -1515,6 +1515,17 @@ static int sock_map_prog_link_lookup(struct bpf_map *map, struct bpf_prog ***ppr
> return 0;
> }
>
> +static int sock_map_prog_attach_check(enum bpf_attach_type attach_type,
> + struct bpf_prog *prog)
> +{
> + /* A stream parser must not modify the skb, only measure it. */
> + if (prog && attach_type == BPF_SK_SKB_STREAM_PARSER &&
> + prog->aux->changes_pkt_data)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
[Severity: High]
This isn't a bug introduced by this patch, but could this attach-time check be
bypassed by using bpf_dynptr_write()?
Because BPF_FUNC_dynptr_write is missing from the
bpf_helper_changes_pkt_data() switch statement in net/core/filter.c, and
bpf_dynptr_from_skb() is not flagged by bpf_is_kfunc_pkt_changing(), the
verifier never sets changes_pkt_data for programs using dynptrs to modify
the packet.
If a BPF program obtains a writable dynptr to the SKB using the
bpf_dynptr_from_skb() kfunc, it can modify the packet using the
bpf_dynptr_write() helper.
For SKB dynptrs, bpf_dynptr_write() calls __bpf_dynptr_write() in
kernel/bpf/helpers.c:
case BPF_DYNPTR_TYPE_SKB:
return __bpf_skb_store_bytes(dst->data, dst->offset + offset, src, len,
flags);
This modifies the SKB and triggers skb_ensure_writable(). If the write
exceeds skb_headlen(skb), this invokes __pskb_pull_tail() and unconditionally
frees the frag_list skbs, causing the exact use-after-free in the stream
parser that this patch intends to fix.
> + return -EINVAL;
> +
> + return 0;
> +}
> +
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260619062959.3277612-1-rhkrqnwk98@gmail.com?part=2
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH bpf v4 3/3] selftests/bpf: test rejection of a packet-modifying SK_SKB stream parser
2026-06-19 6:29 ` [PATCH bpf v4 3/3] selftests/bpf: test rejection of " Sechang Lim
2026-06-19 6:35 ` Jiayuan Chen
@ 2026-06-19 7:08 ` bot+bpf-ci
1 sibling, 0 replies; 10+ messages in thread
From: bot+bpf-ci @ 2026-06-19 7:08 UTC (permalink / raw)
To: rhkrqnwk98, ast, andrii, daniel, eddyz87, memxor, john.fastabend,
jakub, davem, kuba, edumazet, pabeni, kuniyu, willemb, shuah
Cc: jolsa, martin.lau, song, yonghong.song, horms, bobbyeshleman,
jiayuan.chen, bpf, netdev, linux-kernel, linux-kselftest, ast,
andrii, daniel, martin.lau, eddyz87, yonghong.song, clm,
ihor.solodrai
[-- Attachment #1: Type: text/plain, Size: 971 bytes --]
> selftests/bpf: test rejection of a packet-modifying SK_SKB stream parser
>
> Verify that attaching an SK_SKB stream parser that can modify the packet
> is rejected, while a read-only parser still attaches.
>
> Signed-off-by: Sechang Lim <rhkrqnwk98@gmail.com>
This test exercises the rejection of a stream parser that resizes the skb,
which is the use-after-free path introduced when sk_skb programs gained
access to packet data. An earlier single-patch version of this work
carried a Fixes: tag pointing at that commit, and it appears to have been
dropped when the series was split into multiple patches.
Should this commit include:
Fixes: 8a31db561566 ("bpf: add access to sock fields and pkt data from sk_skb programs")
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/27809861429
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH bpf v4 1/3] selftests/bpf: don't modify the skb in the strparser parser prog
2026-06-19 6:29 ` [PATCH bpf v4 1/3] selftests/bpf: don't modify the skb in the strparser parser prog Sechang Lim
2026-06-19 6:35 ` Jiayuan Chen
@ 2026-06-19 7:08 ` bot+bpf-ci
1 sibling, 0 replies; 10+ messages in thread
From: bot+bpf-ci @ 2026-06-19 7:08 UTC (permalink / raw)
To: rhkrqnwk98, ast, andrii, daniel, eddyz87, memxor, john.fastabend,
jakub, davem, kuba, edumazet, pabeni, kuniyu, willemb, shuah
Cc: jolsa, martin.lau, song, yonghong.song, horms, bobbyeshleman,
jiayuan.chen, bpf, netdev, linux-kernel, linux-kselftest, ast,
andrii, daniel, martin.lau, eddyz87, yonghong.song, clm,
ihor.solodrai
[-- Attachment #1: Type: text/plain, Size: 1348 bytes --]
> selftests/bpf: don't modify the skb in the strparser parser prog
>
> sockmap_parse_prog.c is attached as an SK_SKB stream parser and modifies
> the skb. It calls bpf_skb_pull_data() and writes a byte into the packet.
> A stream parser runs on strparser's message head and must not modify it.
> A resize frees the frag_list segments strparser still tracks, leading to
> a use-after-free.
>
> Make the parser read-only. It only needs to return the message length,
> which keeps it attaching once packet-modifying parsers are rejected.
>
> Signed-off-by: Sechang Lim <rhkrqnwk98@gmail.com>
> Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
This removes a use-after-free where bpf_skb_pull_data(skb, 10) resizes and
frees the frag_list segments that strparser still tracks for the message
head. The buggy bpf_skb_pull_data(skb, 10) call and the packet write being
removed here were added by commit 82a8616889d5 ("bpf: add map tests for
BPF_PROG_TYPE_SK_MSG").
Should this carry a Fixes: tag?
Fixes: 82a8616889d5 ("bpf: add map tests for BPF_PROG_TYPE_SK_MSG")
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/27809861429
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-06-19 7:08 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-19 6:29 [PATCH bpf v4 0/3] bpf, sockmap: reject a packet-modifying SK_SKB stream parser Sechang Lim
2026-06-19 6:29 ` [PATCH bpf v4 1/3] selftests/bpf: don't modify the skb in the strparser parser prog Sechang Lim
2026-06-19 6:35 ` Jiayuan Chen
2026-06-19 7:08 ` bot+bpf-ci
2026-06-19 6:29 ` [PATCH bpf v4 2/3] bpf, sockmap: reject a packet-modifying SK_SKB stream parser Sechang Lim
2026-06-19 6:35 ` Jiayuan Chen
2026-06-19 6:51 ` sashiko-bot
2026-06-19 6:29 ` [PATCH bpf v4 3/3] selftests/bpf: test rejection of " Sechang Lim
2026-06-19 6:35 ` Jiayuan Chen
2026-06-19 7:08 ` bot+bpf-ci
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.