grub2/SOURCES/0309-efi-ip-46-_config.c-fi...

128 lines
3.9 KiB
Diff

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