Received: by 2002:a17:90a:9103:0:0:0:0 with SMTP id k3csp11794769pjo; Thu, 2 Jan 2020 14:24:17 -0800 (PST) X-Google-Smtp-Source: APXvYqwB4nA2WStpmFHf2fNKvlzNYFyysoHD0jg3kuObMF+N3v7k8a0UkGjRGJVR/IDHcObEJrlr X-Received: by 2002:a05:6830:1292:: with SMTP id z18mr59477229otp.148.1578003856903; Thu, 02 Jan 2020 14:24:16 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1578003856; cv=none; d=google.com; s=arc-20160816; b=MR49Di+HuW7OxyAWWQlFbq/M70FFBHKXv/lYgU5i5RQKrxmMH03F9crZ/7RBElvXMt yCe7WtcS8xm44kK0OzZ4mJVEm9utTMK7oQhgc8gfxKz/93mU2hVXwyornGIX9JjLW+Yc u+Gx6nxR88t+q6Y285WbVSMpL90UxCrphnZmKsp3CRZtHk7GbnDFUw91HvUI9Z37gZJb xHPJ9tz3TUgsq8F/687y/X7tsTMTTJWKNDmJaQRd+AHY+9LKr7kUgylEfA/CM5GqbeWN NvxAUdoYpQDd1DaMCkO6qPM5QZ+HdkHKmRb6AHkONY9Zwh4uBStCgSS+r9Fuj4MEDotG b/Og== 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=BVk3XM4F833IHfnTvwyT3MVBP1ZlQyX+jpiolXrVRZo=; b=TLSvtq6rabvCrJ/PQwBR+I4LpqWy1cMUW8uSS+u/6RRwMYxPBPsIh1zsE1hSZlAAvD XzcUF/nsF58fNcCmr/q/feKNcW1mpDCyhEfk9bt9KxlB6KTLXmp3Zno+LEdsR/hBLW1Y XTO1lFIrlxLhVQdI1tN1bOxgWuAy2KOR2X9ThOxoABVCe2R8im33qWTFwsgqw75HDOtk AYx4SNjSOUfY9jB/Bq6GXryspelaZ+ZH7vQRj3gyk122bd1uyJj3EDCVkmcIcTgTbrUM It+HEIbUNeohaG89N1d9XuA7ImPF45H979faHoC5kTKQKdcw+P5q/bHtQiKCSBXCB/+P UyBQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=e6LPgiRF; 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 e63si28648969ote.166.2020.01.02.14.24.05; Thu, 02 Jan 2020 14:24:16 -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=e6LPgiRF; 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 S1729226AbgABWX2 (ORCPT + 99 others); Thu, 2 Jan 2020 17:23:28 -0500 Received: from mail.kernel.org ([198.145.29.99]:45526 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728144AbgABWX0 (ORCPT ); Thu, 2 Jan 2020 17:23:26 -0500 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (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 8C87A20866; Thu, 2 Jan 2020 22:23:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1578003805; bh=IBcn7uMd9ZRLxR7Vh+lZjNGm/8Vp8UOrr27oApXzvhQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=e6LPgiRFewSwPzFlLaokNBG4bUC6POdRLTzIZWQXFWP8AJ/eCSpyhZx6w1F+0KOKG 7wpses/MewHrPsbGwBwSPT+J4WquqGx4otybY3NsAIgs1xER31/Sk2zFC9elaPbBu/ VjChXYHWIbT7d6SG3W3gP5mqqKMwqaOniqx67ni4= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Taehee Yoo , Jakub Kicinski Subject: [PATCH 4.19 110/114] gtp: fix an use-after-free in ipv4_pdp_find() Date: Thu, 2 Jan 2020 23:08:02 +0100 Message-Id: <20200102220040.214375202@linuxfoundation.org> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200102220029.183913184@linuxfoundation.org> References: <20200102220029.183913184@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: Taehee Yoo [ Upstream commit 94dc550a5062030569d4aa76e10e50c8fc001930 ] ipv4_pdp_find() is called in TX packet path of GTP. ipv4_pdp_find() internally uses gtp->tid_hash to lookup pdp context. In the current code, gtp->tid_hash and gtp->addr_hash are freed by ->dellink(), which is gtp_dellink(). But gtp_dellink() would be called while packets are processing. So, gtp_dellink() should not free gtp->tid_hash and gtp->addr_hash. Instead, dev->priv_destructor() would be used because this callback is called after all packet processing safely. Test commands: ip link add veth1 type veth peer name veth2 ip a a 172.0.0.1/24 dev veth1 ip link set veth1 up ip a a 172.99.0.1/32 dev lo gtp-link add gtp1 & gtp-tunnel add gtp1 v1 200 100 172.99.0.2 172.0.0.2 ip r a 172.99.0.2/32 dev gtp1 ip link set gtp1 mtu 1500 ip netns add ns2 ip link set veth2 netns ns2 ip netns exec ns2 ip a a 172.0.0.2/24 dev veth2 ip netns exec ns2 ip link set veth2 up ip netns exec ns2 ip a a 172.99.0.2/32 dev lo ip netns exec ns2 ip link set lo up ip netns exec ns2 gtp-link add gtp2 & ip netns exec ns2 gtp-tunnel add gtp2 v1 100 200 172.99.0.1 172.0.0.1 ip netns exec ns2 ip r a 172.99.0.1/32 dev gtp2 ip netns exec ns2 ip link set gtp2 mtu 1500 hping3 172.99.0.2 -2 --flood & ip link del gtp1 Splat looks like: [ 72.568081][ T1195] BUG: KASAN: use-after-free in ipv4_pdp_find.isra.12+0x130/0x170 [gtp] [ 72.568916][ T1195] Read of size 8 at addr ffff8880b9a35d28 by task hping3/1195 [ 72.569631][ T1195] [ 72.569861][ T1195] CPU: 2 PID: 1195 Comm: hping3 Not tainted 5.5.0-rc1 #199 [ 72.570547][ T1195] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 [ 72.571438][ T1195] Call Trace: [ 72.571764][ T1195] dump_stack+0x96/0xdb [ 72.572171][ T1195] ? ipv4_pdp_find.isra.12+0x130/0x170 [gtp] [ 72.572761][ T1195] print_address_description.constprop.5+0x1be/0x360 [ 72.573400][ T1195] ? ipv4_pdp_find.isra.12+0x130/0x170 [gtp] [ 72.573971][ T1195] ? ipv4_pdp_find.isra.12+0x130/0x170 [gtp] [ 72.574544][ T1195] __kasan_report+0x12a/0x16f [ 72.575014][ T1195] ? ipv4_pdp_find.isra.12+0x130/0x170 [gtp] [ 72.575593][ T1195] kasan_report+0xe/0x20 [ 72.576004][ T1195] ipv4_pdp_find.isra.12+0x130/0x170 [gtp] [ 72.576577][ T1195] gtp_build_skb_ip4+0x199/0x1420 [gtp] [ ... ] [ 72.647671][ T1195] BUG: unable to handle page fault for address: ffff8880b9a35d28 [ 72.648512][ T1195] #PF: supervisor read access in kernel mode [ 72.649158][ T1195] #PF: error_code(0x0000) - not-present page [ 72.649849][ T1195] PGD a6c01067 P4D a6c01067 PUD 11fb07067 PMD 11f939067 PTE 800fffff465ca060 [ 72.652958][ T1195] Oops: 0000 [#1] SMP DEBUG_PAGEALLOC KASAN PTI [ 72.653834][ T1195] CPU: 2 PID: 1195 Comm: hping3 Tainted: G B 5.5.0-rc1 #199 [ 72.668062][ T1195] RIP: 0010:ipv4_pdp_find.isra.12+0x86/0x170 [gtp] [ ... ] [ 72.679168][ T1195] Call Trace: [ 72.679603][ T1195] gtp_build_skb_ip4+0x199/0x1420 [gtp] [ 72.681915][ T1195] ? ipv4_pdp_find.isra.12+0x170/0x170 [gtp] [ 72.682513][ T1195] ? lock_acquire+0x164/0x3b0 [ 72.682966][ T1195] ? gtp_dev_xmit+0x35e/0x890 [gtp] [ 72.683481][ T1195] gtp_dev_xmit+0x3c2/0x890 [gtp] [ ... ] Fixes: 459aa660eb1d ("gtp: add initial driver for datapath of GPRS Tunneling Protocol (GTP-U)") Signed-off-by: Taehee Yoo Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- drivers/net/gtp.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) --- a/drivers/net/gtp.c +++ b/drivers/net/gtp.c @@ -644,9 +644,16 @@ static void gtp_link_setup(struct net_de } static int gtp_hashtable_new(struct gtp_dev *gtp, int hsize); -static void gtp_hashtable_free(struct gtp_dev *gtp); static int gtp_encap_enable(struct gtp_dev *gtp, struct nlattr *data[]); +static void gtp_destructor(struct net_device *dev) +{ + struct gtp_dev *gtp = netdev_priv(dev); + + kfree(gtp->addr_hash); + kfree(gtp->tid_hash); +} + static int gtp_newlink(struct net *src_net, struct net_device *dev, struct nlattr *tb[], struct nlattr *data[], struct netlink_ext_ack *extack) @@ -681,13 +688,15 @@ static int gtp_newlink(struct net *src_n gn = net_generic(dev_net(dev), gtp_net_id); list_add_rcu(>p->list, &gn->gtp_dev_list); + dev->priv_destructor = gtp_destructor; netdev_dbg(dev, "registered new GTP interface\n"); return 0; out_hashtable: - gtp_hashtable_free(gtp); + kfree(gtp->addr_hash); + kfree(gtp->tid_hash); out_encap: gtp_encap_disable(gtp); return err; @@ -696,9 +705,14 @@ out_encap: static void gtp_dellink(struct net_device *dev, struct list_head *head) { struct gtp_dev *gtp = netdev_priv(dev); + struct pdp_ctx *pctx; + int i; + + for (i = 0; i < gtp->hash_size; i++) + hlist_for_each_entry_rcu(pctx, >p->tid_hash[i], hlist_tid) + pdp_context_delete(pctx); gtp_encap_disable(gtp); - gtp_hashtable_free(gtp); list_del_rcu(>p->list); unregister_netdevice_queue(dev, head); } @@ -776,20 +790,6 @@ err1: return -ENOMEM; } -static void gtp_hashtable_free(struct gtp_dev *gtp) -{ - struct pdp_ctx *pctx; - int i; - - for (i = 0; i < gtp->hash_size; i++) - hlist_for_each_entry_rcu(pctx, >p->tid_hash[i], hlist_tid) - pdp_context_delete(pctx); - - synchronize_rcu(); - kfree(gtp->addr_hash); - kfree(gtp->tid_hash); -} - static struct sock *gtp_encap_enable_socket(int fd, int type, struct gtp_dev *gtp) {