0004-calloc-Make-sure-we-always-have-an-overflow-checking.patch 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. From 5775eb40862b67468ced816e6d7560dbe22a3670 Mon Sep 17 00:00:00 2001
  2. From: Peter Jones <pjones@redhat.com>
  3. Date: Mon, 15 Jun 2020 12:15:29 -0400
  4. Subject: [PATCH] calloc: Make sure we always have an overflow-checking
  5. calloc() available
  6. MIME-Version: 1.0
  7. Content-Type: text/plain; charset=UTF-8
  8. Content-Transfer-Encoding: 8bit
  9. This tries to make sure that everywhere in this source tree, we always have
  10. an appropriate version of calloc() (i.e. grub_calloc(), xcalloc(), etc.)
  11. available, and that they all safely check for overflow and return NULL when
  12. it would occur.
  13. Signed-off-by: Peter Jones <pjones@redhat.com>
  14. Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
  15. Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
  16. ---
  17. grub-core/kern/emu/misc.c | 12 +++++++++
  18. grub-core/kern/emu/mm.c | 10 ++++++++
  19. grub-core/kern/mm.c | 40 ++++++++++++++++++++++++++++++
  20. grub-core/lib/libgcrypt_wrap/mem.c | 11 ++++++--
  21. grub-core/lib/posix_wrap/stdlib.h | 8 +++++-
  22. include/grub/emu/misc.h | 1 +
  23. include/grub/mm.h | 6 +++++
  24. 7 files changed, 85 insertions(+), 3 deletions(-)
  25. diff --git a/grub-core/kern/emu/misc.c b/grub-core/kern/emu/misc.c
  26. index 65db79baa..dfd8a8ec4 100644
  27. --- a/grub-core/kern/emu/misc.c
  28. +++ b/grub-core/kern/emu/misc.c
  29. @@ -85,6 +85,18 @@ grub_util_error (const char *fmt, ...)
  30. exit (1);
  31. }
  32. +void *
  33. +xcalloc (grub_size_t nmemb, grub_size_t size)
  34. +{
  35. + void *p;
  36. +
  37. + p = calloc (nmemb, size);
  38. + if (!p)
  39. + grub_util_error ("%s", _("out of memory"));
  40. +
  41. + return p;
  42. +}
  43. +
  44. void *
  45. xmalloc (grub_size_t size)
  46. {
  47. diff --git a/grub-core/kern/emu/mm.c b/grub-core/kern/emu/mm.c
  48. index f262e95e3..145b01d37 100644
  49. --- a/grub-core/kern/emu/mm.c
  50. +++ b/grub-core/kern/emu/mm.c
  51. @@ -25,6 +25,16 @@
  52. #include <string.h>
  53. #include <grub/i18n.h>
  54. +void *
  55. +grub_calloc (grub_size_t nmemb, grub_size_t size)
  56. +{
  57. + void *ret;
  58. + ret = calloc (nmemb, size);
  59. + if (!ret)
  60. + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
  61. + return ret;
  62. +}
  63. +
  64. void *
  65. grub_malloc (grub_size_t size)
  66. {
  67. diff --git a/grub-core/kern/mm.c b/grub-core/kern/mm.c
  68. index ee88ff611..f2822a836 100644
  69. --- a/grub-core/kern/mm.c
  70. +++ b/grub-core/kern/mm.c
  71. @@ -67,8 +67,10 @@
  72. #include <grub/dl.h>
  73. #include <grub/i18n.h>
  74. #include <grub/mm_private.h>
  75. +#include <grub/safemath.h>
  76. #ifdef MM_DEBUG
  77. +# undef grub_calloc
  78. # undef grub_malloc
  79. # undef grub_zalloc
  80. # undef grub_realloc
  81. @@ -375,6 +377,30 @@ grub_memalign (grub_size_t align, grub_size_t size)
  82. return 0;
  83. }
  84. +/*
  85. + * Allocate NMEMB instances of SIZE bytes and return the pointer, or error on
  86. + * integer overflow.
  87. + */
  88. +void *
  89. +grub_calloc (grub_size_t nmemb, grub_size_t size)
  90. +{
  91. + void *ret;
  92. + grub_size_t sz = 0;
  93. +
  94. + if (grub_mul (nmemb, size, &sz))
  95. + {
  96. + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
  97. + return NULL;
  98. + }
  99. +
  100. + ret = grub_memalign (0, sz);
  101. + if (!ret)
  102. + return NULL;
  103. +
  104. + grub_memset (ret, 0, sz);
  105. + return ret;
  106. +}
  107. +
  108. /* Allocate SIZE bytes and return the pointer. */
  109. void *
  110. grub_malloc (grub_size_t size)
  111. @@ -561,6 +587,20 @@ grub_mm_dump (unsigned lineno)
  112. grub_printf ("\n");
  113. }
  114. +void *
  115. +grub_debug_calloc (const char *file, int line, grub_size_t nmemb, grub_size_t size)
  116. +{
  117. + void *ptr;
  118. +
  119. + if (grub_mm_debug)
  120. + grub_printf ("%s:%d: calloc (0x%" PRIxGRUB_SIZE ", 0x%" PRIxGRUB_SIZE ") = ",
  121. + file, line, size);
  122. + ptr = grub_calloc (nmemb, size);
  123. + if (grub_mm_debug)
  124. + grub_printf ("%p\n", ptr);
  125. + return ptr;
  126. +}
  127. +
  128. void *
  129. grub_debug_malloc (const char *file, int line, grub_size_t size)
  130. {
  131. diff --git a/grub-core/lib/libgcrypt_wrap/mem.c b/grub-core/lib/libgcrypt_wrap/mem.c
  132. index beeb661a3..74c6eafe5 100644
  133. --- a/grub-core/lib/libgcrypt_wrap/mem.c
  134. +++ b/grub-core/lib/libgcrypt_wrap/mem.c
  135. @@ -4,6 +4,7 @@
  136. #include <grub/crypto.h>
  137. #include <grub/dl.h>
  138. #include <grub/env.h>
  139. +#include <grub/safemath.h>
  140. GRUB_MOD_LICENSE ("GPLv3+");
  141. @@ -36,7 +37,10 @@ void *
  142. gcry_xcalloc (size_t n, size_t m)
  143. {
  144. void *ret;
  145. - ret = grub_zalloc (n * m);
  146. + size_t sz;
  147. + if (grub_mul (n, m, &sz))
  148. + grub_fatal ("gcry_xcalloc would overflow");
  149. + ret = grub_zalloc (sz);
  150. if (!ret)
  151. grub_fatal ("gcry_xcalloc failed");
  152. return ret;
  153. @@ -56,7 +60,10 @@ void *
  154. gcry_xcalloc_secure (size_t n, size_t m)
  155. {
  156. void *ret;
  157. - ret = grub_zalloc (n * m);
  158. + size_t sz;
  159. + if (grub_mul (n, m, &sz))
  160. + grub_fatal ("gcry_xcalloc would overflow");
  161. + ret = grub_zalloc (sz);
  162. if (!ret)
  163. grub_fatal ("gcry_xcalloc failed");
  164. return ret;
  165. diff --git a/grub-core/lib/posix_wrap/stdlib.h b/grub-core/lib/posix_wrap/stdlib.h
  166. index 3b46f47ff..7a8d385e9 100644
  167. --- a/grub-core/lib/posix_wrap/stdlib.h
  168. +++ b/grub-core/lib/posix_wrap/stdlib.h
  169. @@ -21,6 +21,7 @@
  170. #include <grub/mm.h>
  171. #include <grub/misc.h>
  172. +#include <grub/safemath.h>
  173. static inline void
  174. free (void *ptr)
  175. @@ -37,7 +38,12 @@ malloc (grub_size_t size)
  176. static inline void *
  177. calloc (grub_size_t size, grub_size_t nelem)
  178. {
  179. - return grub_zalloc (size * nelem);
  180. + grub_size_t sz;
  181. +
  182. + if (grub_mul (size, nelem, &sz))
  183. + return NULL;
  184. +
  185. + return grub_zalloc (sz);
  186. }
  187. static inline void *
  188. diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h
  189. index ce464cfd0..ff9c48a64 100644
  190. --- a/include/grub/emu/misc.h
  191. +++ b/include/grub/emu/misc.h
  192. @@ -47,6 +47,7 @@ grub_util_device_is_mapped (const char *dev);
  193. #define GRUB_HOST_PRIuLONG_LONG "llu"
  194. #define GRUB_HOST_PRIxLONG_LONG "llx"
  195. +void * EXPORT_FUNC(xcalloc) (grub_size_t nmemb, grub_size_t size) WARN_UNUSED_RESULT;
  196. void * EXPORT_FUNC(xmalloc) (grub_size_t size) WARN_UNUSED_RESULT;
  197. void * EXPORT_FUNC(xrealloc) (void *ptr, grub_size_t size) WARN_UNUSED_RESULT;
  198. char * EXPORT_FUNC(xstrdup) (const char *str) WARN_UNUSED_RESULT;
  199. diff --git a/include/grub/mm.h b/include/grub/mm.h
  200. index 28e2e53eb..9c38dd3ca 100644
  201. --- a/include/grub/mm.h
  202. +++ b/include/grub/mm.h
  203. @@ -29,6 +29,7 @@
  204. #endif
  205. void grub_mm_init_region (void *addr, grub_size_t size);
  206. +void *EXPORT_FUNC(grub_calloc) (grub_size_t nmemb, grub_size_t size);
  207. void *EXPORT_FUNC(grub_malloc) (grub_size_t size);
  208. void *EXPORT_FUNC(grub_zalloc) (grub_size_t size);
  209. void EXPORT_FUNC(grub_free) (void *ptr);
  210. @@ -48,6 +49,9 @@ extern int EXPORT_VAR(grub_mm_debug);
  211. void grub_mm_dump_free (void);
  212. void grub_mm_dump (unsigned lineno);
  213. +#define grub_calloc(nmemb, size) \
  214. + grub_debug_calloc (GRUB_FILE, __LINE__, nmemb, size)
  215. +
  216. #define grub_malloc(size) \
  217. grub_debug_malloc (GRUB_FILE, __LINE__, size)
  218. @@ -63,6 +67,8 @@ void grub_mm_dump (unsigned lineno);
  219. #define grub_free(ptr) \
  220. grub_debug_free (GRUB_FILE, __LINE__, ptr)
  221. +void *EXPORT_FUNC(grub_debug_calloc) (const char *file, int line,
  222. + grub_size_t nmemb, grub_size_t size);
  223. void *EXPORT_FUNC(grub_debug_malloc) (const char *file, int line,
  224. grub_size_t size);
  225. void *EXPORT_FUNC(grub_debug_zalloc) (const char *file, int line,
  226. --
  227. 2.26.2