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

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