
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/ICLIXY -------------------------------- If an AF_PACKET socket is used to send packets through ipvlan l2e and the default xmit function of the AF_PACKET socket is changed from dev_queue_xmit() to dev_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: ================================================================= BUG: KASAN: slab-out-of-bounds in ipvlan_xmit_mode_l2e+0xda/0x6a0 [ipvlan] Read of size 4 at addr ffff888011720cff by task a.out/1909 CPU: 5 PID: 1909 Comm: a.out Tainted: G I E 6.6.0+ #289 Call Trace: <TASK> dump_stack_lvl+0x33/0x50 print_address_description.constprop.0+0x6b/0x3d0 print_report+0xb5/0x270 kasan_report+0xa6/0xe0 ipvlan_xmit_mode_l2e+0xda/0x6a0 [ipvlan] ipvlan_start_xmit+0x29/0x80 [ipvlan] __dev_direct_xmit+0x267/0x370 packet_xmit+0xf2/0x1a0 packet_snd+0xc61/0x14a0 __sock_sendmsg+0x116/0x120 __sys_sendto+0x183/0x220 __x64_sys_sendto+0x72/0x90 do_syscall_64+0x57/0x100 entry_SYSCALL_64_after_hwframe+0x78/0xe2 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. dev_direct_xmit() doesn't reset skb->mac_header as dev_queue_xmit() In this case, skb->mac_header is 65535 when ipvlan_xmit_mode_l2e() is called. So when ipvlan_xmit_mode_l2e() gets mac header with eth_hdr() which use "skb->head + skb->mac_header", out-of-bound access occurs. This patch call skb_reset_mac_header() when mac header was not set to fix the out-of-bound bug. Fixes: 53f51b3cd1e4 ("ipvlan: Introduce l2e mode") Signed-off-by: Zhang Changzhong <zhangchangzhong@huawei.com> --- drivers/net/ipvlan/ipvlan_core.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c index 6e81355..65da4c2 100644 --- a/drivers/net/ipvlan/ipvlan_core.c +++ b/drivers/net/ipvlan/ipvlan_core.c @@ -808,11 +808,15 @@ static int ipvlan_l2e_local_xmit_event(struct ipvl_dev *ipvlan, static int ipvlan_xmit_mode_l2e(struct sk_buff *skb, struct net_device *dev) { struct ipvl_dev *ipvlan = netdev_priv(dev); - struct ethhdr *eth = eth_hdr(skb); struct ipvl_addr *addr; + struct ethhdr *eth; void *lyr3h; int addr_type; + if (!skb_mac_header_was_set(skb)) + skb_reset_mac_header(skb); + + eth = eth_hdr(skb); if (!ipvlan_is_vepa(ipvlan->port) && ether_addr_equal(eth->h_dest, eth->h_source)) { lyr3h = ipvlan_get_L3_hdr(ipvlan->port, skb, &addr_type); -- 2.9.5