Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932119AbdGSKKD (ORCPT ); Wed, 19 Jul 2017 06:10:03 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:40810 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932103AbdGSKKA (ORCPT ); Wed, 19 Jul 2017 06:10:00 -0400 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Bert Kenward , "David S. Miller" Subject: [PATCH 4.11 30/88] sfc: dont read beyond unicast address list Date: Wed, 19 Jul 2017 12:07:52 +0200 Message-Id: <20170719100825.240740822@linuxfoundation.org> X-Mailer: git-send-email 2.13.3 In-Reply-To: <20170719100820.364094938@linuxfoundation.org> References: <20170719100820.364094938@linuxfoundation.org> User-Agent: quilt/0.65 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2250 Lines: 62 4.11-stable review patch. If anyone has any objections, please let me know. ------------------ From: Bert Kenward [ Upstream commit c70d68150f71b84cea6997a53493e17bf18a54db ] If we have more than 32 unicast MAC addresses assigned to an interface we will read beyond the end of the address table in the driver when adding filters. The next 256 entries store multicast addresses, so we will end up attempting to insert duplicate filters, which is mostly harmless. If we add more than 288 unicast addresses we will then read past the multicast address table, which is likely to be more exciting. Fixes: 12fb0da45c9a ("sfc: clean fallbacks between promisc/normal in efx_ef10_filter_sync_rx_mode") Signed-off-by: Bert Kenward Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/sfc/ef10.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) --- a/drivers/net/ethernet/sfc/ef10.c +++ b/drivers/net/ethernet/sfc/ef10.c @@ -5033,12 +5033,9 @@ static void efx_ef10_filter_uc_addr_list struct efx_ef10_filter_table *table = efx->filter_state; struct net_device *net_dev = efx->net_dev; struct netdev_hw_addr *uc; - int addr_count; unsigned int i; - addr_count = netdev_uc_count(net_dev); table->uc_promisc = !!(net_dev->flags & IFF_PROMISC); - table->dev_uc_count = 1 + addr_count; ether_addr_copy(table->dev_uc_list[0].addr, net_dev->dev_addr); i = 1; netdev_for_each_uc_addr(uc, net_dev) { @@ -5049,6 +5046,8 @@ static void efx_ef10_filter_uc_addr_list ether_addr_copy(table->dev_uc_list[i].addr, uc->addr); i++; } + + table->dev_uc_count = i; } static void efx_ef10_filter_mc_addr_list(struct efx_nic *efx) @@ -5056,11 +5055,10 @@ static void efx_ef10_filter_mc_addr_list struct efx_ef10_filter_table *table = efx->filter_state; struct net_device *net_dev = efx->net_dev; struct netdev_hw_addr *mc; - unsigned int i, addr_count; + unsigned int i; table->mc_promisc = !!(net_dev->flags & (IFF_PROMISC | IFF_ALLMULTI)); - addr_count = netdev_mc_count(net_dev); i = 0; netdev_for_each_mc_addr(mc, net_dev) { if (i >= EFX_EF10_FILTER_DEV_MC_MAX) {