diff options
| author | Paul Chaignon <paul.chaignon@gmail.com> | 2023-11-06 23:02:24 +0100 |
|---|---|---|
| committer | Aleksandr Nogikh <nogikh@google.com> | 2023-11-09 18:26:45 +0000 |
| commit | ce85d4183896b735669c38b5f6c441d4f31db1ca (patch) | |
| tree | 11313528415af79dfeeb4b11c41104ce7222a81d /sys/linux | |
| parent | 77fb079dedee5c8c2fc0c2e3781769b5978ce4fe (diff) | |
sys/linux: describe call to BPF helper bpf_ringbuf_submit
This helper has the verifier prototype:
.ret_type = RET_VOID,
.arg1_type = ARG_PTR_TO_RINGBUF_MEM | OBJ_RELEASE,
.arg2_type = ARG_ANYTHING,
We therefore need to pass the pointer retrieved with bpf_ringbuf_reserve
via R2. We saved that pointer to R9 so we can retrieve it from there.
Since bpf_ringbuf_submit doesn't return anything, we need to write
something in R0 before we exit the program.
Our BPF program now looks like:
u64 *e;
e = bpf_ringbuf_reserve(&rb, sizeof(*e), 0);
[...]
bpf_ringbuf_submit(e, 0);
return 0;
It will still fail, but with EACCES instead of EINVAL, due to the
following verifier error:
0: R1=ctx(off=0,imm=0) R10=fp0
0: (18) r0 = 0x0 ; R0_w=0
2: (18) r1 = 0xffff984f66f93600 ; R1_w=map_ptr(off=0,ks=0,vs=0,imm=0)
4: (b7) r2 = 20 ; R2_w=20
5: (b7) r3 = 0 ; R3_w=0
6: (85) call bpf_ringbuf_reserve#131 ; R0_w=ringbuf_mem_or_null(id=2,ref_obj_id=2,off=0,imm=0) refs=2
7: (bf) r9 = r0 ; R0_w=ringbuf_mem_or_null(id=2,ref_obj_id=2,off=0,imm=0)
R9_w=ringbuf_mem_or_null(id=2,ref_obj_id=2,off=0,imm=0) refs=2
8: (bf) r1 = r9 ; R1_w=ringbuf_mem_or_null(id=2,ref_obj_id=2,off=0,imm=0)
R9_w=ringbuf_mem_or_null(id=2,ref_obj_id=2,off=0,imm=0) refs=2
9: (b7) r2 = 0 ; R2_w=0 refs=2
10: (85) call bpf_ringbuf_submit#132
R1 type=ringbuf_mem_or_null expected=ringbuf_mem
In short, we didn't check that the pointer returned by
bpf_ringbug_reserve isn't null.
Signed-off-by: Paul Chaignon <paul.chaignon@gmail.com>
Diffstat (limited to 'sys/linux')
| -rw-r--r-- | sys/linux/bpf.txt | 12 | ||||
| -rw-r--r-- | sys/linux/bpf.txt.const | 1 | ||||
| -rw-r--r-- | sys/linux/test/bpf_helpers | 2 |
3 files changed, 14 insertions, 1 deletions
diff --git a/sys/linux/bpf.txt b/sys/linux/bpf.txt index eb1c2761b..ae84b0c5e 100644 --- a/sys/linux/bpf.txt +++ b/sys/linux/bpf.txt @@ -400,6 +400,7 @@ bpf_program_ringbuf { initr0 bpf_insn_init_r0 reserve bpf_insn_ringbuf_reserve body array[bpf_insn] + free bpf_insn_ringbuf_submit exit bpf_insn_exit } [packed] @@ -749,6 +750,17 @@ bpf_insn_ringbuf_reserve { insn5 bpf_insn_mov_reg[BPF_REG_0, BPF_REG_9] } +# (bf) r1 = r9 +# (b7) r2 = 0 +# (85) call bpf_ringbuf_submit#322192 +# (bf) r0 = 0 +bpf_insn_ringbuf_submit { + insn1 bpf_insn_mov_reg[BPF_REG_9, BPF_REG_1] + insn2 bpf_insn_mov_imm[BPF_REG_2, 0] + insn3 bpf_insn_call_helper_t[const[BPF_FUNC_ringbuf_submit, int32]] + insn4 bpf_insn_mov_imm[BPF_REG_0, 0] +} + define MAX_BPF_REG __MAX_BPF_REG bpf_obj_pin_map [ diff --git a/sys/linux/bpf.txt.const b/sys/linux/bpf.txt.const index 8091b3944..c0ee42926 100644 --- a/sys/linux/bpf.txt.const +++ b/sys/linux/bpf.txt.const @@ -67,6 +67,7 @@ BPF_EXIT0 = 9 BPF_FLOW_DISSECTOR = 17 BPF_FUNC_INFO_SIZE = 8 BPF_FUNC_ringbuf_reserve = 131 +BPF_FUNC_ringbuf_submit = 132 BPF_FUNC_snprintf = 165 BPF_FUNC_tail_call = 12 BPF_FUNC_trace_printk = 6 diff --git a/sys/linux/test/bpf_helpers b/sys/linux/test/bpf_helpers index 0bc1ce513..598395ac2 100644 --- a/sys/linux/test/bpf_helpers +++ b/sys/linux/test/bpf_helpers @@ -25,4 +25,4 @@ r4 = bpf$PROG_LOAD(AUTO, &AUTO={0x3, AUTO, &AUTO=@framed={{AUTO, AUTO, AUTO, AUT r1 = bpf$MAP_CREATE_RINGBUF(AUTO, &AUTO={AUTO, AUTO, AUTO, 0x40000, AUTO, 0x0, 0x0, "00000000000000000000000000000000", 0x0, 0x0, 0x0, 0x0, 0x0, AUTO}, 0x48) -r2 = bpf$PROG_LOAD(AUTO, &AUTO={0x3, AUTO, &AUTO=@ringbuf={{AUTO, AUTO, AUTO, AUTO, 0x0, AUTO, AUTO, AUTO, 0x0}, {{AUTO, AUTO, AUTO, AUTO, r1, AUTO, AUTO, AUTO, AUTO}, {AUTO, AUTO, AUTO, AUTO, AUTO, AUTO, AUTO}, {AUTO, AUTO, AUTO, AUTO, AUTO, AUTO, AUTO}, {AUTO, AUTO, AUTO, AUTO}, {AUTO, AUTO, AUTO, AUTO, AUTO, AUTO, AUTO}}, [], {AUTO, AUTO, AUTO, AUTO}}, &AUTO='GPL\x00', 0x0, 0x0, 0x0, 0x0, 0x0, "00000000000000000000000000000000", 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 0xa0) # EINVAL +r2 = bpf$PROG_LOAD(AUTO, &AUTO={0x3, AUTO, &AUTO=@ringbuf={{AUTO, AUTO, AUTO, AUTO, 0x0, AUTO, AUTO, AUTO, 0x0}, {{AUTO, AUTO, AUTO, AUTO, r1, AUTO, AUTO, AUTO, AUTO}, {AUTO, AUTO, AUTO, AUTO, AUTO, AUTO, AUTO}, {AUTO, AUTO, AUTO, AUTO, AUTO, AUTO, AUTO}, {AUTO, AUTO, AUTO, AUTO}, {AUTO, AUTO, AUTO, AUTO, AUTO, AUTO, AUTO}}, [], {{AUTO, AUTO, AUTO, AUTO, AUTO, AUTO, AUTO}, {AUTO, AUTO, AUTO, AUTO, AUTO, AUTO, AUTO}, {AUTO, AUTO, AUTO, AUTO}, {AUTO, AUTO, AUTO, AUTO, AUTO, AUTO, AUTO}}, {AUTO, AUTO, AUTO, AUTO}}, &AUTO='GPL\x00', 0x0, 0x0, 0x0, 0x0, 0x0, "00000000000000000000000000000000", 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 0xa0) |
