[prev in list] [next in list] [prev in thread] [next in thread] 

List:       freebsd-bugs
Subject:    kern/25421: route structures are being leaked.
From:       msmith () netapp ! com
Date:       2001-02-27 20:26:50
[Download RAW message or body]


> Number:         25421
> Category:       kern
> Synopsis:       route structures are being leaked.
> Confidential:   no
> Severity:       serious
> Priority:       medium
> Responsible:    freebsd-bugs
> State:          open
> Quarter:        
> Keywords:       
> Date-Required:
> Class:          sw-bug
> Submitter-Id:   current-users
> Arrival-Date:   Tue Feb 27 12:30:01 PST 2001
> Closed-Date:
> Last-Modified:
> Originator:     Mark Smith
> Release:        4.2
> Organization:
Network Appliance
> Environment:
> Description:
This was found in a kernel with networking code derived from FreeBSD
not from FreeBSD itself.  However, from a code review of the FreeBSD-4.2 source, it \
appears FreeBSD has the same problem.

In in_losing() we have this:

        if ((rt = inp->inp_route.ro_rt)) {
                inp->inp_route.ro_rt = 0;
                bzero((caddr_t)&info, sizeof(info));
                info.rti_info[RTAX_DST] =
                        (struct sockaddr *)&inp->inp_route.ro_dst;
                info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
                info.rti_info[RTAX_NETMASK] = rt_mask(rt);
                rt_missmsg(RTM_LOSING, &info, rt->rt_flags, 0);
                if (rt->rt_flags & RTF_DYNAMIC)
                        (void) rtrequest(RTM_DELETE, rt_key(rt),
                                rt->rt_gateway, rt_mask(rt), rt->rt_flags,
                                (struct rtentry **)0);
                else
                /*
                 * A new route can be allocated
                 * the next time output is attempted.
                 */
                        rtfree(rt);
        }

Since rt was the cached route of the pcb, the ref count is >= 1 since
the pcb will have a ref count on it.  In the case of a dynamic route,
in_losing calls rtrequest to delete the route but not rtfree.
rtrequest() only deletes the route from the routing table.  It does
not free the route structure unless rt_refcnt is 0.  We know
it won't be zero because the pcb has a ref count.  As a result it
appears that we leak a route structure since it will never be freed.



> How-To-Repeat:
The problem is easiest to recreate on a lossy network where we
receive a lot of route redirects.
> Fix:
In in_losing() the fix appears to be to simply delete the else just
before the rtfree() call so that rtfree is always called.
> Release-Note:
> Audit-Trail:
> Unformatted:

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


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic