Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Describe BPF helper bpf_map_lookup_elem #5408

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion pkg/compiler/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,11 @@ func (comp *compiler) checkPathField(target, t *ast.Type, field *ast.Field) bool
}

func (comp *compiler) checkExprLastField(target *ast.Type, field *ast.Field) {
_, desc := comp.derefPointers(field.Type)
typ, desc := comp.derefPointers(field.Type)
if desc == typeResource {
r := comp.resources[typ.Ident]
desc = comp.getTypeDesc(r.Base)
}
if desc != typeInt && desc != typeFlags && desc != typeConst {
comp.error(target.Pos, "%v does not refer to a constant, an integer, or a flag", field.Name.Name)
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/compiler/testdata/errors2.txt
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ conditional_fields {
f3 some_nested_flags
f4 int32 (if[value[f3:f1] != 0])
f5 int32 (if[value[f3:f2:f4] != 0]) ### value path f2 does not refer to a struct
f6 int32 (if[value[f3:f4] != 0]) ### f4 does not refer to a constant, an integer, or a flag
f6 int32 (if[value[f3:f4] != 0])
f7 int32 (if[value[f3:some_field] != 0]) ### value target some_field does not exist in some_nested_flags
f8 int32 (if[value[f3:f5] != 0]) ### f5 has conditions, so value path cannot reference it
f9 int32 (if[value[parent:a] != 0]) ### value target a does not exist in conditional_fields
Expand Down
16 changes: 13 additions & 3 deletions prog/expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,21 @@ func (v *Value) Evaluate(finder ArgFinder) (uint64, bool) {
if found == nil {
panic(fmt.Sprintf("no argument was found by %v", v.Path))
}
constArg, ok := found.(*ConstArg)
if !ok {
val := uint64(0)
iter:
switch arg := found.(type) {
case *ConstArg:
val = arg.Val
case *ResultArg:
if arg.Res != nil {
found = arg.Res
goto iter
}
val = arg.Val
default:
panic("value expressions must only rely on int fields")
}
return constArg.Val, true
return val, true
}

func makeArgFinder(t *Target, c *Call, unionArg *UnionArg, parents parentStack) ArgFinder {
Expand Down
7 changes: 5 additions & 2 deletions sys/linux/bpf.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ resource bpf_frozen_const_str[fd_bpf_const_str]
resource tail_call_map_fd[fd_bpf_map]
resource tail_call_map[tail_call_map_fd]
resource ringbuf_map_fd[fd_bpf_map]
resource map_key_size[int32]: 1, 2, 4, 8

# NEED: this is a random index in btf_header:types. We can't express this, so we just use a small index.
type btf_type_id int32[1:5]
Expand Down Expand Up @@ -99,6 +100,8 @@ bpf_map_const_str_freeze {
out bpf_frozen_const_str (out_overlay)
}

syz_create_resource$map_key_size(ksize int32) map_key_size

bpf_map_create_arg [
base bpf_map_create_arg_base
bloom_filter bpf_map_create_arg_bf
Expand Down Expand Up @@ -126,8 +129,8 @@ type bpf_map_create_arg_t[TYPE, KSIZE, VSIZE, MAX, FLAGS, MAP_EXTRA] {
pad2 const[0, int32] (if[value[flags] & BPF_F_TOKEN_FD == 0])
} [packed]

type bpf_map_create_arg_base bpf_map_create_arg_t[flags[bpf_map_type, int32], int32, int32, int32, flags[map_flags, int32], const[0, int64]]
type bpf_map_create_arg_bf bpf_map_create_arg_t[const[BPF_MAP_TYPE_BLOOM_FILTER, int32], int32, int32, int32, flags[map_flags, int32], int64[0:15]]
type bpf_map_create_arg_base bpf_map_create_arg_t[flags[bpf_map_type, int32], map_key_size, int32, int32, flags[map_flags, int32], const[0, int64]]
type bpf_map_create_arg_bf bpf_map_create_arg_t[const[BPF_MAP_TYPE_BLOOM_FILTER, int32], map_key_size, int32, int32, flags[map_flags, int32], int64[0:15]]
type bpf_map_create_arg_ringbuf bpf_map_create_arg_t[const[BPF_MAP_TYPE_RINGBUF, int32], const[0, int32], const[0, int32], int32, const[0, int32], const[0, int64]]
type bpf_map_create_arg_const_str bpf_map_create_arg_t[const[BPF_MAP_TYPE_ARRAY, int32], const[4, int32], const[8, int32], const[1, int32], const[BPF_F_RDONLY_PROG, int32], const[0, int64]]
type bpf_map_create_arg_tail_call bpf_map_create_arg_t[const[BPF_MAP_TYPE_PROG_ARRAY, int32], const[4, int32], const[4, int32], const[10, int32], const[0, int32], const[0, int64]]
Expand Down
27 changes: 27 additions & 0 deletions sys/linux/bpf_prog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ bpf_insn [
tail_call bpf_insn_tail_call
ringbuf_query bpf_insn_ringbuf_query
ringbuf_output bpf_insn_ringbuf_output
map_lookup bpf_insn_map_lookup
] [varlen]

bpf_insn_generic {
Expand All @@ -171,6 +172,9 @@ type bpf_insn_ldst_t[CLASS, SZ, MODE, DST, SRC, OFF, IMM] {
}

type bpf_insn_ldst bpf_insn_ldst_t[bpf_ldst_insn, bpf_ldst_size, bpf_ldst_mode, flags[bpf_reg, int8:4], flags[bpf_reg, int8:4], flags[bpf_insn_offsets, int16], flags[bpf_insn_immediates, int32]]
type bpf_insn_st8_reg[SRC, DST, OFF] bpf_insn_ldst_t[BPF_STX, BPF_B0, BPF_MEM0, const[DST, int8:4], const[SRC, int8:4], const[OFF, int16], const[0, int32]]
type bpf_insn_st16_reg[SRC, DST, OFF] bpf_insn_ldst_t[BPF_STX, BPF_H0, BPF_MEM0, const[DST, int8:4], const[SRC, int8:4], const[OFF, int16], const[0, int32]]
type bpf_insn_st32_reg[SRC, DST, OFF] bpf_insn_ldst_t[BPF_STX, BPF_W0, BPF_MEM0, const[DST, int8:4], const[SRC, int8:4], const[OFF, int16], const[0, int32]]
type bpf_insn_st64_reg[SRC, DST, OFF] bpf_insn_ldst_t[BPF_STX, BPF_DW0, BPF_MEM0, const[DST, int8:4], const[SRC, int8:4], const[OFF, int16], const[0, int32]]

bpf_ldst_insn = BPF_LD, BPF_LDX, BPF_ST, BPF_STX
Expand Down Expand Up @@ -555,3 +559,26 @@ bpf_insn_ringbuf_output {
define MAX_BPF_REG __MAX_BPF_REG

bpf_ringbuf_wakeup_flags = 0, BPF_RB_NO_WAKEUP, BPF_RB_FORCE_WAKEUP

# (18) r1 = map[id:10]
# (b7) r8 = X
# (7b) *(u64 *)(r10 -8) = r8
# (bf) r2 = r10
# (07) r2 -= 8
# (85) call bpf_map_lookup_elem
bpf_insn_map_lookup {
insn1 bpf_insn_map_fd_t[const[BPF_REG_1, int8:4], fd_bpf_map]
insn2 bpf_insn_mov_imm_any[BPF_REG_8]
insn3 bpf_insn_stX_reg
insn4 bpf_insn_mov_reg[BPF_REG_10, BPF_REG_2]
insn5 bpf_insn_alu_t[BPF_ALU64, BPF_K0, BPF_SUB0, const[BPF_REG_2, int8:4], const[0, int8:4], const[0, int16], map_key_size]
insn6 bpf_insn_call_helper_t[const[BPF_FUNC_map_lookup_elem, int32]]
} [packed]

bpf_insn_stX_reg [
st8 bpf_insn_st8_reg[BPF_REG_8, BPF_REG_10, -1] (if[value[parent:parent:insn5:imm] == 1])
st16 bpf_insn_st16_reg[BPF_REG_8, BPF_REG_10, -2] (if[value[parent:parent:insn5:imm] == 2])
st32 bpf_insn_st32_reg[BPF_REG_8, BPF_REG_10, -4] (if[value[parent:parent:insn5:imm] == 4])
st64 bpf_insn_st64_reg[BPF_REG_8, BPF_REG_10, -8] (if[value[parent:parent:insn5:imm] == 8])
fallback bpf_insn_st64_reg[BPF_REG_8, BPF_REG_10, -8]
]
1 change: 1 addition & 0 deletions sys/linux/bpf_prog.txt.const
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ BPF_END0 = 13
BPF_EXIT0 = 9
BPF_FLOW_DISSECTOR = 17
BPF_FUNC_INFO_SIZE = 8
BPF_FUNC_map_lookup_elem = 1
BPF_FUNC_ringbuf_discard = 133
BPF_FUNC_ringbuf_output = 130
BPF_FUNC_ringbuf_query = 134
Expand Down
8 changes: 8 additions & 0 deletions sys/linux/test/bpf_helpers_map
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Create a BPF map

r0 = syz_create_resource$map_key_size(0x4)
r1 = bpf$MAP_CREATE(AUTO, &AUTO=@base={0x1, r0, 0x8, 0x1, 0x0, 0x0, 0x0, "00000000000000000000000000000000", 0x0, 0x0, 0x0, 0x0, 0x0, AUTO, @void, @value=AUTO, @void, @value=AUTO}, 0x48)

# Lookup an element from the map

r2 = bpf$PROG_LOAD(AUTO, &AUTO={0x3, AUTO, &AUTO=@framed={{AUTO, AUTO, AUTO, AUTO, 0x0, AUTO, AUTO, AUTO, 0x0}, [@map_lookup={{AUTO, AUTO, AUTO, AUTO, r1, AUTO, AUTO, AUTO, AUTO}, {AUTO, AUTO, AUTO, AUTO, AUTO, AUTO, 0x1234}, @st32=AUTO, AUTO, {AUTO, AUTO, AUTO, AUTO, AUTO, AUTO, r0}, AUTO}], AUTO}, &AUTO='GPL\x00', 0x0, 0x0, 0x0, 0x0, 0x0, "00000000000000000000000000000000", 0x0, @sched_cls=0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, @void, @value=AUTO}, 0xa0)
Loading