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

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