Subject: Re: Syn cache corrupts kernel data!!
To: Juergen Hannken-Illjes <hannken@serv1.eis.cs.tu-bs.de>
From: Jason Thorpe <thorpej@nas.nasa.gov>
List: current-users
Date: 07/27/1997 14:12:37
On Sun, 27 Jul 1997 19:00:22 +0200 (MET DST)
hannken@serv1.eis.cs.tu-bs.de (Juergen Hannken-Illjes) wrote:
> I found a severe bug due to the new `syn_cache' functionality in
> netinet/tcp_input.c
Yow, nice hunting! That bit of code allows a TIME_WAIT socket to be
discarded if a new connection is being attempted. Apparently, this slipped
through my tests because I don't see a large number of connections in
TIME_WAIT!
Your solution is basically correct, however I have tidied it up a bit,
and added some comments about what is happening. Can you please test
this patch and let me know if it solves the problem for you?
(P.S. Sorry I didn't get to this until now; I was out sailing all day
yesterday with hpeyerl@netbsd.org and carrel@netbsd.org :-)
Jason R. Thorpe thorpej@nas.nasa.gov
NASA Ames Research Center Home: 408.866.1912
NAS: M/S 258-6 Work: 415.604.0935
Moffett Field, CA 94035 Pager: 415.428.6939
Index: tcp_input.c
===================================================================
RCS file: /mastersrc/netbsd/src/sys/netinet/tcp_input.c,v
retrieving revision 1.25
diff -c -r1.25 tcp_input.c
*** tcp_input.c 1997/07/25 21:19:39 1.25
--- tcp_input.c 1997/07/27 20:59:17
***************
*** 280,286 ****
register struct inpcb *inp;
caddr_t optp = NULL;
int optlen = 0;
! int len, tlen, off;
register struct tcpcb *tp = 0;
register int tiflags;
struct socket *so = NULL;
--- 280,286 ----
register struct inpcb *inp;
caddr_t optp = NULL;
int optlen = 0;
! int len, tlen, off, hdroptlen;
register struct tcpcb *tp = 0;
register int tiflags;
struct socket *so = NULL;
***************
*** 598,605 ****
/*
* Drop TCP, IP headers and TCP options.
*/
! m->m_data += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
! m->m_len -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
/*
* Calculate amount of space in receive window,
--- 598,606 ----
/*
* Drop TCP, IP headers and TCP options.
*/
! hdroptlen = sizeof(struct tcpiphdr) + off - sizeof(struct tcphdr);
! m->m_data += hdroptlen;
! m->m_len -= hdroptlen;
/*
* Calculate amount of space in receive window,
***************
*** 812,817 ****
--- 813,826 ----
SEQ_GT(ti->ti_seq, tp->rcv_nxt)) {
iss = tp->rcv_nxt + TCP_ISSINCR;
tp = tcp_close(tp);
+ /*
+ * We have already advanced the mbuf
+ * pointers past the IP+TCP headers and
+ * options. Restore those pointers before
+ * attempting to use the TCP header again.
+ */
+ m->m_data -= hdroptlen;
+ m->m_len += hdroptlen;
goto findpcb;
}
/*