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.
127 lines
3.9 KiB
127 lines
3.9 KiB
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 313c818b184..9725e928f7e 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 017c4d05bc7..a46f6f9b685 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];
|
|
|