Received: by 2002:a05:6a10:9848:0:0:0:0 with SMTP id x8csp3427227pxf; Mon, 29 Mar 2021 01:47:29 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw0QyGQySI0ZV7b7Y+eQXFvuiXOrOn8992esEMCpS0sWyC2DYXjBNz0L8cWI1m4lYMBqVy7 X-Received: by 2002:a05:6402:1051:: with SMTP id e17mr27497418edu.42.1617007649030; Mon, 29 Mar 2021 01:47:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1617007649; cv=none; d=google.com; s=arc-20160816; b=kPHkZ9TVW9qewR8pADTbNhPZsSG0ZbnuN9hhTe5PwN/JBhA5wGFjSf47Chv6GaFhCb /KNdyKgU/guGqANfBun83I8pfRbnkOeDAPz6mrtvsH1v9BdzDt+JGHdkn28l3DPFkrRW MyD/D/NniQYz6QU7bjPj3DuGLQganiQ9hdd1OFpWDkcatoK5TersmsZSmWomQJWK+gbm Zla/LBbUe+CIEgn/R5dWNN3Jk6S/y2uVc53pZuZRoXGfyPara0SSnmNKgY9y3iZoLTZB ID44iS0xfz03K01QvAgZWmu5n9GZAizkkJ4IBKNJwC8XGoX+t+Ur44AtnzHapLV2JZr9 7jlg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=mQu76wsn1Pt8XjOmANpRwBN4dYnP63IwsI/tgm9K0bc=; b=dWhMvQBVRzXw743O37x744LqePJUjqFDWW02TtmloQSJiSIVRkGhtu8JpEt2aOg03n 6VxbqOaEwfk/AXfhrqaqMBrZoPZtEKg2628huu5RPfqQpu6F5mWhXcZj5OakFOkhXRwN +WfyT1utEyaXQPH0HeMmk3Ey3LY5JXNaDe3IW1SYAypC7VnhfVy5H/T7JvPNxi5421a7 O+N5V4hIfst5FaBurS6qjtJTOv01owGBm9CliUEYTeDsr0/G590qQkXVKKqn2uKWbRpe gj+Kjd/Exn7NGswtDee5az2flid8RpjtMndO0w4hNa0694lqGsBn0tAsTd2tzleRtJbg qwuw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=ukU9jtkF; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id b9si11539807ejg.509.2021.03.29.01.47.06; Mon, 29 Mar 2021 01:47:29 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=ukU9jtkF; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234944AbhC2Ioe (ORCPT + 99 others); Mon, 29 Mar 2021 04:44:34 -0400 Received: from mail.kernel.org ([198.145.29.99]:41192 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233882AbhC2I11 (ORCPT ); Mon, 29 Mar 2021 04:27:27 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 51D2B61613; Mon, 29 Mar 2021 08:26:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1617006369; bh=hnpor7IztdL54/dqqRQe7pND8hi8h6ZeOxhkV6P1OKc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ukU9jtkFKGiSWjdocPehlQQriA3Au1W7qNzbI4K1vdltT9v9g3zJnmTsl4SaZZ7XG gmbOZc8cJspkMQRS0tC93ngnPpM0+y/HSIyl9w2u7aPPThDjZeCjP5rtqOrBe8RvOx uTuE5hyLRLFJpuIeJLbJnRr5Gq2HFj8d/3OtkyBg= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Daniel Borkmann , "David S. Miller" , Sasha Levin Subject: [PATCH 5.10 181/221] net, bpf: Fix ip6ip6 crash with collect_md populated skbs Date: Mon, 29 Mar 2021 09:58:32 +0200 Message-Id: <20210329075635.183563279@linuxfoundation.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210329075629.172032742@linuxfoundation.org> References: <20210329075629.172032742@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Daniel Borkmann [ Upstream commit a188bb5638d41aa99090ebf2f85d3505ab13fba5 ] I ran into a crash where setting up a ip6ip6 tunnel device which was /not/ set to collect_md mode was receiving collect_md populated skbs for xmit. The BPF prog was populating the skb via bpf_skb_set_tunnel_key() which is assigning special metadata dst entry and then redirecting the skb to the device, taking ip6_tnl_start_xmit() -> ipxip6_tnl_xmit() -> ip6_tnl_xmit() and in the latter it performs a neigh lookup based on skb_dst(skb) where we trigger a NULL pointer dereference on dst->ops->neigh_lookup() since the md_dst_ops do not populate neigh_lookup callback with a fake handler. Transform the md_dst_ops into generic dst_blackhole_ops that can also be reused elsewhere when needed, and use them for the metadata dst entries as callback ops. Also, remove the dst_md_discard{,_out}() ops and rely on dst_discard{,_out}() from dst_init() which free the skb the same way modulo the splat. Given we will be able to recover just fine from there, avoid any potential splats iff this gets ever triggered in future (or worse, panic on warns when set). Fixes: f38a9eb1f77b ("dst: Metadata destinations") Signed-off-by: Daniel Borkmann Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/core/dst.c | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/net/core/dst.c b/net/core/dst.c index 5f6315601776..fb3bcba87744 100644 --- a/net/core/dst.c +++ b/net/core/dst.c @@ -275,37 +275,24 @@ unsigned int dst_blackhole_mtu(const struct dst_entry *dst) } EXPORT_SYMBOL_GPL(dst_blackhole_mtu); -static struct dst_ops md_dst_ops = { - .family = AF_UNSPEC, +static struct dst_ops dst_blackhole_ops = { + .family = AF_UNSPEC, + .neigh_lookup = dst_blackhole_neigh_lookup, + .check = dst_blackhole_check, + .cow_metrics = dst_blackhole_cow_metrics, + .update_pmtu = dst_blackhole_update_pmtu, + .redirect = dst_blackhole_redirect, + .mtu = dst_blackhole_mtu, }; -static int dst_md_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb) -{ - WARN_ONCE(1, "Attempting to call output on metadata dst\n"); - kfree_skb(skb); - return 0; -} - -static int dst_md_discard(struct sk_buff *skb) -{ - WARN_ONCE(1, "Attempting to call input on metadata dst\n"); - kfree_skb(skb); - return 0; -} - static void __metadata_dst_init(struct metadata_dst *md_dst, enum metadata_type type, u8 optslen) - { struct dst_entry *dst; dst = &md_dst->dst; - dst_init(dst, &md_dst_ops, NULL, 1, DST_OBSOLETE_NONE, + dst_init(dst, &dst_blackhole_ops, NULL, 1, DST_OBSOLETE_NONE, DST_METADATA | DST_NOCOUNT); - - dst->input = dst_md_discard; - dst->output = dst_md_discard_out; - memset(dst + 1, 0, sizeof(*md_dst) + optslen - sizeof(*dst)); md_dst->type = type; } -- 2.30.1