Hello all,

#I'm not sure where to discuss this issue.  So please forward this
#mail or reply with CC for the appropriate person or ML.

> FreeBSD-SA-02:21.tcpip                                      Security Advisory
> Topic:          routing table memory leak
> Category:       core
> Module:         net
> Announced:      2002-04-17
> Credits:        Jayanth Vijayaraghavan <[EMAIL PROTECTED]>
>                 Ruslan Ermilov <[EMAIL PROTECTED]>
I have one proposal for this fix.

In this patch, ip_output() is assumed to receive non-NULL rtentry
argument from its caller.

Two files are patched to support this, so there's no problem right
now.  However if some new module calls ip_output() carelessly with
NULL rtentry argument, kernel would crash.
I don't think it is a good change.

KAME rewrote the attached patch to improve this point:
        - This memory leak is fixed, of course:-)
          (at least I confirmed on 5-current).
        - Non-NULL rtentry for ip_output() is still accepted.  So only a
          patch in ip_output.c is enough.

Could you please correct me if I'm wrong, or consider adopting this
patch?
(it's a patch for 5-current, but it's not so difficult to modify it for
 4-stable and 4.5-release branch)

Thanks,
----
SUZUKI, Shinsuke / KAME Project

Index: ip_output.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/ip_output.c,v
retrieving revision 1.154
diff -u -u -r1.154 ip_output.c
--- ip_output.c 1 Apr 2002 21:31:06 -0000       1.154
+++ ip_output.c 18 Apr 2002 07:11:01 -0000
@@ -123,12 +123,12 @@
        struct mbuf *m = m0;
        int hlen = sizeof (struct ip);
        int len, off, error = 0;
+       struct route iproute;
        struct sockaddr_in *dst;
        struct in_ifaddr *ia;
        int isbroadcast, sw_csum;
        struct in_addr pkt_dst;
 #ifdef IPSEC
-       struct route iproute;
        struct socket *so = NULL;
        struct secpolicy *sp = NULL;
 #endif
@@ -189,9 +189,6 @@
 #ifdef DIAGNOSTIC
        if ((m->m_flags & M_PKTHDR) == 0)
                panic("ip_output no HDR");
-       if (!ro)
-               panic("ip_output no route, proto = %d",
-                     mtod(m, struct ip *)->ip_p);
 #endif
        if (opt) {
                m = ip_insertoptions(m, opt, &len);
@@ -217,6 +214,11 @@
                hlen = IP_VHL_HL(ip->ip_vhl) << 2;
        }
 
+       /* Route packet. */
+       if (ro == NULL) {
+               ro = &iproute;
+               bzero(ro, sizeof(*ro));
+       }
        dst = (struct sockaddr_in *)&ro->ro_dst;
        /*
         * If there is a cached route,
@@ -1004,11 +1006,11 @@
                ipstat.ips_fragmented++;
     }
 done:
-#ifdef IPSEC
        if (ro == &iproute && ro->ro_rt) {
                RTFREE(ro->ro_rt);
                ro->ro_rt = NULL;
        }
+#ifdef IPSEC
        if (sp != NULL) {
                KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
                        printf("DP ip_output call free SP:%p\n", sp));

Reply via email to