]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
bpf: add new negative selftests to cover missing check_func_arg_reg_off() and reg...
authorMatt Bobrowski <mattbobrowski@google.com>
Tue, 25 Jun 2024 06:28:57 +0000 (06:28 +0000)
committerAlexei Starovoitov <ast@kernel.org>
Wed, 26 Jun 2024 20:17:32 +0000 (13:17 -0700)
Add new negative selftests which are intended to cover the
out-of-bounds memory access that could be performed on a
CONST_PTR_TO_DYNPTR within functions taking a ARG_PTR_TO_DYNPTR |
MEM_RDONLY as an argument, and acceptance of invalid register types
i.e. PTR_TO_BTF_ID within functions taking a ARG_PTR_TO_DYNPTR |
MEM_RDONLY.

Reported-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Acked-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Matt Bobrowski <mattbobrowski@google.com>
Link: https://lore.kernel.org/r/20240625062857.92760-2-mattbobrowski@google.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/testing/selftests/bpf/progs/dynptr_fail.c
tools/testing/selftests/bpf/progs/test_kfunc_dynptr_param.c
tools/testing/selftests/bpf/progs/test_kfunc_param_nullable.c
tools/testing/selftests/bpf/progs/user_ringbuf_fail.c

index 64cc9d936a1379a419dc47115a173eb2715f0b5a..e35bc1eac52ae6f2a2eb9324184b45bb02e05fd1 100644 (file)
@@ -1686,3 +1686,27 @@ int test_dynptr_skb_small_buff(struct __sk_buff *skb)
 
        return !!data;
 }
+
+__noinline long global_call_bpf_dynptr(const struct bpf_dynptr *dynptr)
+{
+       long ret = 0;
+       /* Avoid leaving this global function empty to avoid having the compiler
+        * optimize away the call to this global function.
+        */
+       __sink(ret);
+       return ret;
+}
+
+SEC("?raw_tp")
+__failure __msg("arg#1 expected pointer to stack or const struct bpf_dynptr")
+int test_dynptr_reg_type(void *ctx)
+{
+       struct task_struct *current = NULL;
+       /* R1 should be holding a PTR_TO_BTF_ID, so this shouldn't be a
+        * reg->type that can be passed to a function accepting a
+        * ARG_PTR_TO_DYNPTR | MEM_RDONLY. process_dynptr_func() should catch
+        * this.
+        */
+       global_call_bpf_dynptr((const struct bpf_dynptr *)current);
+       return 0;
+}
index 2dde8e3fe4c9a2e4bba8a54af0fcf7dfcbd12060..e68667aec6a652b208b2b29a9ae5a8e3c0193c40 100644 (file)
@@ -45,7 +45,7 @@ int BPF_PROG(not_valid_dynptr, int cmd, union bpf_attr *attr, unsigned int size)
 }
 
 SEC("?lsm.s/bpf")
-__failure __msg("arg#0 expected pointer to stack or dynptr_ptr")
+__failure __msg("arg#1 expected pointer to stack or const struct bpf_dynptr")
 int BPF_PROG(not_ptr_to_stack, int cmd, union bpf_attr *attr, unsigned int size)
 {
        unsigned long val = 0;
index 7c75e9b8f4554ab12445bb15577ec11e100cb8ce..7ac7e1de34d811865ca187a200bc6f213d482511 100644 (file)
@@ -29,7 +29,7 @@ int kfunc_dynptr_nullable_test2(struct __sk_buff *skb)
 }
 
 SEC("tc")
-__failure __msg("expected pointer to stack or dynptr_ptr")
+__failure __msg("expected pointer to stack or const struct bpf_dynptr")
 int kfunc_dynptr_nullable_test3(struct __sk_buff *skb)
 {
        struct bpf_dynptr data;
index 11ab25c42c360ad0197a70d44835e6f77d926204..54de0389f8785a463d06231cc50ca558d47f9e03 100644 (file)
@@ -221,3 +221,25 @@ int user_ringbuf_callback_reinit_dynptr_ringbuf(void *ctx)
        bpf_user_ringbuf_drain(&user_ringbuf, try_reinit_dynptr_ringbuf, NULL, 0);
        return 0;
 }
+
+__noinline long global_call_bpf_dynptr_data(struct bpf_dynptr *dynptr)
+{
+       bpf_dynptr_data(dynptr, 0xA, 0xA);
+       return 0;
+}
+
+static long callback_adjust_bpf_dynptr_reg_off(struct bpf_dynptr *dynptr,
+                                              void *ctx)
+{
+       global_call_bpf_dynptr_data(dynptr += 1024);
+       return 0;
+}
+
+SEC("?raw_tp")
+__failure __msg("dereference of modified dynptr_ptr ptr R1 off=16384 disallowed")
+int user_ringbuf_callback_const_ptr_to_dynptr_reg_off(void *ctx)
+{
+       bpf_user_ringbuf_drain(&user_ringbuf,
+                              callback_adjust_bpf_dynptr_reg_off, NULL, 0);
+       return 0;
+}