Subject: kern/15703: Case in route_output() where struct rtentry *rt dereferenced after free.
To: None <gnats-bugs@gnats.netbsd.org>
From: None <seanb@qnx.com>
List: netbsd-bugs
Date: 02/22/2002 09:09:19
>Number:         15703
>Category:       kern
>Synopsis:       Case in route_output() where struct rtentry *rt dereferenced after free.
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Feb 22 09:09:00 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:     Sean Boudreau
>Release:        1-5
>Organization:
QNX
>Environment:
NetBSD fili 1.5.1 NetBSD 1.5.1
>Description:
In route_output(), handling RTM_DELETE, there's a line:
goto report;

The first line after report points 'dst' into rt:
case RTM_GET:
report:
    dst = rt_key(rt);

A little further, 'rt' is freed but further still
'dst' is dereferenced (rt no longer valid).

>How-To-Repeat:
Don't really have a case.  Only seen this here but our
allocator is 'different'.  Might get subtle corruption
depending on threading.
>Fix:
Move final reference to 'dst' up before rtfree(rt):

Index: net/rtsock.c
===================================================================
RCS file: /cvsroot/syssrc/sys/net/rtsock.c,v
retrieving revision 1.54
diff -c -r1.54 rtsock.c
*** rtsock.c    2001/11/12 23:49:48     1.54
--- rtsock.c    2002/02/22 17:03:33
***************
*** 408,413 ****
--- 408,415 ----
                else
                        rtm->rtm_flags |= RTF_DONE;
        }
+       if (dst)
+               route_proto.sp_protocol = dst->sa_family;
        if (rt)
                rtfree(rt);
      {
***************
*** 436,443 ****
        }
        if (rp)
                rp->rcb_proto.sp_family = 0; /* Avoid us */
-       if (dst)
-               route_proto.sp_protocol = dst->sa_family;
        if (m)
                raw_input(m, &route_proto, &route_src, &route_dst);
        if (rp)
--- 438,443 ----
>Release-Note:
>Audit-Trail:
>Unformatted: