Received: by 2002:a25:1506:0:0:0:0:0 with SMTP id 6csp666203ybv; Thu, 13 Feb 2020 07:26:32 -0800 (PST) X-Google-Smtp-Source: APXvYqxNneIEjT+W1Jq2g2tLUrc1HtwKukX/XZltpa6YziFPfEgarPuL2iB+I3sEi0/gGycLNf6C X-Received: by 2002:aca:dc45:: with SMTP id t66mr2887765oig.39.1581607592325; Thu, 13 Feb 2020 07:26:32 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1581607592; cv=none; d=google.com; s=arc-20160816; b=RMRuG33LayAfzOsZmfZ9xY/mYG7tHnrwMZZ5HMVn3XDLe86czaRRRDYmoWctylSda8 9w7SMDe4ZxJlPWi1ZMkG8LTxvUyTZJQ/OsH81oPnJUpqqjzXoH4ktCNay9nHkX0wGJvJ cjXMJ4CMdTA8mYGMtsKArA+5Fs45dl5ttcpWHzAgVuJP2wQ1X4Y1b2uXxHyXfAqpWrgW MLFLmnT09DZuvaRn825EiszNzP4xiePc4dr4PKegv4NfRIG6Mxk0eQ6ANnLNyNw7Mske 5YdX05vPppoIqKjHrA6vDzVrAa9cD90J814n9M3PuN9wDGM7ganke31vg/psgufa+6+6 k71Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=vI4nxTtLmIIV+ctCc6ge1OBRWrozCitU9TO4SzvoV2A=; b=mG7bqVYUWLrKMQXgx3Z4kfw6pYeWcJhcDzUjE76UwFKyEg6LEaS6HYtwLqxh/RkQ/J JHtexshLZVVccFr6K4SSWm0+N6N55lvWq14rbfSR0H0XwgtRGJX7BdiqIICxOU5EJ/lX AMjdcLv8jeWBwcqpCsqtgwrHDve7U2x8dNEvvaJ0sJS7bubbFUyrAVlTSDTPSTYg4JEJ pupfTvFvEW7Gcaj27QhLOG9y0AvGb04nfOk2lPisxvpVC9MVszSBihqCXJXk/OZPMnoR Hvb5jWK85P/+/rLA1cCQZ5WumFnB0MATzKJLosAK3nC51h3O3DOkWJEYhiQCmFoh5DsE y+wg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b="F/sNudoU"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i15si1261798oik.46.2020.02.13.07.26.19; Thu, 13 Feb 2020 07:26:32 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b="F/sNudoU"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387451AbgBMPZd (ORCPT + 99 others); Thu, 13 Feb 2020 10:25:33 -0500 Received: from mail.kernel.org ([198.145.29.99]:36352 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728549AbgBMPX7 (ORCPT ); Thu, 13 Feb 2020 10:23:59 -0500 Received: from localhost (unknown [104.132.1.104]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 1558124691; Thu, 13 Feb 2020 15:23:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1581607438; bh=TmD2bJfVghIxBgeQMl8W9YvpnhUUlp0KThkHrdEJluQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=F/sNudoUU9Ritzm4FraiLLPJ0PdreBVSpfx0F8IhDRESVECEp3cI8UO7IdZIbM0Uv Fd5cq7bU/RNxcBLuzsgMqOqc5KhFFWXclmz5hNtbkEBznRmQzc8V0eks2tpqR6QaO3 kcu6lt8gr9oCC2Jtbx2PtbZqO+ryYORoIDXfIqlI= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Eric Dumazet , syzbot , Jay Vosburgh , Veaceslav Falico , Andy Gospodarek , "David S. Miller" Subject: [PATCH 4.9 075/116] bonding/alb: properly access headers in bond_alb_xmit() Date: Thu, 13 Feb 2020 07:20:19 -0800 Message-Id: <20200213151912.013945504@linuxfoundation.org> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200213151842.259660170@linuxfoundation.org> References: <20200213151842.259660170@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Eric Dumazet [ Upstream commit 38f88c45404293bbc027b956def6c10cbd45c616 ] syzbot managed to send an IPX packet through bond_alb_xmit() and af_packet and triggered a use-after-free. First, bond_alb_xmit() was using ipx_hdr() helper to reach the IPX header, but ipx_hdr() was using the transport offset instead of the network offset. In the particular syzbot report transport offset was 0xFFFF This patch removes ipx_hdr() since it was only (mis)used from bonding. Then we need to make sure IPv4/IPv6/IPX headers are pulled in skb->head before dereferencing anything. BUG: KASAN: use-after-free in bond_alb_xmit+0x153a/0x1590 drivers/net/bonding/bond_alb.c:1452 Read of size 2 at addr ffff8801ce56dfff by task syz-executor.2/18108 (if (ipx_hdr(skb)->ipx_checksum != IPX_NO_CHECKSUM) ...) Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: [] __dump_stack lib/dump_stack.c:17 [inline] [] dump_stack+0x14d/0x20b lib/dump_stack.c:53 [] print_address_description+0x6f/0x20b mm/kasan/report.c:282 [] kasan_report_error mm/kasan/report.c:380 [inline] [] kasan_report mm/kasan/report.c:438 [inline] [] kasan_report.cold+0x8c/0x2a0 mm/kasan/report.c:422 [] __asan_report_load_n_noabort+0xf/0x20 mm/kasan/report.c:469 [] bond_alb_xmit+0x153a/0x1590 drivers/net/bonding/bond_alb.c:1452 [] __bond_start_xmit drivers/net/bonding/bond_main.c:4199 [inline] [] bond_start_xmit+0x4f4/0x1570 drivers/net/bonding/bond_main.c:4224 [] __netdev_start_xmit include/linux/netdevice.h:4525 [inline] [] netdev_start_xmit include/linux/netdevice.h:4539 [inline] [] xmit_one net/core/dev.c:3611 [inline] [] dev_hard_start_xmit+0x168/0x910 net/core/dev.c:3627 [] __dev_queue_xmit+0x1f55/0x33b0 net/core/dev.c:4238 [] dev_queue_xmit+0x18/0x20 net/core/dev.c:4278 [] packet_snd net/packet/af_packet.c:3226 [inline] [] packet_sendmsg+0x4919/0x70b0 net/packet/af_packet.c:3252 [] sock_sendmsg_nosec net/socket.c:673 [inline] [] sock_sendmsg+0x12c/0x160 net/socket.c:684 [] __sys_sendto+0x262/0x380 net/socket.c:1996 [] SYSC_sendto net/socket.c:2008 [inline] [] SyS_sendto+0x40/0x60 net/socket.c:2004 Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Eric Dumazet Reported-by: syzbot Cc: Jay Vosburgh Cc: Veaceslav Falico Cc: Andy Gospodarek Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/bonding/bond_alb.c | 44 +++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -1371,26 +1371,31 @@ int bond_alb_xmit(struct sk_buff *skb, s bool do_tx_balance = true; u32 hash_index = 0; const u8 *hash_start = NULL; - struct ipv6hdr *ip6hdr; skb_reset_mac_header(skb); eth_data = eth_hdr(skb); switch (ntohs(skb->protocol)) { case ETH_P_IP: { - const struct iphdr *iph = ip_hdr(skb); + const struct iphdr *iph; if (ether_addr_equal_64bits(eth_data->h_dest, mac_bcast) || - (iph->daddr == ip_bcast) || - (iph->protocol == IPPROTO_IGMP)) { + (!pskb_network_may_pull(skb, sizeof(*iph)))) { + do_tx_balance = false; + break; + } + iph = ip_hdr(skb); + if (iph->daddr == ip_bcast || iph->protocol == IPPROTO_IGMP) { do_tx_balance = false; break; } hash_start = (char *)&(iph->daddr); hash_size = sizeof(iph->daddr); - } break; - case ETH_P_IPV6: + } + case ETH_P_IPV6: { + const struct ipv6hdr *ip6hdr; + /* IPv6 doesn't really use broadcast mac address, but leave * that here just in case. */ @@ -1407,7 +1412,11 @@ int bond_alb_xmit(struct sk_buff *skb, s break; } - /* Additianally, DAD probes should not be tx-balanced as that + if (!pskb_network_may_pull(skb, sizeof(*ip6hdr))) { + do_tx_balance = false; + break; + } + /* Additionally, DAD probes should not be tx-balanced as that * will lead to false positives for duplicate addresses and * prevent address configuration from working. */ @@ -1417,17 +1426,26 @@ int bond_alb_xmit(struct sk_buff *skb, s break; } - hash_start = (char *)&(ipv6_hdr(skb)->daddr); - hash_size = sizeof(ipv6_hdr(skb)->daddr); + hash_start = (char *)&ip6hdr->daddr; + hash_size = sizeof(ip6hdr->daddr); break; - case ETH_P_IPX: - if (ipx_hdr(skb)->ipx_checksum != IPX_NO_CHECKSUM) { + } + case ETH_P_IPX: { + const struct ipxhdr *ipxhdr; + + if (pskb_network_may_pull(skb, sizeof(*ipxhdr))) { + do_tx_balance = false; + break; + } + ipxhdr = (struct ipxhdr *)skb_network_header(skb); + + if (ipxhdr->ipx_checksum != IPX_NO_CHECKSUM) { /* something is wrong with this packet */ do_tx_balance = false; break; } - if (ipx_hdr(skb)->ipx_type != IPX_TYPE_NCP) { + if (ipxhdr->ipx_type != IPX_TYPE_NCP) { /* The only protocol worth balancing in * this family since it has an "ARP" like * mechanism @@ -1436,9 +1454,11 @@ int bond_alb_xmit(struct sk_buff *skb, s break; } + eth_data = eth_hdr(skb); hash_start = (char *)eth_data->h_dest; hash_size = ETH_ALEN; break; + } case ETH_P_ARP: do_tx_balance = false; if (bond_info->rlb_enabled)