nalika / rpms / grub2

Forked from rpms/grub2 2 years ago
Clone

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

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