From patchwork Sat Jun 17 17:42:31 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wei Wang X-Patchwork-Id: 777361 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 3wql4L0trSz9s2G for ; Sun, 18 Jun 2017 03:44:50 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="FmyeMnXV"; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753071AbdFQRos (ORCPT ); Sat, 17 Jun 2017 13:44:48 -0400 Received: from mail-pf0-f193.google.com ([209.85.192.193]:36198 "EHLO mail-pf0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752653AbdFQRnj (ORCPT ); Sat, 17 Jun 2017 13:43:39 -0400 Received: by mail-pf0-f193.google.com with SMTP id y7so11097011pfd.3 for ; Sat, 17 Jun 2017 10:43:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=aPRgj7q7eD61ojPFmCtVqaOPNaauOybu3e3+5cmL2O0=; b=FmyeMnXVhoCRrNAu3HKfxShzqvFgqSBcYl6WjgCAUtpjhW9YRgztiCFG12EXsqFk8H KKeAmboPRS5pLmWBSaS8nVQJQxhYe94TWhiNeapE+cUuBg9W0d1gz6r8BPtIykhFQg59 v+qCmFIAtvJ4HZt4nWC6zw84PB4A5WOJ9Iezijp+rarUl3DScNkj73AAvw0rAdanQjc4 YdgEu3HrOAfZFQB7sy5J6Q/VeEA2TDWzr9aX2+YwXITG41uhxWGJ25GLqh1d5XvEOiPs vMsFyfPhs8906bBrqIyHyivD0RkDh+GgtRvNtVzrYs66jmoOi161RRsm8UnkUX7hasF4 JTbw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=aPRgj7q7eD61ojPFmCtVqaOPNaauOybu3e3+5cmL2O0=; b=BHW6rj535HQbtvdnFcLZPBOTWGu6psgb/nKD5P26AczZ2LvZDdYd9u1OW4BXHgxjOW oeGO3bpMSKQDEE+tP0fWpHdGEJ8vzpvWdiNJ3s8JmNTI51z504nFAc+yoUs/+N3JAzP/ DvUTQ5iW1BeA0ZXD2+vcsxjIq4Ou0vLbQC5K2lBUqvb3nns8O1LThiVrVv4vY0M7cCc8 0OFckt8kQeH++vsl7T8o5YQ5zuCnCZeu0wD5l1VQYO/wIzra7Ahh8kzRmu3hyWPsmOky v0/iic6Mnpn/O4JpMTx0iCkoZZWY/9qIk4EK2CwQUJp//zrgqjW74RkbT5JzMVDiyu7L QqxQ== X-Gm-Message-State: AKS2vOzC79N137iwYUdvct1BtkdQ7lNVX/TnrOPM9wM37TadLJ+/jAB4 UHOPobOoiag9dA== X-Received: by 10.98.211.198 with SMTP id z67mr17315757pfk.231.1497721419051; Sat, 17 Jun 2017 10:43:39 -0700 (PDT) Received: from weiwan0.mtv.corp.google.com ([100.123.230.66]) by smtp.gmail.com with ESMTPSA id h7sm11352777pfc.97.2017.06.17.10.43.38 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 17 Jun 2017 10:43:38 -0700 (PDT) From: Wei Wang To: David Miller , netdev@vger.kernel.org Cc: Eric Dumazet , Martin KaFai Lau , Wei Wang Subject: [PATCH v2 net-next 08/21] ipv4: call dst_hold_safe() properly Date: Sat, 17 Jun 2017 10:42:31 -0700 Message-Id: <20170617174244.132862-9-tracywwnj@gmail.com> X-Mailer: git-send-email 2.13.1.518.g3df882009-goog In-Reply-To: <20170617174244.132862-1-tracywwnj@gmail.com> References: <20170617174244.132862-1-tracywwnj@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Wei Wang This patch checks all the calls to dst_hold()/skb_dst_force()/dst_clone()/dst_use() to see if dst_hold_safe() is needed to avoid double free issue if dst gc is removed and dst_release() directly destroys dst when dst->__refcnt drops to 0. In tx path, TCP hold sk->sk_rx_dst ref count and also hold sock_lock(). UDP and other similar protocols always hold refcount for skb->_skb_refdst. So both paths seem to be safe. In rx path, as it is lockless and skb_dst_set_noref() is likely to be used, dst_hold_safe() should always be used when trying to hold dst. In the routing code, if dst is held during an rcu protected session, it is necessary to call dst_hold_safe() as the current dst might be in its rcu grace period. Signed-off-by: Wei Wang Acked-by: Martin KaFai Lau --- include/net/route.h | 4 +++- net/ipv4/route.c | 4 +--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/net/route.h b/include/net/route.h index 08e689f23365..cb0a76d9dde1 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -190,7 +190,9 @@ static inline int ip_route_input(struct sk_buff *skb, __be32 dst, __be32 src, rcu_read_lock(); err = ip_route_input_noref(skb, dst, src, tos, devin); if (!err) - skb_dst_force(skb); + skb_dst_force_safe(skb); + if (!skb_dst(skb)) + err = -EINVAL; rcu_read_unlock(); return err; diff --git a/net/ipv4/route.c b/net/ipv4/route.c index d986d80258d2..903a12c601ac 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2234,10 +2234,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res, rth = rcu_dereference(*prth); rt_cache: - if (rt_cache_valid(rth)) { - dst_hold(&rth->dst); + if (rt_cache_valid(rth) && dst_hold_safe(&rth->dst)) return rth; - } } add: