@@ -42,11 +42,14 @@ static struct {
{"release_twice_callback", "arg 1 is an unacquired reference"},
{"dynptr_from_mem_invalid_api",
"Unsupported reg type fp for bpf_dynptr_from_mem data"},
+ {"dynptr_read_into_slot", "potential write to dynptr at off=-16"},
+ {"uninit_write_into_slot", "potential write to dynptr at off=-16"},
/* success cases */
{"test_read_write", NULL},
{"test_data_slice", NULL},
{"test_ringbuf", NULL},
+ {"test_overlap", NULL},
};
static void verify_fail(const char *prog_name, const char *expected_err_msg)
@@ -622,3 +622,38 @@ int dynptr_from_mem_invalid_api(void *ctx)
return 0;
}
+
+/* Reject writes to dynptr slot from bpf_dynptr_read */
+SEC("?raw_tp")
+int dynptr_read_into_slot(void *ctx)
+{
+ union {
+ struct {
+ char _pad[48];
+ struct bpf_dynptr ptr;
+ };
+ char buf[64];
+ } data;
+
+ bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &data.ptr);
+ /* this should fail */
+ bpf_dynptr_read(data.buf, sizeof(data.buf), &data.ptr, 0, 0);
+
+ return 0;
+}
+
+/* Reject writes to dynptr slot for uninit arg */
+SEC("?raw_tp")
+int uninit_write_into_slot(void *ctx)
+{
+ struct {
+ char buf[64];
+ struct bpf_dynptr ptr;
+ } data;
+
+ bpf_ringbuf_reserve_dynptr(&ringbuf, 80, 0, &data.ptr);
+ /* this should fail */
+ bpf_get_current_comm(data.buf, 80);
+
+ return 0;
+}
@@ -162,3 +162,23 @@ int test_ringbuf(void *ctx)
bpf_ringbuf_discard_dynptr(&ptr, 0);
return 0;
}
+
+SEC("tp/syscalls/sys_enter_nanosleep")
+int test_overlap(void *ctx)
+{
+ struct bpf_dynptr ptr;
+ void *p;
+
+ if (bpf_get_current_pid_tgid() >> 32 != pid)
+ return 0;
+ bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &ptr);
+ p = bpf_dynptr_data(&ptr, 0, 16);
+ if (!p) {
+ err = 1;
+ goto done;
+ }
+ bpf_dynptr_read(p + 1, 8, &ptr, 0, 0);
+done:
+ bpf_ringbuf_discard_dynptr(&ptr, 0);
+ return 0;
+}
Test that MEM_UNINIT doesn't allow writing dynptr stack slots. Next, also add a test triggering the memmove case for dynptr_read and dynptr_write. Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> --- .../testing/selftests/bpf/prog_tests/dynptr.c | 3 ++ .../testing/selftests/bpf/progs/dynptr_fail.c | 35 +++++++++++++++++++ .../selftests/bpf/progs/dynptr_success.c | 20 +++++++++++ 3 files changed, 58 insertions(+)