123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- From 5775eb40862b67468ced816e6d7560dbe22a3670 Mon Sep 17 00:00:00 2001
- From: Peter Jones <pjones@redhat.com>
- Date: Mon, 15 Jun 2020 12:15:29 -0400
- Subject: [PATCH] calloc: Make sure we always have an overflow-checking
- calloc() available
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
- 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>
- Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
- ---
- grub-core/kern/emu/misc.c | 12 +++++++++
- grub-core/kern/emu/mm.c | 10 ++++++++
- grub-core/kern/mm.c | 40 ++++++++++++++++++++++++++++++
- grub-core/lib/libgcrypt_wrap/mem.c | 11 ++++++--
- grub-core/lib/posix_wrap/stdlib.h | 8 +++++-
- include/grub/emu/misc.h | 1 +
- include/grub/mm.h | 6 +++++
- 7 files changed, 85 insertions(+), 3 deletions(-)
- diff --git a/grub-core/kern/emu/misc.c b/grub-core/kern/emu/misc.c
- index 65db79baa..dfd8a8ec4 100644
- --- a/grub-core/kern/emu/misc.c
- +++ b/grub-core/kern/emu/misc.c
- @@ -85,6 +85,18 @@ grub_util_error (const char *fmt, ...)
- exit (1);
- }
-
- +void *
- +xcalloc (grub_size_t nmemb, grub_size_t size)
- +{
- + void *p;
- +
- + p = calloc (nmemb, size);
- + if (!p)
- + grub_util_error ("%s", _("out of memory"));
- +
- + return p;
- +}
- +
- void *
- xmalloc (grub_size_t size)
- {
- diff --git a/grub-core/kern/emu/mm.c b/grub-core/kern/emu/mm.c
- index f262e95e3..145b01d37 100644
- --- a/grub-core/kern/emu/mm.c
- +++ b/grub-core/kern/emu/mm.c
- @@ -25,6 +25,16 @@
- #include <string.h>
- #include <grub/i18n.h>
-
- +void *
- +grub_calloc (grub_size_t nmemb, grub_size_t size)
- +{
- + void *ret;
- + ret = calloc (nmemb, size);
- + if (!ret)
- + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
- + return ret;
- +}
- +
- void *
- grub_malloc (grub_size_t size)
- {
- diff --git a/grub-core/kern/mm.c b/grub-core/kern/mm.c
- index ee88ff611..f2822a836 100644
- --- a/grub-core/kern/mm.c
- +++ b/grub-core/kern/mm.c
- @@ -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)
- {
- diff --git a/grub-core/lib/libgcrypt_wrap/mem.c b/grub-core/lib/libgcrypt_wrap/mem.c
- index beeb661a3..74c6eafe5 100644
- --- a/grub-core/lib/libgcrypt_wrap/mem.c
- +++ b/grub-core/lib/libgcrypt_wrap/mem.c
- @@ -4,6 +4,7 @@
- #include <grub/crypto.h>
- #include <grub/dl.h>
- #include <grub/env.h>
- +#include <grub/safemath.h>
-
- GRUB_MOD_LICENSE ("GPLv3+");
-
- @@ -36,7 +37,10 @@ void *
- gcry_xcalloc (size_t n, size_t m)
- {
- void *ret;
- - ret = grub_zalloc (n * m);
- + size_t sz;
- + if (grub_mul (n, m, &sz))
- + grub_fatal ("gcry_xcalloc would overflow");
- + ret = grub_zalloc (sz);
- if (!ret)
- grub_fatal ("gcry_xcalloc failed");
- return ret;
- @@ -56,7 +60,10 @@ void *
- gcry_xcalloc_secure (size_t n, size_t m)
- {
- void *ret;
- - ret = grub_zalloc (n * m);
- + size_t sz;
- + if (grub_mul (n, m, &sz))
- + grub_fatal ("gcry_xcalloc would overflow");
- + ret = grub_zalloc (sz);
- if (!ret)
- grub_fatal ("gcry_xcalloc failed");
- return ret;
- diff --git a/grub-core/lib/posix_wrap/stdlib.h b/grub-core/lib/posix_wrap/stdlib.h
- index 3b46f47ff..7a8d385e9 100644
- --- a/grub-core/lib/posix_wrap/stdlib.h
- +++ b/grub-core/lib/posix_wrap/stdlib.h
- @@ -21,6 +21,7 @@
-
- #include <grub/mm.h>
- #include <grub/misc.h>
- +#include <grub/safemath.h>
-
- static inline void
- free (void *ptr)
- @@ -37,7 +38,12 @@ malloc (grub_size_t size)
- static inline void *
- calloc (grub_size_t size, grub_size_t nelem)
- {
- - return grub_zalloc (size * nelem);
- + grub_size_t sz;
- +
- + if (grub_mul (size, nelem, &sz))
- + return NULL;
- +
- + return grub_zalloc (sz);
- }
-
- static inline void *
- diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h
- index ce464cfd0..ff9c48a64 100644
- --- a/include/grub/emu/misc.h
- +++ b/include/grub/emu/misc.h
- @@ -47,6 +47,7 @@ grub_util_device_is_mapped (const char *dev);
- #define GRUB_HOST_PRIuLONG_LONG "llu"
- #define GRUB_HOST_PRIxLONG_LONG "llx"
-
- +void * EXPORT_FUNC(xcalloc) (grub_size_t nmemb, grub_size_t size) WARN_UNUSED_RESULT;
- void * EXPORT_FUNC(xmalloc) (grub_size_t size) WARN_UNUSED_RESULT;
- void * EXPORT_FUNC(xrealloc) (void *ptr, grub_size_t size) WARN_UNUSED_RESULT;
- char * EXPORT_FUNC(xstrdup) (const char *str) WARN_UNUSED_RESULT;
- diff --git a/include/grub/mm.h b/include/grub/mm.h
- index 28e2e53eb..9c38dd3ca 100644
- --- a/include/grub/mm.h
- +++ b/include/grub/mm.h
- @@ -29,6 +29,7 @@
- #endif
-
- void grub_mm_init_region (void *addr, grub_size_t size);
- +void *EXPORT_FUNC(grub_calloc) (grub_size_t nmemb, grub_size_t size);
- void *EXPORT_FUNC(grub_malloc) (grub_size_t size);
- void *EXPORT_FUNC(grub_zalloc) (grub_size_t size);
- void EXPORT_FUNC(grub_free) (void *ptr);
- @@ -48,6 +49,9 @@ extern int EXPORT_VAR(grub_mm_debug);
- void grub_mm_dump_free (void);
- void grub_mm_dump (unsigned lineno);
-
- +#define grub_calloc(nmemb, size) \
- + grub_debug_calloc (GRUB_FILE, __LINE__, nmemb, size)
- +
- #define grub_malloc(size) \
- grub_debug_malloc (GRUB_FILE, __LINE__, size)
-
- @@ -63,6 +67,8 @@ void grub_mm_dump (unsigned lineno);
- #define grub_free(ptr) \
- grub_debug_free (GRUB_FILE, __LINE__, ptr)
-
- +void *EXPORT_FUNC(grub_debug_calloc) (const char *file, int line,
- + grub_size_t nmemb, grub_size_t size);
- void *EXPORT_FUNC(grub_debug_malloc) (const char *file, int line,
- grub_size_t size);
- void *EXPORT_FUNC(grub_debug_zalloc) (const char *file, int line,
- --
- 2.26.2
|