From patchwork Fri Jan 31 20:57:53 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Dumazet X-Patchwork-Id: 315833 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 768F92C00B3 for ; Sat, 1 Feb 2014 07:58:15 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932361AbaAaU55 (ORCPT ); Fri, 31 Jan 2014 15:57:57 -0500 Received: from mail-pb0-f41.google.com ([209.85.160.41]:34133 "EHLO mail-pb0-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753411AbaAaU5z (ORCPT ); Fri, 31 Jan 2014 15:57:55 -0500 Received: by mail-pb0-f41.google.com with SMTP id up15so4890147pbc.0 for ; Fri, 31 Jan 2014 12:57:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=message-id:subject:from:to:cc:date:in-reply-to:references :content-type:content-transfer-encoding:mime-version; bh=Krlngq46UTK5tEXIJLUwjKVRpsZLIYVQ6LY+h4jRD4k=; b=rvd2v2b/aqYGFZ3E3da/iDvnho6MvljV+8FpCVAEjAqJTVRbjmkdRNhqvPlFxQ0D62 ruI6Qi1ViCN91LDLqLI3r+MeQ7MmnxHt/tDDvl+QrNwEnsq36e0SpEYPu5XvoqrH258Z UqlM7059ajXcVoFZUMjVavSkXNeUjoykWIxgOARRmsjS/jXVTywHdBYPqMj6e0oBFRjU fO0f1PFY0BpWbYnorctB9tgadnJIV6ukJTQBnoX9PPDdBHpQ0aZZ22U+qQQdcNA/B91L ADi2WsMeSGfZnm7YpbXEPQHgl24xtzRiAv4I3tqWtvJRUZDTHy0a7dP753fdL/xm/oWa CFwg== X-Received: by 10.68.129.201 with SMTP id ny9mr23149159pbb.70.1391201874907; Fri, 31 Jan 2014 12:57:54 -0800 (PST) Received: from ?IPv6:2620:0:1000:3e02:650b:1a5d:80a1:16a4? ([2620:0:1000:3e02:650b:1a5d:80a1:16a4]) by mx.google.com with ESMTPSA id gg10sm30669786pbc.46.2014.01.31.12.57.54 for (version=SSLv3 cipher=RC4-SHA bits=128/128); Fri, 31 Jan 2014 12:57:54 -0800 (PST) Message-ID: <1391201873.28432.86.camel@edumazet-glaptop2.roam.corp.google.com> Subject: Re: BUG ip_dst_cache (Not tainted): Poison overwritten From: Eric Dumazet To: Tommi Rantala Cc: netdev@vger.kernel.org, Dave Jones , trinity@vger.kernel.org, LKML Date: Fri, 31 Jan 2014 12:57:53 -0800 In-Reply-To: References: X-Mailer: Evolution 3.2.3-0ubuntu6 Mime-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org On Fri, 2014-01-31 at 22:11 +0200, Tommi Rantala wrote: > Hello, > > Hit this while fuzzing v3.13-9218-g0e47c96 with trinity in a qemu > virtual machine. > > Tommi Hi Tommi Could you please try the following fix ? I'll send an official patch in a couple of hours There are two bugs : One dst leak, and one plain bug, as rt initial NULL value might be scratched. net/ipv4/ip_tunnel.c | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) --- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index bd28f386bd02..bc6acdcb7625 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -101,27 +101,21 @@ static void tunnel_dst_reset_all(struct ip_tunnel *t) __tunnel_dst_set(per_cpu_ptr(t->dst_cache, i), NULL); } -static struct dst_entry *tunnel_dst_get(struct ip_tunnel *t) +static struct dst_entry *tunnel_dst_check(struct ip_tunnel *t, u32 cookie) { struct dst_entry *dst; rcu_read_lock(); dst = rcu_dereference(this_cpu_ptr(t->dst_cache)->dst); - if (dst) + if (dst) { + if (dst->obsolete && dst->ops->check(dst, cookie) == NULL) { + rcu_read_unlock(); + tunnel_dst_reset(t); + return NULL; + } dst_hold(dst); - rcu_read_unlock(); - return dst; -} - -static struct dst_entry *tunnel_dst_check(struct ip_tunnel *t, u32 cookie) -{ - struct dst_entry *dst = tunnel_dst_get(t); - - if (dst && dst->obsolete && dst->ops->check(dst, cookie) == NULL) { - tunnel_dst_reset(t); - return NULL; } - + rcu_read_unlock(); return dst; } @@ -584,7 +578,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi4 fl4; u8 tos, ttl; __be16 df; - struct rtable *rt = NULL; /* Route to the other host */ + struct rtable *rt; /* Route to the other host */ unsigned int max_headroom; /* The extra header space needed */ __be32 dst; int err; @@ -657,8 +651,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, init_tunnel_flow(&fl4, protocol, dst, tnl_params->saddr, tunnel->parms.o_key, RT_TOS(tos), tunnel->parms.link); - if (connected) - rt = (struct rtable *)tunnel_dst_check(tunnel, 0); + rt = (connected) ? (struct rtable *)tunnel_dst_check(tunnel, 0) : NULL; if (!rt) { rt = ip_route_output_key(tunnel->net, &fl4);