Message ID | 20220907101204.255213-1-luwei32@huawei.com (mailing list archive) |
---|---|
State | Accepted |
Commit | 81225b2ea161af48e093f58e8dfee6d705b16af4 |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | [net] ipvlan: Fix out-of-bound bugs caused by unset skb->mac_header | expand |
On Wed, Sep 7, 2022 at 3:09 AM Lu Wei <luwei32@huawei.com> wrote: > > If an AF_PACKET socket is used to send packets through ipvlan and the > default xmit function of the AF_PACKET socket is changed from > dev_queue_xmit() to packet_direct_xmit() via setsockopt() with the option > name of PACKET_QDISC_BYPASS, the skb->mac_header may not be reset and > remains as the initial value of 65535, this may trigger slab-out-of-bounds > bugs as following: > > ================================================================= > UG: KASAN: slab-out-of-bounds in ipvlan_xmit_mode_l2+0xdb/0x330 [ipvlan] > > Fixes: 2ad7bf363841 ("ipvlan: Initial check-in of the IPVLAN driver.") > Signed-off-by: Lu Wei <luwei32@huawei.com> > --- This was on my TODO list, I had a similar KASAN report, after my recent addition in skb_mac_header() DEBUG_NET_WARN_ON_ONCE(!skb_mac_header_was_set(skb)); Reviewed-by: Eric Dumazet <edumazet@google.com> WARNING: CPU: 1 PID: 14752 at include/linux/skbuff.h:2821 skb_mac_header include/linux/skbuff.h:2821 [inline] WARNING: CPU: 1 PID: 14752 at include/linux/skbuff.h:2821 eth_hdr include/linux/if_ether.h:24 [inline] WARNING: CPU: 1 PID: 14752 at include/linux/skbuff.h:2821 ipvlan_xmit_mode_l2 drivers/net/ipvlan/ipvlan_core.c:592 [inline] WARNING: CPU: 1 PID: 14752 at include/linux/skbuff.h:2821 ipvlan_queue_xmit+0xcba/0x19d0 drivers/net/ipvlan/ipvlan_core.c:644 Modules linked in: CPU: 1 PID: 14752 Comm: syz-executor.4 Not tainted 6.0.0-rc3-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/22/2022 RIP: 0010:skb_mac_header include/linux/skbuff.h:2821 [inline] RIP: 0010:eth_hdr include/linux/if_ether.h:24 [inline] RIP: 0010:ipvlan_xmit_mode_l2 drivers/net/ipvlan/ipvlan_core.c:592 [inline] RIP: 0010:ipvlan_queue_xmit+0xcba/0x19d0 drivers/net/ipvlan/ipvlan_core.c:644 Code: 41 0f b7 d6 48 c7 c6 40 c7 75 8a 48 c7 c7 c0 c4 75 8a c6 05 7d 52 d9 08 01 e8 df 0d 4a 04 0f 0b e9 e5 f7 ff ff e8 66 cb 8b fc <0f> 0b e9 ac f8 ff ff e8 6a 35 d8 fc e9 ed f4 ff ff e8 70 35 d8 fc RSP: 0018:ffffc900069b7808 EFLAGS: 00010293 RAX: 0000000000000000 RBX: ffff8880456ea000 RCX: 0000000000000000 RDX: ffff8880214c5880 RSI: ffffffff84f03eca RDI: 0000000000000003 RBP: ffffc900069b79b8 R08: 0000000000000003 R09: 000000000000ffff R10: 000000000000ffff R11: 0000000000000000 R12: ffff888075d62140 R13: 1ffff92000d36f06 R14: 000000000000ffff R15: ffff8880456eaca0 FS: 00007f2302712700(0000) GS:ffff8880b9b00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f23005fe718 CR3: 000000001f461000 CR4: 00000000003506e0 Call Trace: <TASK> ipvlan_start_xmit+0x45/0x150 drivers/net/ipvlan/ipvlan_main.c:220 __netdev_start_xmit include/linux/netdevice.h:4819 [inline] netdev_start_xmit include/linux/netdevice.h:4833 [inline] __dev_direct_xmit+0x500/0x720 net/core/dev.c:4312 dev_direct_xmit include/linux/netdevice.h:3021 [inline] packet_direct_xmit+0x1b3/0x2c0 net/packet/af_packet.c:282 packet_snd net/packet/af_packet.c:3073 [inline] packet_sendmsg+0x3354/0x5500 net/packet/af_packet.c:3104 sock_sendmsg_nosec net/socket.c:714 [inline] sock_sendmsg+0xcf/0x120 net/socket.c:734 __sys_sendto+0x236/0x340 net/socket.c:2117 __do_sys_sendto net/socket.c:2129 [inline] __se_sys_sendto net/socket.c:2125 [inline] __x64_sys_sendto+0xdd/0x1b0 net/socket.c:2125 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd RIP: 0033:0x7f2301689279 Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f2302712168 EFLAGS: 00000246 ORIG_RAX: 000000000000002c RAX: ffffffffffffffda RBX: 00007f230179c120 RCX: 00007f2301689279 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000003 RBP: 00007f23016e3189 R08: 00000000200000c0 R09: 0000000000000014 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 00007f2301ccfb1f R14: 00007f2302712300 R15: 0000000000022000 </TASK>
Hello: This patch was applied to netdev/net.git (master) by David S. Miller <davem@davemloft.net>: On Wed, 7 Sep 2022 18:12:04 +0800 you wrote: > If an AF_PACKET socket is used to send packets through ipvlan and the > default xmit function of the AF_PACKET socket is changed from > dev_queue_xmit() to packet_direct_xmit() via setsockopt() with the option > name of PACKET_QDISC_BYPASS, the skb->mac_header may not be reset and > remains as the initial value of 65535, this may trigger slab-out-of-bounds > bugs as following: > > [...] Here is the summary with links: - [net] ipvlan: Fix out-of-bound bugs caused by unset skb->mac_header https://git.kernel.org/netdev/net/c/81225b2ea161 You are awesome, thank you!
diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c index dfeb5b392e64..bb1c298c1e78 100644 --- a/drivers/net/ipvlan/ipvlan_core.c +++ b/drivers/net/ipvlan/ipvlan_core.c @@ -495,7 +495,6 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb) static int ipvlan_process_outbound(struct sk_buff *skb) { - struct ethhdr *ethh = eth_hdr(skb); int ret = NET_XMIT_DROP; /* The ipvlan is a pseudo-L2 device, so the packets that we receive @@ -505,6 +504,8 @@ static int ipvlan_process_outbound(struct sk_buff *skb) if (skb_mac_header_was_set(skb)) { /* In this mode we dont care about * multicast and broadcast traffic */ + struct ethhdr *ethh = eth_hdr(skb); + if (is_multicast_ether_addr(ethh->h_dest)) { pr_debug_ratelimited( "Dropped {multi|broad}cast of type=[%x]\n", @@ -589,7 +590,7 @@ static int ipvlan_xmit_mode_l3(struct sk_buff *skb, struct net_device *dev) static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev) { const struct ipvl_dev *ipvlan = netdev_priv(dev); - struct ethhdr *eth = eth_hdr(skb); + struct ethhdr *eth = skb_eth_hdr(skb); struct ipvl_addr *addr; void *lyr3h; int addr_type; @@ -619,6 +620,7 @@ static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev) return dev_forward_skb(ipvlan->phy_dev, skb); } else if (is_multicast_ether_addr(eth->h_dest)) { + skb_reset_mac_header(skb); ipvlan_skb_crossing_ns(skb, NULL); ipvlan_multicast_enqueue(ipvlan->port, skb, true); return NET_XMIT_SUCCESS;
If an AF_PACKET socket is used to send packets through ipvlan and the default xmit function of the AF_PACKET socket is changed from dev_queue_xmit() to packet_direct_xmit() via setsockopt() with the option name of PACKET_QDISC_BYPASS, the skb->mac_header may not be reset and remains as the initial value of 65535, this may trigger slab-out-of-bounds bugs as following: ================================================================= UG: KASAN: slab-out-of-bounds in ipvlan_xmit_mode_l2+0xdb/0x330 [ipvlan] PU: 2 PID: 1768 Comm: raw_send Kdump: loaded Not tainted 6.0.0-rc4+ #6 ardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-1.fc33 all Trace: print_address_description.constprop.0+0x1d/0x160 print_report.cold+0x4f/0x112 kasan_report+0xa3/0x130 ipvlan_xmit_mode_l2+0xdb/0x330 [ipvlan] ipvlan_start_xmit+0x29/0xa0 [ipvlan] __dev_direct_xmit+0x2e2/0x380 packet_direct_xmit+0x22/0x60 packet_snd+0x7c9/0xc40 sock_sendmsg+0x9a/0xa0 __sys_sendto+0x18a/0x230 __x64_sys_sendto+0x74/0x90 do_syscall_64+0x3b/0x90 entry_SYSCALL_64_after_hwframe+0x63/0xcd The root cause is: 1. packet_snd() only reset skb->mac_header when sock->type is SOCK_RAW and skb->protocol is not specified as in packet_parse_headers() 2. packet_direct_xmit() doesn't reset skb->mac_header as dev_queue_xmit() In this case, skb->mac_header is 65535 when ipvlan_xmit_mode_l2() is called. So when ipvlan_xmit_mode_l2() gets mac header with eth_hdr() which use "skb->head + skb->mac_header", out-of-bound access occurs. This patch replaces eth_hdr() with skb_eth_hdr() in ipvlan_xmit_mode_l2() and reset mac header in multicast to solve this out-of-bound bug. Fixes: 2ad7bf363841 ("ipvlan: Initial check-in of the IPVLAN driver.") Signed-off-by: Lu Wei <luwei32@huawei.com> --- drivers/net/ipvlan/ipvlan_core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)