6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Chaignon paul.chaignon@gmail.com
[ Upstream commit 6fabca2fc94d33cdf7ec102058983b086293395f ]
Syzkaller found a kernel warning on the following sock_addr program:
0: r0 = 0 1: r2 = *(u32 *)(r1 +60) 2: exit
which triggers:
verifier bug: error during ctx access conversion (0)
This is happening because offset 60 in bpf_sock_addr corresponds to an implicit padding of 4 bytes, right after msg_src_ip4. Access to this padding isn't rejected in sock_addr_is_valid_access and it thus later fails to convert the access.
This patch fixes it by explicitly checking the various fields of bpf_sock_addr in sock_addr_is_valid_access.
I checked the other ctx structures and is_valid_access functions and didn't find any other similar cases. Other cases of (properly handled) padding are covered in new tests in a subsequent patch.
Fixes: 1cedee13d25a ("bpf: Hooks for sys_sendmsg") Reported-by: syzbot+136ca59d411f92e821b7@syzkaller.appspotmail.com Signed-off-by: Paul Chaignon paul.chaignon@gmail.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Acked-by: Eduard Zingerman eddyz87@gmail.com Acked-by: Daniel Borkmann daniel@iogearbox.net Closes: https://syzkaller.appspot.com/bug?extid=136ca59d411f92e821b7 Link: https://lore.kernel.org/bpf/b58609d9490649e76e584b0361da0abd3c2c1779.1758094... Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/filter.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/net/core/filter.c b/net/core/filter.c index 02fedc404d7f7..c850e5d6cbd87 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -9233,13 +9233,17 @@ static bool sock_addr_is_valid_access(int off, int size, return false; info->reg_type = PTR_TO_SOCKET; break; - default: - if (type == BPF_READ) { - if (size != size_default) - return false; - } else { + case bpf_ctx_range(struct bpf_sock_addr, user_family): + case bpf_ctx_range(struct bpf_sock_addr, family): + case bpf_ctx_range(struct bpf_sock_addr, type): + case bpf_ctx_range(struct bpf_sock_addr, protocol): + if (type != BPF_READ) return false; - } + if (size != size_default) + return false; + break; + default: + return false; }
return true;