dcavalca / rpms / grub2

Forked from rpms/grub2 3 years ago
Clone

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

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