The user constructed a BPF program containing a bpf_snprintf() call. The fmt parameter passed to bpf_snprintf() was not assigned a value; it only executed the BPF_MAP_FREEZE command to freeze the fmt string. Furthermore, when bpf_check() executed check_reg_const_str() and check_bpf_snprintf_call() to check the fmt input parameter of the user-constructed BPF program's bpf_snprintf() call, strnchr() only checked if fmt was a null-terminated string. This led the BPF verifier to incorrectly assume the constant format string was valid. When the BPF program was actually executed, the out-of-bounds (OOB) issue reported by syzbot occurred [1]. This issue is strongly related to bpf_snprintf(), therefore adding a check for an empty format string in check_bpf_snprintf_call() would be beneficial. Since it calls bpf_bprintf_prepare(), only adding a check on the result of strnchr() is needed to prevent the case where the format string is empty. [1] BUG: KASAN: slab-out-of-bounds in strnchr+0x5e/0x80 lib/string.c:405 Read of size 1 at addr ffff888029e093b0 by task ksoftirqd/1/23 Call Trace: strnchr+0x5e/0x80 lib/string.c:405 bpf_bprintf_prepare+0x167/0x13d0 kernel/bpf/helpers.c:829 ____bpf_snprintf kernel/bpf/helpers.c:1065 [inline] bpf_snprintf+0xd3/0x1b0 kernel/bpf/helpers.c:1049 Allocated by task 6022: __bpf_map_area_alloc kernel/bpf/syscall.c:395 [inline] bpf_map_area_alloc+0x64/0x180 kernel/bpf/syscall.c:408 insn_array_alloc+0x52/0x140 kernel/bpf/bpf_insn_array.c:49 map_create+0xafd/0x16a0 kernel/bpf/syscall.c:1514 The buggy address is located 0 bytes to the right of allocated 944-byte region [ffff888029e09000, ffff888029e093b0) Fixes: d9c9e4db186a ("bpf: Factorize bpf_trace_printk and bpf_seq_printf") Reported-by: syzbot+2c29addf92581b410079@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=2c29addf92581b410079 Tested-by: syzbot+2c29addf92581b410079@syzkaller.appspotmail.com Signed-off-by: Edward Adam Davis --- kernel/bpf/helpers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index db72b96f9c8c..88da2d0e634c 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -827,7 +827,7 @@ int bpf_bprintf_prepare(const char *fmt, u32 fmt_size, const u64 *raw_args, char fmt_ptype, cur_ip[16], ip_spec[] = "%pXX"; fmt_end = strnchr(fmt, fmt_size, 0); - if (!fmt_end) + if (!fmt_end || fmt_end == fmt) return -EINVAL; fmt_size = fmt_end - fmt; -- 2.43.0