From b747e572ec589543e9ccb870158f467f7fa3d825 Mon Sep 17 00:00:00 2001 From: Paul Chaignon Date: Sun, 19 Dec 2021 20:34:43 +0100 Subject: sys/linux: support map fd arrays Commit [1] upstream introduced a new way to reference BPF maps in eBPF instructions. An array of BPF map fds is passed at program load time. Instructions can then reference fds in this array instead of carrying the fds directly. The goal is to allow BPF instructions to be immutable after compilation. Since we don't yet have a good way to reference indexes in an array, we define a new type map_fd_id for that purpose, with indexes between 0 and 16 only. 1 - https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=387544bfa291 Signed-off-by: Paul Chaignon --- sys/linux/bpf.txt | 55 ++++++++++++++++++++++++++++++++++++----------- sys/linux/bpf.txt.const | 2 ++ sys/linux/test/bpf_cgroup | 2 +- sys/linux/test/btf_id | 4 ++-- 4 files changed, 48 insertions(+), 15 deletions(-) (limited to 'sys/linux') diff --git a/sys/linux/bpf.txt b/sys/linux/bpf.txt index ca46f85d9..e7d3a512b 100644 --- a/sys/linux/bpf.txt +++ b/sys/linux/bpf.txt @@ -26,6 +26,9 @@ type btf_opt_type_id int32[0:5] type btf_name_off int32[1:16] type btf_opt_name_off int32[0:16] +# NEED: offset in bpf_prog_t:fd_array. We can't express this, so we just use a small index. +type map_fd_id int32[0:16] + bpf$MAP_CREATE(cmd const[BPF_MAP_CREATE], arg ptr[in, bpf_map_create_arg], size len[arg]) fd_bpf_map bpf$MAP_LOOKUP_ELEM(cmd const[BPF_MAP_LOOKUP_ELEM], arg ptr[in, bpf_map_lookup_arg], size len[arg]) bpf$MAP_UPDATE_ELEM(cmd const[BPF_MAP_UPDATE_ELEM], arg ptr[in, bpf_map_update_arg], size len[arg]) @@ -185,6 +188,8 @@ type bpf_prog_t[TYPE, ATTACH_TYPE, BTF_ID, PROG_FD] { line_info_cnt len[line_info, int32] attach_btf_id BTF_ID attach_prog_fd PROG_FD + pad const[0, int32] + fd_array ptr64[in, array[fd_bpf_map], opt] } type bpf_prog bpf_prog_t[flags[bpf_prog_type, int32], flags[bpf_attach_type, int32], bpf_btf_id[opt], fd_bpf_prog[opt]] @@ -218,17 +223,19 @@ bpf_framed_program { } [packed] bpf_insn [ - generic bpf_insn_generic - ldst bpf_insn_ldst - alu bpf_insn_alu - jmp bpf_insn_jmp - call bpf_insn_call_helper - func bpf_insn_call_func - exit bpf_insn_exit - initr0 bpf_insn_init_r0 - map bpf_insn_map - map_val bpf_insn_map_value - btf_id bpf_insn_btf_id + generic bpf_insn_generic + ldst bpf_insn_ldst + alu bpf_insn_alu + jmp bpf_insn_jmp + call bpf_insn_call_helper + func bpf_insn_call_func + exit bpf_insn_exit + initr0 bpf_insn_init_r0 + map_fd bpf_insn_map_fd + map_idx bpf_insn_map_idx + map_val bpf_insn_map_value + map_idx_val bpf_insn_map_idx_value + btf_id bpf_insn_btf_id ] [varlen] bpf_insn_generic { @@ -358,7 +365,7 @@ bpf_insn_init_r0 { imm2 int32 } -bpf_insn_map { +bpf_insn_map_fd { code const[bpf_insn_load_imm_dw, int8] dst flags[bpf_reg, int8:4] src const[BPF_PSEUDO_MAP_FD, int8:4] @@ -370,6 +377,18 @@ bpf_insn_map { imm2 const[0, int32] } +bpf_insn_map_idx { + code const[bpf_insn_load_imm_dw, int8] + dst flags[bpf_reg, int8:4] + src const[BPF_PSEUDO_MAP_IDX, int8:4] + off const[0, int16] + imm map_fd_id + code2 const[0, int8] + regs2 const[0, int8] + off2 const[0, int16] + imm2 const[0, int32] +} + bpf_insn_map_value { code const[bpf_insn_load_imm_dw, int8] dst flags[bpf_reg, int8:4] @@ -382,6 +401,18 @@ bpf_insn_map_value { imm2 int32 } +bpf_insn_map_idx_value { + code const[bpf_insn_load_imm_dw, int8] + dst flags[bpf_reg, int8:4] + src const[BPF_PSEUDO_MAP_IDX_VALUE, int8:4] + off const[0, int16] + imm map_fd_id + code2 const[0, int8] + regs2 const[0, int8] + off2 const[0, int16] + imm2 int32 +} + bpf_insn_btf_id { code const[bpf_insn_load_imm_dw, int8] dst flags[bpf_reg, int8:4] diff --git a/sys/linux/bpf.txt.const b/sys/linux/bpf.txt.const index ebced303a..83ff643d5 100644 --- a/sys/linux/bpf.txt.const +++ b/sys/linux/bpf.txt.const @@ -193,6 +193,8 @@ BPF_PROG_TYPE_XDP = 6 BPF_PSEUDO_BTF_ID = 3 BPF_PSEUDO_CALL = 1 BPF_PSEUDO_MAP_FD = 1 +BPF_PSEUDO_MAP_IDX = 5 +BPF_PSEUDO_MAP_IDX_VALUE = 6 BPF_PSEUDO_MAP_VALUE = 2 BPF_REG_0 = 0 BPF_REG_1 = 1 diff --git a/sys/linux/test/bpf_cgroup b/sys/linux/test/bpf_cgroup index e28034c83..ad848e3fb 100644 --- a/sys/linux/test/bpf_cgroup +++ b/sys/linux/test/bpf_cgroup @@ -6,7 +6,7 @@ r1 = write$tcp_congestion(r0, &AUTO='reno\x00', AUTO) # Now, load a BPF_PROG_TYPE_CGROUP_SYSCTL that simply returns 0, which will block all writes to /proc/sys -r2 = bpf$PROG_LOAD(AUTO, &AUTO={0x17, AUTO, &AUTO=@framed={{AUTO, AUTO, AUTO, AUTO, 0x0, AUTO, AUTO, AUTO, 0x0}, [], {AUTO, AUTO, AUTO, AUTO}}, &AUTO='GPL\x00', 0x0, 0x0, 0x0, 0x0, 0x0, "00000000000000000000000000000000", 0x0, 0x12, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 0x78) +r2 = bpf$PROG_LOAD(AUTO, &AUTO={0x17, AUTO, &AUTO=@framed={{AUTO, AUTO, AUTO, AUTO, 0x0, AUTO, AUTO, AUTO, 0x0}, [], {AUTO, AUTO, AUTO, AUTO}}, &AUTO='GPL\x00', 0x0, 0x0, 0x0, 0x0, 0x0, "00000000000000000000000000000000", 0x0, 0x12, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 0x90) r3 = openat(0xffffffffffffff9c, &AUTO='./cgroup\x00', 0x0, 0x0) diff --git a/sys/linux/test/btf_id b/sys/linux/test/btf_id index 0e004659e..dde131829 100644 --- a/sys/linux/test/btf_id +++ b/sys/linux/test/btf_id @@ -4,7 +4,7 @@ r0 = syz_btf_id_by_name$bpf_lsm(&AUTO='bpf_lsm_path_mkdir\x00') # Load the bpf program. -r1 = bpf$BPF_PROG_WITH_BTFID_LOAD(0x5, &AUTO=@bpf_lsm={0x1d, AUTO, &AUTO=@framed={{AUTO, AUTO, AUTO, AUTO, 0x0, AUTO, AUTO, AUTO, 0x0}, [], {AUTO, AUTO, AUTO, AUTO}}, &AUTO='GPL\x00', 0x0, 0x0, 0x0, 0x0, 0x0, "00000000000000000000000000000000", 0x0, 0x1b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, r0, 0x0}, 0x78) +r1 = bpf$BPF_PROG_WITH_BTFID_LOAD(0x5, &AUTO=@bpf_lsm={0x1d, AUTO, &AUTO=@framed={{AUTO, AUTO, AUTO, AUTO, 0x0, AUTO, AUTO, AUTO, 0x0}, [], {AUTO, AUTO, AUTO, AUTO}}, &AUTO='GPL\x00', 0x0, 0x0, 0x0, 0x0, 0x0, "00000000000000000000000000000000", 0x0, 0x1b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, r0, 0x0, 0x0, 0x0}, 0x90) # Attach the bpf program to the lsm hook. @@ -14,6 +14,6 @@ r2 = bpf$BPF_RAW_TRACEPOINT_OPEN_UNNAMED(0x11, &AUTO={AUTO, r1}, 0x10) r3 = syz_btf_id_by_name$bpf_lsm(&AUTO='bpf_lsm_path_mkdir\x00') -r4 = bpf$BPF_PROG_WITH_BTFID_LOAD(0x5, &AUTO=@bpf_lsm={0x1d, AUTO, &AUTO=@framed={{AUTO, AUTO, AUTO, AUTO, 0x0, AUTO, AUTO, AUTO, 0x0}, [], {AUTO, AUTO, AUTO, AUTO}}, &AUTO='GPL\x00', 0x0, 0x0, 0x0, 0x0, 0x0, "00000000000000000000000000000000", 0x0, 0x1b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, r3, 0x0}, 0x78) +r4 = bpf$BPF_PROG_WITH_BTFID_LOAD(0x5, &AUTO=@bpf_lsm={0x1d, AUTO, &AUTO=@framed={{AUTO, AUTO, AUTO, AUTO, 0x0, AUTO, AUTO, AUTO, 0x0}, [], {AUTO, AUTO, AUTO, AUTO}}, &AUTO='GPL\x00', 0x0, 0x0, 0x0, 0x0, 0x0, "00000000000000000000000000000000", 0x0, 0x1b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, r3, 0x0, 0x0, 0x0}, 0x90) r5 = bpf$BPF_RAW_TRACEPOINT_OPEN_UNNAMED(0x11, &AUTO={AUTO, r4}, 0x10) -- cgit mrf-deployment