dcavalca / rpms / grub2

Forked from rpms/grub2 3 years ago
Clone

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

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