From: Michael Brown Date: Thu, 30 Jul 2026 13:56:18 +0000 (+0100) Subject: [http] Avoid potentially comparing TCP header bytes against CRLF X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=48c04ec047a1a9bf49afa016528dceaa7f22bc5f;p=thirdparty%2Fipxe.git [http] Avoid potentially comparing TCP header bytes against CRLF The optimisation to check for a trailing CRLF in http_rx_chunk_data() could potentially underflow and look for the CR and LF bytes in the I/O buffer data that immediately precedes the HTTP content (i.e. in the TCP header). Fix by avoiding the potential underflow. Update the code to use a dedicated CRLF structure, to reduce the proliferation of magic numbers within the function. Signed-off-by: Michael Brown --- diff --git a/src/net/tcp/httpcore.c b/src/net/tcp/httpcore.c index 7dbb0e304..affb48265 100644 --- a/src/net/tcp/httpcore.c +++ b/src/net/tcp/httpcore.c @@ -1808,8 +1808,11 @@ static int http_rx_chunk_len ( struct http_transaction *http, */ static int http_rx_chunk_data ( struct http_transaction *http, struct io_buffer **iobuf ) { + struct { + uint8_t cr; + uint8_t lf; + } __attribute__ (( packed )) *crlf; struct io_buffer *payload; - uint8_t *crlf; size_t len; int rc; @@ -1818,12 +1821,16 @@ static int http_rx_chunk_data ( struct http_transaction *http, * (which we would ignore anyway) and hence avoid * unnecessarily copying the data. */ - if ( iob_len ( *iobuf ) == ( http->remaining + 2 /* CRLF */ ) ) { + len = iob_len ( *iobuf ); + if ( ( len >= sizeof ( *crlf ) ) && + ( ( len - sizeof ( *crlf ) ) == http->remaining ) ) { crlf = ( (*iobuf)->data + http->remaining ); - if ( ( crlf[0] == '\r' ) && ( crlf[1] == '\n' ) ) - iob_unput ( (*iobuf), 2 /* CRLF */ ); + if ( ( crlf->cr == '\r' ) && ( crlf->lf == '\n' ) ) { + iob_unput ( *iobuf, sizeof ( *crlf ) ); + len -= sizeof ( *crlf ); + } } - len = iob_len ( *iobuf ); + assert ( len == iob_len ( *iobuf ) ); /* Use whole/partial buffer as applicable */ if ( len <= http->remaining ) {