dcavalca / rpms / grub2

Forked from rpms/grub2 3 years ago
Clone

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

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