summaryrefslogtreecommitdiffstats
path: root/sys/netinet/in_pcb.c
diff options
context:
space:
mode:
authorru <ru@FreeBSD.org>2001-06-29 12:07:29 +0000
committerru <ru@FreeBSD.org>2001-06-29 12:07:29 +0000
commit9a1f6416f4887280498a50f0ce6ee9d2daa952cc (patch)
tree3ec78594c0cdeb3f4f4e14410f323769d6cbdc89 /sys/netinet/in_pcb.c
parentd6f3122a7619ca1641579e10c64d3b896033b836 (diff)
downloadFreeBSD-src-9a1f6416f4887280498a50f0ce6ee9d2daa952cc.zip
FreeBSD-src-9a1f6416f4887280498a50f0ce6ee9d2daa952cc.tar.gz
Backout CSRG revision 7.22 to this file (if in_losing notices an
RTF_DYNAMIC route, it got freed twice). I am not sure what was the actual problem in 1992, but the current behavior is memory leak if PCB holds a reference to a dynamically created/modified routing table entry. (rt_refcnt>0 and we don't call rtfree().) My test bed was: 1. Set net.inet.tcp.msl to a low value (for test purposes), e.g., 5 seconds, to speed up the transition of TCP connection to a "closed" state. 2. Add a network route which causes ICMP redirect from the gateway. 3. ping(8) host H that matches this route; this creates RTF_DYNAMIC RTF_HOST route to H. (I was forced to use ICMP to cause gateway to generate ICMP host redirect, because gateway in question is a 4.2-STABLE system vulnerable to a problem that was fixed later in ip_icmp.c,v 1.39.2.6, and TCP packets with DF bit set were triggering this bug.) 4. telnet(1) to H 5. Block access to H with ipfw(8) 6. Send something in telnet(1) session; this causes EPERM, followed by an in_losing() call in a few seconds. 7. Delete ipfw(8) rule blocking access to H, and wait for TCP connection moving to a CLOSED state; PCB is freed. 8. Delete host route to H. 9. Watch with netstat(1) that `rttrash' increased. 10. Repeat steps 3-9, and watch `rttrash' increases. PR: kern/25421 MFC after: 2 weeks
Diffstat (limited to 'sys/netinet/in_pcb.c')
-rw-r--r--sys/netinet/in_pcb.c5
1 files changed, 2 insertions, 3 deletions
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index ba5f77f..9965c6a 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -693,7 +693,6 @@ in_losing(inp)
struct rt_addrinfo info;
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;
@@ -704,12 +703,12 @@ in_losing(inp)
(void) rtrequest(RTM_DELETE, rt_key(rt),
rt->rt_gateway, rt_mask(rt), rt->rt_flags,
(struct rtentry **)0);
- else
+ inp->inp_route.ro_rt = 0;
+ rtfree(rt);
/*
* A new route can be allocated
* the next time output is attempted.
*/
- rtfree(rt);
}
}
OpenPOWER on IntegriCloud