The problem reported by syz is as follows: BUG: KASAN: slab-out-of-bounds in __build_skb_around+0x230/0x330 Write of size 32 at addr ffff88807ec6b2c0 by task bpf_repo/6711 Call Trace: <TASK> dump_stack_lvl+0x8e/0xd1 print_report+0x155/0x454 kasan_report+0xba/0x1f0 kasan_check_range+0x35/0x1b0 memset+0x20/0x40 __build_skb_around+0x230/0x330 build_skb+0x4c/0x260 bpf_prog_test_run_skb+0x2fc/0x1ce0 __sys_bpf+0x1798/0x4b60 __x64_sys_bpf+0x75/0xb0 do_syscall_64+0x35/0x80 entry_SYSCALL_64_after_hwframe+0x46/0xb0 </TASK> Allocated by task 6711: kasan_save_stack+0x1e/0x40 kasan_set_track+0x21/0x30 __kasan_kmalloc+0xa1/0xb0 __kmalloc+0x4e/0xb0 bpf_test_init.isra.0+0x77/0x100 bpf_prog_test_run_skb+0x219/0x1ce0 __sys_bpf+0x1798/0x4b60 __x64_sys_bpf+0x75/0xb0 do_syscall_64+0x35/0x80 entry_SYSCALL_64_after_hwframe+0x46/0xb0 The process is as follows: bpf_prog_test_run_skb() bpf_test_init() data = kzalloc() //The length of input is 576. //The actual allocated memory //size is 1024. build_skb() __build_skb_around() size = ksize(data)//size = 1024 size -= SKB_DATA_ALIGN( sizeof(struct skb_shared_info)); //size = 704 skb_set_end_offset(skb, size); shinfo = skb_shinfo(skb);//shinfo = data + 704 memset(shinfo...) //Write out of bounds In bpf_test_init(), the accessible space allocated to data is 576 bytes, and the memory allocated to data is 1024 bytes. In __build_skb_around(), shinfo indicates the offset of 704 bytes of data, which triggers the issue of writing out of bounds. Fixes: 1cf1cae963c2 ("bpf: introduce BPF_PROG_TEST_RUN command") Reported-by: syzbot+fda18eaa8c12534ccb3b@xxxxxxxxxxxxxxxxxxxxxxxxx Signed-off-by: Zhengchao Shao <shaozhengchao@xxxxxxxxxx> --- net/bpf/test_run.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c index fcb3e6c5e03c..fbd5337b8f68 100644 --- a/net/bpf/test_run.c +++ b/net/bpf/test_run.c @@ -766,6 +766,8 @@ static void *bpf_test_init(const union bpf_attr *kattr, u32 user_size, u32 size, u32 headroom, u32 tailroom) { void __user *data_in = u64_to_user_ptr(kattr->test.data_in); + unsigned int true_size; + void *true_data; void *data; if (size < ETH_HLEN || size > PAGE_SIZE - headroom - tailroom) @@ -779,6 +781,14 @@ static void *bpf_test_init(const union bpf_attr *kattr, u32 user_size, if (!data) return ERR_PTR(-ENOMEM); + true_size = ksize(data); + if (size + headroom + tailroom < true_size) { + true_data = krealloc(data, true_size, GFP_USER | __GFP_ZERO); + if (!true_data) + return ERR_PTR(-ENOMEM); + data = true_data; + } + if (copy_from_user(data + headroom, data_in, user_size)) { kfree(data); return ERR_PTR(-EFAULT); -- 2.17.1