Enforce a minimum Send MSS.

Without this enforcement, options larger than the specified MSS can cause
MaxPayloadSize to go negative and cause all sorts of problems.

PiperOrigin-RevId: 460224034
This commit is contained in:
Lucas Manning
2022-07-11 08:56:43 -07:00
committed by gVisor bot
parent 22bc54453d
commit 3aa77e9f0a
3 changed files with 29 additions and 5 deletions
+7
View File
@@ -222,6 +222,10 @@ const (
// same as the value TCP_MIN_MSS defined net/tcp.h.
TCPMinimumMSS = IPv4MaximumHeaderSize + TCPHeaderMaximumSize + MinIPFragmentPayloadSize - IPv4MinimumSize - TCPMinimumSize
// TCPMinimumSendMSS is the minimum value for MSS in a sender. This is the
// same as the value TCP_MIN_SND_MSS in net/tcp.h.
TCPMinimumSendMSS = TCPOptionsMaximumSize + MinIPFragmentPayloadSize
// TCPMaximumMSS is the maximum acceptable value for MSS.
TCPMaximumMSS = 0xffff
@@ -458,6 +462,9 @@ func ParseSynOptions(opts []byte, isAck bool) TCPSynOptions {
return synOpts
}
synOpts.MSS = mss
if mss < TCPMinimumSendMSS {
synOpts.MSS = TCPMinimumSendMSS
}
i += 4
case TCPOptionWS:
-5
View File
@@ -861,11 +861,6 @@ func (s *sender) maybeSendSegment(seg *segment, limit int, end seqnum.Value) (se
if seg.payloadSize() > available {
// A negative value causes splitSeg to panic anyways, so just panic
// earlier to get more information about the cause.
// TOOD(b/236090764): Remove this panic once the cause of negative values
// of "available" is understood.
if available < 0 {
panic(fmt.Sprintf("got available=%d, want available>=0. limit %d, s.MaxPayloadSize %d, seg.payloadSize() %d, gso.MaxSize %d, gso.MSS %d", available, limit, s.MaxPayloadSize, seg.payloadSize(), s.ep.gso.MaxSize, s.ep.gso.MSS))
}
s.splitSeg(seg, available)
}
@@ -3573,6 +3573,28 @@ func TestSetTTL(t *testing.T) {
}
}
func TestSendMSSLessThanOptionsSize(t *testing.T) {
const mss = 10
const writeSize = 300
c := context.New(t, 65535)
defer c.Cleanup()
// The sizes of these options add up to 12.
c.CreateConnectedWithRawOptions(context.TestInitialSequenceNumber, 30000, -1 /* epRcvBuf */, []byte{
header.TCPOptionMSS, 4, byte(mss / 256), byte(mss % 256),
header.TCPOptionTS, header.TCPOptionTSLength, 1, 2, 3, 4, 5, 6, 7, 8,
header.TCPOptionSACKPermitted, header.TCPOptionSackPermittedLength,
})
e2e.CheckBrokenUpWrite(t, c, writeSize)
var r bytes.Reader
r.Reset(make([]byte, writeSize))
_, err := c.EP.Write(&r, tcpip.WriteOptions{})
if err != nil {
t.Fatalf("Write failed: %s", err)
}
}
func TestActiveSendMSSLessThanMTU(t *testing.T) {
const maxPayload = 100
c := context.New(t, 65535)