Subject: kern/1261: TCP accepts 'bad' SYN packets
To: None <gnats-bugs@gnats.netbsd.org, darrenr@candella.arbld.unimelb.EDU.AU>
From: Darren Reed <darrenr@vitruvius.arbld.unimelb.edu.au>
List: netbsd-bugs
Date: 07/23/1995 17:15:00
>Number:         1261
>Category:       kern
>Synopsis:       TCP accepts 'bad' SYN packets
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Jul 23 03:35:01 1995
>Last-Modified:
>Originator:     Darren Reed
>Organization:
University of Melbourne
>Release:        1.0A
>Environment:
Sun IPC, NetBSD-current-sparc
System: NetBSD candella.arbld.unimelb.edu.au 1.0A NetBSD 1.0A (1.0A) #4: Mon Feb 20 18:33:28 EST 1995 root@:/usr/src/sys/arch/sparc/compile/1.0A sparc


>Description:
If a TCP packet with SYN and either (or all of) URG or PUSH or FIN is
received, it is treated as a plain SYN packet.

>How-To-Repeat:
>Fix:
Change TCP to only accept a pure SYN when moving from LISTEN to SYN-RECEIVED.
*** tcp_input.c.org	Sun Jul 23 16:12:04 1995
--- tcp_input.c	Sun Jul 23 17:13:11 1995
***************
*** 267,272 ****
--- 267,278 ----
  	}
  #endif /* TUBA_INCLUDE */
  
+ 	tiflags = ti->ti_flags;
+ 	/*
+ 	 * Check that a packet with a SYN in it doesn't have a FIN/URG/PUSH.
+ 	 */
+ 	if ((tiflags & TH_SYN) && (tiflags & (TH_URG|TH_PUSH|TH_FIN)))
+ 		goto drop;
  	/*
  	 * Check that TCP offset makes sense,
  	 * pull out TCP options and adjust length.		XXX
***************
*** 299,312 ****
  		     (optlen > TCPOLEN_TSTAMP_APPA &&
  			optp[TCPOLEN_TSTAMP_APPA] == TCPOPT_EOL)) &&
  		     *(u_int32_t *)optp == htonl(TCPOPT_TSTAMP_HDR) &&
! 		     (ti->ti_flags & TH_SYN) == 0) {
  			ts_present = 1;
  			ts_val = ntohl(*(u_int32_t *)(optp + 4));
  			ts_ecr = ntohl(*(u_int32_t *)(optp + 8));
  			optp = NULL;	/* we've parsed the options */
  		}
  	}
- 	tiflags = ti->ti_flags;
  
  	/*
  	 * Convert TCP protocol specific fields to host format.
--- 305,317 ----
  		     (optlen > TCPOLEN_TSTAMP_APPA &&
  			optp[TCPOLEN_TSTAMP_APPA] == TCPOPT_EOL)) &&
  		     *(u_int32_t *)optp == htonl(TCPOPT_TSTAMP_HDR) &&
! 		     (tiflags & TH_SYN) == 0) {
  			ts_present = 1;
  			ts_val = ntohl(*(u_int32_t *)(optp + 4));
  			ts_ecr = ntohl(*(u_int32_t *)(optp + 8));
  			optp = NULL;	/* we've parsed the options */
  		}
  	}
  
  	/*
  	 * Convert TCP protocol specific fields to host format.
***************
*** 529,537 ****
  	switch (tp->t_state) {
  
  	/*
! 	 * If the state is LISTEN then ignore segment if it contains an RST.
  	 * If the segment contains an ACK then it is bad and send a RST.
! 	 * If it does not contain a SYN then it is not interesting; drop it.
  	 * Don't bother responding if the destination was a broadcast.
  	 * Otherwise initialize tp->rcv_nxt, and tp->irs, select an initial
  	 * tp->iss, and send a segment:
--- 534,544 ----
  	switch (tp->t_state) {
  
  	/*
! 	 * If the state is LISTEN then:
! 	 * If the segment contains an RST, ignore it.
  	 * If the segment contains an ACK then it is bad and send a RST.
! 	 * If it does not contain just a SYN then it is not interesting;
! 	 * drop it.
  	 * Don't bother responding if the destination was a broadcast.
  	 * Otherwise initialize tp->rcv_nxt, and tp->irs, select an initial
  	 * tp->iss, and send a segment:
***************
*** 549,555 ****
  			goto drop;
  		if (tiflags & TH_ACK)
  			goto dropwithreset;
! 		if ((tiflags & TH_SYN) == 0)
  			goto drop;
  		/*
  		 * RFC1122 4.2.3.10, p. 104: discard bcast/mcast SYN
--- 556,562 ----
  			goto drop;
  		if (tiflags & TH_ACK)
  			goto dropwithreset;
! 		if (tiflags != TH_SYN)
  			goto drop;
  		/*
  		 * RFC1122 4.2.3.10, p. 104: discard bcast/mcast SYN
>Audit-Trail:
>Unformatted: