bpf: Test_progs, add test to catch retval refine error handling
authorJohn Fastabend <john.fastabend@gmail.com>
Mon, 30 Mar 2020 21:37:19 +0000 (14:37 -0700)
committerAlexei Starovoitov <ast@kernel.org>
Mon, 30 Mar 2020 22:00:30 +0000 (15:00 -0700)
Before this series the verifier would clamp return bounds of
bpf_get_stack() to [0, X] and this led the verifier to believe
that a JMP_JSLT 0 would be false and so would prune that path.

The result is anything hidden behind that JSLT would be unverified.
Add a test to catch this case by hiding an goto pc-1 behind the
check which will cause an infinite loop if not rejected.

Signed-off-by: John Fastabend <john.fastabend@gmail.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/158560423908.10843.11783152347709008373.stgit@john-Precision-5820-Tower
tools/testing/selftests/bpf/prog_tests/get_stack_raw_tp.c
tools/testing/selftests/bpf/progs/test_get_stack_rawtp_err.c [new file with mode: 0644]

index eba9a97..9257222 100644 (file)
@@ -82,6 +82,7 @@ static void get_stack_print_output(void *ctx, int cpu, void *data, __u32 size)
 void test_get_stack_raw_tp(void)
 {
        const char *file = "./test_get_stack_rawtp.o";
+       const char *file_err = "./test_get_stack_rawtp_err.o";
        const char *prog_name = "raw_tracepoint/sys_enter";
        int i, err, prog_fd, exp_cnt = MAX_CNT_RAWTP;
        struct perf_buffer_opts pb_opts = {};
@@ -93,6 +94,10 @@ void test_get_stack_raw_tp(void)
        struct bpf_map *map;
        cpu_set_t cpu_set;
 
+       err = bpf_prog_load(file_err, BPF_PROG_TYPE_RAW_TRACEPOINT, &obj, &prog_fd);
+       if (CHECK(err >= 0, "prog_load raw tp", "err %d errno %d\n", err, errno))
+               return;
+
        err = bpf_prog_load(file, BPF_PROG_TYPE_RAW_TRACEPOINT, &obj, &prog_fd);
        if (CHECK(err, "prog_load raw tp", "err %d errno %d\n", err, errno))
                return;
diff --git a/tools/testing/selftests/bpf/progs/test_get_stack_rawtp_err.c b/tools/testing/selftests/bpf/progs/test_get_stack_rawtp_err.c
new file mode 100644 (file)
index 0000000..8941a41
--- /dev/null
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/bpf.h>
+#include <bpf/bpf_helpers.h>
+
+#define MAX_STACK_RAWTP 10
+
+SEC("raw_tracepoint/sys_enter")
+int bpf_prog2(void *ctx)
+{
+       __u64 stack[MAX_STACK_RAWTP];
+       int error;
+
+       /* set all the flags which should return -EINVAL */
+       error = bpf_get_stack(ctx, stack, 0, -1);
+       if (error < 0)
+               goto loop;
+
+       return error;
+loop:
+       while (1) {
+               error++;
+       }
+}
+
+char _license[] SEC("license") = "GPL";