From 1069c21677ca6e58333c4190412cb3cddab5cd7c Mon Sep 17 00:00:00 2001 From: Chotiwat Chawannakul Date: Fri, 25 Oct 2024 15:49:59 -0700 Subject: [PATCH] fix and bound buffer length, add documentation from PR 11843 by maxl99 --- pkg/tcpproxy/tcp.go | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/pkg/tcpproxy/tcp.go b/pkg/tcpproxy/tcp.go index 65923aa209..6780f40585 100644 --- a/pkg/tcpproxy/tcp.go +++ b/pkg/tcpproxy/tcp.go @@ -59,8 +59,21 @@ func (p *TCPProxy) Get(host string) *TCPServer { // and open a connection to the passthrough server. func (p *TCPProxy) Handle(conn net.Conn) { defer conn.Close() - // See: https://www.ibm.com/docs/en/ztpf/1.1.0.15?topic=sessions-ssl-record-format - data := make([]byte, 16384) + // [Documentation by @maxl99](https://github.com/kubernetes/ingress-nginx/pull/11843/files#diff-aef3e187fd37c68706ad582d7b89a2d9ad11691bd929a2158b86f93362244105R67-R79) + // It appears that the ClientHello must fit into *one* TLSPlaintext message: + // When a client first connects to a server, it is REQUIRED to send the ClientHello as its first TLS message. + // Source: https://datatracker.ietf.org/doc/html/rfc8446#section-4.1.2 + // + // length: The length (in bytes) of the following TLSPlaintext.fragment. The length MUST NOT exceed 2^14 bytes. + // An endpoint that receives a record that exceeds this length MUST terminate the connection with a "record_overflow" alert. + // Source: https://datatracker.ietf.org/doc/html/rfc8446#section-5.1 + // bytes 0 : content type + // bytes 1-2: legacy version + // bytes 3-4: length + // bytes 5+ : message + // https://en.wikipedia.org/wiki/Transport_Layer_Security#TLS_record + // Thus, we need to allocate 5 + 16384 bytes + data := make([]byte, parser.TLSHeaderLength+16384) // read the tls header first _, err := io.ReadFull(conn, data[:parser.TLSHeaderLength]) @@ -69,7 +82,7 @@ func (p *TCPProxy) Handle(conn net.Conn) { return } // get the total data length then read the rest - length := int(data[3])<<8 + int(data[4]) + parser.TLSHeaderLength + length := min(int(data[3])<<8+int(data[4])+parser.TLSHeaderLength, len(data)) _, err = io.ReadFull(conn, data[parser.TLSHeaderLength:length]) if err != nil { klog.V(4).ErrorS(err, "Error reading data from the connection")