Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 5 Jun 2002 20:02:22 +0300
From:      Ruslan Ermilov <ru@FreeBSD.org>
To:        Garrett Wollman <wollman@FreeBSD.org>, Qing Li <Qing.Li@windriver.com>
Cc:        net@FreeBSD.org, bug-followup@FreeBSD.org
Subject:   Re: kern/37606: genmask, rt_fixchange causes kernel panic
Message-ID:  <20020605170222.GA90718@sunbay.com>
In-Reply-To: <DMEGKJAJNLKBGDDBEAIPAEFEEOAA.Qing.Li@windriver.com>
References:  <DMEGKJAJNLKBGDDBEAIPAEFEEOAA.Qing.Li@windriver.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, Apr 30, 2002 at 11:13:40AM -0700, Qing Li wrote:
> 
> Creating a route entry with -cloning flag and the -genmask
> option causes a kernel panic on 4.5-STABLE.
> 
> The cloned entry created is a network route. The problem
> appears to be in route.c, in "rtrequest1" function, where
> 
>     if (!(rt->rt_flags & RTF_HOST) && (rt_mask(rt) !=0)
>       <snip>
>                rnh->rnh_walktree_from(..,rt_fixchange,.)
> 
> This newly created entry is immediately removed inside
> rt_fixchange. This invalid "rt" pointer is returned back
> to the caller.
> 
> This problem did not show up in the previous version of
> the code apparently due to the missing flag check on
> RTF_CLONING in the code above,
> 
>    if (cmd == RTM_RESOLVE)
>       <snip>
>       if ((*ret_nrt)->rt_flags & RTF_PRCLONING) (old version)
> 
>    new version
>       if ((*ret_nrt)->rt_flags & (RTF_CLONING & RTF_PRCLONING)
> 
>    The rt_parent is not assigned so rt_fixchange returned
>    immediately in the previous version.
> 
>    I am also not sure why rt_fixchange is needed if
>    cmd is RTM_RESOLVE.
> 
I am not sure as well, and hereby asking the original author.
Garrett, what was the intent of adding this code to rtrequest1()
in rev. 1.22:

   /*
    * We repeat the same procedure from rt_setgate() here because
    * it doesn't fire when we call it there because the node
    * hasn't been added to the tree yet.
    */
   if (!(rt->rt_flags & RTF_HOST)) {
           struct rtfc_arg arg;
           arg.rnh = rnh;
           arg.rt0 = rt;
           rnh->rnh_walktree_from(rnh, rt_key(rt), rt_mask(rt),
                                  rt_fixchange, &arg);
   }

We are obviously either adding or cloning heer, why do we need to
call rt_fixchange() at all?  Moreover, the node is already in the
tree.

Do we probably need to do this in the RTM_ADD case only, if yes,
why?

> >How-To-Repeat:
> 
>   route add -net 10.2.10.5 -netmask 255.255.0.0 -cloning
>   -genmask 255.255.255.0 64.81.55.1
> 
>   ping 10.2.10.6
> 
> >Fix:
> 
> *** route.c.org	Tue Apr 30 10:19:47 2002
> --- route.c	Tue Apr 30 10:20:49 2002
> ***************
> *** 846,851 ****
> --- 846,854 ----
>   		printf("rt_fixchange: rt %p, rt0 %p\n", rt, rt0);
>   #endif
> 
> +         if (rt == rt0)
> +           return 0;
> +
>   	if (!rt->rt_parent || (rt->rt_flags & RTF_PINNED)) {
>   #ifdef DEBUG
>   		if(rtfcdebug) printf("no parent or pinned\n");

-- 
Ruslan Ermilov		Sysadmin and DBA,
ru@sunbay.com		Sunbay Software AG,
ru@FreeBSD.org		FreeBSD committer,
+380.652.512.251	Simferopol, Ukraine

http://www.FreeBSD.org	The Power To Serve
http://www.oracle.com	Enabling The Information Age

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020605170222.GA90718>