dcavalca / rpms / grub2

Forked from rpms/grub2 3 years ago
Clone

Blame SOURCES/0179-AUDIT-0-http-boot-tracker-bug.patch

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