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