]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
bpf: Explicitly check accesses to bpf_sock_addr
authorPaul Chaignon <paul.chaignon@gmail.com>
Wed, 17 Sep 2025 08:08:00 +0000 (10:08 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 15 Oct 2025 09:56:29 +0000 (11:56 +0200)
[ 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.1758094761.git.paul.chaignon@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
net/core/filter.c

index cd0c28e94979a4b9a1984471649fe81798c6c31f..183ede9345e6101657819ee70c2970b78353fc75 100644 (file)
@@ -9100,13 +9100,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;