nalika / rpms / grub2

Forked from rpms/grub2 2 years ago
Clone

Blame SOURCES/0158-efi-ip-46-_config.c-fix-some-potential-allocation-ov.patch

8e15ce
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
8e15ce
From: Peter Jones <pjones@redhat.com>
8e15ce
Date: Sun, 19 Jul 2020 17:27:00 -0400
8e15ce
Subject: [PATCH] efi/ip[46]_config.c: fix some potential allocation overflows
8e15ce
8e15ce
In theory all of this data comes from the firmware stack and it should
8e15ce
be safe, but it's better to be paranoid.
8e15ce
8e15ce
Signed-off-by: Peter Jones <pjones@redhat.com>
8e15ce
---
8e15ce
 grub-core/net/efi/ip4_config.c | 25 ++++++++++++++++++-------
8e15ce
 grub-core/net/efi/ip6_config.c | 13 ++++++++++---
8e15ce
 2 files changed, 28 insertions(+), 10 deletions(-)
8e15ce
8e15ce
diff --git a/grub-core/net/efi/ip4_config.c b/grub-core/net/efi/ip4_config.c
8e15ce
index 313c818b184..9725e928f7e 100644
8e15ce
--- a/grub-core/net/efi/ip4_config.c
8e15ce
+++ b/grub-core/net/efi/ip4_config.c
8e15ce
@@ -4,15 +4,20 @@
8e15ce
 #include <grub/misc.h>
8e15ce
 #include <grub/net/efi.h>
8e15ce
 #include <grub/charset.h>
8e15ce
+#include <grub/safemath.h>
8e15ce
 
8e15ce
 char *
8e15ce
 grub_efi_hw_address_to_string (grub_efi_uint32_t hw_address_size, grub_efi_mac_address_t hw_address)
8e15ce
 {
8e15ce
   char *hw_addr, *p;
8e15ce
-  int sz, s;
8e15ce
-  int i;
8e15ce
+  grub_size_t sz, s, i;
8e15ce
 
8e15ce
-  sz = (int)hw_address_size * (sizeof ("XX:") - 1) + 1;
8e15ce
+  if (grub_mul (hw_address_size, sizeof ("XX:") - 1, &sz) ||
8e15ce
+      grub_add (sz, 1, &sz))
8e15ce
+    {
8e15ce
+      grub_errno = GRUB_ERR_OUT_OF_RANGE;
8e15ce
+      return NULL;
8e15ce
+    }
8e15ce
 
8e15ce
   hw_addr = grub_malloc (sz);
8e15ce
   if (!hw_addr)
8e15ce
@@ -20,7 +25,7 @@ grub_efi_hw_address_to_string (grub_efi_uint32_t hw_address_size, grub_efi_mac_a
8e15ce
 
8e15ce
   p = hw_addr;
8e15ce
   s = sz;
8e15ce
-  for (i = 0; i < (int)hw_address_size; i++)
8e15ce
+  for (i = 0; i < hw_address_size; i++)
8e15ce
     {
8e15ce
       grub_snprintf (p, sz, "%02x:", hw_address[i]);
8e15ce
       p +=  sizeof ("XX:") - 1;
8e15ce
@@ -238,14 +243,20 @@ grub_efi_ip4_interface_route_table (struct grub_efi_net_device *dev)
8e15ce
 {
8e15ce
   grub_efi_ip4_config2_interface_info_t *interface_info;
8e15ce
   char **ret;
8e15ce
-  int i, id;
8e15ce
+  int id;
8e15ce
+  grub_size_t i, nmemb;
8e15ce
 
8e15ce
   interface_info = efi_ip4_config_interface_info (dev->ip4_config);
8e15ce
   if (!interface_info)
8e15ce
     return NULL;
8e15ce
 
8e15ce
-  ret = grub_malloc (sizeof (*ret) * (interface_info->route_table_size + 1));
8e15ce
+  if (grub_add (interface_info->route_table_size, 1, &nmemb))
8e15ce
+    {
8e15ce
+      grub_errno = GRUB_ERR_OUT_OF_RANGE;
8e15ce
+      return NULL;
8e15ce
+    }
8e15ce
 
8e15ce
+  ret = grub_calloc (nmemb, sizeof (*ret));
8e15ce
   if (!ret)
8e15ce
     {
8e15ce
       grub_free (interface_info);
8e15ce
@@ -253,7 +264,7 @@ grub_efi_ip4_interface_route_table (struct grub_efi_net_device *dev)
8e15ce
     }
8e15ce
 
8e15ce
   id = 0;
8e15ce
-  for (i = 0; i < (int)interface_info->route_table_size; i++)
8e15ce
+  for (i = 0; i < interface_info->route_table_size; i++)
8e15ce
     {
8e15ce
       char *subnet, *gateway, *mask;
8e15ce
       grub_uint32_t u32_subnet, u32_gateway;
8e15ce
diff --git a/grub-core/net/efi/ip6_config.c b/grub-core/net/efi/ip6_config.c
8e15ce
index 017c4d05bc7..a46f6f9b685 100644
8e15ce
--- a/grub-core/net/efi/ip6_config.c
8e15ce
+++ b/grub-core/net/efi/ip6_config.c
8e15ce
@@ -3,6 +3,7 @@
8e15ce
 #include <grub/misc.h>
8e15ce
 #include <grub/net/efi.h>
8e15ce
 #include <grub/charset.h>
8e15ce
+#include <grub/safemath.h>
8e15ce
 
8e15ce
 char *
8e15ce
 grub_efi_ip6_address_to_string (grub_efi_pxe_ipv6_address_t *address)
8e15ce
@@ -228,14 +229,20 @@ grub_efi_ip6_interface_route_table (struct grub_efi_net_device *dev)
8e15ce
 {
8e15ce
   grub_efi_ip6_config_interface_info_t *interface_info;
8e15ce
   char **ret;
8e15ce
-  int i, id;
8e15ce
+  int id;
8e15ce
+  grub_size_t i, nmemb;
8e15ce
 
8e15ce
   interface_info = efi_ip6_config_interface_info (dev->ip6_config);
8e15ce
   if (!interface_info)
8e15ce
     return NULL;
8e15ce
 
8e15ce
-  ret = grub_malloc (sizeof (*ret) * (interface_info->route_count + 1));
8e15ce
+  if (grub_add (interface_info->route_count, 1, &nmemb))
8e15ce
+    {
8e15ce
+      grub_errno = GRUB_ERR_OUT_OF_RANGE;
8e15ce
+      return NULL;
8e15ce
+    }
8e15ce
 
8e15ce
+  ret = grub_calloc (nmemb, sizeof (*ret));
8e15ce
   if (!ret)
8e15ce
     {
8e15ce
       grub_free (interface_info);
8e15ce
@@ -243,7 +250,7 @@ grub_efi_ip6_interface_route_table (struct grub_efi_net_device *dev)
8e15ce
     }
8e15ce
 
8e15ce
   id = 0;
8e15ce
-  for (i = 0; i < (int)interface_info->route_count ; i++)
8e15ce
+  for (i = 0; i < interface_info->route_count ; i++)
8e15ce
     {
8e15ce
       char *gateway, *destination;
8e15ce
       grub_uint64_t u64_gateway[2];