]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
selftests/bpf: Add tests for rejection of ALU ops with negative offsets
authorEduard Zingerman <eddyz87@gmail.com>
Thu, 2 Oct 2025 19:11:40 +0000 (12:11 -0700)
committerAlexei Starovoitov <ast@kernel.org>
Thu, 2 Oct 2025 20:34:08 +0000 (13:34 -0700)
Define a simple program using MOD, DIV, ADD instructions,
make sure that the program is rejected if invalid offset
field is used for instruction.

These are test cases for
commit 55c0ced59fe1 ("bpf: Reject negative offsets for ALU ops")
Link: https://lore.kernel.org/all/tencent_70D024BAE70A0A309A4781694C7B764B0608@qq.com/
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/testing/selftests/bpf/progs/verifier_value_illegal_alu.c

index dcaab61a11a09574b12e2792fc35e4913d3ba851..2129e4353fd97d4e1d444f382a315ff906b211f3 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <linux/bpf.h>
 #include <bpf/bpf_helpers.h>
+#include "../../../include/linux/filter.h"
 #include "bpf_misc.h"
 
 #define MAX_ENTRIES 11
@@ -183,4 +184,32 @@ __naked void flow_keys_illegal_variable_offset_alu(void)
        : __clobber_all);
 }
 
+#define DEFINE_BAD_OFFSET_TEST(name, op, off, imm)     \
+       SEC("socket")                                   \
+       __failure __msg("BPF_ALU uses reserved fields") \
+       __naked void name(void)                         \
+       {                                               \
+               asm volatile(                           \
+                       "r0 = 1;"                       \
+                       ".8byte %[insn];"               \
+                       "r0 = 0;"                       \
+                       "exit;"                         \
+               :                                       \
+               : __imm_insn(insn, BPF_RAW_INSN((op), 0, 0, (off), (imm))) \
+               : __clobber_all);                       \
+       }
+
+/*
+ * Offset fields of 0 and 1 are legal for BPF_{DIV,MOD} instructions.
+ * Offset fields of 0 are legal for the rest of ALU instructions.
+ * Test that error is reported for illegal offsets, assuming that tests
+ * for legal offsets exist.
+ */
+DEFINE_BAD_OFFSET_TEST(bad_offset_divx, BPF_ALU64 | BPF_DIV | BPF_X, -1, 0)
+DEFINE_BAD_OFFSET_TEST(bad_offset_modk, BPF_ALU64 | BPF_MOD | BPF_K, -1, 1)
+DEFINE_BAD_OFFSET_TEST(bad_offset_addx, BPF_ALU64 | BPF_ADD | BPF_X, -1, 0)
+DEFINE_BAD_OFFSET_TEST(bad_offset_divx2, BPF_ALU64 | BPF_DIV | BPF_X, 2, 0)
+DEFINE_BAD_OFFSET_TEST(bad_offset_modk2, BPF_ALU64 | BPF_MOD | BPF_K, 2, 1)
+DEFINE_BAD_OFFSET_TEST(bad_offset_addx2, BPF_ALU64 | BPF_ADD | BPF_X, 1, 0)
+
 char _license[] SEC("license") = "GPL";