Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp8065491ybl; Thu, 16 Jan 2020 10:02:55 -0800 (PST) X-Google-Smtp-Source: APXvYqwr6isizQf8bBQKxxR3ANJS8er2W+aAN8h27Xkl9Xoo/FNjku78hFWYrYS6QL3eUAvgtn9X X-Received: by 2002:aca:5487:: with SMTP id i129mr195004oib.167.1579197774889; Thu, 16 Jan 2020 10:02:54 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1579197774; cv=none; d=google.com; s=arc-20160816; b=yywQVW/eQxCIHvCrJHIqZLYpKgwicmsw1mLPvnDmHA7f8dCp1ANB8npZzmzSq0BDSD lCsHgVzl1bBWw1YJ6DMxgyTv6X6Kmznzx2kVHIdgpkWd0VIEwgLZ/bMOqqFw/rAfJwjo sZuJHOBCnq0+7LFN99ZvMRuTL7eFr925VmqaRG8I22y7etXCL/DOovsLiO/w8bDBsgqF tZh97hPhZjBqLHEZdgR3dbkOQW+MTRPQ03AfqRqv5aTXb1GILEri99LnZzyFQ9XjGbax ljybSePVRyOVOZnV4TbkYAINnQGf75/Trsahdoi8TWPEihDN424SOQHkSPVbq8QJKi/c +yTw== 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 :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=ml3/cPqVHyfbArLRpdIAqohQHgkdArgeYkrBRZp1nVs=; b=JB6tbhBaBs0qWuA9fiIgRw+a62jRfKVmjc58kz/V7fEB+JEWfhAvMd1Fuc2ujn9oRz mMqoq79WvjttHxFv3t32kqVdTc3iBlD4XsyaAHJ6c8ut1D0Mp3hzjUpiLVoxeoDjN5rT K8MVgqRRXVrqCqc0L1kBizH6xytVLqM2k0OtGijJW28cWaQfFH6gjAsGNhyXRDEX93sb LbcW4In9psomlvSAJ4zTnA6gS9rmpBhZPYgjBpxpYW7wybWiwmFceB6yCIQx1epaAqxe kH46daJrWWF9WXYbA8wEeFFoce7WLu83UAQB1TRzAX0CF0cr7F5cZfkeBhYH8AyHubYd 1fVA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=iWWaT9Lr; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id c79si12549426oig.208.2020.01.16.10.02.42; Thu, 16 Jan 2020 10:02:54 -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=iWWaT9Lr; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2405743AbgAPRlh (ORCPT + 99 others); Thu, 16 Jan 2020 12:41:37 -0500 Received: from mail.kernel.org ([198.145.29.99]:58132 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2393681AbgAPRkr (ORCPT ); Thu, 16 Jan 2020 12:40:47 -0500 Received: from sasha-vm.mshome.net (c-73-47-72-35.hsd1.nh.comcast.net [73.47.72.35]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 5D57E2467C; Thu, 16 Jan 2020 17:40:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1579196446; bh=Ut3tPM1J6O1dUxnSqz1RUUXoYV8LfA+dmqmHxVXwJG8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iWWaT9LrqIWUSfd+qO2vbU530j+aIvxaRM4scxRVBQsA7eAvBwYsGw148OxBXkBPY aTD2b/OP2SswDt5daQ1ja0f5mQzHiJ7ylSXnVyHOUnaxzRFmT67PnIVjv0+gM4PgzL HabDK/kHwlTSo5Zc+Na1lB4qhSvY5SNNDP4UnSOc= From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: David Ahern , Rajendra Dendukuri , Eric Dumazet , "David S . Miller" , Sasha Levin , netdev@vger.kernel.org Subject: [PATCH AUTOSEL 4.9 208/251] ipv6: Handle race in addrconf_dad_work Date: Thu, 16 Jan 2020 12:35:57 -0500 Message-Id: <20200116173641.22137-168-sashal@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200116173641.22137-1-sashal@kernel.org> References: <20200116173641.22137-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: David Ahern [ Upstream commit a3ce2a21bb8969ae27917281244fa91bf5f286d7 ] Rajendra reported a kernel panic when a link was taken down: [ 6870.263084] BUG: unable to handle kernel NULL pointer dereference at 00000000000000a8 [ 6870.271856] IP: [] __ipv6_ifa_notify+0x154/0x290 [ 6870.570501] Call Trace: [ 6870.573238] [] ? ipv6_ifa_notify+0x26/0x40 [ 6870.579665] [] ? addrconf_dad_completed+0x4c/0x2c0 [ 6870.586869] [] ? ipv6_dev_mc_inc+0x196/0x260 [ 6870.593491] [] ? addrconf_dad_work+0x10a/0x430 [ 6870.600305] [] ? __switch_to_asm+0x34/0x70 [ 6870.606732] [] ? process_one_work+0x18a/0x430 [ 6870.613449] [] ? worker_thread+0x4d/0x490 [ 6870.619778] [] ? process_one_work+0x430/0x430 [ 6870.626495] [] ? kthread+0xd9/0xf0 [ 6870.632145] [] ? __switch_to_asm+0x34/0x70 [ 6870.638573] [] ? kthread_park+0x60/0x60 [ 6870.644707] [] ? ret_from_fork+0x57/0x70 [ 6870.650936] Code: 31 c0 31 d2 41 b9 20 00 08 02 b9 09 00 00 0 addrconf_dad_work is kicked to be scheduled when a device is brought up. There is a race between addrcond_dad_work getting scheduled and taking the rtnl lock and a process taking the link down (under rtnl). The latter removes the host route from the inet6_addr as part of addrconf_ifdown which is run for NETDEV_DOWN. The former attempts to use the host route in ipv6_ifa_notify. If the down event removes the host route due to the race to the rtnl, then the BUG listed above occurs. This scenario does not occur when the ipv6 address is not kept (net.ipv6.conf.all.keep_addr_on_down = 0) as addrconf_ifdown sets the state of the ifp to DEAD. Handle when the addresses are kept by checking IF_READY which is reset by addrconf_ifdown. The 'dead' flag for an inet6_addr is set only under rtnl, in addrconf_ifdown and it means the device is getting removed (or IPv6 is disabled). The interesting cases for changing the idev flag are addrconf_notify (NETDEV_UP and NETDEV_CHANGE) and addrconf_ifdown (reset the flag). The former does not have the idev lock - only rtnl; the latter has both. Based on that the existing dead + IF_READY check can be moved to right after the rtnl_lock in addrconf_dad_work. Fixes: f1705ec197e7 ("net: ipv6: Make address flushing on ifdown optional") Reported-by: Rajendra Dendukuri Signed-off-by: David Ahern Reviewed-by: Eric Dumazet Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/ipv6/addrconf.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 6b1310d5e808..61fd8ff922d9 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -3859,6 +3859,12 @@ static void addrconf_dad_work(struct work_struct *w) rtnl_lock(); + /* check if device was taken down before this delayed work + * function could be canceled + */ + if (idev->dead || !(idev->if_flags & IF_READY)) + goto out; + spin_lock_bh(&ifp->lock); if (ifp->state == INET6_IFADDR_STATE_PREDAD) { action = DAD_BEGIN; @@ -3902,11 +3908,6 @@ static void addrconf_dad_work(struct work_struct *w) goto out; write_lock_bh(&idev->lock); - if (idev->dead || !(idev->if_flags & IF_READY)) { - write_unlock_bh(&idev->lock); - goto out; - } - spin_lock(&ifp->lock); if (ifp->state == INET6_IFADDR_STATE_DEAD) { spin_unlock(&ifp->lock); -- 2.20.1