RFC 7112 requires a host to put the complete IP header chain
including the TCP header in the first IP packet. Enforce this in tcp_output(). In addition make sure that at least one byte payload fits in the TCP segement to allow making progress. Without this check, a kernel with INVARIANTS will panic. This issue was found by running an instance of syzkaller. Reviewed by: jtl@ MFC after: 3 days Sponsored by: Netflix, Inc. Differential Revision: https://reviews.freebsd.org/D21665
This commit is contained in:
parent
3e6fdbf4be
commit
5f6d43232d
@ -941,6 +941,20 @@ send:
|
||||
if (tp->t_flags & TF_NEEDFIN)
|
||||
sendalot = 1;
|
||||
} else {
|
||||
if (optlen + ipoptlen >= tp->t_maxseg) {
|
||||
/*
|
||||
* Since we don't have enough space to put
|
||||
* the IP header chain and the TCP header in
|
||||
* one packet as required by RFC 7112, don't
|
||||
* send it. Also ensure that at least one
|
||||
* byte of the payload can be put into the
|
||||
* TCP segment.
|
||||
*/
|
||||
SOCKBUF_UNLOCK(&so->so_snd);
|
||||
error = EMSGSIZE;
|
||||
sack_rxmit = 0;
|
||||
goto out;
|
||||
}
|
||||
len = tp->t_maxseg - optlen - ipoptlen;
|
||||
sendalot = 1;
|
||||
if (dont_sendalot)
|
||||
|
@ -13343,12 +13343,14 @@ send:
|
||||
}
|
||||
} else {
|
||||
/* Not doing TSO */
|
||||
if (optlen + ipoptlen > tp->t_maxseg) {
|
||||
if (optlen + ipoptlen >= tp->t_maxseg) {
|
||||
/*
|
||||
* Since we don't have enough space to put
|
||||
* the IP header chain and the TCP header in
|
||||
* one packet as required by RFC 7112, don't
|
||||
* send it.
|
||||
* send it. Also ensure that at least one
|
||||
* byte of the payload can be put into the
|
||||
* TCP segment.
|
||||
*/
|
||||
SOCKBUF_UNLOCK(&so->so_snd);
|
||||
error = EMSGSIZE;
|
||||
|
@ -9200,12 +9200,14 @@ send:
|
||||
sendalot = 1;
|
||||
|
||||
} else {
|
||||
if (optlen + ipoptlen > tp->t_maxseg) {
|
||||
if (optlen + ipoptlen >= tp->t_maxseg) {
|
||||
/*
|
||||
* Since we don't have enough space to put
|
||||
* the IP header chain and the TCP header in
|
||||
* one packet as required by RFC 7112, don't
|
||||
* send it.
|
||||
* send it. Also ensure that at least one
|
||||
* byte of the payload can be put into the
|
||||
* TCP segment.
|
||||
*/
|
||||
SOCKBUF_UNLOCK(&so->so_snd);
|
||||
error = EMSGSIZE;
|
||||
|
Loading…
x
Reference in New Issue
Block a user