dcavalca / rpms / grub2

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