Browse Source

[http] Treat any unexpected connection close as an error

iPXE currently checks that the server has not closed the connection
mid-stream (i.e. in the middle of a chunked transfer, or before the
specified Content-Length has been received), but does not check that
the server got as far as starting to send data.  Consequently, if the
server closes the connection before any data is transferred (e.g. if
the server gives up waiting while iPXE performs the validation steps
for TLS), then iPXE will treat this as a successful transfer of a
zero-length file.

Fix by checking the RX connection state, and forcing an error if the
server has closed the connection at an unexpected point.

Originally-fixed-by: Marin Hannache <mareo@mareo.fr>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 12 years ago
parent
commit
501527daab
1 changed files with 15 additions and 7 deletions
  1. 15
    7
      src/net/tcp/httpcore.c

+ 15
- 7
src/net/tcp/httpcore.c View File

60
 #define EIO_CONTENT_LENGTH __einfo_error ( EINFO_EIO_CONTENT_LENGTH )
60
 #define EIO_CONTENT_LENGTH __einfo_error ( EINFO_EIO_CONTENT_LENGTH )
61
 #define EINFO_EIO_CONTENT_LENGTH \
61
 #define EINFO_EIO_CONTENT_LENGTH \
62
 	__einfo_uniqify ( EINFO_EIO, 0x02, "Content length mismatch" )
62
 	__einfo_uniqify ( EINFO_EIO, 0x02, "Content length mismatch" )
63
-#define EIO_CHUNK __einfo_error ( EINFO_EIO_CHUNK )
64
-#define EINFO_EIO_CHUNK \
65
-	__einfo_uniqify ( EINFO_EIO, 0x03, "Terminated mid-chunk" )
66
 #define EINVAL_RESPONSE __einfo_error ( EINFO_EINVAL_RESPONSE )
63
 #define EINVAL_RESPONSE __einfo_error ( EINFO_EINVAL_RESPONSE )
67
 #define EINFO_EINVAL_RESPONSE \
64
 #define EINFO_EINVAL_RESPONSE \
68
 	__einfo_uniqify ( EINFO_EINVAL, 0x01, "Invalid content length" )
65
 	__einfo_uniqify ( EINFO_EINVAL, 0x01, "Invalid content length" )
111
 	HTTP_RX_RESPONSE = 0,
108
 	HTTP_RX_RESPONSE = 0,
112
 	HTTP_RX_HEADER,
109
 	HTTP_RX_HEADER,
113
 	HTTP_RX_CHUNK_LEN,
110
 	HTTP_RX_CHUNK_LEN,
111
+	/* In HTTP_RX_DATA, it is acceptable for the server to close
112
+	 * the connection (unless we are in the middle of a chunked
113
+	 * transfer).
114
+	 */
114
 	HTTP_RX_DATA,
115
 	HTTP_RX_DATA,
116
+	/* In the following states, it is acceptable for the server to
117
+	 * close the connection.
118
+	 */
115
 	HTTP_RX_TRAILER,
119
 	HTTP_RX_TRAILER,
116
 	HTTP_RX_IDLE,
120
 	HTTP_RX_IDLE,
117
 	HTTP_RX_DEAD,
121
 	HTTP_RX_DEAD,
251
 static void http_done ( struct http_request *http ) {
255
 static void http_done ( struct http_request *http ) {
252
 	int rc;
256
 	int rc;
253
 
257
 
254
-	/* If we are in the middle of a chunked transfer, force an error */
255
-	if ( http->chunked ) {
256
-		DBGC ( http, "HTTP %p terminated mid-chunk\n", http );
257
-		http_close ( http, -EIO_CHUNK );
258
+	/* If we are not at an appropriate stage of the protocol
259
+	 * (including being in the middle of a chunked transfer),
260
+	 * force an error.
261
+	 */
262
+	if ( ( http->rx_state < HTTP_RX_DATA ) || ( http->chunked != 0 ) ) {
263
+		DBGC ( http, "HTTP %p connection closed unexpectedly\n",
264
+		       http );
265
+		http_close ( http, -ECONNRESET );
258
 		return;
266
 		return;
259
 	}
267
 	}
260
 
268
 

Loading…
Cancel
Save