63f1a98
From d7e857c8a02ae15a940faacc6e8b688cc590c4d7 Mon Sep 17 00:00:00 2001
63f1a98
From: Sebastian Krahmer <krahmer@suse.com>
63f1a98
Date: Tue, 28 Nov 2017 17:24:38 +0800
31cddd6
Subject: [PATCH] AUDIT-0: http boot tracker bug
63f1a98
63f1a98
Fixing a memory leak in case of error, and a integer overflow, leading to a
63f1a98
heap overflow due to overly large chunk sizes.
63f1a98
63f1a98
We need to check against some maximum value, otherwise values like 0xffffffff
63f1a98
will eventually lead in the allocation functions to small sized buffers, since
63f1a98
the len is rounded up to the next reasonable alignment. The following memcpy
63f1a98
will then smash the heap, leading to RCE.
63f1a98
63f1a98
This is no big issue for pure http boot, since its going to execute an
63f1a98
untrusted kernel anyway, but it will break trusted boot scenarios, where only
63f1a98
signed code is allowed to be executed.
63f1a98
63f1a98
Signed-off-by: Michael Chang <mchang@suse.com>
63f1a98
---
63f1a98
 grub-core/net/efi/net.c | 4 +++-
63f1a98
 grub-core/net/http.c    | 5 ++++-
63f1a98
 2 files changed, 7 insertions(+), 2 deletions(-)
63f1a98
63f1a98
diff --git a/grub-core/net/efi/net.c b/grub-core/net/efi/net.c
63f1a98
index 9e0078ac1c6..2bf15447fd5 100644
63f1a98
--- a/grub-core/net/efi/net.c
63f1a98
+++ b/grub-core/net/efi/net.c
63f1a98
@@ -645,8 +645,10 @@ grub_efihttp_chunk_read (grub_file_t file, char *buf,
63f1a98
 
63f1a98
       rd = efi_net_interface (read, file, chunk, sz);
63f1a98
 
63f1a98
-      if (rd <= 0)
63f1a98
+      if (rd <= 0) {
63f1a98
+	grub_free (chunk);
63f1a98
 	return rd;
63f1a98
+      }
63f1a98
 
63f1a98
       if (buf)
63f1a98
 	{
63f1a98
diff --git a/grub-core/net/http.c b/grub-core/net/http.c
63f1a98
index f182d7b871d..5004ecfee42 100644
63f1a98
--- a/grub-core/net/http.c
63f1a98
+++ b/grub-core/net/http.c
63f1a98
@@ -31,7 +31,8 @@ GRUB_MOD_LICENSE ("GPLv3+");
63f1a98
 
63f1a98
 enum
63f1a98
   {
63f1a98
-    HTTP_PORT = 80
63f1a98
+    HTTP_PORT = 80,
63f1a98
+    HTTP_MAX_CHUNK_SIZE = 0x80000000
63f1a98
   };
63f1a98
 
63f1a98
 
63f1a98
@@ -78,6 +79,8 @@ parse_line (grub_file_t file, http_data_t data, char *ptr, grub_size_t len)
63f1a98
   if (data->in_chunk_len == 2)
63f1a98
     {
63f1a98
       data->chunk_rem = grub_strtoul (ptr, 0, 16);
63f1a98
+      if (data->chunk_rem > HTTP_MAX_CHUNK_SIZE)
63f1a98
+	  return GRUB_ERR_NET_PACKET_TOO_BIG;
63f1a98
       grub_errno = GRUB_ERR_NONE;
63f1a98
       if (data->chunk_rem == 0)
63f1a98
 	{