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