Blame SOURCES/0146-efi-http-Enclose-literal-IPv6-addresses-in-square-br.patch

5593c8
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
5593c8
From: Javier Martinez Canillas <javierm@redhat.com>
5593c8
Date: Thu, 5 Mar 2020 16:21:58 +0100
5593c8
Subject: [PATCH] efi/http: Enclose literal IPv6 addresses in square brackets
5593c8
5593c8
According to RFC 2732 (https://www.ietf.org/rfc/rfc2732.txt), literal IPv6
5593c8
addresses must be enclosed in square brackets. But GRUB currently does not
5593c8
do this and is causing HTTP servers to send Bad Request (400) responses.
5593c8
5593c8
For example, the following is the HTTP stream when fetching a config file:
5593c8
5593c8
HEAD /EFI/BOOT/grub.cfg HTTP/1.1
5593c8
Host: 2000:dead:beef:a::1
5593c8
Accept: */*
5593c8
User-Agent: UefiHttpBoot/1.0
5593c8
5593c8
HTTP/1.1 400 Bad Request
5593c8
Date: Thu, 05 Mar 2020 14:46:02 GMT
5593c8
Server: Apache/2.4.41 (Fedora) OpenSSL/1.1.1d
5593c8
Connection: close
5593c8
Content-Type: text/html; charset=iso-8859-1
5593c8
5593c8
and after enclosing the IPv6 address the HTTP request is successful:
5593c8
5593c8
HEAD /EFI/BOOT/grub.cfg HTTP/1.1
5593c8
Host: [2000:dead:beef:a::1]
5593c8
Accept: */*
5593c8
User-Agent: UefiHttpBoot/1.0
5593c8
5593c8
HTTP/1.1 200 OK
5593c8
Date: Thu, 05 Mar 2020 14:48:04 GMT
5593c8
Server: Apache/2.4.41 (Fedora) OpenSSL/1.1.1d
5593c8
Last-Modified: Thu, 27 Feb 2020 17:45:58 GMT
5593c8
ETag: "206-59f924b24b1da"
5593c8
Accept-Ranges: bytes
5593c8
Content-Length: 518
5593c8
5593c8
Resolves: rhbz#1732765
5593c8
5593c8
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
5593c8
---
5593c8
 grub-core/net/efi/http.c | 37 ++++++++++++++++++++++++++++---------
5593c8
 1 file changed, 28 insertions(+), 9 deletions(-)
5593c8
5593c8
diff --git a/grub-core/net/efi/http.c b/grub-core/net/efi/http.c
d3c3ab
index 755b7a6d054..fc8cb25ae0a 100644
5593c8
--- a/grub-core/net/efi/http.c
5593c8
+++ b/grub-core/net/efi/http.c
5593c8
@@ -158,13 +158,7 @@ efihttp_request (grub_efi_http_t *http, char *server, char *name, int use_https,
5593c8
   grub_efi_status_t status;
5593c8
   grub_efi_boot_services_t *b = grub_efi_system_table->boot_services;
5593c8
   char *url = NULL;
5593c8
-
5593c8
-  request_headers[0].field_name = (grub_efi_char8_t *)"Host";
5593c8
-  request_headers[0].field_value = (grub_efi_char8_t *)server;
5593c8
-  request_headers[1].field_name = (grub_efi_char8_t *)"Accept";
5593c8
-  request_headers[1].field_value = (grub_efi_char8_t *)"*/*";
5593c8
-  request_headers[2].field_name = (grub_efi_char8_t *)"User-Agent";
5593c8
-  request_headers[2].field_value = (grub_efi_char8_t *)"UefiHttpBoot/1.0";
5593c8
+  char *hostname = NULL;
5593c8
 
5593c8
   {
5593c8
     grub_efi_ipv6_address_t address;
5593c8
@@ -174,9 +168,24 @@ efihttp_request (grub_efi_http_t *http, char *server, char *name, int use_https,
5593c8
     const char *protocol = (use_https == 1) ? "https" : "http";
5593c8
 
5593c8
     if (grub_efi_string_to_ip6_address (server, &address, &rest) && *rest == 0)
5593c8
-      url = grub_xasprintf ("%s://[%s]%s", protocol, server, name);
5593c8
+      {
5593c8
+        hostname = grub_xasprintf ("[%s]", server);
5593c8
+        if (!hostname)
5593c8
+          return GRUB_ERR_OUT_OF_MEMORY;
5593c8
+
5593c8
+        server = hostname;
5593c8
+
5593c8
+        url = grub_xasprintf ("%s://%s%s", protocol, server, name);
5593c8
+        if (!url)
5593c8
+          {
5593c8
+            grub_free (hostname);
5593c8
+            return GRUB_ERR_OUT_OF_MEMORY;
5593c8
+          }
5593c8
+      }
5593c8
     else
5593c8
-      url = grub_xasprintf ("%s://%s%s", protocol, server, name);
5593c8
+      {
5593c8
+        url = grub_xasprintf ("%s://%s%s", protocol, server, name);
5593c8
+      }
5593c8
 
5593c8
     if (!url)
5593c8
       {
5593c8
@@ -199,6 +208,13 @@ efihttp_request (grub_efi_http_t *http, char *server, char *name, int use_https,
5593c8
     request_data.url = ucs2_url;
5593c8
   }
5593c8
 
5593c8
+  request_headers[0].field_name = (grub_efi_char8_t *)"Host";
5593c8
+  request_headers[0].field_value = (grub_efi_char8_t *)server;
5593c8
+  request_headers[1].field_name = (grub_efi_char8_t *)"Accept";
5593c8
+  request_headers[1].field_value = (grub_efi_char8_t *)"*/*";
5593c8
+  request_headers[2].field_name = (grub_efi_char8_t *)"User-Agent";
5593c8
+  request_headers[2].field_value = (grub_efi_char8_t *)"UefiHttpBoot/1.0";
5593c8
+
5593c8
   request_data.method = (headeronly > 0) ? GRUB_EFI_HTTPMETHODHEAD : GRUB_EFI_HTTPMETHODGET;
5593c8
 
5593c8
   request_message.data.request = &request_data;
5593c8
@@ -228,6 +244,9 @@ efihttp_request (grub_efi_http_t *http, char *server, char *name, int use_https,
5593c8
 
5593c8
   status = efi_call_2 (http->request, http, &request_token);
5593c8
 
5593c8
+  if (hostname)
5593c8
+    grub_free (hostname);
5593c8
+
5593c8
   if (status != GRUB_EFI_SUCCESS)
5593c8
     {
5593c8
       efi_call_1 (b->close_event, request_token.event);