From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Peter Jones 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 --- 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 #include #include +#include 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 #include #include +#include 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];