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 <[email protected]>
---
 .../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


Reply via email to