From 8ad4a8143de26cbdb7d7b9e4e4477eab73a146ff Mon Sep 17 00:00:00 2001 From: Paul Chaignon Date: Mon, 2 Oct 2023 13:19:01 +0200 Subject: sys/linux: describe full call to bpf_snprintf helper This commit describes the full snippet of BPF bytecode required to successfully call the bpf_snprintf helper. That helper has the following prototype: long bpf_snprintf(char *str, u32 str_size, const char *fmt, u64 *data, u32 data_len) with the following verifier types: .arg1_type = ARG_PTR_TO_MEM_OR_NULL, .arg2_type = ARG_CONST_SIZE_OR_ZERO, .arg3_type = ARG_PTR_TO_CONST_STR, .arg4_type = ARG_PTR_TO_MEM | PTR_MAYBE_NULL | MEM_RDONLY, .arg5_type = ARG_CONST_SIZE_OR_ZERO, The first and fourth arguments can point to nulled buffers on the stack. The second and fifth arguments contain the sizes of those buffers. Finally, the third argument must point to a map holding a constant string; we can use the type introduced in the previous commit for that. The corresponding eBPF bytecode is kept in comment as that is much easier to parse for anyone familiar with the bytecode. In addition to the test case introduced in the next commit, this description was tested by running syzkaller with a focus on the necessary bpf syscalls. Specifically, syscalls bpf$MAP_CREATE_CONST_STR, bpf$MAP_UPDATE_CONST_STR, bpf$BPF_MAP_CONST_STR_FREEZE, bpf$PROG_LOAD, and bpf$BPF_PROG_TEST_RUN were executed on 16 VMs (with two logical cores each). Syzkaller was then able to reach the formatter parsing logic of function bpf_bprintf_prepare [1], which bpf_snprintf calls. 1 - https://github.com/torvalds/linux/blob/v6.5/kernel/bpf/helpers.c#L875 Signed-off-by: Paul Chaignon --- sys/linux/bpf.txt.const | 1 + 1 file changed, 1 insertion(+) (limited to 'sys/linux/bpf.txt.const') diff --git a/sys/linux/bpf.txt.const b/sys/linux/bpf.txt.const index e6eff547d..07c73dece 100644 --- a/sys/linux/bpf.txt.const +++ b/sys/linux/bpf.txt.const @@ -61,6 +61,7 @@ BPF_EXIST = 2 BPF_EXIT0 = 9 BPF_FLOW_DISSECTOR = 17 BPF_FUNC_INFO_SIZE = 8 +BPF_FUNC_snprintf = 165 BPF_FUNC_trace_printk = 6 BPF_F_AFTER = 16 BPF_F_ALLOW_MULTI = 2 -- cgit mrf-deployment