From patchwork Thu Apr 20 12:55:12 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Herbert Xu X-Patchwork-Id: 752790 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3w7zQK5vG2z9s7L for ; Thu, 20 Apr 2017 22:56:25 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S945482AbdDTM4W (ORCPT ); Thu, 20 Apr 2017 08:56:22 -0400 Received: from [198.176.57.175] ([198.176.57.175]:36838 "EHLO deadmen.hmeau.com" rhost-flags-FAIL-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S941359AbdDTM4W (ORCPT ); Thu, 20 Apr 2017 08:56:22 -0400 Received: from gondobar.mordor.me.apana.org.au ([192.168.128.4] helo=gondobar) by deadmen.hmeau.com with esmtp (Exim 4.84_2 #2 (Debian)) id 1d1BcF-0007Nx-JW; Thu, 20 Apr 2017 20:55:19 +0800 Received: from herbert by gondobar with local (Exim 4.84_2) (envelope-from ) id 1d1Bc8-0002OJ-Ue; Thu, 20 Apr 2017 20:55:12 +0800 Date: Thu, 20 Apr 2017 20:55:12 +0800 From: Herbert Xu To: Joe.Ghalam@dell.com Cc: davem@davemloft.net, Clifford.Wichmann@dell.com, netdev@vger.kernel.org Subject: macvlan: Fix device ref leak when purging bc_queue Message-ID: <20170420125512.GA9113@gondor.apana.org.au> References: <1492618528011.11322@Dell.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <1492618528011.11322@Dell.com> User-Agent: Mutt/1.5.23 (2014-03-12) Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org When a parent macvlan device is destroyed we end up purging its broadcast queue without dropping the device reference count on the packet source device. This causes the source device to linger. This patch drops that reference count. Fixes: 260916dfb48c ("macvlan: Fix potential use-after free for...") Reported-by: Joe Ghalam Signed-off-by: Herbert Xu diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 9261722..b34eaaa 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -1139,6 +1139,7 @@ static int macvlan_port_create(struct net_device *dev) static void macvlan_port_destroy(struct net_device *dev) { struct macvlan_port *port = macvlan_port_get_rtnl(dev); + struct sk_buff *skb; dev->priv_flags &= ~IFF_MACVLAN_PORT; netdev_rx_handler_unregister(dev); @@ -1147,7 +1148,15 @@ static void macvlan_port_destroy(struct net_device *dev) * but we need to cancel it and purge left skbs if any. */ cancel_work_sync(&port->bc_work); - __skb_queue_purge(&port->bc_queue); + + while ((skb = __skb_dequeue(&port->bc_queue))) { + const struct macvlan_dev *src = MACVLAN_SKB_CB(skb)->src; + + if (src) + dev_put(src->dev); + + kfree_skb(skb); + } kfree(port); }