From patchwork Tue Feb 28 00:07:43 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cong Wang X-Patchwork-Id: 733239 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 3vXJp36KdZz9s9x for ; Tue, 28 Feb 2017 11:08:43 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="GF6v8Aji"; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751550AbdB1AIe (ORCPT ); Mon, 27 Feb 2017 19:08:34 -0500 Received: from mail-pf0-f196.google.com ([209.85.192.196]:34137 "EHLO mail-pf0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751030AbdB1AIb (ORCPT ); Mon, 27 Feb 2017 19:08:31 -0500 Received: by mail-pf0-f196.google.com with SMTP id o64so5219505pfb.1 for ; Mon, 27 Feb 2017 16:07:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=KaKPJ2MtQIqb6/utgIAtJ5mDrOVihY/o6WylOfE8qOI=; b=GF6v8Aji4j6iXGXCAqUDBawoDBiJcg8k75ZX6UYBAFMenWeOPX+r5sJy5Qpmmh00QE vGBGH3+TV88ciLdV2GT5SYvdeqrLEVSk8TxgEzUcUHwhRWHNKvjAVPXIuUeZL0QckXWD fBYpXdenpSQd+Gp7kubQc88B6QdR6c/IJrcCEQIRJ2PzbiAWfwIURTWKqpXEOt4MiNnQ HZsTxGjCXuXfOi7cP1qX5oM/HQCEU91ao4u7BrahL6ZaDsBJwkDX8NZc7zpEEhfj5WYd y/4l81r3BOTHUf/U8cPcd/Muol6J3Iq627TRqp2f9XsAu9p9nProo8xA7ifWRfaD8gOo vF+A== 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; bh=KaKPJ2MtQIqb6/utgIAtJ5mDrOVihY/o6WylOfE8qOI=; b=HD4TdVLhSUKS+u51oO7aZSRnnrVcBIOVb3HnCrUl+giR+sx67Gt0BgXoU8CSP/vvBx T0PXfsAjZqNcG8h8IBdP/0GYj9hf/D4IxXcF+M1N44VoKnVd2SundXBpY17/TzW3Ja7s iH60gXWTOQutss+c6KHv2dh7bRAMNyonaUChVDyFSq9MHflLHTE3OXbCG3jimZItsFbC ghJSYiVePbveDtec8OotEp2gR1YbQr0W5cavFDAuEr7LNOTusbjWdJNflhjfFm5jlsau wea3BNMjn9j9Q/eb2WNC+ts1KRdAstrbJqF+qdsPX4pu/rODVQEwW4lc2IY4gSWlDrx6 +I9w== X-Gm-Message-State: AMke39mfTNEE3s7aMqGrdRAri8UmDORTeVRve0WtAVsI73qokQCcukDCVBCP1yC9TuAmVg== X-Received: by 10.99.44.3 with SMTP id s3mr24465038pgs.148.1488240469839; Mon, 27 Feb 2017 16:07:49 -0800 (PST) Received: from tw-172-25-29-91.office.twttr.net ([8.25.197.27]) by smtp.gmail.com with ESMTPSA id h9sm31451294pfd.103.2017.02.27.16.07.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 27 Feb 2017 16:07:48 -0800 (PST) From: Cong Wang To: netdev@vger.kernel.org Cc: andreyknvl@google.com, Cong Wang , David Ahern , Eric Dumazet Subject: [Patch net v3] ipv6: check for ip6_null_entry in __ip6_del_rt_siblings() Date: Mon, 27 Feb 2017 16:07:43 -0800 Message-Id: <1488240463-12000-1-git-send-email-xiyou.wangcong@gmail.com> X-Mailer: git-send-email 2.5.5 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Andrey reported a NULL pointer deref bug in ipv6_route_ioctl() -> ip6_route_del() -> __ip6_del_rt_siblings() code path. This is because ip6_null_entry is returned in this path since ip6_null_entry is kinda default for a ipv6 route table root node. Quote from David Ahern: ip6_null_entry is the root of all ipv6 fib tables making it integrated into the table ... We should ignore any attempt of trying to delete it, like we do in __ip6_del_rt() path and several others. Reported-by: Andrey Konovalov Fixes: 0ae8133586ad ("net: ipv6: Allow shorthand delete of all nexthops in multipath route") Cc: David Ahern Cc: Eric Dumazet Signed-off-by: Cong Wang Acked-by: David Ahern --- net/ipv6/route.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index f54f426..77c7ce7 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -2169,10 +2169,13 @@ int ip6_del_rt(struct rt6_info *rt) static int __ip6_del_rt_siblings(struct rt6_info *rt, struct fib6_config *cfg) { struct nl_info *info = &cfg->fc_nlinfo; + struct net *net = info->nl_net; struct sk_buff *skb = NULL; struct fib6_table *table; - int err; + int err = -ENOENT; + if (rt == net->ipv6.ip6_null_entry) + goto out_put; table = rt->rt6i_table; write_lock_bh(&table->tb6_lock); @@ -2184,7 +2187,7 @@ static int __ip6_del_rt_siblings(struct rt6_info *rt, struct fib6_config *cfg) if (skb) { u32 seq = info->nlh ? info->nlh->nlmsg_seq : 0; - if (rt6_fill_node(info->nl_net, skb, rt, + if (rt6_fill_node(net, skb, rt, NULL, NULL, 0, RTM_DELROUTE, info->portid, seq, 0) < 0) { kfree_skb(skb); @@ -2198,17 +2201,18 @@ static int __ip6_del_rt_siblings(struct rt6_info *rt, struct fib6_config *cfg) rt6i_siblings) { err = fib6_del(sibling, info); if (err) - goto out; + goto out_unlock; } } err = fib6_del(rt, info); -out: +out_unlock: write_unlock_bh(&table->tb6_lock); +out_put: ip6_rt_put(rt); if (skb) { - rtnl_notify(skb, info->nl_net, info->portid, RTNLGRP_IPV6_ROUTE, + rtnl_notify(skb, net, info->portid, RTNLGRP_IPV6_ROUTE, info->nlh, gfp_any()); } return err;