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: