calloc: Make sure we always have an overflow-checking calloc() available

This tries to make sure that everywhere in this source tree, we always have
an appropriate version of calloc() (i.e. grub_calloc(), xcalloc(), etc.)
available, and that they all safely check for overflow and return NULL when
it would occur.

Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This commit is contained in:
Peter Jones 2020-06-15 12:15:29 -04:00 committed by Daniel Kiper
parent 68708c4503
commit 64e26162eb
7 changed files with 85 additions and 3 deletions

View file

@ -67,8 +67,10 @@
#include <grub/dl.h>
#include <grub/i18n.h>
#include <grub/mm_private.h>
#include <grub/safemath.h>
#ifdef MM_DEBUG
# undef grub_calloc
# undef grub_malloc
# undef grub_zalloc
# undef grub_realloc
@ -375,6 +377,30 @@ grub_memalign (grub_size_t align, grub_size_t size)
return 0;
}
/*
* Allocate NMEMB instances of SIZE bytes and return the pointer, or error on
* integer overflow.
*/
void *
grub_calloc (grub_size_t nmemb, grub_size_t size)
{
void *ret;
grub_size_t sz = 0;
if (grub_mul (nmemb, size, &sz))
{
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
return NULL;
}
ret = grub_memalign (0, sz);
if (!ret)
return NULL;
grub_memset (ret, 0, sz);
return ret;
}
/* Allocate SIZE bytes and return the pointer. */
void *
grub_malloc (grub_size_t size)
@ -561,6 +587,20 @@ grub_mm_dump (unsigned lineno)
grub_printf ("\n");
}
void *
grub_debug_calloc (const char *file, int line, grub_size_t nmemb, grub_size_t size)
{
void *ptr;
if (grub_mm_debug)
grub_printf ("%s:%d: calloc (0x%" PRIxGRUB_SIZE ", 0x%" PRIxGRUB_SIZE ") = ",
file, line, size);
ptr = grub_calloc (nmemb, size);
if (grub_mm_debug)
grub_printf ("%p\n", ptr);
return ptr;
}
void *
grub_debug_malloc (const char *file, int line, grub_size_t size)
{