mirror of
https://github.com/xcat2/xNBA.git
synced 2024-11-29 12:49:49 +00:00
[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>
This commit is contained in:
parent
c7eea31ed8
commit
501527daab
@ -60,9 +60,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
||||
#define EIO_CONTENT_LENGTH __einfo_error ( EINFO_EIO_CONTENT_LENGTH )
|
||||
#define EINFO_EIO_CONTENT_LENGTH \
|
||||
__einfo_uniqify ( EINFO_EIO, 0x02, "Content length mismatch" )
|
||||
#define EIO_CHUNK __einfo_error ( EINFO_EIO_CHUNK )
|
||||
#define EINFO_EIO_CHUNK \
|
||||
__einfo_uniqify ( EINFO_EIO, 0x03, "Terminated mid-chunk" )
|
||||
#define EINVAL_RESPONSE __einfo_error ( EINFO_EINVAL_RESPONSE )
|
||||
#define EINFO_EINVAL_RESPONSE \
|
||||
__einfo_uniqify ( EINFO_EINVAL, 0x01, "Invalid content length" )
|
||||
@ -111,7 +108,14 @@ enum http_rx_state {
|
||||
HTTP_RX_RESPONSE = 0,
|
||||
HTTP_RX_HEADER,
|
||||
HTTP_RX_CHUNK_LEN,
|
||||
/* In HTTP_RX_DATA, it is acceptable for the server to close
|
||||
* the connection (unless we are in the middle of a chunked
|
||||
* transfer).
|
||||
*/
|
||||
HTTP_RX_DATA,
|
||||
/* In the following states, it is acceptable for the server to
|
||||
* close the connection.
|
||||
*/
|
||||
HTTP_RX_TRAILER,
|
||||
HTTP_RX_IDLE,
|
||||
HTTP_RX_DEAD,
|
||||
@ -251,10 +255,14 @@ static int http_socket_open ( struct http_request *http ) {
|
||||
static void http_done ( struct http_request *http ) {
|
||||
int rc;
|
||||
|
||||
/* If we are in the middle of a chunked transfer, force an error */
|
||||
if ( http->chunked ) {
|
||||
DBGC ( http, "HTTP %p terminated mid-chunk\n", http );
|
||||
http_close ( http, -EIO_CHUNK );
|
||||
/* If we are not at an appropriate stage of the protocol
|
||||
* (including being in the middle of a chunked transfer),
|
||||
* force an error.
|
||||
*/
|
||||
if ( ( http->rx_state < HTTP_RX_DATA ) || ( http->chunked != 0 ) ) {
|
||||
DBGC ( http, "HTTP %p connection closed unexpectedly\n",
|
||||
http );
|
||||
http_close ( http, -ECONNRESET );
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user