From: Alexei Starovoitov A fix of the declaration of a helper. This series needs it: scalar evolution keeps the expression of a stack slot across a call unless bpf_may_write_mask() of the call has the slot, and liveness.c computes that mask from the argument types of the helper. union bpf_attr attr = { .btf = .., .btf_size = .., .btf_log_level = 1 }; bpf_sys_bpf(BPF_BTF_LOAD, &attr, sizeof(attr)); BPF_BTF_LOAD and BPF_PROG_LOAD store log_true_size into the attr of the caller. When BPF_PROG_LOAD rejects func_info, line_info or core_relo records that are larger than it knows, it stores the record size that it expects. For the helper the attr is a kernel pointer, so copy_to_bpfptr_offset() writes to the memory of the program. arg2_type in struct bpf_func_proto bpf_sys_bpf_proto is ARG_PTR_TO_MEM | MEM_RDONLY. So the verifier keeps what it knows about an attr on the stack across the call: a slot that held 0 is taken for 0 after it. bpf_may_write_mask() of the call does not have the slots of the attr. And an attr in a map that the program cannot write to is accepted. Say MEM_WRITE. An attr in read-only memory, such as a 'static const union bpf_attr' in .rodata, is refused now: "write into map forbidden". Fixes: 37cce22dbd51 ("bpf: verifier: Refactor helper access type tracking") Fixes: 216e3cd2f28d ("bpf: Add MEM_RDONLY for helper args that are pointers to rdonly mem.") Signed-off-by: Alexei Starovoitov --- kernel/bpf/syscall.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 9004f2673ccf..04a3b3c80c74 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -6692,7 +6692,7 @@ static const struct bpf_func_proto bpf_sys_bpf_proto = { .might_sleep = true, .ret_type = RET_INTEGER, .arg1_type = ARG_ANYTHING, - .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, + .arg2_type = ARG_PTR_TO_MEM | MEM_WRITE, .arg3_type = ARG_MEM_SIZE, }; -- 2.55.0