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

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