diff options
author | ru <ru@FreeBSD.org> | 2001-06-29 12:07:29 +0000 |
---|---|---|
committer | ru <ru@FreeBSD.org> | 2001-06-29 12:07:29 +0000 |
commit | 9a1f6416f4887280498a50f0ce6ee9d2daa952cc (patch) | |
tree | 3ec78594c0cdeb3f4f4e14410f323769d6cbdc89 /sys/netinet/in_pcb.c | |
parent | d6f3122a7619ca1641579e10c64d3b896033b836 (diff) | |
download | FreeBSD-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.c | 5 |
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); } } |