| From 8bd67ebb50c0145fd2ca8681ab65eb7e8cde1afc Mon Sep 17 00:00:00 2001 |
| From: Nikolay Aleksandrov <razor@blackwall.org> |
| Date: Mon, 13 May 2024 13:34:19 +0300 |
| Subject: net: bridge: xmit: make sure we have at least eth header len bytes |
| |
| From: Nikolay Aleksandrov <razor@blackwall.org> |
| |
| commit 8bd67ebb50c0145fd2ca8681ab65eb7e8cde1afc upstream. |
| |
| syzbot triggered an uninit value[1] error in bridge device's xmit path |
| by sending a short (less than ETH_HLEN bytes) skb. To fix it check if |
| we can actually pull that amount instead of assuming. |
| |
| Tested with dropwatch: |
| drop at: br_dev_xmit+0xb93/0x12d0 [bridge] (0xffffffffc06739b3) |
| origin: software |
| timestamp: Mon May 13 11:31:53 2024 778214037 nsec |
| protocol: 0x88a8 |
| length: 2 |
| original length: 2 |
| drop reason: PKT_TOO_SMALL |
| |
| [1] |
| BUG: KMSAN: uninit-value in br_dev_xmit+0x61d/0x1cb0 net/bridge/br_device.c:65 |
| br_dev_xmit+0x61d/0x1cb0 net/bridge/br_device.c:65 |
| __netdev_start_xmit include/linux/netdevice.h:4903 [inline] |
| netdev_start_xmit include/linux/netdevice.h:4917 [inline] |
| xmit_one net/core/dev.c:3531 [inline] |
| dev_hard_start_xmit+0x247/0xa20 net/core/dev.c:3547 |
| __dev_queue_xmit+0x34db/0x5350 net/core/dev.c:4341 |
| dev_queue_xmit include/linux/netdevice.h:3091 [inline] |
| __bpf_tx_skb net/core/filter.c:2136 [inline] |
| __bpf_redirect_common net/core/filter.c:2180 [inline] |
| __bpf_redirect+0x14a6/0x1620 net/core/filter.c:2187 |
| ____bpf_clone_redirect net/core/filter.c:2460 [inline] |
| bpf_clone_redirect+0x328/0x470 net/core/filter.c:2432 |
| ___bpf_prog_run+0x13fe/0xe0f0 kernel/bpf/core.c:1997 |
| __bpf_prog_run512+0xb5/0xe0 kernel/bpf/core.c:2238 |
| bpf_dispatcher_nop_func include/linux/bpf.h:1234 [inline] |
| __bpf_prog_run include/linux/filter.h:657 [inline] |
| bpf_prog_run include/linux/filter.h:664 [inline] |
| bpf_test_run+0x499/0xc30 net/bpf/test_run.c:425 |
| bpf_prog_test_run_skb+0x14ea/0x1f20 net/bpf/test_run.c:1058 |
| bpf_prog_test_run+0x6b7/0xad0 kernel/bpf/syscall.c:4269 |
| __sys_bpf+0x6aa/0xd90 kernel/bpf/syscall.c:5678 |
| __do_sys_bpf kernel/bpf/syscall.c:5767 [inline] |
| __se_sys_bpf kernel/bpf/syscall.c:5765 [inline] |
| __x64_sys_bpf+0xa0/0xe0 kernel/bpf/syscall.c:5765 |
| x64_sys_call+0x96b/0x3b50 arch/x86/include/generated/asm/syscalls_64.h:322 |
| do_syscall_x64 arch/x86/entry/common.c:52 [inline] |
| do_syscall_64+0xcf/0x1e0 arch/x86/entry/common.c:83 |
| entry_SYSCALL_64_after_hwframe+0x77/0x7f |
| |
| Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") |
| Reported-by: syzbot+a63a1f6a062033cf0f40@syzkaller.appspotmail.com |
| Closes: https://syzkaller.appspot.com/bug?extid=a63a1f6a062033cf0f40 |
| Signed-off-by: Nikolay Aleksandrov <razor@blackwall.org> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Randy MacLeod <Randy.MacLeod@windriver.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| net/bridge/br_device.c | 5 +++++ |
| 1 file changed, 5 insertions(+) |
| |
| --- a/net/bridge/br_device.c |
| +++ b/net/bridge/br_device.c |
| @@ -35,6 +35,11 @@ netdev_tx_t br_dev_xmit(struct sk_buff * |
| const unsigned char *dest; |
| u16 vid = 0; |
| |
| + if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) { |
| + kfree_skb(skb); |
| + return NETDEV_TX_OK; |
| + } |
| + |
| memset(skb->cb, 0, sizeof(struct br_input_skb_cb)); |
| |
| rcu_read_lock(); |