On 4/10/26 1:37 PM, Jiayuan Chen wrote:
Add a selftest that reproduces the null-ptr-deref in
bond_rr_gen_slave_id() when XDP redirect targets a bond device in
round-robin mode that was never brought up. The test verifies the fix
by ensuring no crash occurs.

Test setup:
- bond0: active-backup mode, UP, with native XDP (enables
   bpf_master_redirect_enabled_key globally)
- bond1: round-robin mode, never UP
- veth1: slave of bond1, with generic XDP (XDP_TX)
- BPF_PROG_TEST_RUN with live frames triggers the redirect path

Signed-off-by: Jiayuan Chen <[email protected]>

I checked locally that this XDP test passes fine and triggers a NULL
pointer deref without the fix.

[...]
+       /* Attach generic XDP (XDP_TX) to veth1.
+        * When packets arrive at veth1 via netif_receive_skb, do_xdp_generic()
+        * runs this program. XDP_TX + bond slave triggers 
xdp_master_redirect().
+        */
+       xdp_tx_fd = bpf_program__fd(skeletons->xdp_tx->progs.xdp_tx);
+       if (!ASSERT_GE(xdp_tx_fd, 0, "xdp_tx prog_fd"))
+               goto out;

nit: no need for the ASSERT_GE given the skeleton loaded, see also the various
other tests gathering bpf_program__fd().

+       err = bpf_xdp_attach(veth1_ifindex, xdp_tx_fd,
+                            XDP_FLAGS_SKB_MODE, NULL);
+       if (!ASSERT_OK(err, "attach generic XDP to veth1"))
+               goto out;
+
+       /* Run BPF_PROG_TEST_RUN with XDP_PASS live frames on veth1.
+        * XDP_PASS frames become SKBs with skb->dev = veth1, entering
+        * netif_receive_skb -> do_xdp_generic -> xdp_master_redirect.
+        * Without the fix, bond_rr_gen_slave_id() dereferences NULL
+        * rr_tx_counter and crashes.
+        */
+       xdp_pass_fd = 
bpf_program__fd(skeletons->xdp_dummy->progs.xdp_dummy_prog);
+       if (!ASSERT_GE(xdp_pass_fd, 0, "xdp_pass prog_fd"))
+               goto out;

ditto, can be simplified a bit into:

diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_bonding.c 
b/tools/testing/selftests/bpf/prog_tests/xdp_bonding.c
index 0d4ec1e5b401..c42488e445c2 100644
--- a/tools/testing/selftests/bpf/prog_tests/xdp_bonding.c
+++ b/tools/testing/selftests/bpf/prog_tests/xdp_bonding.c
@@ -506,7 +506,7 @@ static void test_xdp_bonding_nested(struct skeletons 
*skeletons)
 static void test_xdp_bonding_redirect_no_up(struct skeletons *skeletons)
 {
        struct nstoken *nstoken = NULL;
-       int xdp_pass_fd, xdp_tx_fd;
+       int xdp_pass_fd;
        int veth1_ifindex;
        int err;
        char pkt[ETH_HLEN + 1];
@@ -555,11 +555,8 @@ static void test_xdp_bonding_redirect_no_up(struct 
skeletons *skeletons)
         * When packets arrive at veth1 via netif_receive_skb, do_xdp_generic()
         * runs this program. XDP_TX + bond slave triggers 
xdp_master_redirect().
         */
-       xdp_tx_fd = bpf_program__fd(skeletons->xdp_tx->progs.xdp_tx);
-       if (!ASSERT_GE(xdp_tx_fd, 0, "xdp_tx prog_fd"))
-               goto out;
-
-       err = bpf_xdp_attach(veth1_ifindex, xdp_tx_fd,
+       err = bpf_xdp_attach(veth1_ifindex,
+                            bpf_program__fd(skeletons->xdp_tx->progs.xdp_tx),
                             XDP_FLAGS_SKB_MODE, NULL);
        if (!ASSERT_OK(err, "attach generic XDP to veth1"))
                goto out;
@@ -571,8 +568,6 @@ static void test_xdp_bonding_redirect_no_up(struct 
skeletons *skeletons)
         * rr_tx_counter and crashes.
         */
        xdp_pass_fd = 
bpf_program__fd(skeletons->xdp_dummy->progs.xdp_dummy_prog);
-       if (!ASSERT_GE(xdp_pass_fd, 0, "xdp_pass prog_fd"))
-               goto out;
memset(pkt, 0, sizeof(pkt));
        ctx_in.data_end = sizeof(pkt);


Reply via email to