You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
3.9 KiB
128 lines
3.9 KiB
1 month ago
|
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 313c818b18..9725e928f7 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 017c4d05bc..a46f6f9b68 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];
|