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

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