From 3cf6dbdcfe042501e246f264546cad9047f3ecad Mon Sep 17 00:00:00 2001 From: Dennis Tseng Date: Mon, 12 Feb 2024 22:15:37 +0800 Subject: [PATCH] reject message with different values in multiple Content-Length header field If multiple headers occur, usually the last header would have authority; however the section 3.3.3 of RFC 7230 states that: If a message is received without Transfer-Encoding and with either multiple Content-Length header fields having differing field-values or ..., then the message framing is invalid and the recipient MUST treat it as an unrecoverable error. For example: If there are 2 headers, for example, "Content-Length: 42" and "Content-Length: 52", then current shim httpboot.c will accept the last one which is "Content-Length": 52". This is not correct. This patch allows multiple values if they are the same, but rejects message if any different value is found. In function receive_http_response() of httpboot.c, each received duplicate Content-Length field must be checked whether its value is different. If it is, then this message is invalid. Signed-off-by: Dennis Tseng --- httpboot.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/httpboot.c b/httpboot.c index 4b26fc8db..9b0947d87 100644 --- a/httpboot.c +++ b/httpboot.c @@ -562,7 +562,7 @@ receive_http_response(EFI_HTTP_PROTOCOL *http, VOID **buffer, UINT64 *buf_size) EFI_HTTP_RESPONSE_DATA response; EFI_HTTP_STATUS_CODE http_status; BOOLEAN response_done; - UINTN i, downloaded; + UINTN i, j, downloaded; CHAR8 rx_buffer[9216]; EFI_STATUS efi_status; EFI_STATUS event_status; @@ -619,6 +619,15 @@ receive_http_response(EFI_HTTP_PROTOCOL *http, VOID **buffer, UINT64 *buf_size) if (!strcasecmp(rx_message.Headers[i].FieldName, (CHAR8 *)"Content-Length")) { *buf_size = ascii_to_int(rx_message.Headers[i].FieldValue); + for(j = 0; j < i; j++) { + if (!strcasecmp(rx_message.Headers[i].FieldName, + (CHAR8 *)"Content-Length")) { + if (*buf_size != ascii_to_int(rx_message.Headers[j].FieldValue)) { + perror(L"Content-Length is invalid\n"); + goto error; + } + } + } } }