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,9 +60,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
60 60
 #define EIO_CONTENT_LENGTH __einfo_error ( EINFO_EIO_CONTENT_LENGTH )
61 61
 #define EINFO_EIO_CONTENT_LENGTH \
62 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 63
 #define EINVAL_RESPONSE __einfo_error ( EINFO_EINVAL_RESPONSE )
67 64
 #define EINFO_EINVAL_RESPONSE \
68 65
 	__einfo_uniqify ( EINFO_EINVAL, 0x01, "Invalid content length" )
@@ -111,7 +108,14 @@ enum http_rx_state {
111 108
 	HTTP_RX_RESPONSE = 0,
112 109
 	HTTP_RX_HEADER,
113 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 115
 	HTTP_RX_DATA,
116
+	/* In the following states, it is acceptable for the server to
117
+	 * close the connection.
118
+	 */
115 119
 	HTTP_RX_TRAILER,
116 120
 	HTTP_RX_IDLE,
117 121
 	HTTP_RX_DEAD,
@@ -251,10 +255,14 @@ static int http_socket_open ( struct http_request *http ) {
251 255
 static void http_done ( struct http_request *http ) {
252 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 266
 		return;
259 267
 	}
260 268
 

Loading…
Cancel
Save