]>
Commit | Line | Data |
---|---|---|
f8561a5c AF |
1 | From 705b89f19fff03054f7167e1785461492688d61b Mon Sep 17 00:00:00 2001 |
2 | From: Peter Jones <pjones@redhat.com> | |
3 | Date: Wed, 15 Apr 2020 15:45:02 -0400 | |
4 | Subject: yylex: Make lexer fatal errors actually be fatal | |
5 | ||
6 | When presented with a command that can't be tokenized to anything | |
7 | smaller than YYLMAX characters, the parser calls YY_FATAL_ERROR(errmsg), | |
8 | expecting that will stop further processing, as such: | |
9 | ||
10 | #define YY_DO_BEFORE_ACTION \ | |
11 | yyg->yytext_ptr = yy_bp; \ | |
12 | yyleng = (int) (yy_cp - yy_bp); \ | |
13 | yyg->yy_hold_char = *yy_cp; \ | |
14 | *yy_cp = '\0'; \ | |
15 | if ( yyleng >= YYLMAX ) \ | |
16 | YY_FATAL_ERROR( "token too large, exceeds YYLMAX" ); \ | |
17 | yy_flex_strncpy( yytext, yyg->yytext_ptr, yyleng + 1 , yyscanner); \ | |
18 | yyg->yy_c_buf_p = yy_cp; | |
19 | ||
20 | The code flex generates expects that YY_FATAL_ERROR() will either return | |
21 | for it or do some form of longjmp(), or handle the error in some way at | |
22 | least, and so the strncpy() call isn't in an "else" clause, and thus if | |
23 | YY_FATAL_ERROR() is *not* actually fatal, it does the call with the | |
24 | questionable limit, and predictable results ensue. | |
25 | ||
26 | Unfortunately, our implementation of YY_FATAL_ERROR() is: | |
27 | ||
28 | #define YY_FATAL_ERROR(msg) \ | |
29 | do { \ | |
30 | grub_printf (_("fatal error: %s\n"), _(msg)); \ | |
31 | } while (0) | |
32 | ||
33 | The same pattern exists in yyless(), and similar problems exist in users | |
34 | of YY_INPUT(), several places in the main parsing loop, | |
35 | yy_get_next_buffer(), yy_load_buffer_state(), yyensure_buffer_stack, | |
36 | yy_scan_buffer(), etc. | |
37 | ||
38 | All of these callers expect YY_FATAL_ERROR() to actually be fatal, and | |
39 | the things they do if it returns after calling it are wildly unsafe. | |
40 | ||
41 | Fixes: CVE-2020-10713 | |
42 | ||
43 | Signed-off-by: Peter Jones <pjones@redhat.com> | |
44 | Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> | |
45 | --- | |
46 | grub-core/script/yylex.l | 4 ++-- | |
47 | 1 file changed, 2 insertions(+), 2 deletions(-) | |
48 | ||
49 | diff --git a/grub-core/script/yylex.l b/grub-core/script/yylex.l | |
50 | index 7b44c37b7..b7203c823 100644 | |
51 | --- a/grub-core/script/yylex.l | |
52 | +++ b/grub-core/script/yylex.l | |
53 | @@ -37,11 +37,11 @@ | |
54 | ||
55 | /* | |
56 | * As we don't have access to yyscanner, we cannot do much except to | |
57 | - * print the fatal error. | |
58 | + * print the fatal error and exit. | |
59 | */ | |
60 | #define YY_FATAL_ERROR(msg) \ | |
61 | do { \ | |
62 | - grub_printf (_("fatal error: %s\n"), _(msg)); \ | |
63 | + grub_fatal (_("fatal error: %s\n"), _(msg));\ | |
64 | } while (0) | |
65 | ||
66 | #define COPY(str, hint) \ | |
67 | ||
68 | From 016977edbd5d9f6fbab6412fb8b4d1f50eb432e7 Mon Sep 17 00:00:00 2001 | |
69 | From: Peter Jones <pjones@redhat.com> | |
70 | Date: Mon, 15 Jun 2020 10:58:42 -0400 | |
71 | Subject: safemath: Add some arithmetic primitives that check for | |
72 | overflow | |
73 | ||
74 | This adds a new header, include/grub/safemath.h, that includes easy to | |
75 | use wrappers for __builtin_{add,sub,mul}_overflow() declared like: | |
76 | ||
77 | bool OP(a, b, res) | |
78 | ||
79 | where OP is grub_add, grub_sub or grub_mul. OP() returns true in the | |
80 | case where the operation would overflow and res is not modified. | |
81 | Otherwise, false is returned and the operation is executed. | |
82 | ||
83 | These arithmetic primitives require newer compiler versions. So, bump | |
84 | these requirements in the INSTALL file too. | |
85 | ||
86 | Signed-off-by: Peter Jones <pjones@redhat.com> | |
87 | Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> | |
88 | --- | |
89 | INSTALL | 22 ++-------------------- | |
90 | include/grub/compiler.h | 8 ++++++++ | |
91 | include/grub/safemath.h | 37 +++++++++++++++++++++++++++++++++++++ | |
92 | 3 files changed, 47 insertions(+), 20 deletions(-) | |
93 | create mode 100644 include/grub/safemath.h | |
94 | ||
95 | diff --git a/INSTALL b/INSTALL | |
96 | index 342c158e9..991479b52 100644 | |
97 | --- a/INSTALL | |
98 | +++ b/INSTALL | |
99 | @@ -11,27 +11,9 @@ GRUB depends on some software packages installed into your system. If | |
100 | you don't have any of them, please obtain and install them before | |
101 | configuring the GRUB. | |
102 | ||
103 | -* GCC 4.1.3 or later | |
104 | - Note: older versions may work but support is limited | |
105 | - | |
106 | - Experimental support for clang 3.3 or later (results in much bigger binaries) | |
107 | +* GCC 5.1.0 or later | |
108 | + Experimental support for clang 3.8.0 or later (results in much bigger binaries) | |
109 | for i386, x86_64, arm (including thumb), arm64, mips(el), powerpc, sparc64 | |
110 | - Note: clang 3.2 or later works for i386 and x86_64 targets but results in | |
111 | - much bigger binaries. | |
112 | - earlier versions not tested | |
113 | - Note: clang 3.2 or later works for arm | |
114 | - earlier versions not tested | |
115 | - Note: clang on arm64 is not supported due to | |
116 | - https://llvm.org/bugs/show_bug.cgi?id=26030 | |
117 | - Note: clang 3.3 or later works for mips(el) | |
118 | - earlier versions fail to generate .reginfo and hence gprel relocations | |
119 | - fail. | |
120 | - Note: clang 3.2 or later works for powerpc | |
121 | - earlier versions not tested | |
122 | - Note: clang 3.5 or later works for sparc64 | |
123 | - earlier versions return "error: unable to interface with target machine" | |
124 | - Note: clang has no support for ia64 and hence you can't compile GRUB | |
125 | - for ia64 with clang | |
126 | * GNU Make | |
127 | * GNU Bison 2.3 or later | |
128 | * GNU gettext 0.17 or later | |
129 | diff --git a/include/grub/compiler.h b/include/grub/compiler.h | |
130 | index c9e1d7a73..8f3be3ae7 100644 | |
131 | --- a/include/grub/compiler.h | |
132 | +++ b/include/grub/compiler.h | |
133 | @@ -48,4 +48,12 @@ | |
134 | # define WARN_UNUSED_RESULT | |
135 | #endif | |
136 | ||
137 | +#if defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__) | |
138 | +# define CLANG_PREREQ(maj,min) \ | |
139 | + ((__clang_major__ > (maj)) || \ | |
140 | + (__clang_major__ == (maj) && __clang_minor__ >= (min))) | |
141 | +#else | |
142 | +# define CLANG_PREREQ(maj,min) 0 | |
143 | +#endif | |
144 | + | |
145 | #endif /* ! GRUB_COMPILER_HEADER */ | |
146 | diff --git a/include/grub/safemath.h b/include/grub/safemath.h | |
147 | new file mode 100644 | |
148 | index 000000000..c17b89bba | |
149 | --- /dev/null | |
150 | +++ b/include/grub/safemath.h | |
151 | @@ -0,0 +1,37 @@ | |
152 | +/* | |
153 | + * GRUB -- GRand Unified Bootloader | |
154 | + * Copyright (C) 2020 Free Software Foundation, Inc. | |
155 | + * | |
156 | + * GRUB is free software: you can redistribute it and/or modify | |
157 | + * it under the terms of the GNU General Public License as published by | |
158 | + * the Free Software Foundation, either version 3 of the License, or | |
159 | + * (at your option) any later version. | |
160 | + * | |
161 | + * GRUB is distributed in the hope that it will be useful, | |
162 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
163 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
164 | + * GNU General Public License for more details. | |
165 | + * | |
166 | + * You should have received a copy of the GNU General Public License | |
167 | + * along with GRUB. If not, see <http://www.gnu.org/licenses/>. | |
168 | + * | |
169 | + * Arithmetic operations that protect against overflow. | |
170 | + */ | |
171 | + | |
172 | +#ifndef GRUB_SAFEMATH_H | |
173 | +#define GRUB_SAFEMATH_H 1 | |
174 | + | |
175 | +#include <grub/compiler.h> | |
176 | + | |
177 | +/* These appear in gcc 5.1 and clang 3.8. */ | |
178 | +#if GNUC_PREREQ(5, 1) || CLANG_PREREQ(3, 8) | |
179 | + | |
180 | +#define grub_add(a, b, res) __builtin_add_overflow(a, b, res) | |
181 | +#define grub_sub(a, b, res) __builtin_sub_overflow(a, b, res) | |
182 | +#define grub_mul(a, b, res) __builtin_mul_overflow(a, b, res) | |
183 | + | |
184 | +#else | |
185 | +#error gcc 5.1 or newer or clang 3.8 or newer is required | |
186 | +#endif | |
187 | + | |
188 | +#endif /* GRUB_SAFEMATH_H */ | |
189 | ||
190 | From f80ca28e207484650fc7634545cd3dc6037de3c8 Mon Sep 17 00:00:00 2001 | |
191 | From: Peter Jones <pjones@redhat.com> | |
192 | Date: Mon, 15 Jun 2020 12:15:29 -0400 | |
193 | Subject: calloc: Make sure we always have an overflow-checking | |
194 | calloc() available | |
195 | ||
196 | This tries to make sure that everywhere in this source tree, we always have | |
197 | an appropriate version of calloc() (i.e. grub_calloc(), xcalloc(), etc.) | |
198 | available, and that they all safely check for overflow and return NULL when | |
199 | it would occur. | |
200 | ||
201 | Signed-off-by: Peter Jones <pjones@redhat.com> | |
202 | Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> | |
203 | --- | |
204 | grub-core/kern/emu/misc.c | 12 +++++++++ | |
205 | grub-core/kern/emu/mm.c | 10 ++++++++ | |
206 | grub-core/kern/mm.c | 40 ++++++++++++++++++++++++++++++ | |
207 | grub-core/lib/libgcrypt_wrap/mem.c | 11 ++++++-- | |
208 | grub-core/lib/posix_wrap/stdlib.h | 8 +++++- | |
209 | include/grub/emu/misc.h | 1 + | |
210 | include/grub/mm.h | 6 +++++ | |
211 | 7 files changed, 85 insertions(+), 3 deletions(-) | |
212 | ||
213 | diff --git a/grub-core/kern/emu/misc.c b/grub-core/kern/emu/misc.c | |
214 | index 65db79baa..dfd8a8ec4 100644 | |
215 | --- a/grub-core/kern/emu/misc.c | |
216 | +++ b/grub-core/kern/emu/misc.c | |
217 | @@ -85,6 +85,18 @@ grub_util_error (const char *fmt, ...) | |
218 | exit (1); | |
219 | } | |
220 | ||
221 | +void * | |
222 | +xcalloc (grub_size_t nmemb, grub_size_t size) | |
223 | +{ | |
224 | + void *p; | |
225 | + | |
226 | + p = calloc (nmemb, size); | |
227 | + if (!p) | |
228 | + grub_util_error ("%s", _("out of memory")); | |
229 | + | |
230 | + return p; | |
231 | +} | |
232 | + | |
233 | void * | |
234 | xmalloc (grub_size_t size) | |
235 | { | |
236 | diff --git a/grub-core/kern/emu/mm.c b/grub-core/kern/emu/mm.c | |
237 | index f262e95e3..145b01d37 100644 | |
238 | --- a/grub-core/kern/emu/mm.c | |
239 | +++ b/grub-core/kern/emu/mm.c | |
240 | @@ -25,6 +25,16 @@ | |
241 | #include <string.h> | |
242 | #include <grub/i18n.h> | |
243 | ||
244 | +void * | |
245 | +grub_calloc (grub_size_t nmemb, grub_size_t size) | |
246 | +{ | |
247 | + void *ret; | |
248 | + ret = calloc (nmemb, size); | |
249 | + if (!ret) | |
250 | + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); | |
251 | + return ret; | |
252 | +} | |
253 | + | |
254 | void * | |
255 | grub_malloc (grub_size_t size) | |
256 | { | |
257 | diff --git a/grub-core/kern/mm.c b/grub-core/kern/mm.c | |
258 | index ee88ff611..f2822a836 100644 | |
259 | --- a/grub-core/kern/mm.c | |
260 | +++ b/grub-core/kern/mm.c | |
261 | @@ -67,8 +67,10 @@ | |
262 | #include <grub/dl.h> | |
263 | #include <grub/i18n.h> | |
264 | #include <grub/mm_private.h> | |
265 | +#include <grub/safemath.h> | |
266 | ||
267 | #ifdef MM_DEBUG | |
268 | +# undef grub_calloc | |
269 | # undef grub_malloc | |
270 | # undef grub_zalloc | |
271 | # undef grub_realloc | |
272 | @@ -375,6 +377,30 @@ grub_memalign (grub_size_t align, grub_size_t size) | |
273 | return 0; | |
274 | } | |
275 | ||
276 | +/* | |
277 | + * Allocate NMEMB instances of SIZE bytes and return the pointer, or error on | |
278 | + * integer overflow. | |
279 | + */ | |
280 | +void * | |
281 | +grub_calloc (grub_size_t nmemb, grub_size_t size) | |
282 | +{ | |
283 | + void *ret; | |
284 | + grub_size_t sz = 0; | |
285 | + | |
286 | + if (grub_mul (nmemb, size, &sz)) | |
287 | + { | |
288 | + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); | |
289 | + return NULL; | |
290 | + } | |
291 | + | |
292 | + ret = grub_memalign (0, sz); | |
293 | + if (!ret) | |
294 | + return NULL; | |
295 | + | |
296 | + grub_memset (ret, 0, sz); | |
297 | + return ret; | |
298 | +} | |
299 | + | |
300 | /* Allocate SIZE bytes and return the pointer. */ | |
301 | void * | |
302 | grub_malloc (grub_size_t size) | |
303 | @@ -561,6 +587,20 @@ grub_mm_dump (unsigned lineno) | |
304 | grub_printf ("\n"); | |
305 | } | |
306 | ||
307 | +void * | |
308 | +grub_debug_calloc (const char *file, int line, grub_size_t nmemb, grub_size_t size) | |
309 | +{ | |
310 | + void *ptr; | |
311 | + | |
312 | + if (grub_mm_debug) | |
313 | + grub_printf ("%s:%d: calloc (0x%" PRIxGRUB_SIZE ", 0x%" PRIxGRUB_SIZE ") = ", | |
314 | + file, line, size); | |
315 | + ptr = grub_calloc (nmemb, size); | |
316 | + if (grub_mm_debug) | |
317 | + grub_printf ("%p\n", ptr); | |
318 | + return ptr; | |
319 | +} | |
320 | + | |
321 | void * | |
322 | grub_debug_malloc (const char *file, int line, grub_size_t size) | |
323 | { | |
324 | diff --git a/grub-core/lib/libgcrypt_wrap/mem.c b/grub-core/lib/libgcrypt_wrap/mem.c | |
325 | index beeb661a3..74c6eafe5 100644 | |
326 | --- a/grub-core/lib/libgcrypt_wrap/mem.c | |
327 | +++ b/grub-core/lib/libgcrypt_wrap/mem.c | |
328 | @@ -4,6 +4,7 @@ | |
329 | #include <grub/crypto.h> | |
330 | #include <grub/dl.h> | |
331 | #include <grub/env.h> | |
332 | +#include <grub/safemath.h> | |
333 | ||
334 | GRUB_MOD_LICENSE ("GPLv3+"); | |
335 | ||
336 | @@ -36,7 +37,10 @@ void * | |
337 | gcry_xcalloc (size_t n, size_t m) | |
338 | { | |
339 | void *ret; | |
340 | - ret = grub_zalloc (n * m); | |
341 | + size_t sz; | |
342 | + if (grub_mul (n, m, &sz)) | |
343 | + grub_fatal ("gcry_xcalloc would overflow"); | |
344 | + ret = grub_zalloc (sz); | |
345 | if (!ret) | |
346 | grub_fatal ("gcry_xcalloc failed"); | |
347 | return ret; | |
348 | @@ -56,7 +60,10 @@ void * | |
349 | gcry_xcalloc_secure (size_t n, size_t m) | |
350 | { | |
351 | void *ret; | |
352 | - ret = grub_zalloc (n * m); | |
353 | + size_t sz; | |
354 | + if (grub_mul (n, m, &sz)) | |
355 | + grub_fatal ("gcry_xcalloc would overflow"); | |
356 | + ret = grub_zalloc (sz); | |
357 | if (!ret) | |
358 | grub_fatal ("gcry_xcalloc failed"); | |
359 | return ret; | |
360 | diff --git a/grub-core/lib/posix_wrap/stdlib.h b/grub-core/lib/posix_wrap/stdlib.h | |
361 | index 3b46f47ff..7a8d385e9 100644 | |
362 | --- a/grub-core/lib/posix_wrap/stdlib.h | |
363 | +++ b/grub-core/lib/posix_wrap/stdlib.h | |
364 | @@ -21,6 +21,7 @@ | |
365 | ||
366 | #include <grub/mm.h> | |
367 | #include <grub/misc.h> | |
368 | +#include <grub/safemath.h> | |
369 | ||
370 | static inline void | |
371 | free (void *ptr) | |
372 | @@ -37,7 +38,12 @@ malloc (grub_size_t size) | |
373 | static inline void * | |
374 | calloc (grub_size_t size, grub_size_t nelem) | |
375 | { | |
376 | - return grub_zalloc (size * nelem); | |
377 | + grub_size_t sz; | |
378 | + | |
379 | + if (grub_mul (size, nelem, &sz)) | |
380 | + return NULL; | |
381 | + | |
382 | + return grub_zalloc (sz); | |
383 | } | |
384 | ||
385 | static inline void * | |
386 | diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h | |
387 | index ce464cfd0..ff9c48a64 100644 | |
388 | --- a/include/grub/emu/misc.h | |
389 | +++ b/include/grub/emu/misc.h | |
390 | @@ -47,6 +47,7 @@ grub_util_device_is_mapped (const char *dev); | |
391 | #define GRUB_HOST_PRIuLONG_LONG "llu" | |
392 | #define GRUB_HOST_PRIxLONG_LONG "llx" | |
393 | ||
394 | +void * EXPORT_FUNC(xcalloc) (grub_size_t nmemb, grub_size_t size) WARN_UNUSED_RESULT; | |
395 | void * EXPORT_FUNC(xmalloc) (grub_size_t size) WARN_UNUSED_RESULT; | |
396 | void * EXPORT_FUNC(xrealloc) (void *ptr, grub_size_t size) WARN_UNUSED_RESULT; | |
397 | char * EXPORT_FUNC(xstrdup) (const char *str) WARN_UNUSED_RESULT; | |
398 | diff --git a/include/grub/mm.h b/include/grub/mm.h | |
399 | index 28e2e53eb..9c38dd3ca 100644 | |
400 | --- a/include/grub/mm.h | |
401 | +++ b/include/grub/mm.h | |
402 | @@ -29,6 +29,7 @@ | |
403 | #endif | |
404 | ||
405 | void grub_mm_init_region (void *addr, grub_size_t size); | |
406 | +void *EXPORT_FUNC(grub_calloc) (grub_size_t nmemb, grub_size_t size); | |
407 | void *EXPORT_FUNC(grub_malloc) (grub_size_t size); | |
408 | void *EXPORT_FUNC(grub_zalloc) (grub_size_t size); | |
409 | void EXPORT_FUNC(grub_free) (void *ptr); | |
410 | @@ -48,6 +49,9 @@ extern int EXPORT_VAR(grub_mm_debug); | |
411 | void grub_mm_dump_free (void); | |
412 | void grub_mm_dump (unsigned lineno); | |
413 | ||
414 | +#define grub_calloc(nmemb, size) \ | |
415 | + grub_debug_calloc (GRUB_FILE, __LINE__, nmemb, size) | |
416 | + | |
417 | #define grub_malloc(size) \ | |
418 | grub_debug_malloc (GRUB_FILE, __LINE__, size) | |
419 | ||
420 | @@ -63,6 +67,8 @@ void grub_mm_dump (unsigned lineno); | |
421 | #define grub_free(ptr) \ | |
422 | grub_debug_free (GRUB_FILE, __LINE__, ptr) | |
423 | ||
424 | +void *EXPORT_FUNC(grub_debug_calloc) (const char *file, int line, | |
425 | + grub_size_t nmemb, grub_size_t size); | |
426 | void *EXPORT_FUNC(grub_debug_malloc) (const char *file, int line, | |
427 | grub_size_t size); | |
428 | void *EXPORT_FUNC(grub_debug_zalloc) (const char *file, int line, | |
429 | ||
430 | From 65dfa11751111173ce6f492afce13d4a2c2b006c Mon Sep 17 00:00:00 2001 | |
431 | From: Peter Jones <pjones@redhat.com> | |
432 | Date: Mon, 15 Jun 2020 12:26:01 -0400 | |
433 | Subject: calloc: Use calloc() at most places | |
434 | ||
435 | This modifies most of the places we do some form of: | |
436 | ||
437 | X = malloc(Y * Z); | |
438 | ||
439 | to use calloc(Y, Z) instead. | |
440 | ||
441 | Among other issues, this fixes: | |
442 | - allocation of integer overflow in grub_png_decode_image_header() | |
443 | reported by Chris Coulson, | |
444 | - allocation of integer overflow in luks_recover_key() | |
445 | reported by Chris Coulson, | |
446 | - allocation of integer overflow in grub_lvm_detect() | |
447 | reported by Chris Coulson. | |
448 | ||
449 | Fixes: CVE-2020-14308 | |
450 | ||
451 | Signed-off-by: Peter Jones <pjones@redhat.com> | |
452 | Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> | |
453 | --- | |
454 | grub-core/bus/usb/usbhub.c | 8 ++++---- | |
455 | grub-core/commands/efi/lsefisystab.c | 3 ++- | |
456 | grub-core/commands/legacycfg.c | 6 +++--- | |
457 | grub-core/commands/menuentry.c | 2 +- | |
458 | grub-core/commands/nativedisk.c | 2 +- | |
459 | grub-core/commands/parttool.c | 12 +++++++++--- | |
460 | grub-core/commands/regexp.c | 2 +- | |
461 | grub-core/commands/search_wrap.c | 2 +- | |
462 | grub-core/disk/diskfilter.c | 4 ++-- | |
463 | grub-core/disk/ieee1275/ofdisk.c | 2 +- | |
464 | grub-core/disk/ldm.c | 14 +++++++------- | |
465 | grub-core/disk/luks.c | 2 +- | |
466 | grub-core/disk/lvm.c | 8 ++++---- | |
467 | grub-core/disk/xen/xendisk.c | 2 +- | |
468 | grub-core/efiemu/loadcore.c | 2 +- | |
469 | grub-core/efiemu/mm.c | 6 +++--- | |
470 | grub-core/font/font.c | 3 +-- | |
471 | grub-core/fs/affs.c | 6 +++--- | |
472 | grub-core/fs/btrfs.c | 6 +++--- | |
473 | grub-core/fs/hfs.c | 2 +- | |
474 | grub-core/fs/hfsplus.c | 6 +++--- | |
475 | grub-core/fs/iso9660.c | 2 +- | |
476 | grub-core/fs/ntfs.c | 4 ++-- | |
477 | grub-core/fs/sfs.c | 2 +- | |
478 | grub-core/fs/tar.c | 2 +- | |
479 | grub-core/fs/udf.c | 4 ++-- | |
480 | grub-core/fs/zfs/zfs.c | 4 ++-- | |
481 | grub-core/gfxmenu/gui_string_util.c | 2 +- | |
482 | grub-core/gfxmenu/widget-box.c | 4 ++-- | |
483 | grub-core/io/gzio.c | 2 +- | |
484 | grub-core/kern/efi/efi.c | 6 +++--- | |
485 | grub-core/kern/emu/hostdisk.c | 2 +- | |
486 | grub-core/kern/fs.c | 2 +- | |
487 | grub-core/kern/misc.c | 2 +- | |
488 | grub-core/kern/parser.c | 2 +- | |
489 | grub-core/kern/uboot/uboot.c | 2 +- | |
490 | grub-core/lib/libgcrypt/cipher/ac.c | 8 ++++---- | |
491 | grub-core/lib/libgcrypt/cipher/primegen.c | 4 ++-- | |
492 | grub-core/lib/libgcrypt/cipher/pubkey.c | 4 ++-- | |
493 | grub-core/lib/priority_queue.c | 2 +- | |
494 | grub-core/lib/reed_solomon.c | 7 +++---- | |
495 | grub-core/lib/relocator.c | 10 +++++----- | |
496 | grub-core/lib/zstd/fse_decompress.c | 2 +- | |
497 | grub-core/loader/arm/linux.c | 2 +- | |
498 | grub-core/loader/efi/chainloader.c | 2 +- | |
499 | grub-core/loader/i386/bsdXX.c | 2 +- | |
500 | grub-core/loader/i386/xnu.c | 4 ++-- | |
501 | grub-core/loader/macho.c | 2 +- | |
502 | grub-core/loader/multiboot_elfxx.c | 2 +- | |
503 | grub-core/loader/xnu.c | 2 +- | |
504 | grub-core/mmap/mmap.c | 4 ++-- | |
505 | grub-core/net/bootp.c | 2 +- | |
506 | grub-core/net/dns.c | 10 +++++----- | |
507 | grub-core/net/net.c | 4 ++-- | |
508 | grub-core/normal/charset.c | 10 +++++----- | |
509 | grub-core/normal/cmdline.c | 14 +++++++------- | |
510 | grub-core/normal/menu_entry.c | 14 +++++++------- | |
511 | grub-core/normal/menu_text.c | 4 ++-- | |
512 | grub-core/normal/term.c | 4 ++-- | |
513 | grub-core/osdep/linux/getroot.c | 6 +++--- | |
514 | grub-core/osdep/windows/getroot.c | 2 +- | |
515 | grub-core/osdep/windows/hostdisk.c | 4 ++-- | |
516 | grub-core/osdep/windows/init.c | 2 +- | |
517 | grub-core/osdep/windows/platform.c | 4 ++-- | |
518 | grub-core/osdep/windows/relpath.c | 2 +- | |
519 | grub-core/partmap/gpt.c | 2 +- | |
520 | grub-core/partmap/msdos.c | 2 +- | |
521 | grub-core/script/execute.c | 2 +- | |
522 | grub-core/tests/fake_input.c | 2 +- | |
523 | grub-core/tests/video_checksum.c | 6 +++--- | |
524 | grub-core/video/capture.c | 2 +- | |
525 | grub-core/video/emu/sdl.c | 2 +- | |
526 | grub-core/video/i386/pc/vga.c | 2 +- | |
527 | grub-core/video/readers/png.c | 2 +- | |
528 | include/grub/unicode.h | 4 ++-- | |
529 | util/getroot.c | 2 +- | |
530 | util/grub-file.c | 2 +- | |
531 | util/grub-fstest.c | 4 ++-- | |
532 | util/grub-install-common.c | 2 +- | |
533 | util/grub-install.c | 4 ++-- | |
534 | util/grub-mkimagexx.c | 6 ++---- | |
535 | util/grub-mkrescue.c | 4 ++-- | |
536 | util/grub-mkstandalone.c | 2 +- | |
537 | util/grub-pe2elf.c | 12 +++++------- | |
538 | util/grub-probe.c | 4 ++-- | |
539 | 85 files changed, 175 insertions(+), 174 deletions(-) | |
540 | ||
541 | diff --git a/grub-core/bus/usb/usbhub.c b/grub-core/bus/usb/usbhub.c | |
542 | index 34a7ff1b5..a06cce302 100644 | |
543 | --- a/grub-core/bus/usb/usbhub.c | |
544 | +++ b/grub-core/bus/usb/usbhub.c | |
545 | @@ -149,8 +149,8 @@ grub_usb_add_hub (grub_usb_device_t dev) | |
546 | grub_usb_set_configuration (dev, 1); | |
547 | ||
548 | dev->nports = hubdesc.portcnt; | |
549 | - dev->children = grub_zalloc (hubdesc.portcnt * sizeof (dev->children[0])); | |
550 | - dev->ports = grub_zalloc (dev->nports * sizeof (dev->ports[0])); | |
551 | + dev->children = grub_calloc (hubdesc.portcnt, sizeof (dev->children[0])); | |
552 | + dev->ports = grub_calloc (dev->nports, sizeof (dev->ports[0])); | |
553 | if (!dev->children || !dev->ports) | |
554 | { | |
555 | grub_free (dev->children); | |
556 | @@ -268,8 +268,8 @@ grub_usb_controller_dev_register_iter (grub_usb_controller_t controller, void *d | |
557 | ||
558 | /* Query the number of ports the root Hub has. */ | |
559 | hub->nports = controller->dev->hubports (controller); | |
560 | - hub->devices = grub_zalloc (sizeof (hub->devices[0]) * hub->nports); | |
561 | - hub->ports = grub_zalloc (sizeof (hub->ports[0]) * hub->nports); | |
562 | + hub->devices = grub_calloc (hub->nports, sizeof (hub->devices[0])); | |
563 | + hub->ports = grub_calloc (hub->nports, sizeof (hub->ports[0])); | |
564 | if (!hub->devices || !hub->ports) | |
565 | { | |
566 | grub_free (hub->devices); | |
567 | diff --git a/grub-core/commands/efi/lsefisystab.c b/grub-core/commands/efi/lsefisystab.c | |
568 | index df1030221..cd81507f5 100644 | |
569 | --- a/grub-core/commands/efi/lsefisystab.c | |
570 | +++ b/grub-core/commands/efi/lsefisystab.c | |
571 | @@ -71,7 +71,8 @@ grub_cmd_lsefisystab (struct grub_command *cmd __attribute__ ((unused)), | |
572 | grub_printf ("Vendor: "); | |
573 | ||
574 | for (vendor_utf16 = st->firmware_vendor; *vendor_utf16; vendor_utf16++); | |
575 | - vendor = grub_malloc (4 * (vendor_utf16 - st->firmware_vendor) + 1); | |
576 | + /* Allocate extra 3 bytes to simplify math. */ | |
577 | + vendor = grub_calloc (4, vendor_utf16 - st->firmware_vendor + 1); | |
578 | if (!vendor) | |
579 | return grub_errno; | |
580 | *grub_utf16_to_utf8 ((grub_uint8_t *) vendor, st->firmware_vendor, | |
581 | diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c | |
582 | index db7a8f002..5e3ec0d5e 100644 | |
583 | --- a/grub-core/commands/legacycfg.c | |
584 | +++ b/grub-core/commands/legacycfg.c | |
585 | @@ -314,7 +314,7 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)), | |
586 | if (argc < 2) | |
587 | return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); | |
588 | ||
589 | - cutargs = grub_malloc (sizeof (cutargs[0]) * (argc - 1)); | |
590 | + cutargs = grub_calloc (argc - 1, sizeof (cutargs[0])); | |
591 | if (!cutargs) | |
592 | return grub_errno; | |
593 | cutargc = argc - 1; | |
594 | @@ -436,7 +436,7 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)), | |
595 | { | |
596 | char rbuf[3] = "-r"; | |
597 | bsdargc = cutargc + 2; | |
598 | - bsdargs = grub_malloc (sizeof (bsdargs[0]) * bsdargc); | |
599 | + bsdargs = grub_calloc (bsdargc, sizeof (bsdargs[0])); | |
600 | if (!bsdargs) | |
601 | { | |
602 | err = grub_errno; | |
603 | @@ -559,7 +559,7 @@ grub_cmd_legacy_initrdnounzip (struct grub_command *mycmd __attribute__ ((unused | |
604 | return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("can't find command `%s'"), | |
605 | "module"); | |
606 | ||
607 | - newargs = grub_malloc ((argc + 1) * sizeof (newargs[0])); | |
608 | + newargs = grub_calloc (argc + 1, sizeof (newargs[0])); | |
609 | if (!newargs) | |
610 | return grub_errno; | |
611 | grub_memcpy (newargs + 1, args, argc * sizeof (newargs[0])); | |
612 | diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c | |
613 | index 2c5363da7..9164df744 100644 | |
614 | --- a/grub-core/commands/menuentry.c | |
615 | +++ b/grub-core/commands/menuentry.c | |
616 | @@ -154,7 +154,7 @@ grub_normal_add_menu_entry (int argc, const char **args, | |
617 | goto fail; | |
618 | ||
619 | /* Save argc, args to pass as parameters to block arg later. */ | |
620 | - menu_args = grub_malloc (sizeof (char*) * (argc + 1)); | |
621 | + menu_args = grub_calloc (argc + 1, sizeof (char *)); | |
622 | if (! menu_args) | |
623 | goto fail; | |
624 | ||
625 | diff --git a/grub-core/commands/nativedisk.c b/grub-core/commands/nativedisk.c | |
626 | index 699447d11..7c8f97f6a 100644 | |
627 | --- a/grub-core/commands/nativedisk.c | |
628 | +++ b/grub-core/commands/nativedisk.c | |
629 | @@ -195,7 +195,7 @@ grub_cmd_nativedisk (grub_command_t cmd __attribute__ ((unused)), | |
630 | else | |
631 | path_prefix = prefix; | |
632 | ||
633 | - mods = grub_malloc (argc * sizeof (mods[0])); | |
634 | + mods = grub_calloc (argc, sizeof (mods[0])); | |
635 | if (!mods) | |
636 | return grub_errno; | |
637 | ||
638 | diff --git a/grub-core/commands/parttool.c b/grub-core/commands/parttool.c | |
639 | index 22b46b187..051e31320 100644 | |
640 | --- a/grub-core/commands/parttool.c | |
641 | +++ b/grub-core/commands/parttool.c | |
642 | @@ -59,7 +59,13 @@ grub_parttool_register(const char *part_name, | |
643 | for (nargs = 0; args[nargs].name != 0; nargs++); | |
644 | cur->nargs = nargs; | |
645 | cur->args = (struct grub_parttool_argdesc *) | |
646 | - grub_malloc ((nargs + 1) * sizeof (struct grub_parttool_argdesc)); | |
647 | + grub_calloc (nargs + 1, sizeof (struct grub_parttool_argdesc)); | |
648 | + if (!cur->args) | |
649 | + { | |
650 | + grub_free (cur); | |
651 | + curhandle--; | |
652 | + return -1; | |
653 | + } | |
654 | grub_memcpy (cur->args, args, | |
655 | (nargs + 1) * sizeof (struct grub_parttool_argdesc)); | |
656 | ||
657 | @@ -257,7 +263,7 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)), | |
658 | return err; | |
659 | } | |
660 | ||
661 | - parsed = (int *) grub_zalloc (argc * sizeof (int)); | |
662 | + parsed = (int *) grub_calloc (argc, sizeof (int)); | |
663 | ||
664 | for (i = 1; i < argc; i++) | |
665 | if (! parsed[i]) | |
666 | @@ -290,7 +296,7 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)), | |
667 | } | |
668 | ptool = cur; | |
669 | pargs = (struct grub_parttool_args *) | |
670 | - grub_zalloc (ptool->nargs * sizeof (struct grub_parttool_args)); | |
671 | + grub_calloc (ptool->nargs, sizeof (struct grub_parttool_args)); | |
672 | for (j = i; j < argc; j++) | |
673 | if (! parsed[j]) | |
674 | { | |
675 | diff --git a/grub-core/commands/regexp.c b/grub-core/commands/regexp.c | |
676 | index f00b184c8..4019164f3 100644 | |
677 | --- a/grub-core/commands/regexp.c | |
678 | +++ b/grub-core/commands/regexp.c | |
679 | @@ -116,7 +116,7 @@ grub_cmd_regexp (grub_extcmd_context_t ctxt, int argc, char **args) | |
680 | if (ret) | |
681 | goto fail; | |
682 | ||
683 | - matches = grub_zalloc (sizeof (*matches) * (regex.re_nsub + 1)); | |
684 | + matches = grub_calloc (regex.re_nsub + 1, sizeof (*matches)); | |
685 | if (! matches) | |
686 | goto fail; | |
687 | ||
688 | diff --git a/grub-core/commands/search_wrap.c b/grub-core/commands/search_wrap.c | |
689 | index d7fd26b94..47fc8eb99 100644 | |
690 | --- a/grub-core/commands/search_wrap.c | |
691 | +++ b/grub-core/commands/search_wrap.c | |
692 | @@ -122,7 +122,7 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args) | |
693 | for (i = 0; state[SEARCH_HINT_BAREMETAL].args[i]; i++) | |
694 | nhints++; | |
695 | ||
696 | - hints = grub_malloc (sizeof (hints[0]) * nhints); | |
697 | + hints = grub_calloc (nhints, sizeof (hints[0])); | |
698 | if (!hints) | |
699 | return grub_errno; | |
700 | j = 0; | |
701 | diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c | |
702 | index c3b578acf..68ca9e0be 100644 | |
703 | --- a/grub-core/disk/diskfilter.c | |
704 | +++ b/grub-core/disk/diskfilter.c | |
705 | @@ -1134,7 +1134,7 @@ grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb, | |
706 | array->lvs->segments->node_count = nmemb; | |
707 | array->lvs->segments->raid_member_size = disk_size; | |
708 | array->lvs->segments->nodes | |
709 | - = grub_zalloc (nmemb * sizeof (array->lvs->segments->nodes[0])); | |
710 | + = grub_calloc (nmemb, sizeof (array->lvs->segments->nodes[0])); | |
711 | array->lvs->segments->stripe_size = stripe_size; | |
712 | for (i = 0; i < nmemb; i++) | |
713 | { | |
714 | @@ -1226,7 +1226,7 @@ insert_array (grub_disk_t disk, const struct grub_diskfilter_pv_id *id, | |
715 | grub_partition_t p; | |
716 | for (p = disk->partition; p; p = p->parent) | |
717 | s++; | |
718 | - pv->partmaps = xmalloc (s * sizeof (pv->partmaps[0])); | |
719 | + pv->partmaps = xcalloc (s, sizeof (pv->partmaps[0])); | |
720 | s = 0; | |
721 | for (p = disk->partition; p; p = p->parent) | |
722 | pv->partmaps[s++] = xstrdup (p->partmap->name); | |
723 | diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c | |
724 | index f73257e66..03674cb47 100644 | |
725 | --- a/grub-core/disk/ieee1275/ofdisk.c | |
726 | +++ b/grub-core/disk/ieee1275/ofdisk.c | |
727 | @@ -297,7 +297,7 @@ dev_iterate (const struct grub_ieee1275_devalias *alias) | |
728 | /* Power machines documentation specify 672 as maximum SAS disks in | |
729 | one system. Using a slightly larger value to be safe. */ | |
730 | table_size = 768; | |
731 | - table = grub_malloc (table_size * sizeof (grub_uint64_t)); | |
732 | + table = grub_calloc (table_size, sizeof (grub_uint64_t)); | |
733 | ||
734 | if (!table) | |
735 | { | |
736 | diff --git a/grub-core/disk/ldm.c b/grub-core/disk/ldm.c | |
737 | index 2a22d2d6c..e6323701a 100644 | |
738 | --- a/grub-core/disk/ldm.c | |
739 | +++ b/grub-core/disk/ldm.c | |
740 | @@ -323,8 +323,8 @@ make_vg (grub_disk_t disk, | |
741 | lv->segments->type = GRUB_DISKFILTER_MIRROR; | |
742 | lv->segments->node_count = 0; | |
743 | lv->segments->node_alloc = 8; | |
744 | - lv->segments->nodes = grub_zalloc (sizeof (*lv->segments->nodes) | |
745 | - * lv->segments->node_alloc); | |
746 | + lv->segments->nodes = grub_calloc (lv->segments->node_alloc, | |
747 | + sizeof (*lv->segments->nodes)); | |
748 | if (!lv->segments->nodes) | |
749 | goto fail2; | |
750 | ptr = vblk[i].dynamic; | |
751 | @@ -543,8 +543,8 @@ make_vg (grub_disk_t disk, | |
752 | { | |
753 | comp->segment_alloc = 8; | |
754 | comp->segment_count = 0; | |
755 | - comp->segments = grub_malloc (sizeof (*comp->segments) | |
756 | - * comp->segment_alloc); | |
757 | + comp->segments = grub_calloc (comp->segment_alloc, | |
758 | + sizeof (*comp->segments)); | |
759 | if (!comp->segments) | |
760 | goto fail2; | |
761 | } | |
762 | @@ -590,8 +590,8 @@ make_vg (grub_disk_t disk, | |
763 | } | |
764 | comp->segments->node_count = read_int (ptr + 1, *ptr); | |
765 | comp->segments->node_alloc = comp->segments->node_count; | |
766 | - comp->segments->nodes = grub_zalloc (sizeof (*comp->segments->nodes) | |
767 | - * comp->segments->node_alloc); | |
768 | + comp->segments->nodes = grub_calloc (comp->segments->node_alloc, | |
769 | + sizeof (*comp->segments->nodes)); | |
770 | if (!lv->segments->nodes) | |
771 | goto fail2; | |
772 | } | |
773 | @@ -1017,7 +1017,7 @@ grub_util_ldm_embed (struct grub_disk *disk, unsigned int *nsectors, | |
774 | *nsectors = lv->size; | |
775 | if (*nsectors > max_nsectors) | |
776 | *nsectors = max_nsectors; | |
777 | - *sectors = grub_malloc (*nsectors * sizeof (**sectors)); | |
778 | + *sectors = grub_calloc (*nsectors, sizeof (**sectors)); | |
779 | if (!*sectors) | |
780 | return grub_errno; | |
781 | for (i = 0; i < *nsectors; i++) | |
782 | diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c | |
783 | index 86c50c612..18b3a8bb1 100644 | |
784 | --- a/grub-core/disk/luks.c | |
785 | +++ b/grub-core/disk/luks.c | |
786 | @@ -336,7 +336,7 @@ luks_recover_key (grub_disk_t source, | |
787 | && grub_be_to_cpu32 (header.keyblock[i].stripes) > max_stripes) | |
788 | max_stripes = grub_be_to_cpu32 (header.keyblock[i].stripes); | |
789 | ||
790 | - split_key = grub_malloc (keysize * max_stripes); | |
791 | + split_key = grub_calloc (keysize, max_stripes); | |
792 | if (!split_key) | |
793 | return grub_errno; | |
794 | ||
795 | diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c | |
796 | index 7b265c780..d1df640b3 100644 | |
797 | --- a/grub-core/disk/lvm.c | |
798 | +++ b/grub-core/disk/lvm.c | |
799 | @@ -173,7 +173,7 @@ grub_lvm_detect (grub_disk_t disk, | |
800 | first one. */ | |
801 | ||
802 | /* Allocate buffer space for the circular worst-case scenario. */ | |
803 | - metadatabuf = grub_malloc (2 * mda_size); | |
804 | + metadatabuf = grub_calloc (2, mda_size); | |
805 | if (! metadatabuf) | |
806 | goto fail; | |
807 | ||
808 | @@ -426,7 +426,7 @@ grub_lvm_detect (grub_disk_t disk, | |
809 | #endif | |
810 | goto lvs_fail; | |
811 | } | |
812 | - lv->segments = grub_zalloc (sizeof (*seg) * lv->segment_count); | |
813 | + lv->segments = grub_calloc (lv->segment_count, sizeof (*seg)); | |
814 | seg = lv->segments; | |
815 | ||
816 | for (i = 0; i < lv->segment_count; i++) | |
817 | @@ -483,8 +483,8 @@ grub_lvm_detect (grub_disk_t disk, | |
818 | if (seg->node_count != 1) | |
819 | seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = "); | |
820 | ||
821 | - seg->nodes = grub_zalloc (sizeof (*stripe) | |
822 | - * seg->node_count); | |
823 | + seg->nodes = grub_calloc (seg->node_count, | |
824 | + sizeof (*stripe)); | |
825 | stripe = seg->nodes; | |
826 | ||
827 | p = grub_strstr (p, "stripes = ["); | |
828 | diff --git a/grub-core/disk/xen/xendisk.c b/grub-core/disk/xen/xendisk.c | |
829 | index 48476cbbf..d6612eebd 100644 | |
830 | --- a/grub-core/disk/xen/xendisk.c | |
831 | +++ b/grub-core/disk/xen/xendisk.c | |
832 | @@ -426,7 +426,7 @@ grub_xendisk_init (void) | |
833 | if (!ctr) | |
834 | return; | |
835 | ||
836 | - virtdisks = grub_malloc (ctr * sizeof (virtdisks[0])); | |
837 | + virtdisks = grub_calloc (ctr, sizeof (virtdisks[0])); | |
838 | if (!virtdisks) | |
839 | return; | |
840 | if (grub_xenstore_dir ("device/vbd", fill, &ctr)) | |
841 | diff --git a/grub-core/efiemu/loadcore.c b/grub-core/efiemu/loadcore.c | |
842 | index 44085ef81..2b924623f 100644 | |
843 | --- a/grub-core/efiemu/loadcore.c | |
844 | +++ b/grub-core/efiemu/loadcore.c | |
845 | @@ -201,7 +201,7 @@ grub_efiemu_count_symbols (const Elf_Ehdr *e) | |
846 | ||
847 | grub_efiemu_nelfsyms = (unsigned) s->sh_size / (unsigned) s->sh_entsize; | |
848 | grub_efiemu_elfsyms = (struct grub_efiemu_elf_sym *) | |
849 | - grub_malloc (sizeof (struct grub_efiemu_elf_sym) * grub_efiemu_nelfsyms); | |
850 | + grub_calloc (grub_efiemu_nelfsyms, sizeof (struct grub_efiemu_elf_sym)); | |
851 | ||
852 | /* Relocators */ | |
853 | for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); | |
854 | diff --git a/grub-core/efiemu/mm.c b/grub-core/efiemu/mm.c | |
855 | index 52a032f7b..9b8e0d0ad 100644 | |
856 | --- a/grub-core/efiemu/mm.c | |
857 | +++ b/grub-core/efiemu/mm.c | |
858 | @@ -554,11 +554,11 @@ grub_efiemu_mmap_sort_and_uniq (void) | |
859 | /* Initialize variables*/ | |
860 | grub_memset (present, 0, sizeof (int) * GRUB_EFI_MAX_MEMORY_TYPE); | |
861 | scanline_events = (struct grub_efiemu_mmap_scan *) | |
862 | - grub_malloc (sizeof (struct grub_efiemu_mmap_scan) * 2 * mmap_num); | |
863 | + grub_calloc (mmap_num, sizeof (struct grub_efiemu_mmap_scan) * 2); | |
864 | ||
865 | /* Number of chunks can't increase more than by factor of 2 */ | |
866 | result = (grub_efi_memory_descriptor_t *) | |
867 | - grub_malloc (sizeof (grub_efi_memory_descriptor_t) * 2 * mmap_num); | |
868 | + grub_calloc (mmap_num, sizeof (grub_efi_memory_descriptor_t) * 2); | |
869 | if (!result || !scanline_events) | |
870 | { | |
871 | grub_free (result); | |
872 | @@ -660,7 +660,7 @@ grub_efiemu_mm_do_alloc (void) | |
873 | ||
874 | /* Preallocate mmap */ | |
875 | efiemu_mmap = (grub_efi_memory_descriptor_t *) | |
876 | - grub_malloc (mmap_reserved_size * sizeof (grub_efi_memory_descriptor_t)); | |
877 | + grub_calloc (mmap_reserved_size, sizeof (grub_efi_memory_descriptor_t)); | |
878 | if (!efiemu_mmap) | |
879 | { | |
880 | grub_efiemu_unload (); | |
881 | diff --git a/grub-core/font/font.c b/grub-core/font/font.c | |
882 | index 85a292557..8e118b315 100644 | |
883 | --- a/grub-core/font/font.c | |
884 | +++ b/grub-core/font/font.c | |
885 | @@ -293,8 +293,7 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct | |
886 | font->num_chars = sect_length / FONT_CHAR_INDEX_ENTRY_SIZE; | |
887 | ||
888 | /* Allocate the character index array. */ | |
889 | - font->char_index = grub_malloc (font->num_chars | |
890 | - * sizeof (struct char_index_entry)); | |
891 | + font->char_index = grub_calloc (font->num_chars, sizeof (struct char_index_entry)); | |
892 | if (!font->char_index) | |
893 | return 1; | |
894 | font->bmp_idx = grub_malloc (0x10000 * sizeof (grub_uint16_t)); | |
895 | diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c | |
896 | index 6b6a2bc91..220b3712f 100644 | |
897 | --- a/grub-core/fs/affs.c | |
898 | +++ b/grub-core/fs/affs.c | |
899 | @@ -301,7 +301,7 @@ grub_affs_read_symlink (grub_fshelp_node_t node) | |
900 | return 0; | |
901 | } | |
902 | latin1[symlink_size] = 0; | |
903 | - utf8 = grub_malloc (symlink_size * GRUB_MAX_UTF8_PER_LATIN1 + 1); | |
904 | + utf8 = grub_calloc (GRUB_MAX_UTF8_PER_LATIN1 + 1, symlink_size); | |
905 | if (!utf8) | |
906 | { | |
907 | grub_free (latin1); | |
908 | @@ -422,7 +422,7 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir, | |
909 | return 1; | |
910 | } | |
911 | ||
912 | - hashtable = grub_zalloc (data->htsize * sizeof (*hashtable)); | |
913 | + hashtable = grub_calloc (data->htsize, sizeof (*hashtable)); | |
914 | if (!hashtable) | |
915 | return 1; | |
916 | ||
917 | @@ -628,7 +628,7 @@ grub_affs_label (grub_device_t device, char **label) | |
918 | len = file.namelen; | |
919 | if (len > sizeof (file.name)) | |
920 | len = sizeof (file.name); | |
921 | - *label = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1); | |
922 | + *label = grub_calloc (GRUB_MAX_UTF8_PER_LATIN1 + 1, len); | |
923 | if (*label) | |
924 | *grub_latin1_to_utf8 ((grub_uint8_t *) *label, file.name, len) = '\0'; | |
925 | } | |
926 | diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c | |
927 | index 63f9657a6..4b8380439 100644 | |
928 | --- a/grub-core/fs/btrfs.c | |
929 | +++ b/grub-core/fs/btrfs.c | |
930 | @@ -415,7 +415,7 @@ lower_bound (struct grub_btrfs_data *data, | |
931 | { | |
932 | desc->allocated = 16; | |
933 | desc->depth = 0; | |
934 | - desc->data = grub_malloc (sizeof (desc->data[0]) * desc->allocated); | |
935 | + desc->data = grub_calloc (desc->allocated, sizeof (desc->data[0])); | |
936 | if (!desc->data) | |
937 | return grub_errno; | |
938 | } | |
939 | @@ -754,7 +754,7 @@ raid56_read_retry (struct grub_btrfs_data *data, | |
940 | grub_err_t ret = GRUB_ERR_OUT_OF_MEMORY; | |
941 | grub_uint64_t i, failed_devices; | |
942 | ||
943 | - buffers = grub_zalloc (sizeof(*buffers) * nstripes); | |
944 | + buffers = grub_calloc (nstripes, sizeof (*buffers)); | |
945 | if (!buffers) | |
946 | goto cleanup; | |
947 | ||
948 | @@ -2167,7 +2167,7 @@ grub_btrfs_embed (grub_device_t device __attribute__ ((unused)), | |
949 | *nsectors = 64 * 2 - 1; | |
950 | if (*nsectors > max_nsectors) | |
951 | *nsectors = max_nsectors; | |
952 | - *sectors = grub_malloc (*nsectors * sizeof (**sectors)); | |
953 | + *sectors = grub_calloc (*nsectors, sizeof (**sectors)); | |
954 | if (!*sectors) | |
955 | return grub_errno; | |
956 | for (i = 0; i < *nsectors; i++) | |
957 | diff --git a/grub-core/fs/hfs.c b/grub-core/fs/hfs.c | |
958 | index ac0a40990..3fe842b4d 100644 | |
959 | --- a/grub-core/fs/hfs.c | |
960 | +++ b/grub-core/fs/hfs.c | |
961 | @@ -1360,7 +1360,7 @@ grub_hfs_label (grub_device_t device, char **label) | |
962 | grub_size_t len = data->sblock.volname[0]; | |
963 | if (len > sizeof (data->sblock.volname) - 1) | |
964 | len = sizeof (data->sblock.volname) - 1; | |
965 | - *label = grub_malloc (len * MAX_UTF8_PER_MAC_ROMAN + 1); | |
966 | + *label = grub_calloc (MAX_UTF8_PER_MAC_ROMAN + 1, len); | |
967 | if (*label) | |
968 | macroman_to_utf8 (*label, data->sblock.volname + 1, | |
969 | len + 1, 0); | |
970 | diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c | |
971 | index 54786bb1c..dae43becc 100644 | |
972 | --- a/grub-core/fs/hfsplus.c | |
973 | +++ b/grub-core/fs/hfsplus.c | |
974 | @@ -720,7 +720,7 @@ list_nodes (void *record, void *hook_arg) | |
975 | if (! filename) | |
976 | return 0; | |
977 | ||
978 | - keyname = grub_malloc (grub_be_to_cpu16 (catkey->namelen) * sizeof (*keyname)); | |
979 | + keyname = grub_calloc (grub_be_to_cpu16 (catkey->namelen), sizeof (*keyname)); | |
980 | if (!keyname) | |
981 | { | |
982 | grub_free (filename); | |
983 | @@ -1007,7 +1007,7 @@ grub_hfsplus_label (grub_device_t device, char **label) | |
984 | grub_hfsplus_btree_recptr (&data->catalog_tree, node, ptr); | |
985 | ||
986 | label_len = grub_be_to_cpu16 (catkey->namelen); | |
987 | - label_name = grub_malloc (label_len * sizeof (*label_name)); | |
988 | + label_name = grub_calloc (label_len, sizeof (*label_name)); | |
989 | if (!label_name) | |
990 | { | |
991 | grub_free (node); | |
992 | @@ -1029,7 +1029,7 @@ grub_hfsplus_label (grub_device_t device, char **label) | |
993 | } | |
994 | } | |
995 | ||
996 | - *label = grub_malloc (label_len * GRUB_MAX_UTF8_PER_UTF16 + 1); | |
997 | + *label = grub_calloc (label_len, GRUB_MAX_UTF8_PER_UTF16 + 1); | |
998 | if (! *label) | |
999 | { | |
1000 | grub_free (label_name); | |
1001 | diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c | |
1002 | index 49c0c632b..4f1b52a55 100644 | |
1003 | --- a/grub-core/fs/iso9660.c | |
1004 | +++ b/grub-core/fs/iso9660.c | |
1005 | @@ -331,7 +331,7 @@ grub_iso9660_convert_string (grub_uint8_t *us, int len) | |
1006 | int i; | |
1007 | grub_uint16_t t[MAX_NAMELEN / 2 + 1]; | |
1008 | ||
1009 | - p = grub_malloc (len * GRUB_MAX_UTF8_PER_UTF16 + 1); | |
1010 | + p = grub_calloc (len, GRUB_MAX_UTF8_PER_UTF16 + 1); | |
1011 | if (! p) | |
1012 | return NULL; | |
1013 | ||
1014 | diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c | |
1015 | index fc4e1f678..2f34f76da 100644 | |
1016 | --- a/grub-core/fs/ntfs.c | |
1017 | +++ b/grub-core/fs/ntfs.c | |
1018 | @@ -556,8 +556,8 @@ get_utf8 (grub_uint8_t *in, grub_size_t len) | |
1019 | grub_uint16_t *tmp; | |
1020 | grub_size_t i; | |
1021 | ||
1022 | - buf = grub_malloc (len * GRUB_MAX_UTF8_PER_UTF16 + 1); | |
1023 | - tmp = grub_malloc (len * sizeof (tmp[0])); | |
1024 | + buf = grub_calloc (len, GRUB_MAX_UTF8_PER_UTF16 + 1); | |
1025 | + tmp = grub_calloc (len, sizeof (tmp[0])); | |
1026 | if (!buf || !tmp) | |
1027 | { | |
1028 | grub_free (buf); | |
1029 | diff --git a/grub-core/fs/sfs.c b/grub-core/fs/sfs.c | |
1030 | index 50c1fe72f..90f7fb379 100644 | |
1031 | --- a/grub-core/fs/sfs.c | |
1032 | +++ b/grub-core/fs/sfs.c | |
1033 | @@ -266,7 +266,7 @@ grub_sfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) | |
1034 | node->next_extent = node->block; | |
1035 | node->cache_size = 0; | |
1036 | ||
1037 | - node->cache = grub_malloc (sizeof (node->cache[0]) * cache_size); | |
1038 | + node->cache = grub_calloc (cache_size, sizeof (node->cache[0])); | |
1039 | if (!node->cache) | |
1040 | { | |
1041 | grub_errno = 0; | |
1042 | diff --git a/grub-core/fs/tar.c b/grub-core/fs/tar.c | |
1043 | index 7d63e0c99..c551ed6b5 100644 | |
1044 | --- a/grub-core/fs/tar.c | |
1045 | +++ b/grub-core/fs/tar.c | |
1046 | @@ -120,7 +120,7 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name, | |
1047 | if (data->linkname_alloc < linksize + 1) | |
1048 | { | |
1049 | char *n; | |
1050 | - n = grub_malloc (2 * (linksize + 1)); | |
1051 | + n = grub_calloc (2, linksize + 1); | |
1052 | if (!n) | |
1053 | return grub_errno; | |
1054 | grub_free (data->linkname); | |
1055 | diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c | |
1056 | index dc8b6e2d1..a83761674 100644 | |
1057 | --- a/grub-core/fs/udf.c | |
1058 | +++ b/grub-core/fs/udf.c | |
1059 | @@ -873,7 +873,7 @@ read_string (const grub_uint8_t *raw, grub_size_t sz, char *outbuf) | |
1060 | { | |
1061 | unsigned i; | |
1062 | utf16len = sz - 1; | |
1063 | - utf16 = grub_malloc (utf16len * sizeof (utf16[0])); | |
1064 | + utf16 = grub_calloc (utf16len, sizeof (utf16[0])); | |
1065 | if (!utf16) | |
1066 | return NULL; | |
1067 | for (i = 0; i < utf16len; i++) | |
1068 | @@ -883,7 +883,7 @@ read_string (const grub_uint8_t *raw, grub_size_t sz, char *outbuf) | |
1069 | { | |
1070 | unsigned i; | |
1071 | utf16len = (sz - 1) / 2; | |
1072 | - utf16 = grub_malloc (utf16len * sizeof (utf16[0])); | |
1073 | + utf16 = grub_calloc (utf16len, sizeof (utf16[0])); | |
1074 | if (!utf16) | |
1075 | return NULL; | |
1076 | for (i = 0; i < utf16len; i++) | |
1077 | diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c | |
1078 | index 2f72e42bf..381dde556 100644 | |
1079 | --- a/grub-core/fs/zfs/zfs.c | |
1080 | +++ b/grub-core/fs/zfs/zfs.c | |
1081 | @@ -3325,7 +3325,7 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, | |
1082 | } | |
1083 | subvol->nkeys = 0; | |
1084 | zap_iterate (&keychain_dn, 8, count_zap_keys, &ctx, data); | |
1085 | - subvol->keyring = grub_zalloc (subvol->nkeys * sizeof (subvol->keyring[0])); | |
1086 | + subvol->keyring = grub_calloc (subvol->nkeys, sizeof (subvol->keyring[0])); | |
1087 | if (!subvol->keyring) | |
1088 | { | |
1089 | grub_free (fsname); | |
1090 | @@ -4336,7 +4336,7 @@ grub_zfs_embed (grub_device_t device __attribute__ ((unused)), | |
1091 | *nsectors = (VDEV_BOOT_SIZE >> GRUB_DISK_SECTOR_BITS); | |
1092 | if (*nsectors > max_nsectors) | |
1093 | *nsectors = max_nsectors; | |
1094 | - *sectors = grub_malloc (*nsectors * sizeof (**sectors)); | |
1095 | + *sectors = grub_calloc (*nsectors, sizeof (**sectors)); | |
1096 | if (!*sectors) | |
1097 | return grub_errno; | |
1098 | for (i = 0; i < *nsectors; i++) | |
1099 | diff --git a/grub-core/gfxmenu/gui_string_util.c b/grub-core/gfxmenu/gui_string_util.c | |
1100 | index a9a415e31..ba1e1eab3 100644 | |
1101 | --- a/grub-core/gfxmenu/gui_string_util.c | |
1102 | +++ b/grub-core/gfxmenu/gui_string_util.c | |
1103 | @@ -55,7 +55,7 @@ canonicalize_path (const char *path) | |
1104 | if (*p == '/') | |
1105 | components++; | |
1106 | ||
1107 | - char **path_array = grub_malloc (components * sizeof (*path_array)); | |
1108 | + char **path_array = grub_calloc (components, sizeof (*path_array)); | |
1109 | if (! path_array) | |
1110 | return 0; | |
1111 | ||
1112 | diff --git a/grub-core/gfxmenu/widget-box.c b/grub-core/gfxmenu/widget-box.c | |
1113 | index b60602889..470597ded 100644 | |
1114 | --- a/grub-core/gfxmenu/widget-box.c | |
1115 | +++ b/grub-core/gfxmenu/widget-box.c | |
1116 | @@ -303,10 +303,10 @@ grub_gfxmenu_create_box (const char *pixmaps_prefix, | |
1117 | box->content_height = 0; | |
1118 | box->raw_pixmaps = | |
1119 | (struct grub_video_bitmap **) | |
1120 | - grub_malloc (BOX_NUM_PIXMAPS * sizeof (struct grub_video_bitmap *)); | |
1121 | + grub_calloc (BOX_NUM_PIXMAPS, sizeof (struct grub_video_bitmap *)); | |
1122 | box->scaled_pixmaps = | |
1123 | (struct grub_video_bitmap **) | |
1124 | - grub_malloc (BOX_NUM_PIXMAPS * sizeof (struct grub_video_bitmap *)); | |
1125 | + grub_calloc (BOX_NUM_PIXMAPS, sizeof (struct grub_video_bitmap *)); | |
1126 | ||
1127 | /* Initialize all pixmap pointers to NULL so that proper destruction can | |
1128 | be performed if an error is encountered partway through construction. */ | |
1129 | diff --git a/grub-core/io/gzio.c b/grub-core/io/gzio.c | |
1130 | index 6208a9763..43d98a7bd 100644 | |
1131 | --- a/grub-core/io/gzio.c | |
1132 | +++ b/grub-core/io/gzio.c | |
1133 | @@ -554,7 +554,7 @@ huft_build (unsigned *b, /* code lengths in bits (all assumed <= BMAX) */ | |
1134 | z = 1 << j; /* table entries for j-bit table */ | |
1135 | ||
1136 | /* allocate and link in new table */ | |
1137 | - q = (struct huft *) grub_zalloc ((z + 1) * sizeof (struct huft)); | |
1138 | + q = (struct huft *) grub_calloc (z + 1, sizeof (struct huft)); | |
1139 | if (! q) | |
1140 | { | |
1141 | if (h) | |
1142 | diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c | |
1143 | index 96204e39b..ad170c7ce 100644 | |
1144 | --- a/grub-core/kern/efi/efi.c | |
1145 | +++ b/grub-core/kern/efi/efi.c | |
1146 | @@ -202,7 +202,7 @@ grub_efi_set_variable(const char *var, const grub_efi_guid_t *guid, | |
1147 | ||
1148 | len = grub_strlen (var); | |
1149 | len16 = len * GRUB_MAX_UTF16_PER_UTF8; | |
1150 | - var16 = grub_malloc ((len16 + 1) * sizeof (var16[0])); | |
1151 | + var16 = grub_calloc (len16 + 1, sizeof (var16[0])); | |
1152 | if (!var16) | |
1153 | return grub_errno; | |
1154 | len16 = grub_utf8_to_utf16 (var16, len16, (grub_uint8_t *) var, len, NULL); | |
1155 | @@ -237,7 +237,7 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid, | |
1156 | ||
1157 | len = grub_strlen (var); | |
1158 | len16 = len * GRUB_MAX_UTF16_PER_UTF8; | |
1159 | - var16 = grub_malloc ((len16 + 1) * sizeof (var16[0])); | |
1160 | + var16 = grub_calloc (len16 + 1, sizeof (var16[0])); | |
1161 | if (!var16) | |
1162 | return NULL; | |
1163 | len16 = grub_utf8_to_utf16 (var16, len16, (grub_uint8_t *) var, len, NULL); | |
1164 | @@ -411,7 +411,7 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0) | |
1165 | while (len > 0 && fp->path_name[len - 1] == 0) | |
1166 | len--; | |
1167 | ||
1168 | - dup_name = grub_malloc (len * sizeof (*dup_name)); | |
1169 | + dup_name = grub_calloc (len, sizeof (*dup_name)); | |
1170 | if (!dup_name) | |
1171 | { | |
1172 | grub_free (name); | |
1173 | diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c | |
1174 | index 8ac523953..f90b6c9ce 100644 | |
1175 | --- a/grub-core/kern/emu/hostdisk.c | |
1176 | +++ b/grub-core/kern/emu/hostdisk.c | |
1177 | @@ -627,7 +627,7 @@ static char * | |
1178 | grub_util_path_concat_real (size_t n, int ext, va_list ap) | |
1179 | { | |
1180 | size_t totlen = 0; | |
1181 | - char **l = xmalloc ((n + ext) * sizeof (l[0])); | |
1182 | + char **l = xcalloc (n + ext, sizeof (l[0])); | |
1183 | char *r, *p, *pi; | |
1184 | size_t i; | |
1185 | int first = 1; | |
1186 | diff --git a/grub-core/kern/fs.c b/grub-core/kern/fs.c | |
1187 | index 2b85f4950..f90be6566 100644 | |
1188 | --- a/grub-core/kern/fs.c | |
1189 | +++ b/grub-core/kern/fs.c | |
1190 | @@ -151,7 +151,7 @@ grub_fs_blocklist_open (grub_file_t file, const char *name) | |
1191 | while (p); | |
1192 | ||
1193 | /* Allocate a block list. */ | |
1194 | - blocks = grub_zalloc (sizeof (struct grub_fs_block) * (num + 1)); | |
1195 | + blocks = grub_calloc (num + 1, sizeof (struct grub_fs_block)); | |
1196 | if (! blocks) | |
1197 | return 0; | |
1198 | ||
1199 | diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c | |
1200 | index 18cad5803..83c068d61 100644 | |
1201 | --- a/grub-core/kern/misc.c | |
1202 | +++ b/grub-core/kern/misc.c | |
1203 | @@ -691,7 +691,7 @@ parse_printf_args (const char *fmt0, struct printf_args *args, | |
1204 | args->ptr = args->prealloc; | |
1205 | else | |
1206 | { | |
1207 | - args->ptr = grub_malloc (args->count * sizeof (args->ptr[0])); | |
1208 | + args->ptr = grub_calloc (args->count, sizeof (args->ptr[0])); | |
1209 | if (!args->ptr) | |
1210 | { | |
1211 | grub_errno = GRUB_ERR_NONE; | |
1212 | diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c | |
1213 | index 78175aac2..619db3122 100644 | |
1214 | --- a/grub-core/kern/parser.c | |
1215 | +++ b/grub-core/kern/parser.c | |
1216 | @@ -213,7 +213,7 @@ grub_parser_split_cmdline (const char *cmdline, | |
1217 | return grub_errno; | |
1218 | grub_memcpy (args, buffer, bp - buffer); | |
1219 | ||
1220 | - *argv = grub_malloc (sizeof (char *) * (*argc + 1)); | |
1221 | + *argv = grub_calloc (*argc + 1, sizeof (char *)); | |
1222 | if (!*argv) | |
1223 | { | |
1224 | grub_free (args); | |
1225 | diff --git a/grub-core/kern/uboot/uboot.c b/grub-core/kern/uboot/uboot.c | |
1226 | index be4816fe6..aac8f9ae1 100644 | |
1227 | --- a/grub-core/kern/uboot/uboot.c | |
1228 | +++ b/grub-core/kern/uboot/uboot.c | |
1229 | @@ -133,7 +133,7 @@ grub_uboot_dev_enum (void) | |
1230 | return num_devices; | |
1231 | ||
1232 | max_devices = 2; | |
1233 | - enum_devices = grub_malloc (sizeof(struct device_info) * max_devices); | |
1234 | + enum_devices = grub_calloc (max_devices, sizeof(struct device_info)); | |
1235 | if (!enum_devices) | |
1236 | return 0; | |
1237 | ||
1238 | diff --git a/grub-core/lib/libgcrypt/cipher/ac.c b/grub-core/lib/libgcrypt/cipher/ac.c | |
1239 | index f5e946a2d..63f6fcd11 100644 | |
1240 | --- a/grub-core/lib/libgcrypt/cipher/ac.c | |
1241 | +++ b/grub-core/lib/libgcrypt/cipher/ac.c | |
1242 | @@ -185,7 +185,7 @@ ac_data_mpi_copy (gcry_ac_mpi_t *data_mpis, unsigned int data_mpis_n, | |
1243 | gcry_mpi_t mpi; | |
1244 | char *label; | |
1245 | ||
1246 | - data_mpis_new = gcry_malloc (sizeof (*data_mpis_new) * data_mpis_n); | |
1247 | + data_mpis_new = gcry_calloc (data_mpis_n, sizeof (*data_mpis_new)); | |
1248 | if (! data_mpis_new) | |
1249 | { | |
1250 | err = gcry_error_from_errno (errno); | |
1251 | @@ -572,7 +572,7 @@ _gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp, | |
1252 | } | |
1253 | ||
1254 | /* Add MPI list. */ | |
1255 | - arg_list = gcry_malloc (sizeof (*arg_list) * (data_n + 1)); | |
1256 | + arg_list = gcry_calloc (data_n + 1, sizeof (*arg_list)); | |
1257 | if (! arg_list) | |
1258 | { | |
1259 | err = gcry_error_from_errno (errno); | |
1260 | @@ -1283,7 +1283,7 @@ ac_data_construct (const char *identifier, int include_flags, | |
1261 | /* We build a list of arguments to pass to | |
1262 | gcry_sexp_build_array(). */ | |
1263 | data_length = _gcry_ac_data_length (data); | |
1264 | - arg_list = gcry_malloc (sizeof (*arg_list) * (data_length * 2)); | |
1265 | + arg_list = gcry_calloc (data_length, sizeof (*arg_list) * 2); | |
1266 | if (! arg_list) | |
1267 | { | |
1268 | err = gcry_error_from_errno (errno); | |
1269 | @@ -1593,7 +1593,7 @@ _gcry_ac_key_pair_generate (gcry_ac_handle_t handle, unsigned int nbits, | |
1270 | arg_list_n += 2; | |
1271 | ||
1272 | /* Allocate list. */ | |
1273 | - arg_list = gcry_malloc (sizeof (*arg_list) * arg_list_n); | |
1274 | + arg_list = gcry_calloc (arg_list_n, sizeof (*arg_list)); | |
1275 | if (! arg_list) | |
1276 | { | |
1277 | err = gcry_error_from_errno (errno); | |
1278 | diff --git a/grub-core/lib/libgcrypt/cipher/primegen.c b/grub-core/lib/libgcrypt/cipher/primegen.c | |
1279 | index 2788e349f..b12e79b19 100644 | |
1280 | --- a/grub-core/lib/libgcrypt/cipher/primegen.c | |
1281 | +++ b/grub-core/lib/libgcrypt/cipher/primegen.c | |
1282 | @@ -383,7 +383,7 @@ prime_generate_internal (int need_q_factor, | |
1283 | } | |
1284 | ||
1285 | /* Allocate an array to track pool usage. */ | |
1286 | - pool_in_use = gcry_malloc (n * sizeof *pool_in_use); | |
1287 | + pool_in_use = gcry_calloc (n, sizeof *pool_in_use); | |
1288 | if (!pool_in_use) | |
1289 | { | |
1290 | err = gpg_err_code_from_errno (errno); | |
1291 | @@ -765,7 +765,7 @@ gen_prime (unsigned int nbits, int secret, int randomlevel, | |
1292 | if (nbits < 16) | |
1293 | log_fatal ("can't generate a prime with less than %d bits\n", 16); | |
1294 | ||
1295 | - mods = gcry_xmalloc( no_of_small_prime_numbers * sizeof *mods ); | |
1296 | + mods = gcry_xcalloc( no_of_small_prime_numbers, sizeof *mods); | |
1297 | /* Make nbits fit into gcry_mpi_t implementation. */ | |
1298 | val_2 = mpi_alloc_set_ui( 2 ); | |
1299 | val_3 = mpi_alloc_set_ui( 3); | |
1300 | diff --git a/grub-core/lib/libgcrypt/cipher/pubkey.c b/grub-core/lib/libgcrypt/cipher/pubkey.c | |
1301 | index 910982141..ca087ad75 100644 | |
1302 | --- a/grub-core/lib/libgcrypt/cipher/pubkey.c | |
1303 | +++ b/grub-core/lib/libgcrypt/cipher/pubkey.c | |
1304 | @@ -2941,7 +2941,7 @@ gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey) | |
1305 | * array to a format string, so we have to do it this way :-(. */ | |
1306 | /* FIXME: There is now such a format specifier, so we can | |
1307 | change the code to be more clear. */ | |
1308 | - arg_list = malloc (nelem * sizeof *arg_list); | |
1309 | + arg_list = calloc (nelem, sizeof *arg_list); | |
1310 | if (!arg_list) | |
1311 | { | |
1312 | rc = gpg_err_code_from_syserror (); | |
1313 | @@ -3233,7 +3233,7 @@ gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey) | |
1314 | } | |
1315 | strcpy (p, "))"); | |
1316 | ||
1317 | - arg_list = malloc (nelem * sizeof *arg_list); | |
1318 | + arg_list = calloc (nelem, sizeof *arg_list); | |
1319 | if (!arg_list) | |
1320 | { | |
1321 | rc = gpg_err_code_from_syserror (); | |
1322 | diff --git a/grub-core/lib/priority_queue.c b/grub-core/lib/priority_queue.c | |
1323 | index 659be0b7f..7d5e7c05a 100644 | |
1324 | --- a/grub-core/lib/priority_queue.c | |
1325 | +++ b/grub-core/lib/priority_queue.c | |
1326 | @@ -92,7 +92,7 @@ grub_priority_queue_new (grub_size_t elsize, | |
1327 | { | |
1328 | struct grub_priority_queue *ret; | |
1329 | void *els; | |
1330 | - els = grub_malloc (elsize * 8); | |
1331 | + els = grub_calloc (8, elsize); | |
1332 | if (!els) | |
1333 | return 0; | |
1334 | ret = (struct grub_priority_queue *) grub_malloc (sizeof (*ret)); | |
1335 | diff --git a/grub-core/lib/reed_solomon.c b/grub-core/lib/reed_solomon.c | |
1336 | index ee9fa7b4f..467305b46 100644 | |
1337 | --- a/grub-core/lib/reed_solomon.c | |
1338 | +++ b/grub-core/lib/reed_solomon.c | |
1339 | @@ -20,6 +20,7 @@ | |
1340 | #include <stdio.h> | |
1341 | #include <string.h> | |
1342 | #include <stdlib.h> | |
1343 | +#define xcalloc calloc | |
1344 | #define xmalloc malloc | |
1345 | #define grub_memset memset | |
1346 | #define grub_memcpy memcpy | |
1347 | @@ -158,11 +159,9 @@ rs_encode (gf_single_t *data, grub_size_t s, grub_size_t rs) | |
1348 | gf_single_t *rs_polynomial; | |
1349 | int i, j; | |
1350 | gf_single_t *m; | |
1351 | - m = xmalloc ((s + rs) * sizeof (gf_single_t)); | |
1352 | + m = xcalloc (s + rs, sizeof (gf_single_t)); | |
1353 | grub_memcpy (m, data, s * sizeof (gf_single_t)); | |
1354 | - grub_memset (m + s, 0, rs * sizeof (gf_single_t)); | |
1355 | - rs_polynomial = xmalloc ((rs + 1) * sizeof (gf_single_t)); | |
1356 | - grub_memset (rs_polynomial, 0, (rs + 1) * sizeof (gf_single_t)); | |
1357 | + rs_polynomial = xcalloc (rs + 1, sizeof (gf_single_t)); | |
1358 | rs_polynomial[rs] = 1; | |
1359 | /* Multiply with X - a^r */ | |
1360 | for (j = 0; j < rs; j++) | |
1361 | diff --git a/grub-core/lib/relocator.c b/grub-core/lib/relocator.c | |
1362 | index ea3ebc719..5847aac36 100644 | |
1363 | --- a/grub-core/lib/relocator.c | |
1364 | +++ b/grub-core/lib/relocator.c | |
1365 | @@ -495,9 +495,9 @@ malloc_in_range (struct grub_relocator *rel, | |
1366 | } | |
1367 | #endif | |
1368 | ||
1369 | - eventt = grub_malloc (maxevents * sizeof (events[0])); | |
1370 | + eventt = grub_calloc (maxevents, sizeof (events[0])); | |
1371 | counter = grub_malloc ((DIGITSORT_MASK + 2) * sizeof (counter[0])); | |
1372 | - events = grub_malloc (maxevents * sizeof (events[0])); | |
1373 | + events = grub_calloc (maxevents, sizeof (events[0])); | |
1374 | if (!events || !eventt || !counter) | |
1375 | { | |
1376 | grub_dprintf ("relocator", "events or counter allocation failed %d\n", | |
1377 | @@ -963,7 +963,7 @@ malloc_in_range (struct grub_relocator *rel, | |
1378 | #endif | |
1379 | unsigned cural = 0; | |
1380 | int oom = 0; | |
1381 | - res->subchunks = grub_malloc (sizeof (res->subchunks[0]) * nallocs); | |
1382 | + res->subchunks = grub_calloc (nallocs, sizeof (res->subchunks[0])); | |
1383 | if (!res->subchunks) | |
1384 | oom = 1; | |
1385 | res->nsubchunks = nallocs; | |
1386 | @@ -1562,8 +1562,8 @@ grub_relocator_prepare_relocs (struct grub_relocator *rel, grub_addr_t addr, | |
1387 | count[(chunk->src & 0xff) + 1]++; | |
1388 | } | |
1389 | } | |
1390 | - from = grub_malloc (nchunks * sizeof (sorted[0])); | |
1391 | - to = grub_malloc (nchunks * sizeof (sorted[0])); | |
1392 | + from = grub_calloc (nchunks, sizeof (sorted[0])); | |
1393 | + to = grub_calloc (nchunks, sizeof (sorted[0])); | |
1394 | if (!from || !to) | |
1395 | { | |
1396 | grub_free (from); | |
1397 | diff --git a/grub-core/lib/zstd/fse_decompress.c b/grub-core/lib/zstd/fse_decompress.c | |
1398 | index 72bbead5b..2227b84bc 100644 | |
1399 | --- a/grub-core/lib/zstd/fse_decompress.c | |
1400 | +++ b/grub-core/lib/zstd/fse_decompress.c | |
1401 | @@ -82,7 +82,7 @@ | |
1402 | FSE_DTable* FSE_createDTable (unsigned tableLog) | |
1403 | { | |
1404 | if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX; | |
1405 | - return (FSE_DTable*)malloc( FSE_DTABLE_SIZE_U32(tableLog) * sizeof (U32) ); | |
1406 | + return (FSE_DTable*)calloc( FSE_DTABLE_SIZE_U32(tableLog), sizeof (U32) ); | |
1407 | } | |
1408 | ||
1409 | void FSE_freeDTable (FSE_DTable* dt) | |
1410 | diff --git a/grub-core/loader/arm/linux.c b/grub-core/loader/arm/linux.c | |
1411 | index 092e8e307..979d425df 100644 | |
1412 | --- a/grub-core/loader/arm/linux.c | |
1413 | +++ b/grub-core/loader/arm/linux.c | |
1414 | @@ -82,7 +82,7 @@ linux_prepare_atag (void *target_atag) | |
1415 | ||
1416 | /* some place for cmdline, initrd and terminator. */ | |
1417 | tmp_size = get_atag_size (atag_orig) + 20 + (arg_size) / 4; | |
1418 | - tmp_atag = grub_malloc (tmp_size * sizeof (grub_uint32_t)); | |
1419 | + tmp_atag = grub_calloc (tmp_size, sizeof (grub_uint32_t)); | |
1420 | if (!tmp_atag) | |
1421 | return grub_errno; | |
1422 | ||
1423 | diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c | |
1424 | index cd92ea3f2..daf8c6b54 100644 | |
1425 | --- a/grub-core/loader/efi/chainloader.c | |
1426 | +++ b/grub-core/loader/efi/chainloader.c | |
1427 | @@ -116,7 +116,7 @@ copy_file_path (grub_efi_file_path_device_path_t *fp, | |
1428 | fp->header.type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE; | |
1429 | fp->header.subtype = GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE; | |
1430 | ||
1431 | - path_name = grub_malloc (len * GRUB_MAX_UTF16_PER_UTF8 * sizeof (*path_name)); | |
1432 | + path_name = grub_calloc (len, GRUB_MAX_UTF16_PER_UTF8 * sizeof (*path_name)); | |
1433 | if (!path_name) | |
1434 | return; | |
1435 | ||
1436 | diff --git a/grub-core/loader/i386/bsdXX.c b/grub-core/loader/i386/bsdXX.c | |
1437 | index af6741d15..a8d8bf7da 100644 | |
1438 | --- a/grub-core/loader/i386/bsdXX.c | |
1439 | +++ b/grub-core/loader/i386/bsdXX.c | |
1440 | @@ -48,7 +48,7 @@ read_headers (grub_file_t file, const char *filename, Elf_Ehdr *e, char **shdr) | |
1441 | if (e->e_ident[EI_CLASS] != SUFFIX (ELFCLASS)) | |
1442 | return grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-dependent ELF magic")); | |
1443 | ||
1444 | - *shdr = grub_malloc ((grub_uint32_t) e->e_shnum * e->e_shentsize); | |
1445 | + *shdr = grub_calloc (e->e_shnum, e->e_shentsize); | |
1446 | if (! *shdr) | |
1447 | return grub_errno; | |
1448 | ||
1449 | diff --git a/grub-core/loader/i386/xnu.c b/grub-core/loader/i386/xnu.c | |
1450 | index e64ed08f5..b7d176b5d 100644 | |
1451 | --- a/grub-core/loader/i386/xnu.c | |
1452 | +++ b/grub-core/loader/i386/xnu.c | |
1453 | @@ -295,7 +295,7 @@ grub_xnu_devprop_add_property_utf8 (struct grub_xnu_devprop_device_descriptor *d | |
1454 | return grub_errno; | |
1455 | ||
1456 | len = grub_strlen (name); | |
1457 | - utf16 = grub_malloc (sizeof (grub_uint16_t) * len); | |
1458 | + utf16 = grub_calloc (len, sizeof (grub_uint16_t)); | |
1459 | if (!utf16) | |
1460 | { | |
1461 | grub_free (utf8); | |
1462 | @@ -331,7 +331,7 @@ grub_xnu_devprop_add_property_utf16 (struct grub_xnu_devprop_device_descriptor * | |
1463 | grub_uint16_t *utf16; | |
1464 | grub_err_t err; | |
1465 | ||
1466 | - utf16 = grub_malloc (sizeof (grub_uint16_t) * namelen); | |
1467 | + utf16 = grub_calloc (namelen, sizeof (grub_uint16_t)); | |
1468 | if (!utf16) | |
1469 | return grub_errno; | |
1470 | grub_memcpy (utf16, name, sizeof (grub_uint16_t) * namelen); | |
1471 | diff --git a/grub-core/loader/macho.c b/grub-core/loader/macho.c | |
1472 | index 085f9c689..05710c48e 100644 | |
1473 | --- a/grub-core/loader/macho.c | |
1474 | +++ b/grub-core/loader/macho.c | |
1475 | @@ -97,7 +97,7 @@ grub_macho_file (grub_file_t file, const char *filename, int is_64bit) | |
1476 | if (grub_file_seek (macho->file, sizeof (struct grub_macho_fat_header)) | |
1477 | == (grub_off_t) -1) | |
1478 | goto fail; | |
1479 | - archs = grub_malloc (sizeof (struct grub_macho_fat_arch) * narchs); | |
1480 | + archs = grub_calloc (narchs, sizeof (struct grub_macho_fat_arch)); | |
1481 | if (!archs) | |
1482 | goto fail; | |
1483 | if (grub_file_read (macho->file, archs, | |
1484 | diff --git a/grub-core/loader/multiboot_elfxx.c b/grub-core/loader/multiboot_elfxx.c | |
1485 | index 70cd1db51..cc6853692 100644 | |
1486 | --- a/grub-core/loader/multiboot_elfxx.c | |
1487 | +++ b/grub-core/loader/multiboot_elfxx.c | |
1488 | @@ -217,7 +217,7 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) | |
1489 | { | |
1490 | grub_uint8_t *shdr, *shdrptr; | |
1491 | ||
1492 | - shdr = grub_malloc ((grub_uint32_t) ehdr->e_shnum * ehdr->e_shentsize); | |
1493 | + shdr = grub_calloc (ehdr->e_shnum, ehdr->e_shentsize); | |
1494 | if (!shdr) | |
1495 | return grub_errno; | |
1496 | ||
1497 | diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c | |
1498 | index 7f74d1d6f..77d7060e1 100644 | |
1499 | --- a/grub-core/loader/xnu.c | |
1500 | +++ b/grub-core/loader/xnu.c | |
1501 | @@ -800,7 +800,7 @@ grub_cmd_xnu_mkext (grub_command_t cmd __attribute__ ((unused)), | |
1502 | if (grub_be_to_cpu32 (head.magic) == GRUB_MACHO_FAT_MAGIC) | |
1503 | { | |
1504 | narchs = grub_be_to_cpu32 (head.nfat_arch); | |
1505 | - archs = grub_malloc (sizeof (struct grub_macho_fat_arch) * narchs); | |
1506 | + archs = grub_calloc (narchs, sizeof (struct grub_macho_fat_arch)); | |
1507 | if (! archs) | |
1508 | { | |
1509 | grub_file_close (file); | |
1510 | diff --git a/grub-core/mmap/mmap.c b/grub-core/mmap/mmap.c | |
1511 | index 6a31cbae3..57b4e9a72 100644 | |
1512 | --- a/grub-core/mmap/mmap.c | |
1513 | +++ b/grub-core/mmap/mmap.c | |
1514 | @@ -143,9 +143,9 @@ grub_mmap_iterate (grub_memory_hook_t hook, void *hook_data) | |
1515 | ||
1516 | /* Initialize variables. */ | |
1517 | ctx.scanline_events = (struct grub_mmap_scan *) | |
1518 | - grub_malloc (sizeof (struct grub_mmap_scan) * 2 * mmap_num); | |
1519 | + grub_calloc (mmap_num, sizeof (struct grub_mmap_scan) * 2); | |
1520 | ||
1521 | - present = grub_zalloc (sizeof (present[0]) * current_priority); | |
1522 | + present = grub_calloc (current_priority, sizeof (present[0])); | |
1523 | ||
1524 | if (! ctx.scanline_events || !present) | |
1525 | { | |
1526 | diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c | |
1527 | index 558d97ba1..dd0ffcdae 100644 | |
1528 | --- a/grub-core/net/bootp.c | |
1529 | +++ b/grub-core/net/bootp.c | |
1530 | @@ -1559,7 +1559,7 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)), | |
1531 | if (ncards == 0) | |
1532 | return grub_error (GRUB_ERR_NET_NO_CARD, N_("no network card found")); | |
1533 | ||
1534 | - ifaces = grub_zalloc (ncards * sizeof (ifaces[0])); | |
1535 | + ifaces = grub_calloc (ncards, sizeof (ifaces[0])); | |
1536 | if (!ifaces) | |
1537 | return grub_errno; | |
1538 | ||
1539 | diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c | |
1540 | index 5d9afe093..e332d5eb4 100644 | |
1541 | --- a/grub-core/net/dns.c | |
1542 | +++ b/grub-core/net/dns.c | |
1543 | @@ -285,8 +285,8 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)), | |
1544 | ptr++; | |
1545 | ptr += 4; | |
1546 | } | |
1547 | - *data->addresses = grub_malloc (sizeof ((*data->addresses)[0]) | |
1548 | - * grub_be_to_cpu16 (head->ancount)); | |
1549 | + *data->addresses = grub_calloc (grub_be_to_cpu16 (head->ancount), | |
1550 | + sizeof ((*data->addresses)[0])); | |
1551 | if (!*data->addresses) | |
1552 | { | |
1553 | grub_errno = GRUB_ERR_NONE; | |
1554 | @@ -406,8 +406,8 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)), | |
1555 | dns_cache[h].addresses = 0; | |
1556 | dns_cache[h].name = grub_strdup (data->oname); | |
1557 | dns_cache[h].naddresses = *data->naddresses; | |
1558 | - dns_cache[h].addresses = grub_malloc (*data->naddresses | |
1559 | - * sizeof (dns_cache[h].addresses[0])); | |
1560 | + dns_cache[h].addresses = grub_calloc (*data->naddresses, | |
1561 | + sizeof (dns_cache[h].addresses[0])); | |
1562 | dns_cache[h].limit_time = grub_get_time_ms () + 1000 * ttl_all; | |
1563 | if (!dns_cache[h].addresses || !dns_cache[h].name) | |
1564 | { | |
1565 | @@ -479,7 +479,7 @@ grub_net_dns_lookup (const char *name, | |
1566 | } | |
1567 | } | |
1568 | ||
1569 | - sockets = grub_malloc (sizeof (sockets[0]) * n_servers); | |
1570 | + sockets = grub_calloc (n_servers, sizeof (sockets[0])); | |
1571 | if (!sockets) | |
1572 | return grub_errno; | |
1573 | ||
1574 | diff --git a/grub-core/net/net.c b/grub-core/net/net.c | |
1575 | index b917a75d5..fed7bc57c 100644 | |
1576 | --- a/grub-core/net/net.c | |
1577 | +++ b/grub-core/net/net.c | |
1578 | @@ -333,8 +333,8 @@ grub_cmd_ipv6_autoconf (struct grub_command *cmd __attribute__ ((unused)), | |
1579 | ncards++; | |
1580 | } | |
1581 | ||
1582 | - ifaces = grub_zalloc (ncards * sizeof (ifaces[0])); | |
1583 | - slaacs = grub_zalloc (ncards * sizeof (slaacs[0])); | |
1584 | + ifaces = grub_calloc (ncards, sizeof (ifaces[0])); | |
1585 | + slaacs = grub_calloc (ncards, sizeof (slaacs[0])); | |
1586 | if (!ifaces || !slaacs) | |
1587 | { | |
1588 | grub_free (ifaces); | |
1589 | diff --git a/grub-core/normal/charset.c b/grub-core/normal/charset.c | |
1590 | index b0ab47d73..d57fb72fa 100644 | |
1591 | --- a/grub-core/normal/charset.c | |
1592 | +++ b/grub-core/normal/charset.c | |
1593 | @@ -203,7 +203,7 @@ grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg, | |
1594 | { | |
1595 | grub_size_t msg_len = grub_strlen (msg); | |
1596 | ||
1597 | - *unicode_msg = grub_malloc (msg_len * sizeof (grub_uint32_t)); | |
1598 | + *unicode_msg = grub_calloc (msg_len, sizeof (grub_uint32_t)); | |
1599 | ||
1600 | if (!*unicode_msg) | |
1601 | return -1; | |
1602 | @@ -488,7 +488,7 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, | |
1603 | } | |
1604 | else | |
1605 | { | |
1606 | - n = grub_malloc (sizeof (n[0]) * (out->ncomb + 1)); | |
1607 | + n = grub_calloc (out->ncomb + 1, sizeof (n[0])); | |
1608 | if (!n) | |
1609 | { | |
1610 | grub_errno = GRUB_ERR_NONE; | |
1611 | @@ -842,7 +842,7 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical, | |
1612 | } \ | |
1613 | } | |
1614 | ||
1615 | - visual = grub_malloc (sizeof (visual[0]) * logical_len); | |
1616 | + visual = grub_calloc (logical_len, sizeof (visual[0])); | |
1617 | if (!visual) | |
1618 | return -1; | |
1619 | ||
1620 | @@ -1165,8 +1165,8 @@ grub_bidi_logical_to_visual (const grub_uint32_t *logical, | |
1621 | { | |
1622 | const grub_uint32_t *line_start = logical, *ptr; | |
1623 | struct grub_unicode_glyph *visual_ptr; | |
1624 | - *visual_out = visual_ptr = grub_malloc (3 * sizeof (visual_ptr[0]) | |
1625 | - * (logical_len + 2)); | |
1626 | + *visual_out = visual_ptr = grub_calloc (logical_len + 2, | |
1627 | + 3 * sizeof (visual_ptr[0])); | |
1628 | if (!visual_ptr) | |
1629 | return -1; | |
1630 | for (ptr = logical; ptr <= logical + logical_len; ptr++) | |
1631 | diff --git a/grub-core/normal/cmdline.c b/grub-core/normal/cmdline.c | |
1632 | index c037d5050..c57242e2e 100644 | |
1633 | --- a/grub-core/normal/cmdline.c | |
1634 | +++ b/grub-core/normal/cmdline.c | |
1635 | @@ -41,7 +41,7 @@ grub_err_t | |
1636 | grub_set_history (int newsize) | |
1637 | { | |
1638 | grub_uint32_t **old_hist_lines = hist_lines; | |
1639 | - hist_lines = grub_malloc (sizeof (grub_uint32_t *) * newsize); | |
1640 | + hist_lines = grub_calloc (newsize, sizeof (grub_uint32_t *)); | |
1641 | ||
1642 | /* Copy the old lines into the new buffer. */ | |
1643 | if (old_hist_lines) | |
1644 | @@ -114,7 +114,7 @@ static void | |
1645 | grub_history_set (int pos, grub_uint32_t *s, grub_size_t len) | |
1646 | { | |
1647 | grub_free (hist_lines[pos]); | |
1648 | - hist_lines[pos] = grub_malloc ((len + 1) * sizeof (grub_uint32_t)); | |
1649 | + hist_lines[pos] = grub_calloc (len + 1, sizeof (grub_uint32_t)); | |
1650 | if (!hist_lines[pos]) | |
1651 | { | |
1652 | grub_print_error (); | |
1653 | @@ -349,7 +349,7 @@ grub_cmdline_get (const char *prompt_translated) | |
1654 | char *ret; | |
1655 | unsigned nterms; | |
1656 | ||
1657 | - buf = grub_malloc (max_len * sizeof (grub_uint32_t)); | |
1658 | + buf = grub_calloc (max_len, sizeof (grub_uint32_t)); | |
1659 | if (!buf) | |
1660 | return 0; | |
1661 | ||
1662 | @@ -377,7 +377,7 @@ grub_cmdline_get (const char *prompt_translated) | |
1663 | FOR_ACTIVE_TERM_OUTPUTS(cur) | |
1664 | nterms++; | |
1665 | ||
1666 | - cl_terms = grub_malloc (sizeof (cl_terms[0]) * nterms); | |
1667 | + cl_terms = grub_calloc (nterms, sizeof (cl_terms[0])); | |
1668 | if (!cl_terms) | |
1669 | { | |
1670 | grub_free (buf); | |
1671 | @@ -385,7 +385,7 @@ grub_cmdline_get (const char *prompt_translated) | |
1672 | } | |
1673 | cl_term_cur = cl_terms; | |
1674 | ||
1675 | - unicode_msg = grub_malloc (msg_len * sizeof (grub_uint32_t)); | |
1676 | + unicode_msg = grub_calloc (msg_len, sizeof (grub_uint32_t)); | |
1677 | if (!unicode_msg) | |
1678 | { | |
1679 | grub_free (buf); | |
1680 | @@ -495,7 +495,7 @@ grub_cmdline_get (const char *prompt_translated) | |
1681 | grub_uint32_t *insert; | |
1682 | ||
1683 | insertlen = grub_strlen (insertu8); | |
1684 | - insert = grub_malloc ((insertlen + 1) * sizeof (grub_uint32_t)); | |
1685 | + insert = grub_calloc (insertlen + 1, sizeof (grub_uint32_t)); | |
1686 | if (!insert) | |
1687 | { | |
1688 | grub_free (insertu8); | |
1689 | @@ -602,7 +602,7 @@ grub_cmdline_get (const char *prompt_translated) | |
1690 | ||
1691 | grub_free (kill_buf); | |
1692 | ||
1693 | - kill_buf = grub_malloc ((n + 1) * sizeof(grub_uint32_t)); | |
1694 | + kill_buf = grub_calloc (n + 1, sizeof (grub_uint32_t)); | |
1695 | if (grub_errno) | |
1696 | { | |
1697 | grub_print_error (); | |
1698 | diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c | |
1699 | index cdf3590a3..1993995be 100644 | |
1700 | --- a/grub-core/normal/menu_entry.c | |
1701 | +++ b/grub-core/normal/menu_entry.c | |
1702 | @@ -95,8 +95,8 @@ init_line (struct screen *screen, struct line *linep) | |
1703 | { | |
1704 | linep->len = 0; | |
1705 | linep->max_len = 80; | |
1706 | - linep->buf = grub_malloc ((linep->max_len + 1) * sizeof (linep->buf[0])); | |
1707 | - linep->pos = grub_zalloc (screen->nterms * sizeof (linep->pos[0])); | |
1708 | + linep->buf = grub_calloc (linep->max_len + 1, sizeof (linep->buf[0])); | |
1709 | + linep->pos = grub_calloc (screen->nterms, sizeof (linep->pos[0])); | |
1710 | if (! linep->buf || !linep->pos) | |
1711 | { | |
1712 | grub_free (linep->buf); | |
1713 | @@ -287,7 +287,7 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen, | |
1714 | pos = linep->pos + (term_screen - screen->terms); | |
1715 | ||
1716 | if (!*pos) | |
1717 | - *pos = grub_zalloc ((linep->len + 1) * sizeof (**pos)); | |
1718 | + *pos = grub_calloc (linep->len + 1, sizeof (**pos)); | |
1719 | ||
1720 | if (i == region_start || linep == screen->lines + screen->line | |
1721 | || (i > region_start && mode == ALL_LINES)) | |
1722 | @@ -471,7 +471,7 @@ insert_string (struct screen *screen, const char *s, int update) | |
1723 | ||
1724 | /* Insert the string. */ | |
1725 | current_linep = screen->lines + screen->line; | |
1726 | - unicode_msg = grub_malloc ((p - s) * sizeof (grub_uint32_t)); | |
1727 | + unicode_msg = grub_calloc (p - s, sizeof (grub_uint32_t)); | |
1728 | ||
1729 | if (!unicode_msg) | |
1730 | return 0; | |
1731 | @@ -1023,7 +1023,7 @@ complete (struct screen *screen, int continuous, int update) | |
1732 | if (completion_buffer.buf) | |
1733 | { | |
1734 | buflen = grub_strlen (completion_buffer.buf); | |
1735 | - ucs4 = grub_malloc (sizeof (grub_uint32_t) * (buflen + 1)); | |
1736 | + ucs4 = grub_calloc (buflen + 1, sizeof (grub_uint32_t)); | |
1737 | ||
1738 | if (!ucs4) | |
1739 | { | |
1740 | @@ -1268,7 +1268,7 @@ grub_menu_entry_run (grub_menu_entry_t entry) | |
1741 | for (i = 0; i < (unsigned) screen->num_lines; i++) | |
1742 | { | |
1743 | grub_free (screen->lines[i].pos); | |
1744 | - screen->lines[i].pos = grub_zalloc (screen->nterms * sizeof (screen->lines[i].pos[0])); | |
1745 | + screen->lines[i].pos = grub_calloc (screen->nterms, sizeof (screen->lines[i].pos[0])); | |
1746 | if (! screen->lines[i].pos) | |
1747 | { | |
1748 | grub_print_error (); | |
1749 | @@ -1278,7 +1278,7 @@ grub_menu_entry_run (grub_menu_entry_t entry) | |
1750 | } | |
1751 | } | |
1752 | ||
1753 | - screen->terms = grub_zalloc (screen->nterms * sizeof (screen->terms[0])); | |
1754 | + screen->terms = grub_calloc (screen->nterms, sizeof (screen->terms[0])); | |
1755 | if (!screen->terms) | |
1756 | { | |
1757 | grub_print_error (); | |
1758 | diff --git a/grub-core/normal/menu_text.c b/grub-core/normal/menu_text.c | |
1759 | index e22bb91f6..18240e76c 100644 | |
1760 | --- a/grub-core/normal/menu_text.c | |
1761 | +++ b/grub-core/normal/menu_text.c | |
1762 | @@ -78,7 +78,7 @@ grub_print_message_indented_real (const char *msg, int margin_left, | |
1763 | grub_size_t msg_len = grub_strlen (msg) + 2; | |
1764 | int ret = 0; | |
1765 | ||
1766 | - unicode_msg = grub_malloc (msg_len * sizeof (grub_uint32_t)); | |
1767 | + unicode_msg = grub_calloc (msg_len, sizeof (grub_uint32_t)); | |
1768 | ||
1769 | if (!unicode_msg) | |
1770 | return 0; | |
1771 | @@ -211,7 +211,7 @@ print_entry (int y, int highlight, grub_menu_entry_t entry, | |
1772 | ||
1773 | title = entry ? entry->title : ""; | |
1774 | title_len = grub_strlen (title); | |
1775 | - unicode_title = grub_malloc (title_len * sizeof (*unicode_title)); | |
1776 | + unicode_title = grub_calloc (title_len, sizeof (*unicode_title)); | |
1777 | if (! unicode_title) | |
1778 | /* XXX How to show this error? */ | |
1779 | return; | |
1780 | diff --git a/grub-core/normal/term.c b/grub-core/normal/term.c | |
1781 | index a1e5c5a0d..cc8c173b6 100644 | |
1782 | --- a/grub-core/normal/term.c | |
1783 | +++ b/grub-core/normal/term.c | |
1784 | @@ -264,7 +264,7 @@ grub_term_save_pos (void) | |
1785 | FOR_ACTIVE_TERM_OUTPUTS(cur) | |
1786 | cnt++; | |
1787 | ||
1788 | - ret = grub_malloc (cnt * sizeof (ret[0])); | |
1789 | + ret = grub_calloc (cnt, sizeof (ret[0])); | |
1790 | if (!ret) | |
1791 | return NULL; | |
1792 | ||
1793 | @@ -1013,7 +1013,7 @@ grub_xnputs (const char *str, grub_size_t msg_len) | |
1794 | ||
1795 | grub_error_push (); | |
1796 | ||
1797 | - unicode_str = grub_malloc (msg_len * sizeof (grub_uint32_t)); | |
1798 | + unicode_str = grub_calloc (msg_len, sizeof (grub_uint32_t)); | |
1799 | ||
1800 | grub_error_pop (); | |
1801 | ||
1802 | diff --git a/grub-core/osdep/linux/getroot.c b/grub-core/osdep/linux/getroot.c | |
1803 | index 7adc0f30e..a5bd0752f 100644 | |
1804 | --- a/grub-core/osdep/linux/getroot.c | |
1805 | +++ b/grub-core/osdep/linux/getroot.c | |
1806 | @@ -168,7 +168,7 @@ grub_util_raid_getmembers (const char *name, int bootable) | |
1807 | if (ret != 0) | |
1808 | grub_util_error (_("ioctl GET_ARRAY_INFO error: %s"), strerror (errno)); | |
1809 | ||
1810 | - devicelist = xmalloc ((info.nr_disks + 1) * sizeof (char *)); | |
1811 | + devicelist = xcalloc (info.nr_disks + 1, sizeof (char *)); | |
1812 | ||
1813 | for (i = 0, j = 0; j < info.nr_disks; i++) | |
1814 | { | |
1815 | @@ -241,7 +241,7 @@ grub_find_root_devices_from_btrfs (const char *dir) | |
1816 | return NULL; | |
1817 | } | |
1818 | ||
1819 | - ret = xmalloc ((fsi.num_devices + 1) * sizeof (ret[0])); | |
1820 | + ret = xcalloc (fsi.num_devices + 1, sizeof (ret[0])); | |
1821 | ||
1822 | for (i = 1; i <= fsi.max_id && j < fsi.num_devices; i++) | |
1823 | { | |
1824 | @@ -396,7 +396,7 @@ grub_find_root_devices_from_mountinfo (const char *dir, char **relroot) | |
1825 | if (relroot) | |
1826 | *relroot = NULL; | |
1827 | ||
1828 | - entries = xmalloc (entry_max * sizeof (*entries)); | |
1829 | + entries = xcalloc (entry_max, sizeof (*entries)); | |
1830 | ||
1831 | again: | |
1832 | fp = grub_util_fopen ("/proc/self/mountinfo", "r"); | |
1833 | diff --git a/grub-core/osdep/windows/getroot.c b/grub-core/osdep/windows/getroot.c | |
1834 | index 661d95461..eada663b2 100644 | |
1835 | --- a/grub-core/osdep/windows/getroot.c | |
1836 | +++ b/grub-core/osdep/windows/getroot.c | |
1837 | @@ -59,7 +59,7 @@ grub_get_mount_point (const TCHAR *path) | |
1838 | ||
1839 | for (ptr = path; *ptr; ptr++); | |
1840 | allocsize = (ptr - path + 10) * 2; | |
1841 | - out = xmalloc (allocsize * sizeof (out[0])); | |
1842 | + out = xcalloc (allocsize, sizeof (out[0])); | |
1843 | ||
1844 | /* When pointing to EFI system partition GetVolumePathName fails | |
1845 | for ESP root and returns abberant information for everything | |
1846 | diff --git a/grub-core/osdep/windows/hostdisk.c b/grub-core/osdep/windows/hostdisk.c | |
1847 | index 355100789..0be327394 100644 | |
1848 | --- a/grub-core/osdep/windows/hostdisk.c | |
1849 | +++ b/grub-core/osdep/windows/hostdisk.c | |
1850 | @@ -111,7 +111,7 @@ grub_util_get_windows_path_real (const char *path) | |
1851 | ||
1852 | while (1) | |
1853 | { | |
1854 | - fpa = xmalloc (alloc * sizeof (fpa[0])); | |
1855 | + fpa = xcalloc (alloc, sizeof (fpa[0])); | |
1856 | ||
1857 | len = GetFullPathName (tpath, alloc, fpa, NULL); | |
1858 | if (len >= alloc) | |
1859 | @@ -399,7 +399,7 @@ grub_util_fd_opendir (const char *name) | |
1860 | for (l = 0; name_windows[l]; l++); | |
1861 | for (l--; l >= 0 && (name_windows[l] == '\\' || name_windows[l] == '/'); l--); | |
1862 | l++; | |
1863 | - pattern = xmalloc ((l + 3) * sizeof (pattern[0])); | |
1864 | + pattern = xcalloc (l + 3, sizeof (pattern[0])); | |
1865 | memcpy (pattern, name_windows, l * sizeof (pattern[0])); | |
1866 | pattern[l] = '\\'; | |
1867 | pattern[l + 1] = '*'; | |
1868 | diff --git a/grub-core/osdep/windows/init.c b/grub-core/osdep/windows/init.c | |
1869 | index e8ffd62c6..6297de632 100644 | |
1870 | --- a/grub-core/osdep/windows/init.c | |
1871 | +++ b/grub-core/osdep/windows/init.c | |
1872 | @@ -161,7 +161,7 @@ grub_util_host_init (int *argc __attribute__ ((unused)), | |
1873 | LPWSTR *targv; | |
1874 | ||
1875 | targv = CommandLineToArgvW (tcmdline, argc); | |
1876 | - *argv = xmalloc ((*argc + 1) * sizeof (argv[0])); | |
1877 | + *argv = xcalloc (*argc + 1, sizeof (argv[0])); | |
1878 | ||
1879 | for (i = 0; i < *argc; i++) | |
1880 | (*argv)[i] = grub_util_tchar_to_utf8 (targv[i]); | |
1881 | diff --git a/grub-core/osdep/windows/platform.c b/grub-core/osdep/windows/platform.c | |
1882 | index e19a3d9a8..cb626c8c3 100644 | |
1883 | --- a/grub-core/osdep/windows/platform.c | |
1884 | +++ b/grub-core/osdep/windows/platform.c | |
1885 | @@ -231,8 +231,8 @@ grub_install_register_efi (grub_device_t efidir_grub_dev, | |
1886 | grub_util_error ("%s", _("no EFI routines are available when running in BIOS mode")); | |
1887 | ||
1888 | distrib8_len = grub_strlen (efi_distributor); | |
1889 | - distributor16 = xmalloc ((distrib8_len + 1) * GRUB_MAX_UTF16_PER_UTF8 | |
1890 | - * sizeof (grub_uint16_t)); | |
1891 | + distributor16 = xcalloc (distrib8_len + 1, | |
1892 | + GRUB_MAX_UTF16_PER_UTF8 * sizeof (grub_uint16_t)); | |
1893 | distrib16_len = grub_utf8_to_utf16 (distributor16, distrib8_len * GRUB_MAX_UTF16_PER_UTF8, | |
1894 | (const grub_uint8_t *) efi_distributor, | |
1895 | distrib8_len, 0); | |
1896 | diff --git a/grub-core/osdep/windows/relpath.c b/grub-core/osdep/windows/relpath.c | |
1897 | index cb0861744..478e8ef14 100644 | |
1898 | --- a/grub-core/osdep/windows/relpath.c | |
1899 | +++ b/grub-core/osdep/windows/relpath.c | |
1900 | @@ -72,7 +72,7 @@ grub_make_system_path_relative_to_its_root (const char *path) | |
1901 | if (dirwindows[0] && dirwindows[1] == ':') | |
1902 | offset = 2; | |
1903 | } | |
1904 | - ret = xmalloc (sizeof (ret[0]) * (flen - offset + 2)); | |
1905 | + ret = xcalloc (flen - offset + 2, sizeof (ret[0])); | |
1906 | if (dirwindows[offset] != '\\' | |
1907 | && dirwindows[offset] != '/' | |
1908 | && dirwindows[offset]) | |
1909 | diff --git a/grub-core/partmap/gpt.c b/grub-core/partmap/gpt.c | |
1910 | index 103f6796f..72a2e37cd 100644 | |
1911 | --- a/grub-core/partmap/gpt.c | |
1912 | +++ b/grub-core/partmap/gpt.c | |
1913 | @@ -199,7 +199,7 @@ gpt_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors, | |
1914 | *nsectors = ctx.len; | |
1915 | if (*nsectors > max_nsectors) | |
1916 | *nsectors = max_nsectors; | |
1917 | - *sectors = grub_malloc (*nsectors * sizeof (**sectors)); | |
1918 | + *sectors = grub_calloc (*nsectors, sizeof (**sectors)); | |
1919 | if (!*sectors) | |
1920 | return grub_errno; | |
1921 | for (i = 0; i < *nsectors; i++) | |
1922 | diff --git a/grub-core/partmap/msdos.c b/grub-core/partmap/msdos.c | |
1923 | index 7b8e45076..ee3f24982 100644 | |
1924 | --- a/grub-core/partmap/msdos.c | |
1925 | +++ b/grub-core/partmap/msdos.c | |
1926 | @@ -337,7 +337,7 @@ pc_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors, | |
1927 | avail_nsectors = *nsectors; | |
1928 | if (*nsectors > max_nsectors) | |
1929 | *nsectors = max_nsectors; | |
1930 | - *sectors = grub_malloc (*nsectors * sizeof (**sectors)); | |
1931 | + *sectors = grub_calloc (*nsectors, sizeof (**sectors)); | |
1932 | if (!*sectors) | |
1933 | return grub_errno; | |
1934 | for (i = 0; i < *nsectors; i++) | |
1935 | diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c | |
1936 | index ee299fd0e..c8d6806fe 100644 | |
1937 | --- a/grub-core/script/execute.c | |
1938 | +++ b/grub-core/script/execute.c | |
1939 | @@ -553,7 +553,7 @@ gettext_append (struct grub_script_argv *result, const char *orig_str) | |
1940 | for (iptr = orig_str; *iptr; iptr++) | |
1941 | if (*iptr == '$') | |
1942 | dollar_cnt++; | |
1943 | - ctx.allowed_strings = grub_malloc (sizeof (ctx.allowed_strings[0]) * dollar_cnt); | |
1944 | + ctx.allowed_strings = grub_calloc (dollar_cnt, sizeof (ctx.allowed_strings[0])); | |
1945 | ||
1946 | if (parse_string (orig_str, gettext_save_allow, &ctx, 0)) | |
1947 | goto fail; | |
1948 | diff --git a/grub-core/tests/fake_input.c b/grub-core/tests/fake_input.c | |
1949 | index 2d6085298..b5eb516be 100644 | |
1950 | --- a/grub-core/tests/fake_input.c | |
1951 | +++ b/grub-core/tests/fake_input.c | |
1952 | @@ -49,7 +49,7 @@ grub_terminal_input_fake_sequence (int *seq_in, int nseq_in) | |
1953 | saved = grub_term_inputs; | |
1954 | if (seq) | |
1955 | grub_free (seq); | |
1956 | - seq = grub_malloc (nseq_in * sizeof (seq[0])); | |
1957 | + seq = grub_calloc (nseq_in, sizeof (seq[0])); | |
1958 | if (!seq) | |
1959 | return; | |
1960 | ||
1961 | diff --git a/grub-core/tests/video_checksum.c b/grub-core/tests/video_checksum.c | |
1962 | index 74d5b65e5..44d081069 100644 | |
1963 | --- a/grub-core/tests/video_checksum.c | |
1964 | +++ b/grub-core/tests/video_checksum.c | |
1965 | @@ -336,7 +336,7 @@ grub_video_capture_write_bmp (const char *fname, | |
1966 | { | |
1967 | case 4: | |
1968 | { | |
1969 | - grub_uint8_t *buffer = xmalloc (mode_info->width * 3); | |
1970 | + grub_uint8_t *buffer = xcalloc (3, mode_info->width); | |
1971 | grub_uint32_t rmask = ((1 << mode_info->red_mask_size) - 1); | |
1972 | grub_uint32_t gmask = ((1 << mode_info->green_mask_size) - 1); | |
1973 | grub_uint32_t bmask = ((1 << mode_info->blue_mask_size) - 1); | |
1974 | @@ -367,7 +367,7 @@ grub_video_capture_write_bmp (const char *fname, | |
1975 | } | |
1976 | case 3: | |
1977 | { | |
1978 | - grub_uint8_t *buffer = xmalloc (mode_info->width * 3); | |
1979 | + grub_uint8_t *buffer = xcalloc (3, mode_info->width); | |
1980 | grub_uint32_t rmask = ((1 << mode_info->red_mask_size) - 1); | |
1981 | grub_uint32_t gmask = ((1 << mode_info->green_mask_size) - 1); | |
1982 | grub_uint32_t bmask = ((1 << mode_info->blue_mask_size) - 1); | |
1983 | @@ -407,7 +407,7 @@ grub_video_capture_write_bmp (const char *fname, | |
1984 | } | |
1985 | case 2: | |
1986 | { | |
1987 | - grub_uint8_t *buffer = xmalloc (mode_info->width * 3); | |
1988 | + grub_uint8_t *buffer = xcalloc (3, mode_info->width); | |
1989 | grub_uint16_t rmask = ((1 << mode_info->red_mask_size) - 1); | |
1990 | grub_uint16_t gmask = ((1 << mode_info->green_mask_size) - 1); | |
1991 | grub_uint16_t bmask = ((1 << mode_info->blue_mask_size) - 1); | |
1992 | diff --git a/grub-core/video/capture.c b/grub-core/video/capture.c | |
1993 | index 4f83c7441..4d3195e01 100644 | |
1994 | --- a/grub-core/video/capture.c | |
1995 | +++ b/grub-core/video/capture.c | |
1996 | @@ -89,7 +89,7 @@ grub_video_capture_start (const struct grub_video_mode_info *mode_info, | |
1997 | framebuffer.mode_info = *mode_info; | |
1998 | framebuffer.mode_info.blit_format = grub_video_get_blit_format (&framebuffer.mode_info); | |
1999 | ||
2000 | - framebuffer.ptr = grub_malloc (framebuffer.mode_info.height * framebuffer.mode_info.pitch); | |
2001 | + framebuffer.ptr = grub_calloc (framebuffer.mode_info.height, framebuffer.mode_info.pitch); | |
2002 | if (!framebuffer.ptr) | |
2003 | return grub_errno; | |
2004 | ||
2005 | diff --git a/grub-core/video/emu/sdl.c b/grub-core/video/emu/sdl.c | |
2006 | index a2f639f66..0ebab6f57 100644 | |
2007 | --- a/grub-core/video/emu/sdl.c | |
2008 | +++ b/grub-core/video/emu/sdl.c | |
2009 | @@ -172,7 +172,7 @@ grub_video_sdl_set_palette (unsigned int start, unsigned int count, | |
2010 | if (start + count > mode_info.number_of_colors) | |
2011 | count = mode_info.number_of_colors - start; | |
2012 | ||
2013 | - tmp = grub_malloc (count * sizeof (tmp[0])); | |
2014 | + tmp = grub_calloc (count, sizeof (tmp[0])); | |
2015 | for (i = 0; i < count; i++) | |
2016 | { | |
2017 | tmp[i].r = palette_data[i].r; | |
2018 | diff --git a/grub-core/video/i386/pc/vga.c b/grub-core/video/i386/pc/vga.c | |
2019 | index 01f47112d..b2f776c99 100644 | |
2020 | --- a/grub-core/video/i386/pc/vga.c | |
2021 | +++ b/grub-core/video/i386/pc/vga.c | |
2022 | @@ -127,7 +127,7 @@ grub_video_vga_setup (unsigned int width, unsigned int height, | |
2023 | ||
2024 | vga_height = height ? : 480; | |
2025 | ||
2026 | - framebuffer.temporary_buffer = grub_malloc (vga_height * VGA_WIDTH); | |
2027 | + framebuffer.temporary_buffer = grub_calloc (vga_height, VGA_WIDTH); | |
2028 | framebuffer.front_page = 0; | |
2029 | framebuffer.back_page = 0; | |
2030 | if (!framebuffer.temporary_buffer) | |
2031 | diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c | |
2032 | index 777e71334..61bd64537 100644 | |
2033 | --- a/grub-core/video/readers/png.c | |
2034 | +++ b/grub-core/video/readers/png.c | |
2035 | @@ -309,7 +309,7 @@ grub_png_decode_image_header (struct grub_png_data *data) | |
2036 | if (data->is_16bit || data->is_gray || data->is_palette) | |
2037 | #endif | |
2038 | { | |
2039 | - data->image_data = grub_malloc (data->image_height * data->row_bytes); | |
2040 | + data->image_data = grub_calloc (data->image_height, data->row_bytes); | |
2041 | if (grub_errno) | |
2042 | return grub_errno; | |
2043 | ||
2044 | diff --git a/include/grub/unicode.h b/include/grub/unicode.h | |
2045 | index a0403e91f..4de986a85 100644 | |
2046 | --- a/include/grub/unicode.h | |
2047 | +++ b/include/grub/unicode.h | |
2048 | @@ -293,7 +293,7 @@ grub_unicode_glyph_dup (const struct grub_unicode_glyph *in) | |
2049 | grub_memcpy (out, in, sizeof (*in)); | |
2050 | if (in->ncomb > ARRAY_SIZE (out->combining_inline)) | |
2051 | { | |
2052 | - out->combining_ptr = grub_malloc (in->ncomb * sizeof (out->combining_ptr[0])); | |
2053 | + out->combining_ptr = grub_calloc (in->ncomb, sizeof (out->combining_ptr[0])); | |
2054 | if (!out->combining_ptr) | |
2055 | { | |
2056 | grub_free (out); | |
2057 | @@ -315,7 +315,7 @@ grub_unicode_set_glyph (struct grub_unicode_glyph *out, | |
2058 | grub_memcpy (out, in, sizeof (*in)); | |
2059 | if (in->ncomb > ARRAY_SIZE (out->combining_inline)) | |
2060 | { | |
2061 | - out->combining_ptr = grub_malloc (in->ncomb * sizeof (out->combining_ptr[0])); | |
2062 | + out->combining_ptr = grub_calloc (in->ncomb, sizeof (out->combining_ptr[0])); | |
2063 | if (!out->combining_ptr) | |
2064 | return; | |
2065 | grub_memcpy (out->combining_ptr, in->combining_ptr, | |
2066 | diff --git a/util/getroot.c b/util/getroot.c | |
2067 | index cdd41153c..6ae35ecaa 100644 | |
2068 | --- a/util/getroot.c | |
2069 | +++ b/util/getroot.c | |
2070 | @@ -200,7 +200,7 @@ make_device_name (const char *drive) | |
2071 | char *ret, *ptr; | |
2072 | const char *iptr; | |
2073 | ||
2074 | - ret = xmalloc (strlen (drive) * 2); | |
2075 | + ret = xcalloc (2, strlen (drive)); | |
2076 | ptr = ret; | |
2077 | for (iptr = drive; *iptr; iptr++) | |
2078 | { | |
2079 | diff --git a/util/grub-file.c b/util/grub-file.c | |
2080 | index 50c18b683..b2e7dd69f 100644 | |
2081 | --- a/util/grub-file.c | |
2082 | +++ b/util/grub-file.c | |
2083 | @@ -54,7 +54,7 @@ main (int argc, char *argv[]) | |
2084 | ||
2085 | grub_util_host_init (&argc, &argv); | |
2086 | ||
2087 | - argv2 = xmalloc (argc * sizeof (argv2[0])); | |
2088 | + argv2 = xcalloc (argc, sizeof (argv2[0])); | |
2089 | ||
2090 | if (argc == 2 && strcmp (argv[1], "--version") == 0) | |
2091 | { | |
2092 | diff --git a/util/grub-fstest.c b/util/grub-fstest.c | |
2093 | index f14e02d97..57246af7c 100644 | |
2094 | --- a/util/grub-fstest.c | |
2095 | +++ b/util/grub-fstest.c | |
2096 | @@ -650,7 +650,7 @@ argp_parser (int key, char *arg, struct argp_state *state) | |
2097 | if (args_count < num_disks) | |
2098 | { | |
2099 | if (args_count == 0) | |
2100 | - images = xmalloc (num_disks * sizeof (images[0])); | |
2101 | + images = xcalloc (num_disks, sizeof (images[0])); | |
2102 | images[args_count] = grub_canonicalize_file_name (arg); | |
2103 | args_count++; | |
2104 | return 0; | |
2105 | @@ -734,7 +734,7 @@ main (int argc, char *argv[]) | |
2106 | ||
2107 | grub_util_host_init (&argc, &argv); | |
2108 | ||
2109 | - args = xmalloc (argc * sizeof (args[0])); | |
2110 | + args = xcalloc (argc, sizeof (args[0])); | |
2111 | ||
2112 | argp_parse (&argp, argc, argv, 0, 0, 0); | |
2113 | ||
2114 | diff --git a/util/grub-install-common.c b/util/grub-install-common.c | |
2115 | index fdfe2c7ea..447504d3f 100644 | |
2116 | --- a/util/grub-install-common.c | |
2117 | +++ b/util/grub-install-common.c | |
2118 | @@ -286,7 +286,7 @@ handle_install_list (struct install_list *il, const char *val, | |
2119 | il->n_entries++; | |
2120 | } | |
2121 | il->n_alloc = il->n_entries + 1; | |
2122 | - il->entries = xmalloc (il->n_alloc * sizeof (il->entries[0])); | |
2123 | + il->entries = xcalloc (il->n_alloc, sizeof (il->entries[0])); | |
2124 | ptr = val; | |
2125 | for (ce = il->entries; ; ce++) | |
2126 | { | |
2127 | diff --git a/util/grub-install.c b/util/grub-install.c | |
2128 | index 666cef3d2..bd6d8dbb3 100644 | |
2129 | --- a/util/grub-install.c | |
2130 | +++ b/util/grub-install.c | |
2131 | @@ -655,7 +655,7 @@ device_map_check_duplicates (const char *dev_map) | |
2132 | if (! fp) | |
2133 | return; | |
2134 | ||
2135 | - d = xmalloc (alloced * sizeof (d[0])); | |
2136 | + d = xcalloc (alloced, sizeof (d[0])); | |
2137 | ||
2138 | while (fgets (buf, sizeof (buf), fp)) | |
2139 | { | |
2140 | @@ -1374,7 +1374,7 @@ main (int argc, char *argv[]) | |
2141 | ndev++; | |
2142 | } | |
2143 | ||
2144 | - grub_drives = xmalloc (sizeof (grub_drives[0]) * (ndev + 1)); | |
2145 | + grub_drives = xcalloc (ndev + 1, sizeof (grub_drives[0])); | |
2146 | ||
2147 | for (curdev = grub_devices, curdrive = grub_drives; *curdev; curdev++, | |
2148 | curdrive++) | |
2149 | diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c | |
2150 | index bc087c2b5..d97d0e7be 100644 | |
2151 | --- a/util/grub-mkimagexx.c | |
2152 | +++ b/util/grub-mkimagexx.c | |
2153 | @@ -2294,10 +2294,8 @@ SUFFIX (grub_mkimage_load_image) (const char *kernel_path, | |
2154 | + grub_host_to_target16 (e->e_shstrndx) * smd.section_entsize); | |
2155 | smd.strtab = (char *) e + grub_host_to_target_addr (s->sh_offset); | |
2156 | ||
2157 | - smd.addrs = xmalloc (sizeof (*smd.addrs) * smd.num_sections); | |
2158 | - memset (smd.addrs, 0, sizeof (*smd.addrs) * smd.num_sections); | |
2159 | - smd.vaddrs = xmalloc (sizeof (*smd.vaddrs) * smd.num_sections); | |
2160 | - memset (smd.vaddrs, 0, sizeof (*smd.vaddrs) * smd.num_sections); | |
2161 | + smd.addrs = xcalloc (smd.num_sections, sizeof (*smd.addrs)); | |
2162 | + smd.vaddrs = xcalloc (smd.num_sections, sizeof (*smd.vaddrs)); | |
2163 | ||
2164 | SUFFIX (locate_sections) (e, kernel_path, &smd, layout, image_target); | |
2165 | ||
2166 | diff --git a/util/grub-mkrescue.c b/util/grub-mkrescue.c | |
2167 | index 45d6140d3..cb972f120 100644 | |
2168 | --- a/util/grub-mkrescue.c | |
2169 | +++ b/util/grub-mkrescue.c | |
2170 | @@ -441,8 +441,8 @@ main (int argc, char *argv[]) | |
2171 | xorriso = xstrdup ("xorriso"); | |
2172 | label_font = grub_util_path_concat (2, pkgdatadir, "unicode.pf2"); | |
2173 | ||
2174 | - argp_argv = xmalloc (sizeof (argp_argv[0]) * argc); | |
2175 | - xorriso_tail_argv = xmalloc (sizeof (argp_argv[0]) * argc); | |
2176 | + argp_argv = xcalloc (argc, sizeof (argp_argv[0])); | |
2177 | + xorriso_tail_argv = xcalloc (argc, sizeof (argp_argv[0])); | |
2178 | ||
2179 | xorriso_tail_argc = 0; | |
2180 | /* Program name */ | |
2181 | diff --git a/util/grub-mkstandalone.c b/util/grub-mkstandalone.c | |
2182 | index 4907d44c0..edf309717 100644 | |
2183 | --- a/util/grub-mkstandalone.c | |
2184 | +++ b/util/grub-mkstandalone.c | |
2185 | @@ -296,7 +296,7 @@ main (int argc, char *argv[]) | |
2186 | grub_util_host_init (&argc, &argv); | |
2187 | grub_util_disable_fd_syncs (); | |
2188 | ||
2189 | - files = xmalloc ((argc + 1) * sizeof (files[0])); | |
2190 | + files = xcalloc (argc + 1, sizeof (files[0])); | |
2191 | ||
2192 | argp_parse (&argp, argc, argv, 0, 0, 0); | |
2193 | ||
2194 | diff --git a/util/grub-pe2elf.c b/util/grub-pe2elf.c | |
2195 | index 0d4084a10..11331294f 100644 | |
2196 | --- a/util/grub-pe2elf.c | |
2197 | +++ b/util/grub-pe2elf.c | |
2198 | @@ -100,9 +100,9 @@ write_section_data (FILE* fp, const char *name, char *image, | |
2199 | char *pe_strtab = (image + pe_chdr->symtab_offset | |
2200 | + pe_chdr->num_symbols * sizeof (struct grub_pe32_symbol)); | |
2201 | ||
2202 | - section_map = xmalloc ((2 * pe_chdr->num_sections + 5) * sizeof (int)); | |
2203 | + section_map = xcalloc (2 * pe_chdr->num_sections + 5, sizeof (int)); | |
2204 | section_map[0] = 0; | |
2205 | - shdr = xmalloc ((2 * pe_chdr->num_sections + 5) * sizeof (shdr[0])); | |
2206 | + shdr = xcalloc (2 * pe_chdr->num_sections + 5, sizeof (shdr[0])); | |
2207 | idx = 1; | |
2208 | idx_reloc = pe_chdr->num_sections + 1; | |
2209 | ||
2210 | @@ -233,7 +233,7 @@ write_reloc_section (FILE* fp, const char *name, char *image, | |
2211 | ||
2212 | pe_sec = pe_shdr + shdr[i].sh_link; | |
2213 | pe_rel = (struct grub_pe32_reloc *) (image + pe_sec->relocations_offset); | |
2214 | - rel = (elf_reloc_t *) xmalloc (pe_sec->num_relocations * sizeof (elf_reloc_t)); | |
2215 | + rel = (elf_reloc_t *) xcalloc (pe_sec->num_relocations, sizeof (elf_reloc_t)); | |
2216 | num_rels = 0; | |
2217 | modified = 0; | |
2218 | ||
2219 | @@ -365,12 +365,10 @@ write_symbol_table (FILE* fp, const char *name, char *image, | |
2220 | pe_symtab = (struct grub_pe32_symbol *) (image + pe_chdr->symtab_offset); | |
2221 | pe_strtab = (char *) (pe_symtab + pe_chdr->num_symbols); | |
2222 | ||
2223 | - symtab = (Elf_Sym *) xmalloc ((pe_chdr->num_symbols + 1) * | |
2224 | - sizeof (Elf_Sym)); | |
2225 | - memset (symtab, 0, (pe_chdr->num_symbols + 1) * sizeof (Elf_Sym)); | |
2226 | + symtab = (Elf_Sym *) xcalloc (pe_chdr->num_symbols + 1, sizeof (Elf_Sym)); | |
2227 | num_syms = 1; | |
2228 | ||
2229 | - symtab_map = (int *) xmalloc (pe_chdr->num_symbols * sizeof (int)); | |
2230 | + symtab_map = (int *) xcalloc (pe_chdr->num_symbols, sizeof (int)); | |
2231 | ||
2232 | for (i = 0; i < (int) pe_chdr->num_symbols; | |
2233 | i += pe_symtab->num_aux + 1, pe_symtab += pe_symtab->num_aux + 1) | |
2234 | diff --git a/util/grub-probe.c b/util/grub-probe.c | |
2235 | index 81d27eead..cbe6ed94c 100644 | |
2236 | --- a/util/grub-probe.c | |
2237 | +++ b/util/grub-probe.c | |
2238 | @@ -361,8 +361,8 @@ probe (const char *path, char **device_names, char delim) | |
2239 | grub_util_pull_device (*curdev); | |
2240 | ndev++; | |
2241 | } | |
2242 | - | |
2243 | - drives_names = xmalloc (sizeof (drives_names[0]) * (ndev + 1)); | |
2244 | + | |
2245 | + drives_names = xcalloc (ndev + 1, sizeof (drives_names[0])); | |
2246 | ||
2247 | for (curdev = device_names, curdrive = drives_names; *curdev; curdev++, | |
2248 | curdrive++) | |
2249 | ||
2250 | From d84e89f4734711d8ff3c84b6c58985c824b4d889 Mon Sep 17 00:00:00 2001 | |
2251 | From: Peter Jones <pjones@redhat.com> | |
2252 | Date: Mon, 15 Jun 2020 12:28:27 -0400 | |
2253 | Subject: malloc: Use overflow checking primitives where we do | |
2254 | complex allocations | |
2255 | ||
2256 | This attempts to fix the places where we do the following where | |
2257 | arithmetic_expr may include unvalidated data: | |
2258 | ||
2259 | X = grub_malloc(arithmetic_expr); | |
2260 | ||
2261 | It accomplishes this by doing the arithmetic ahead of time using grub_add(), | |
2262 | grub_sub(), grub_mul() and testing for overflow before proceeding. | |
2263 | ||
2264 | Among other issues, this fixes: | |
2265 | - allocation of integer overflow in grub_video_bitmap_create() | |
2266 | reported by Chris Coulson, | |
2267 | - allocation of integer overflow in grub_png_decode_image_header() | |
2268 | reported by Chris Coulson, | |
2269 | - allocation of integer overflow in grub_squash_read_symlink() | |
2270 | reported by Chris Coulson, | |
2271 | - allocation of integer overflow in grub_ext2_read_symlink() | |
2272 | reported by Chris Coulson, | |
2273 | - allocation of integer overflow in read_section_as_string() | |
2274 | reported by Chris Coulson. | |
2275 | ||
2276 | Fixes: CVE-2020-14309, CVE-2020-14310, CVE-2020-14311 | |
2277 | ||
2278 | Signed-off-by: Peter Jones <pjones@redhat.com> | |
2279 | Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> | |
2280 | --- | |
2281 | grub-core/commands/legacycfg.c | 29 +++++++++++++++---- | |
2282 | grub-core/commands/wildcard.c | 36 ++++++++++++++++++++---- | |
2283 | grub-core/disk/ldm.c | 32 +++++++++++++++------ | |
2284 | grub-core/font/font.c | 7 ++++- | |
2285 | grub-core/fs/btrfs.c | 28 +++++++++++++------ | |
2286 | grub-core/fs/ext2.c | 10 ++++++- | |
2287 | grub-core/fs/iso9660.c | 51 ++++++++++++++++++++++++---------- | |
2288 | grub-core/fs/sfs.c | 27 ++++++++++++++---- | |
2289 | grub-core/fs/squash4.c | 45 ++++++++++++++++++++++-------- | |
2290 | grub-core/fs/udf.c | 41 +++++++++++++++++---------- | |
2291 | grub-core/fs/xfs.c | 11 +++++--- | |
2292 | grub-core/fs/zfs/zfs.c | 22 ++++++++++----- | |
2293 | grub-core/fs/zfs/zfscrypt.c | 7 ++++- | |
2294 | grub-core/lib/arg.c | 20 +++++++++++-- | |
2295 | grub-core/loader/i386/bsd.c | 8 +++++- | |
2296 | grub-core/net/dns.c | 9 +++++- | |
2297 | grub-core/normal/charset.c | 10 +++++-- | |
2298 | grub-core/normal/cmdline.c | 14 ++++++++-- | |
2299 | grub-core/normal/menu_entry.c | 13 +++++++-- | |
2300 | grub-core/script/argv.c | 16 +++++++++-- | |
2301 | grub-core/script/lexer.c | 21 ++++++++++++-- | |
2302 | grub-core/video/bitmap.c | 25 +++++++++++------ | |
2303 | grub-core/video/readers/png.c | 13 +++++++-- | |
2304 | 23 files changed, 382 insertions(+), 113 deletions(-) | |
2305 | ||
2306 | diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c | |
2307 | index 5e3ec0d5e..cc5971f4d 100644 | |
2308 | --- a/grub-core/commands/legacycfg.c | |
2309 | +++ b/grub-core/commands/legacycfg.c | |
2310 | @@ -32,6 +32,7 @@ | |
2311 | #include <grub/auth.h> | |
2312 | #include <grub/disk.h> | |
2313 | #include <grub/partition.h> | |
2314 | +#include <grub/safemath.h> | |
2315 | ||
2316 | GRUB_MOD_LICENSE ("GPLv3+"); | |
2317 | ||
2318 | @@ -104,13 +105,22 @@ legacy_file (const char *filename) | |
2319 | if (newsuffix) | |
2320 | { | |
2321 | char *t; | |
2322 | - | |
2323 | + grub_size_t sz; | |
2324 | + | |
2325 | + if (grub_add (grub_strlen (suffix), grub_strlen (newsuffix), &sz) || | |
2326 | + grub_add (sz, 1, &sz)) | |
2327 | + { | |
2328 | + grub_errno = GRUB_ERR_OUT_OF_RANGE; | |
2329 | + goto fail_0; | |
2330 | + } | |
2331 | + | |
2332 | t = suffix; | |
2333 | - suffix = grub_realloc (suffix, grub_strlen (suffix) | |
2334 | - + grub_strlen (newsuffix) + 1); | |
2335 | + suffix = grub_realloc (suffix, sz); | |
2336 | if (!suffix) | |
2337 | { | |
2338 | grub_free (t); | |
2339 | + | |
2340 | + fail_0: | |
2341 | grub_free (entrysrc); | |
2342 | grub_free (parsed); | |
2343 | grub_free (newsuffix); | |
2344 | @@ -154,13 +164,22 @@ legacy_file (const char *filename) | |
2345 | else | |
2346 | { | |
2347 | char *t; | |
2348 | + grub_size_t sz; | |
2349 | + | |
2350 | + if (grub_add (grub_strlen (entrysrc), grub_strlen (parsed), &sz) || | |
2351 | + grub_add (sz, 1, &sz)) | |
2352 | + { | |
2353 | + grub_errno = GRUB_ERR_OUT_OF_RANGE; | |
2354 | + goto fail_1; | |
2355 | + } | |
2356 | ||
2357 | t = entrysrc; | |
2358 | - entrysrc = grub_realloc (entrysrc, grub_strlen (entrysrc) | |
2359 | - + grub_strlen (parsed) + 1); | |
2360 | + entrysrc = grub_realloc (entrysrc, sz); | |
2361 | if (!entrysrc) | |
2362 | { | |
2363 | grub_free (t); | |
2364 | + | |
2365 | + fail_1: | |
2366 | grub_free (parsed); | |
2367 | grub_free (suffix); | |
2368 | return grub_errno; | |
2369 | diff --git a/grub-core/commands/wildcard.c b/grub-core/commands/wildcard.c | |
2370 | index 4a106ca04..cc3290311 100644 | |
2371 | --- a/grub-core/commands/wildcard.c | |
2372 | +++ b/grub-core/commands/wildcard.c | |
2373 | @@ -23,6 +23,7 @@ | |
2374 | #include <grub/file.h> | |
2375 | #include <grub/device.h> | |
2376 | #include <grub/script_sh.h> | |
2377 | +#include <grub/safemath.h> | |
2378 | ||
2379 | #include <regex.h> | |
2380 | ||
2381 | @@ -48,6 +49,7 @@ merge (char **dest, char **ps) | |
2382 | int i; | |
2383 | int j; | |
2384 | char **p; | |
2385 | + grub_size_t sz; | |
2386 | ||
2387 | if (! dest) | |
2388 | return ps; | |
2389 | @@ -60,7 +62,12 @@ merge (char **dest, char **ps) | |
2390 | for (j = 0; ps[j]; j++) | |
2391 | ; | |
2392 | ||
2393 | - p = grub_realloc (dest, sizeof (char*) * (i + j + 1)); | |
2394 | + if (grub_add (i, j, &sz) || | |
2395 | + grub_add (sz, 1, &sz) || | |
2396 | + grub_mul (sz, sizeof (char *), &sz)) | |
2397 | + return dest; | |
2398 | + | |
2399 | + p = grub_realloc (dest, sz); | |
2400 | if (! p) | |
2401 | { | |
2402 | grub_free (dest); | |
2403 | @@ -115,8 +122,15 @@ make_regex (const char *start, const char *end, regex_t *regexp) | |
2404 | char ch; | |
2405 | int i = 0; | |
2406 | unsigned len = end - start; | |
2407 | - char *buffer = grub_malloc (len * 2 + 2 + 1); /* worst case size. */ | |
2408 | + char *buffer; | |
2409 | + grub_size_t sz; | |
2410 | ||
2411 | + /* Worst case size is (len * 2 + 2 + 1). */ | |
2412 | + if (grub_mul (len, 2, &sz) || | |
2413 | + grub_add (sz, 3, &sz)) | |
2414 | + return 1; | |
2415 | + | |
2416 | + buffer = grub_malloc (sz); | |
2417 | if (! buffer) | |
2418 | return 1; | |
2419 | ||
2420 | @@ -226,6 +240,7 @@ match_devices_iter (const char *name, void *data) | |
2421 | struct match_devices_ctx *ctx = data; | |
2422 | char **t; | |
2423 | char *buffer; | |
2424 | + grub_size_t sz; | |
2425 | ||
2426 | /* skip partitions if asked to. */ | |
2427 | if (ctx->noparts && grub_strchr (name, ',')) | |
2428 | @@ -239,11 +254,16 @@ match_devices_iter (const char *name, void *data) | |
2429 | if (regexec (ctx->regexp, buffer, 0, 0, 0)) | |
2430 | { | |
2431 | grub_dprintf ("expand", "not matched\n"); | |
2432 | + fail: | |
2433 | grub_free (buffer); | |
2434 | return 0; | |
2435 | } | |
2436 | ||
2437 | - t = grub_realloc (ctx->devs, sizeof (char*) * (ctx->ndev + 2)); | |
2438 | + if (grub_add (ctx->ndev, 2, &sz) || | |
2439 | + grub_mul (sz, sizeof (char *), &sz)) | |
2440 | + goto fail; | |
2441 | + | |
2442 | + t = grub_realloc (ctx->devs, sz); | |
2443 | if (! t) | |
2444 | { | |
2445 | grub_free (buffer); | |
2446 | @@ -300,6 +320,7 @@ match_files_iter (const char *name, | |
2447 | struct match_files_ctx *ctx = data; | |
2448 | char **t; | |
2449 | char *buffer; | |
2450 | + grub_size_t sz; | |
2451 | ||
2452 | /* skip . and .. names */ | |
2453 | if (grub_strcmp(".", name) == 0 || grub_strcmp("..", name) == 0) | |
2454 | @@ -315,9 +336,14 @@ match_files_iter (const char *name, | |
2455 | if (! buffer) | |
2456 | return 1; | |
2457 | ||
2458 | - t = grub_realloc (ctx->files, sizeof (char*) * (ctx->nfile + 2)); | |
2459 | - if (! t) | |
2460 | + if (grub_add (ctx->nfile, 2, &sz) || | |
2461 | + grub_mul (sz, sizeof (char *), &sz)) | |
2462 | + goto fail; | |
2463 | + | |
2464 | + t = grub_realloc (ctx->files, sz); | |
2465 | + if (!t) | |
2466 | { | |
2467 | + fail: | |
2468 | grub_free (buffer); | |
2469 | return 1; | |
2470 | } | |
2471 | diff --git a/grub-core/disk/ldm.c b/grub-core/disk/ldm.c | |
2472 | index e6323701a..58f8a53e1 100644 | |
2473 | --- a/grub-core/disk/ldm.c | |
2474 | +++ b/grub-core/disk/ldm.c | |
2475 | @@ -25,6 +25,7 @@ | |
2476 | #include <grub/msdos_partition.h> | |
2477 | #include <grub/gpt_partition.h> | |
2478 | #include <grub/i18n.h> | |
2479 | +#include <grub/safemath.h> | |
2480 | ||
2481 | #ifdef GRUB_UTIL | |
2482 | #include <grub/emu/misc.h> | |
2483 | @@ -289,6 +290,7 @@ make_vg (grub_disk_t disk, | |
2484 | struct grub_ldm_vblk vblk[GRUB_DISK_SECTOR_SIZE | |
2485 | / sizeof (struct grub_ldm_vblk)]; | |
2486 | unsigned i; | |
2487 | + grub_size_t sz; | |
2488 | err = grub_disk_read (disk, cursec, 0, | |
2489 | sizeof(vblk), &vblk); | |
2490 | if (err) | |
2491 | @@ -350,7 +352,13 @@ make_vg (grub_disk_t disk, | |
2492 | grub_free (lv); | |
2493 | goto fail2; | |
2494 | } | |
2495 | - lv->name = grub_malloc (*ptr + 1); | |
2496 | + if (grub_add (*ptr, 1, &sz)) | |
2497 | + { | |
2498 | + grub_free (lv->internal_id); | |
2499 | + grub_free (lv); | |
2500 | + goto fail2; | |
2501 | + } | |
2502 | + lv->name = grub_malloc (sz); | |
2503 | if (!lv->name) | |
2504 | { | |
2505 | grub_free (lv->internal_id); | |
2506 | @@ -599,10 +607,13 @@ make_vg (grub_disk_t disk, | |
2507 | if (lv->segments->node_alloc == lv->segments->node_count) | |
2508 | { | |
2509 | void *t; | |
2510 | - lv->segments->node_alloc *= 2; | |
2511 | - t = grub_realloc (lv->segments->nodes, | |
2512 | - sizeof (*lv->segments->nodes) | |
2513 | - * lv->segments->node_alloc); | |
2514 | + grub_size_t sz; | |
2515 | + | |
2516 | + if (grub_mul (lv->segments->node_alloc, 2, &lv->segments->node_alloc) || | |
2517 | + grub_mul (lv->segments->node_alloc, sizeof (*lv->segments->nodes), &sz)) | |
2518 | + goto fail2; | |
2519 | + | |
2520 | + t = grub_realloc (lv->segments->nodes, sz); | |
2521 | if (!t) | |
2522 | goto fail2; | |
2523 | lv->segments->nodes = t; | |
2524 | @@ -723,10 +734,13 @@ make_vg (grub_disk_t disk, | |
2525 | if (comp->segment_alloc == comp->segment_count) | |
2526 | { | |
2527 | void *t; | |
2528 | - comp->segment_alloc *= 2; | |
2529 | - t = grub_realloc (comp->segments, | |
2530 | - comp->segment_alloc | |
2531 | - * sizeof (*comp->segments)); | |
2532 | + grub_size_t sz; | |
2533 | + | |
2534 | + if (grub_mul (comp->segment_alloc, 2, &comp->segment_alloc) || | |
2535 | + grub_mul (comp->segment_alloc, sizeof (*comp->segments), &sz)) | |
2536 | + goto fail2; | |
2537 | + | |
2538 | + t = grub_realloc (comp->segments, sz); | |
2539 | if (!t) | |
2540 | goto fail2; | |
2541 | comp->segments = t; | |
2542 | diff --git a/grub-core/font/font.c b/grub-core/font/font.c | |
2543 | index 8e118b315..5edb477ac 100644 | |
2544 | --- a/grub-core/font/font.c | |
2545 | +++ b/grub-core/font/font.c | |
2546 | @@ -30,6 +30,7 @@ | |
2547 | #include <grub/unicode.h> | |
2548 | #include <grub/fontformat.h> | |
2549 | #include <grub/env.h> | |
2550 | +#include <grub/safemath.h> | |
2551 | ||
2552 | GRUB_MOD_LICENSE ("GPLv3+"); | |
2553 | ||
2554 | @@ -360,9 +361,13 @@ static char * | |
2555 | read_section_as_string (struct font_file_section *section) | |
2556 | { | |
2557 | char *str; | |
2558 | + grub_size_t sz; | |
2559 | grub_ssize_t ret; | |
2560 | ||
2561 | - str = grub_malloc (section->length + 1); | |
2562 | + if (grub_add (section->length, 1, &sz)) | |
2563 | + return NULL; | |
2564 | + | |
2565 | + str = grub_malloc (sz); | |
2566 | if (!str) | |
2567 | return 0; | |
2568 | ||
2569 | diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c | |
2570 | index 4b8380439..27339bdb3 100644 | |
2571 | --- a/grub-core/fs/btrfs.c | |
2572 | +++ b/grub-core/fs/btrfs.c | |
2573 | @@ -40,6 +40,7 @@ | |
2574 | #include <grub/btrfs.h> | |
2575 | #include <grub/crypto.h> | |
2576 | #include <grub/diskfilter.h> | |
2577 | +#include <grub/safemath.h> | |
2578 | ||
2579 | GRUB_MOD_LICENSE ("GPLv3+"); | |
2580 | ||
2581 | @@ -331,9 +332,13 @@ save_ref (struct grub_btrfs_leaf_descriptor *desc, | |
2582 | if (desc->allocated < desc->depth) | |
2583 | { | |
2584 | void *newdata; | |
2585 | - desc->allocated *= 2; | |
2586 | - newdata = grub_realloc (desc->data, sizeof (desc->data[0]) | |
2587 | - * desc->allocated); | |
2588 | + grub_size_t sz; | |
2589 | + | |
2590 | + if (grub_mul (desc->allocated, 2, &desc->allocated) || | |
2591 | + grub_mul (desc->allocated, sizeof (desc->data[0]), &sz)) | |
2592 | + return GRUB_ERR_OUT_OF_RANGE; | |
2593 | + | |
2594 | + newdata = grub_realloc (desc->data, sz); | |
2595 | if (!newdata) | |
2596 | return grub_errno; | |
2597 | desc->data = newdata; | |
2598 | @@ -624,16 +629,21 @@ find_device (struct grub_btrfs_data *data, grub_uint64_t id) | |
2599 | if (data->n_devices_attached > data->n_devices_allocated) | |
2600 | { | |
2601 | void *tmp; | |
2602 | - data->n_devices_allocated = 2 * data->n_devices_attached + 1; | |
2603 | - data->devices_attached | |
2604 | - = grub_realloc (tmp = data->devices_attached, | |
2605 | - data->n_devices_allocated | |
2606 | - * sizeof (data->devices_attached[0])); | |
2607 | + grub_size_t sz; | |
2608 | + | |
2609 | + if (grub_mul (data->n_devices_attached, 2, &data->n_devices_allocated) || | |
2610 | + grub_add (data->n_devices_allocated, 1, &data->n_devices_allocated) || | |
2611 | + grub_mul (data->n_devices_allocated, sizeof (data->devices_attached[0]), &sz)) | |
2612 | + goto fail; | |
2613 | + | |
2614 | + data->devices_attached = grub_realloc (tmp = data->devices_attached, sz); | |
2615 | if (!data->devices_attached) | |
2616 | { | |
2617 | + data->devices_attached = tmp; | |
2618 | + | |
2619 | + fail: | |
2620 | if (ctx.dev_found) | |
2621 | grub_device_close (ctx.dev_found); | |
2622 | - data->devices_attached = tmp; | |
2623 | return NULL; | |
2624 | } | |
2625 | } | |
2626 | diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c | |
2627 | index 9b389802a..ac33bcd68 100644 | |
2628 | --- a/grub-core/fs/ext2.c | |
2629 | +++ b/grub-core/fs/ext2.c | |
2630 | @@ -46,6 +46,7 @@ | |
2631 | #include <grub/dl.h> | |
2632 | #include <grub/types.h> | |
2633 | #include <grub/fshelp.h> | |
2634 | +#include <grub/safemath.h> | |
2635 | ||
2636 | GRUB_MOD_LICENSE ("GPLv3+"); | |
2637 | ||
2638 | @@ -703,6 +704,7 @@ grub_ext2_read_symlink (grub_fshelp_node_t node) | |
2639 | { | |
2640 | char *symlink; | |
2641 | struct grub_fshelp_node *diro = node; | |
2642 | + grub_size_t sz; | |
2643 | ||
2644 | if (! diro->inode_read) | |
2645 | { | |
2646 | @@ -717,7 +719,13 @@ grub_ext2_read_symlink (grub_fshelp_node_t node) | |
2647 | } | |
2648 | } | |
2649 | ||
2650 | - symlink = grub_malloc (grub_le_to_cpu32 (diro->inode.size) + 1); | |
2651 | + if (grub_add (grub_le_to_cpu32 (diro->inode.size), 1, &sz)) | |
2652 | + { | |
2653 | + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); | |
2654 | + return NULL; | |
2655 | + } | |
2656 | + | |
2657 | + symlink = grub_malloc (sz); | |
2658 | if (! symlink) | |
2659 | return 0; | |
2660 | ||
2661 | diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c | |
2662 | index 4f1b52a55..7ba5b300b 100644 | |
2663 | --- a/grub-core/fs/iso9660.c | |
2664 | +++ b/grub-core/fs/iso9660.c | |
2665 | @@ -28,6 +28,7 @@ | |
2666 | #include <grub/fshelp.h> | |
2667 | #include <grub/charset.h> | |
2668 | #include <grub/datetime.h> | |
2669 | +#include <grub/safemath.h> | |
2670 | ||
2671 | GRUB_MOD_LICENSE ("GPLv3+"); | |
2672 | ||
2673 | @@ -531,8 +532,13 @@ add_part (struct iterate_dir_ctx *ctx, | |
2674 | int len2) | |
2675 | { | |
2676 | int size = ctx->symlink ? grub_strlen (ctx->symlink) : 0; | |
2677 | + grub_size_t sz; | |
2678 | ||
2679 | - ctx->symlink = grub_realloc (ctx->symlink, size + len2 + 1); | |
2680 | + if (grub_add (size, len2, &sz) || | |
2681 | + grub_add (sz, 1, &sz)) | |
2682 | + return; | |
2683 | + | |
2684 | + ctx->symlink = grub_realloc (ctx->symlink, sz); | |
2685 | if (! ctx->symlink) | |
2686 | return; | |
2687 | ||
2688 | @@ -560,17 +566,24 @@ susp_iterate_dir (struct grub_iso9660_susp_entry *entry, | |
2689 | { | |
2690 | grub_size_t off = 0, csize = 1; | |
2691 | char *old; | |
2692 | + grub_size_t sz; | |
2693 | + | |
2694 | csize = entry->len - 5; | |
2695 | old = ctx->filename; | |
2696 | if (ctx->filename_alloc) | |
2697 | { | |
2698 | off = grub_strlen (ctx->filename); | |
2699 | - ctx->filename = grub_realloc (ctx->filename, csize + off + 1); | |
2700 | + if (grub_add (csize, off, &sz) || | |
2701 | + grub_add (sz, 1, &sz)) | |
2702 | + return GRUB_ERR_OUT_OF_RANGE; | |
2703 | + ctx->filename = grub_realloc (ctx->filename, sz); | |
2704 | } | |
2705 | else | |
2706 | { | |
2707 | off = 0; | |
2708 | - ctx->filename = grub_zalloc (csize + 1); | |
2709 | + if (grub_add (csize, 1, &sz)) | |
2710 | + return GRUB_ERR_OUT_OF_RANGE; | |
2711 | + ctx->filename = grub_zalloc (sz); | |
2712 | } | |
2713 | if (!ctx->filename) | |
2714 | { | |
2715 | @@ -776,14 +789,18 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, | |
2716 | if (node->have_dirents >= node->alloc_dirents) | |
2717 | { | |
2718 | struct grub_fshelp_node *new_node; | |
2719 | - node->alloc_dirents *= 2; | |
2720 | - new_node = grub_realloc (node, | |
2721 | - sizeof (struct grub_fshelp_node) | |
2722 | - + ((node->alloc_dirents | |
2723 | - - ARRAY_SIZE (node->dirents)) | |
2724 | - * sizeof (node->dirents[0]))); | |
2725 | + grub_size_t sz; | |
2726 | + | |
2727 | + if (grub_mul (node->alloc_dirents, 2, &node->alloc_dirents) || | |
2728 | + grub_sub (node->alloc_dirents, ARRAY_SIZE (node->dirents), &sz) || | |
2729 | + grub_mul (sz, sizeof (node->dirents[0]), &sz) || | |
2730 | + grub_add (sz, sizeof (struct grub_fshelp_node), &sz)) | |
2731 | + goto fail_0; | |
2732 | + | |
2733 | + new_node = grub_realloc (node, sz); | |
2734 | if (!new_node) | |
2735 | { | |
2736 | + fail_0: | |
2737 | if (ctx.filename_alloc) | |
2738 | grub_free (ctx.filename); | |
2739 | grub_free (node); | |
2740 | @@ -799,14 +816,18 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, | |
2741 | * sizeof (node->dirents[0]) < grub_strlen (ctx.symlink) + 1) | |
2742 | { | |
2743 | struct grub_fshelp_node *new_node; | |
2744 | - new_node = grub_realloc (node, | |
2745 | - sizeof (struct grub_fshelp_node) | |
2746 | - + ((node->alloc_dirents | |
2747 | - - ARRAY_SIZE (node->dirents)) | |
2748 | - * sizeof (node->dirents[0])) | |
2749 | - + grub_strlen (ctx.symlink) + 1); | |
2750 | + grub_size_t sz; | |
2751 | + | |
2752 | + if (grub_sub (node->alloc_dirents, ARRAY_SIZE (node->dirents), &sz) || | |
2753 | + grub_mul (sz, sizeof (node->dirents[0]), &sz) || | |
2754 | + grub_add (sz, sizeof (struct grub_fshelp_node) + 1, &sz) || | |
2755 | + grub_add (sz, grub_strlen (ctx.symlink), &sz)) | |
2756 | + goto fail_1; | |
2757 | + | |
2758 | + new_node = grub_realloc (node, sz); | |
2759 | if (!new_node) | |
2760 | { | |
2761 | + fail_1: | |
2762 | if (ctx.filename_alloc) | |
2763 | grub_free (ctx.filename); | |
2764 | grub_free (node); | |
2765 | diff --git a/grub-core/fs/sfs.c b/grub-core/fs/sfs.c | |
2766 | index 90f7fb379..de2b107a4 100644 | |
2767 | --- a/grub-core/fs/sfs.c | |
2768 | +++ b/grub-core/fs/sfs.c | |
2769 | @@ -26,6 +26,7 @@ | |
2770 | #include <grub/types.h> | |
2771 | #include <grub/fshelp.h> | |
2772 | #include <grub/charset.h> | |
2773 | +#include <grub/safemath.h> | |
2774 | ||
2775 | GRUB_MOD_LICENSE ("GPLv3+"); | |
2776 | ||
2777 | @@ -307,10 +308,15 @@ grub_sfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) | |
2778 | if (node->cache && node->cache_size >= node->cache_allocated) | |
2779 | { | |
2780 | struct cache_entry *e = node->cache; | |
2781 | - e = grub_realloc (node->cache,node->cache_allocated * 2 | |
2782 | - * sizeof (e[0])); | |
2783 | + grub_size_t sz; | |
2784 | + | |
2785 | + if (grub_mul (node->cache_allocated, 2 * sizeof (e[0]), &sz)) | |
2786 | + goto fail; | |
2787 | + | |
2788 | + e = grub_realloc (node->cache, sz); | |
2789 | if (!e) | |
2790 | { | |
2791 | + fail: | |
2792 | grub_errno = 0; | |
2793 | grub_free (node->cache); | |
2794 | node->cache = 0; | |
2795 | @@ -477,10 +483,16 @@ grub_sfs_create_node (struct grub_fshelp_node **node, | |
2796 | grub_size_t len = grub_strlen (name); | |
2797 | grub_uint8_t *name_u8; | |
2798 | int ret; | |
2799 | + grub_size_t sz; | |
2800 | + | |
2801 | + if (grub_mul (len, GRUB_MAX_UTF8_PER_LATIN1, &sz) || | |
2802 | + grub_add (sz, 1, &sz)) | |
2803 | + return 1; | |
2804 | + | |
2805 | *node = grub_malloc (sizeof (**node)); | |
2806 | if (!*node) | |
2807 | return 1; | |
2808 | - name_u8 = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1); | |
2809 | + name_u8 = grub_malloc (sz); | |
2810 | if (!name_u8) | |
2811 | { | |
2812 | grub_free (*node); | |
2813 | @@ -724,8 +736,13 @@ grub_sfs_label (grub_device_t device, char **label) | |
2814 | data = grub_sfs_mount (disk); | |
2815 | if (data) | |
2816 | { | |
2817 | - grub_size_t len = grub_strlen (data->label); | |
2818 | - *label = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1); | |
2819 | + grub_size_t sz, len = grub_strlen (data->label); | |
2820 | + | |
2821 | + if (grub_mul (len, GRUB_MAX_UTF8_PER_LATIN1, &sz) || | |
2822 | + grub_add (sz, 1, &sz)) | |
2823 | + return GRUB_ERR_OUT_OF_RANGE; | |
2824 | + | |
2825 | + *label = grub_malloc (sz); | |
2826 | if (*label) | |
2827 | *grub_latin1_to_utf8 ((grub_uint8_t *) *label, | |
2828 | (const grub_uint8_t *) data->label, | |
2829 | diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c | |
2830 | index 95d5c1e1f..785123894 100644 | |
2831 | --- a/grub-core/fs/squash4.c | |
2832 | +++ b/grub-core/fs/squash4.c | |
2833 | @@ -26,6 +26,7 @@ | |
2834 | #include <grub/types.h> | |
2835 | #include <grub/fshelp.h> | |
2836 | #include <grub/deflate.h> | |
2837 | +#include <grub/safemath.h> | |
2838 | #include <minilzo.h> | |
2839 | ||
2840 | #include "xz.h" | |
2841 | @@ -459,7 +460,17 @@ grub_squash_read_symlink (grub_fshelp_node_t node) | |
2842 | { | |
2843 | char *ret; | |
2844 | grub_err_t err; | |
2845 | - ret = grub_malloc (grub_le_to_cpu32 (node->ino.symlink.namelen) + 1); | |
2846 | + grub_size_t sz; | |
2847 | + | |
2848 | + if (grub_add (grub_le_to_cpu32 (node->ino.symlink.namelen), 1, &sz)) | |
2849 | + { | |
2850 | + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); | |
2851 | + return NULL; | |
2852 | + } | |
2853 | + | |
2854 | + ret = grub_malloc (sz); | |
2855 | + if (!ret) | |
2856 | + return NULL; | |
2857 | ||
2858 | err = read_chunk (node->data, ret, | |
2859 | grub_le_to_cpu32 (node->ino.symlink.namelen), | |
2860 | @@ -506,11 +517,16 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, | |
2861 | ||
2862 | { | |
2863 | grub_fshelp_node_t node; | |
2864 | - node = grub_malloc (sizeof (*node) + dir->stsize * sizeof (dir->stack[0])); | |
2865 | + grub_size_t sz; | |
2866 | + | |
2867 | + if (grub_mul (dir->stsize, sizeof (dir->stack[0]), &sz) || | |
2868 | + grub_add (sz, sizeof (*node), &sz)) | |
2869 | + return 0; | |
2870 | + | |
2871 | + node = grub_malloc (sz); | |
2872 | if (!node) | |
2873 | return 0; | |
2874 | - grub_memcpy (node, dir, | |
2875 | - sizeof (*node) + dir->stsize * sizeof (dir->stack[0])); | |
2876 | + grub_memcpy (node, dir, sz); | |
2877 | if (hook (".", GRUB_FSHELP_DIR, node, hook_data)) | |
2878 | return 1; | |
2879 | ||
2880 | @@ -518,12 +534,15 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, | |
2881 | { | |
2882 | grub_err_t err; | |
2883 | ||
2884 | - node = grub_malloc (sizeof (*node) + dir->stsize * sizeof (dir->stack[0])); | |
2885 | + if (grub_mul (dir->stsize, sizeof (dir->stack[0]), &sz) || | |
2886 | + grub_add (sz, sizeof (*node), &sz)) | |
2887 | + return 0; | |
2888 | + | |
2889 | + node = grub_malloc (sz); | |
2890 | if (!node) | |
2891 | return 0; | |
2892 | ||
2893 | - grub_memcpy (node, dir, | |
2894 | - sizeof (*node) + dir->stsize * sizeof (dir->stack[0])); | |
2895 | + grub_memcpy (node, dir, sz); | |
2896 | ||
2897 | node->stsize--; | |
2898 | err = read_chunk (dir->data, &node->ino, sizeof (node->ino), | |
2899 | @@ -557,6 +576,7 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, | |
2900 | enum grub_fshelp_filetype filetype = GRUB_FSHELP_REG; | |
2901 | struct grub_squash_dirent di; | |
2902 | struct grub_squash_inode ino; | |
2903 | + grub_size_t sz; | |
2904 | ||
2905 | err = read_chunk (dir->data, &di, sizeof (di), | |
2906 | grub_le_to_cpu64 (dir->data->sb.diroffset) | |
2907 | @@ -589,13 +609,16 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, | |
2908 | if (grub_le_to_cpu16 (di.type) == SQUASH_TYPE_SYMLINK) | |
2909 | filetype = GRUB_FSHELP_SYMLINK; | |
2910 | ||
2911 | - node = grub_malloc (sizeof (*node) | |
2912 | - + (dir->stsize + 1) * sizeof (dir->stack[0])); | |
2913 | + if (grub_add (dir->stsize, 1, &sz) || | |
2914 | + grub_mul (sz, sizeof (dir->stack[0]), &sz) || | |
2915 | + grub_add (sz, sizeof (*node), &sz)) | |
2916 | + return 0; | |
2917 | + | |
2918 | + node = grub_malloc (sz); | |
2919 | if (! node) | |
2920 | return 0; | |
2921 | ||
2922 | - grub_memcpy (node, dir, | |
2923 | - sizeof (*node) + dir->stsize * sizeof (dir->stack[0])); | |
2924 | + grub_memcpy (node, dir, sz - sizeof(dir->stack[0])); | |
2925 | ||
2926 | node->ino = ino; | |
2927 | node->stack[node->stsize].ino_chunk = grub_le_to_cpu32 (dh.ino_chunk); | |
2928 | diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c | |
2929 | index a83761674..21ac7f446 100644 | |
2930 | --- a/grub-core/fs/udf.c | |
2931 | +++ b/grub-core/fs/udf.c | |
2932 | @@ -28,6 +28,7 @@ | |
2933 | #include <grub/charset.h> | |
2934 | #include <grub/datetime.h> | |
2935 | #include <grub/udf.h> | |
2936 | +#include <grub/safemath.h> | |
2937 | ||
2938 | GRUB_MOD_LICENSE ("GPLv3+"); | |
2939 | ||
2940 | @@ -890,9 +891,19 @@ read_string (const grub_uint8_t *raw, grub_size_t sz, char *outbuf) | |
2941 | utf16[i] = (raw[2 * i + 1] << 8) | raw[2*i + 2]; | |
2942 | } | |
2943 | if (!outbuf) | |
2944 | - outbuf = grub_malloc (utf16len * GRUB_MAX_UTF8_PER_UTF16 + 1); | |
2945 | + { | |
2946 | + grub_size_t size; | |
2947 | + | |
2948 | + if (grub_mul (utf16len, GRUB_MAX_UTF8_PER_UTF16, &size) || | |
2949 | + grub_add (size, 1, &size)) | |
2950 | + goto fail; | |
2951 | + | |
2952 | + outbuf = grub_malloc (size); | |
2953 | + } | |
2954 | if (outbuf) | |
2955 | *grub_utf16_to_utf8 ((grub_uint8_t *) outbuf, utf16, utf16len) = '\0'; | |
2956 | + | |
2957 | + fail: | |
2958 | grub_free (utf16); | |
2959 | return outbuf; | |
2960 | } | |
2961 | @@ -1005,7 +1016,7 @@ grub_udf_read_symlink (grub_fshelp_node_t node) | |
2962 | grub_size_t sz = U64 (node->block.fe.file_size); | |
2963 | grub_uint8_t *raw; | |
2964 | const grub_uint8_t *ptr; | |
2965 | - char *out, *optr; | |
2966 | + char *out = NULL, *optr; | |
2967 | ||
2968 | if (sz < 4) | |
2969 | return NULL; | |
2970 | @@ -1013,14 +1024,16 @@ grub_udf_read_symlink (grub_fshelp_node_t node) | |
2971 | if (!raw) | |
2972 | return NULL; | |
2973 | if (grub_udf_read_file (node, NULL, NULL, 0, sz, (char *) raw) < 0) | |
2974 | - { | |
2975 | - grub_free (raw); | |
2976 | - return NULL; | |
2977 | - } | |
2978 | + goto fail_1; | |
2979 | ||
2980 | - out = grub_malloc (sz * 2 + 1); | |
2981 | + if (grub_mul (sz, 2, &sz) || | |
2982 | + grub_add (sz, 1, &sz)) | |
2983 | + goto fail_0; | |
2984 | + | |
2985 | + out = grub_malloc (sz); | |
2986 | if (!out) | |
2987 | { | |
2988 | + fail_0: | |
2989 | grub_free (raw); | |
2990 | return NULL; | |
2991 | } | |
2992 | @@ -1031,17 +1044,17 @@ grub_udf_read_symlink (grub_fshelp_node_t node) | |
2993 | { | |
2994 | grub_size_t s; | |
2995 | if ((grub_size_t) (ptr - raw + 4) > sz) | |
2996 | - goto fail; | |
2997 | + goto fail_1; | |
2998 | if (!(ptr[2] == 0 && ptr[3] == 0)) | |
2999 | - goto fail; | |
3000 | + goto fail_1; | |
3001 | s = 4 + ptr[1]; | |
3002 | if ((grub_size_t) (ptr - raw + s) > sz) | |
3003 | - goto fail; | |
3004 | + goto fail_1; | |
3005 | switch (*ptr) | |
3006 | { | |
3007 | case 1: | |
3008 | if (ptr[1]) | |
3009 | - goto fail; | |
3010 | + goto fail_1; | |
3011 | /* Fallthrough. */ | |
3012 | case 2: | |
3013 | /* in 4 bytes. out: 1 byte. */ | |
3014 | @@ -1066,11 +1079,11 @@ grub_udf_read_symlink (grub_fshelp_node_t node) | |
3015 | if (optr != out) | |
3016 | *optr++ = '/'; | |
3017 | if (!read_string (ptr + 4, s - 4, optr)) | |
3018 | - goto fail; | |
3019 | + goto fail_1; | |
3020 | optr += grub_strlen (optr); | |
3021 | break; | |
3022 | default: | |
3023 | - goto fail; | |
3024 | + goto fail_1; | |
3025 | } | |
3026 | ptr += s; | |
3027 | } | |
3028 | @@ -1078,7 +1091,7 @@ grub_udf_read_symlink (grub_fshelp_node_t node) | |
3029 | grub_free (raw); | |
3030 | return out; | |
3031 | ||
3032 | - fail: | |
3033 | + fail_1: | |
3034 | grub_free (raw); | |
3035 | grub_free (out); | |
3036 | grub_error (GRUB_ERR_BAD_FS, "invalid symlink"); | |
3037 | diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c | |
3038 | index 96ffecbfc..ea6590290 100644 | |
3039 | --- a/grub-core/fs/xfs.c | |
3040 | +++ b/grub-core/fs/xfs.c | |
3041 | @@ -25,6 +25,7 @@ | |
3042 | #include <grub/dl.h> | |
3043 | #include <grub/types.h> | |
3044 | #include <grub/fshelp.h> | |
3045 | +#include <grub/safemath.h> | |
3046 | ||
3047 | GRUB_MOD_LICENSE ("GPLv3+"); | |
3048 | ||
3049 | @@ -899,6 +900,7 @@ static struct grub_xfs_data * | |
3050 | grub_xfs_mount (grub_disk_t disk) | |
3051 | { | |
3052 | struct grub_xfs_data *data = 0; | |
3053 | + grub_size_t sz; | |
3054 | ||
3055 | data = grub_zalloc (sizeof (struct grub_xfs_data)); | |
3056 | if (!data) | |
3057 | @@ -913,10 +915,11 @@ grub_xfs_mount (grub_disk_t disk) | |
3058 | if (!grub_xfs_sb_valid(data)) | |
3059 | goto fail; | |
3060 | ||
3061 | - data = grub_realloc (data, | |
3062 | - sizeof (struct grub_xfs_data) | |
3063 | - - sizeof (struct grub_xfs_inode) | |
3064 | - + grub_xfs_inode_size(data) + 1); | |
3065 | + if (grub_add (grub_xfs_inode_size (data), | |
3066 | + sizeof (struct grub_xfs_data) - sizeof (struct grub_xfs_inode) + 1, &sz)) | |
3067 | + goto fail; | |
3068 | + | |
3069 | + data = grub_realloc (data, sz); | |
3070 | ||
3071 | if (! data) | |
3072 | goto fail; | |
3073 | diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c | |
3074 | index 381dde556..36d0373a6 100644 | |
3075 | --- a/grub-core/fs/zfs/zfs.c | |
3076 | +++ b/grub-core/fs/zfs/zfs.c | |
3077 | @@ -55,6 +55,7 @@ | |
3078 | #include <grub/deflate.h> | |
3079 | #include <grub/crypto.h> | |
3080 | #include <grub/i18n.h> | |
3081 | +#include <grub/safemath.h> | |
3082 | ||
3083 | GRUB_MOD_LICENSE ("GPLv3+"); | |
3084 | ||
3085 | @@ -773,11 +774,14 @@ fill_vdev_info (struct grub_zfs_data *data, | |
3086 | if (data->n_devices_attached > data->n_devices_allocated) | |
3087 | { | |
3088 | void *tmp; | |
3089 | - data->n_devices_allocated = 2 * data->n_devices_attached + 1; | |
3090 | - data->devices_attached | |
3091 | - = grub_realloc (tmp = data->devices_attached, | |
3092 | - data->n_devices_allocated | |
3093 | - * sizeof (data->devices_attached[0])); | |
3094 | + grub_size_t sz; | |
3095 | + | |
3096 | + if (grub_mul (data->n_devices_attached, 2, &data->n_devices_allocated) || | |
3097 | + grub_add (data->n_devices_allocated, 1, &data->n_devices_allocated) || | |
3098 | + grub_mul (data->n_devices_allocated, sizeof (data->devices_attached[0]), &sz)) | |
3099 | + return GRUB_ERR_OUT_OF_RANGE; | |
3100 | + | |
3101 | + data->devices_attached = grub_realloc (tmp = data->devices_attached, sz); | |
3102 | if (!data->devices_attached) | |
3103 | { | |
3104 | data->devices_attached = tmp; | |
3105 | @@ -3468,14 +3472,18 @@ grub_zfs_nvlist_lookup_nvlist (const char *nvlist, const char *name) | |
3106 | { | |
3107 | char *nvpair; | |
3108 | char *ret; | |
3109 | - grub_size_t size; | |
3110 | + grub_size_t size, sz; | |
3111 | int found; | |
3112 | ||
3113 | found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST, &nvpair, | |
3114 | &size, 0); | |
3115 | if (!found) | |
3116 | return 0; | |
3117 | - ret = grub_zalloc (size + 3 * sizeof (grub_uint32_t)); | |
3118 | + | |
3119 | + if (grub_add (size, 3 * sizeof (grub_uint32_t), &sz)) | |
3120 | + return 0; | |
3121 | + | |
3122 | + ret = grub_zalloc (sz); | |
3123 | if (!ret) | |
3124 | return 0; | |
3125 | grub_memcpy (ret, nvlist, sizeof (grub_uint32_t)); | |
3126 | diff --git a/grub-core/fs/zfs/zfscrypt.c b/grub-core/fs/zfs/zfscrypt.c | |
3127 | index 1402e0bc2..de3b015f5 100644 | |
3128 | --- a/grub-core/fs/zfs/zfscrypt.c | |
3129 | +++ b/grub-core/fs/zfs/zfscrypt.c | |
3130 | @@ -22,6 +22,7 @@ | |
3131 | #include <grub/misc.h> | |
3132 | #include <grub/disk.h> | |
3133 | #include <grub/partition.h> | |
3134 | +#include <grub/safemath.h> | |
3135 | #include <grub/dl.h> | |
3136 | #include <grub/types.h> | |
3137 | #include <grub/zfs/zfs.h> | |
3138 | @@ -82,9 +83,13 @@ grub_zfs_add_key (grub_uint8_t *key_in, | |
3139 | int passphrase) | |
3140 | { | |
3141 | struct grub_zfs_wrap_key *key; | |
3142 | + grub_size_t sz; | |
3143 | + | |
3144 | if (!passphrase && keylen > 32) | |
3145 | keylen = 32; | |
3146 | - key = grub_malloc (sizeof (*key) + keylen); | |
3147 | + if (grub_add (sizeof (*key), keylen, &sz)) | |
3148 | + return GRUB_ERR_OUT_OF_RANGE; | |
3149 | + key = grub_malloc (sz); | |
3150 | if (!key) | |
3151 | return grub_errno; | |
3152 | key->is_passphrase = passphrase; | |
3153 | diff --git a/grub-core/lib/arg.c b/grub-core/lib/arg.c | |
3154 | index fd7744a6f..3288609a5 100644 | |
3155 | --- a/grub-core/lib/arg.c | |
3156 | +++ b/grub-core/lib/arg.c | |
3157 | @@ -23,6 +23,7 @@ | |
3158 | #include <grub/term.h> | |
3159 | #include <grub/extcmd.h> | |
3160 | #include <grub/i18n.h> | |
3161 | +#include <grub/safemath.h> | |
3162 | ||
3163 | /* Built-in parser for default options. */ | |
3164 | static const struct grub_arg_option help_options[] = | |
3165 | @@ -216,7 +217,13 @@ static inline grub_err_t | |
3166 | add_arg (char ***argl, int *num, char *s) | |
3167 | { | |
3168 | char **p = *argl; | |
3169 | - *argl = grub_realloc (*argl, (++(*num) + 1) * sizeof (char *)); | |
3170 | + grub_size_t sz; | |
3171 | + | |
3172 | + if (grub_add (++(*num), 1, &sz) || | |
3173 | + grub_mul (sz, sizeof (char *), &sz)) | |
3174 | + return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); | |
3175 | + | |
3176 | + *argl = grub_realloc (*argl, sz); | |
3177 | if (! *argl) | |
3178 | { | |
3179 | grub_free (p); | |
3180 | @@ -431,6 +438,7 @@ grub_arg_list_alloc(grub_extcmd_t extcmd, int argc, | |
3181 | grub_size_t argcnt; | |
3182 | struct grub_arg_list *list; | |
3183 | const struct grub_arg_option *options; | |
3184 | + grub_size_t sz0, sz1; | |
3185 | ||
3186 | options = extcmd->options; | |
3187 | if (! options) | |
3188 | @@ -443,7 +451,15 @@ grub_arg_list_alloc(grub_extcmd_t extcmd, int argc, | |
3189 | argcnt += ((grub_size_t) argc + 1) / 2 + 1; /* max possible for any option */ | |
3190 | } | |
3191 | ||
3192 | - list = grub_zalloc (sizeof (*list) * i + sizeof (char*) * argcnt); | |
3193 | + if (grub_mul (sizeof (*list), i, &sz0) || | |
3194 | + grub_mul (sizeof (char *), argcnt, &sz1) || | |
3195 | + grub_add (sz0, sz1, &sz0)) | |
3196 | + { | |
3197 | + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); | |
3198 | + return 0; | |
3199 | + } | |
3200 | + | |
3201 | + list = grub_zalloc (sz0); | |
3202 | if (! list) | |
3203 | return 0; | |
3204 | ||
3205 | diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c | |
3206 | index 3730ed382..b92cbe98d 100644 | |
3207 | --- a/grub-core/loader/i386/bsd.c | |
3208 | +++ b/grub-core/loader/i386/bsd.c | |
3209 | @@ -35,6 +35,7 @@ | |
3210 | #include <grub/ns8250.h> | |
3211 | #include <grub/bsdlabel.h> | |
3212 | #include <grub/crypto.h> | |
3213 | +#include <grub/safemath.h> | |
3214 | #include <grub/verify.h> | |
3215 | #ifdef GRUB_MACHINE_PCBIOS | |
3216 | #include <grub/machine/int.h> | |
3217 | @@ -1012,11 +1013,16 @@ grub_netbsd_add_modules (void) | |
3218 | struct grub_netbsd_btinfo_modules *mods; | |
3219 | unsigned i; | |
3220 | grub_err_t err; | |
3221 | + grub_size_t sz; | |
3222 | ||
3223 | for (mod = netbsd_mods; mod; mod = mod->next) | |
3224 | modcnt++; | |
3225 | ||
3226 | - mods = grub_malloc (sizeof (*mods) + sizeof (mods->mods[0]) * modcnt); | |
3227 | + if (grub_mul (modcnt, sizeof (mods->mods[0]), &sz) || | |
3228 | + grub_add (sz, sizeof (*mods), &sz)) | |
3229 | + return GRUB_ERR_OUT_OF_RANGE; | |
3230 | + | |
3231 | + mods = grub_malloc (sz); | |
3232 | if (!mods) | |
3233 | return grub_errno; | |
3234 | ||
3235 | diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c | |
3236 | index e332d5eb4..906ec7d67 100644 | |
3237 | --- a/grub-core/net/dns.c | |
3238 | +++ b/grub-core/net/dns.c | |
3239 | @@ -22,6 +22,7 @@ | |
3240 | #include <grub/i18n.h> | |
3241 | #include <grub/err.h> | |
3242 | #include <grub/time.h> | |
3243 | +#include <grub/safemath.h> | |
3244 | ||
3245 | struct dns_cache_element | |
3246 | { | |
3247 | @@ -51,9 +52,15 @@ grub_net_add_dns_server (const struct grub_net_network_level_address *s) | |
3248 | { | |
3249 | int na = dns_servers_alloc * 2; | |
3250 | struct grub_net_network_level_address *ns; | |
3251 | + grub_size_t sz; | |
3252 | + | |
3253 | if (na < 8) | |
3254 | na = 8; | |
3255 | - ns = grub_realloc (dns_servers, na * sizeof (ns[0])); | |
3256 | + | |
3257 | + if (grub_mul (na, sizeof (ns[0]), &sz)) | |
3258 | + return GRUB_ERR_OUT_OF_RANGE; | |
3259 | + | |
3260 | + ns = grub_realloc (dns_servers, sz); | |
3261 | if (!ns) | |
3262 | return grub_errno; | |
3263 | dns_servers_alloc = na; | |
3264 | diff --git a/grub-core/normal/charset.c b/grub-core/normal/charset.c | |
3265 | index d57fb72fa..4dfcc3107 100644 | |
3266 | --- a/grub-core/normal/charset.c | |
3267 | +++ b/grub-core/normal/charset.c | |
3268 | @@ -48,6 +48,7 @@ | |
3269 | #include <grub/unicode.h> | |
3270 | #include <grub/term.h> | |
3271 | #include <grub/normal.h> | |
3272 | +#include <grub/safemath.h> | |
3273 | ||
3274 | #if HAVE_FONT_SOURCE | |
3275 | #include "widthspec.h" | |
3276 | @@ -464,6 +465,7 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, | |
3277 | { | |
3278 | struct grub_unicode_combining *n; | |
3279 | unsigned j; | |
3280 | + grub_size_t sz; | |
3281 | ||
3282 | if (!haveout) | |
3283 | continue; | |
3284 | @@ -477,10 +479,14 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, | |
3285 | n = out->combining_inline; | |
3286 | else if (out->ncomb > (int) ARRAY_SIZE (out->combining_inline)) | |
3287 | { | |
3288 | - n = grub_realloc (out->combining_ptr, | |
3289 | - sizeof (n[0]) * (out->ncomb + 1)); | |
3290 | + if (grub_add (out->ncomb, 1, &sz) || | |
3291 | + grub_mul (sz, sizeof (n[0]), &sz)) | |
3292 | + goto fail; | |
3293 | + | |
3294 | + n = grub_realloc (out->combining_ptr, sz); | |
3295 | if (!n) | |
3296 | { | |
3297 | + fail: | |
3298 | grub_errno = GRUB_ERR_NONE; | |
3299 | continue; | |
3300 | } | |
3301 | diff --git a/grub-core/normal/cmdline.c b/grub-core/normal/cmdline.c | |
3302 | index c57242e2e..de03fe63b 100644 | |
3303 | --- a/grub-core/normal/cmdline.c | |
3304 | +++ b/grub-core/normal/cmdline.c | |
3305 | @@ -28,6 +28,7 @@ | |
3306 | #include <grub/env.h> | |
3307 | #include <grub/i18n.h> | |
3308 | #include <grub/charset.h> | |
3309 | +#include <grub/safemath.h> | |
3310 | ||
3311 | static grub_uint32_t *kill_buf; | |
3312 | ||
3313 | @@ -307,12 +308,21 @@ cl_insert (struct cmdline_term *cl_terms, unsigned nterms, | |
3314 | if (len + (*llen) >= (*max_len)) | |
3315 | { | |
3316 | grub_uint32_t *nbuf; | |
3317 | - (*max_len) *= 2; | |
3318 | - nbuf = grub_realloc ((*buf), sizeof (grub_uint32_t) * (*max_len)); | |
3319 | + grub_size_t sz; | |
3320 | + | |
3321 | + if (grub_mul (*max_len, 2, max_len) || | |
3322 | + grub_mul (*max_len, sizeof (grub_uint32_t), &sz)) | |
3323 | + { | |
3324 | + grub_errno = GRUB_ERR_OUT_OF_RANGE; | |
3325 | + goto fail; | |
3326 | + } | |
3327 | + | |
3328 | + nbuf = grub_realloc ((*buf), sz); | |
3329 | if (nbuf) | |
3330 | (*buf) = nbuf; | |
3331 | else | |
3332 | { | |
3333 | + fail: | |
3334 | grub_print_error (); | |
3335 | grub_errno = GRUB_ERR_NONE; | |
3336 | (*max_len) /= 2; | |
3337 | diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c | |
3338 | index 1993995be..50eef918c 100644 | |
3339 | --- a/grub-core/normal/menu_entry.c | |
3340 | +++ b/grub-core/normal/menu_entry.c | |
3341 | @@ -27,6 +27,7 @@ | |
3342 | #include <grub/auth.h> | |
3343 | #include <grub/i18n.h> | |
3344 | #include <grub/charset.h> | |
3345 | +#include <grub/safemath.h> | |
3346 | ||
3347 | enum update_mode | |
3348 | { | |
3349 | @@ -113,10 +114,18 @@ ensure_space (struct line *linep, int extra) | |
3350 | { | |
3351 | if (linep->max_len < linep->len + extra) | |
3352 | { | |
3353 | - linep->max_len = 2 * (linep->len + extra); | |
3354 | - linep->buf = grub_realloc (linep->buf, (linep->max_len + 1) * sizeof (linep->buf[0])); | |
3355 | + grub_size_t sz0, sz1; | |
3356 | + | |
3357 | + if (grub_add (linep->len, extra, &sz0) || | |
3358 | + grub_mul (sz0, 2, &sz0) || | |
3359 | + grub_add (sz0, 1, &sz1) || | |
3360 | + grub_mul (sz1, sizeof (linep->buf[0]), &sz1)) | |
3361 | + return 0; | |
3362 | + | |
3363 | + linep->buf = grub_realloc (linep->buf, sz1); | |
3364 | if (! linep->buf) | |
3365 | return 0; | |
3366 | + linep->max_len = sz0; | |
3367 | } | |
3368 | ||
3369 | return 1; | |
3370 | diff --git a/grub-core/script/argv.c b/grub-core/script/argv.c | |
3371 | index 217ec5d1e..5751fdd57 100644 | |
3372 | --- a/grub-core/script/argv.c | |
3373 | +++ b/grub-core/script/argv.c | |
3374 | @@ -20,6 +20,7 @@ | |
3375 | #include <grub/mm.h> | |
3376 | #include <grub/misc.h> | |
3377 | #include <grub/script_sh.h> | |
3378 | +#include <grub/safemath.h> | |
3379 | ||
3380 | /* Return nearest power of two that is >= v. */ | |
3381 | static unsigned | |
3382 | @@ -81,11 +82,16 @@ int | |
3383 | grub_script_argv_next (struct grub_script_argv *argv) | |
3384 | { | |
3385 | char **p = argv->args; | |
3386 | + grub_size_t sz; | |
3387 | ||
3388 | if (argv->args && argv->argc && argv->args[argv->argc - 1] == 0) | |
3389 | return 0; | |
3390 | ||
3391 | - p = grub_realloc (p, round_up_exp ((argv->argc + 2) * sizeof (char *))); | |
3392 | + if (grub_add (argv->argc, 2, &sz) || | |
3393 | + grub_mul (sz, sizeof (char *), &sz)) | |
3394 | + return 1; | |
3395 | + | |
3396 | + p = grub_realloc (p, round_up_exp (sz)); | |
3397 | if (! p) | |
3398 | return 1; | |
3399 | ||
3400 | @@ -105,13 +111,19 @@ grub_script_argv_append (struct grub_script_argv *argv, const char *s, | |
3401 | { | |
3402 | grub_size_t a; | |
3403 | char *p = argv->args[argv->argc - 1]; | |
3404 | + grub_size_t sz; | |
3405 | ||
3406 | if (! s) | |
3407 | return 0; | |
3408 | ||
3409 | a = p ? grub_strlen (p) : 0; | |
3410 | ||
3411 | - p = grub_realloc (p, round_up_exp ((a + slen + 1) * sizeof (char))); | |
3412 | + if (grub_add (a, slen, &sz) || | |
3413 | + grub_add (sz, 1, &sz) || | |
3414 | + grub_mul (sz, sizeof (char), &sz)) | |
3415 | + return 1; | |
3416 | + | |
3417 | + p = grub_realloc (p, round_up_exp (sz)); | |
3418 | if (! p) | |
3419 | return 1; | |
3420 | ||
3421 | diff --git a/grub-core/script/lexer.c b/grub-core/script/lexer.c | |
3422 | index c6bd3172f..5fb0cbd0b 100644 | |
3423 | --- a/grub-core/script/lexer.c | |
3424 | +++ b/grub-core/script/lexer.c | |
3425 | @@ -24,6 +24,7 @@ | |
3426 | #include <grub/mm.h> | |
3427 | #include <grub/script_sh.h> | |
3428 | #include <grub/i18n.h> | |
3429 | +#include <grub/safemath.h> | |
3430 | ||
3431 | #define yytext_ptr char * | |
3432 | #include "grub_script.tab.h" | |
3433 | @@ -110,10 +111,14 @@ grub_script_lexer_record (struct grub_parser_param *parser, char *str) | |
3434 | old = lexer->recording; | |
3435 | if (lexer->recordlen < len) | |
3436 | lexer->recordlen = len; | |
3437 | - lexer->recordlen *= 2; | |
3438 | + | |
3439 | + if (grub_mul (lexer->recordlen, 2, &lexer->recordlen)) | |
3440 | + goto fail; | |
3441 | + | |
3442 | lexer->recording = grub_realloc (lexer->recording, lexer->recordlen); | |
3443 | if (!lexer->recording) | |
3444 | { | |
3445 | + fail: | |
3446 | grub_free (old); | |
3447 | lexer->recordpos = 0; | |
3448 | lexer->recordlen = 0; | |
3449 | @@ -130,7 +135,7 @@ int | |
3450 | grub_script_lexer_yywrap (struct grub_parser_param *parserstate, | |
3451 | const char *input) | |
3452 | { | |
3453 | - grub_size_t len = 0; | |
3454 | + grub_size_t len = 0, sz; | |
3455 | char *p = 0; | |
3456 | char *line = 0; | |
3457 | YY_BUFFER_STATE buffer; | |
3458 | @@ -168,12 +173,22 @@ grub_script_lexer_yywrap (struct grub_parser_param *parserstate, | |
3459 | } | |
3460 | else if (len && line[len - 1] != '\n') | |
3461 | { | |
3462 | - p = grub_realloc (line, len + 2); | |
3463 | + if (grub_add (len, 2, &sz)) | |
3464 | + { | |
3465 | + grub_free (line); | |
3466 | + grub_script_yyerror (parserstate, N_("overflow is detected")); | |
3467 | + return 1; | |
3468 | + } | |
3469 | + | |
3470 | + p = grub_realloc (line, sz); | |
3471 | if (p) | |
3472 | { | |
3473 | p[len++] = '\n'; | |
3474 | p[len] = '\0'; | |
3475 | } | |
3476 | + else | |
3477 | + grub_free (line); | |
3478 | + | |
3479 | line = p; | |
3480 | } | |
3481 | ||
3482 | diff --git a/grub-core/video/bitmap.c b/grub-core/video/bitmap.c | |
3483 | index b2e031566..6256e209a 100644 | |
3484 | --- a/grub-core/video/bitmap.c | |
3485 | +++ b/grub-core/video/bitmap.c | |
3486 | @@ -23,6 +23,7 @@ | |
3487 | #include <grub/mm.h> | |
3488 | #include <grub/misc.h> | |
3489 | #include <grub/i18n.h> | |
3490 | +#include <grub/safemath.h> | |
3491 | ||
3492 | GRUB_MOD_LICENSE ("GPLv3+"); | |
3493 | ||
3494 | @@ -58,7 +59,7 @@ grub_video_bitmap_create (struct grub_video_bitmap **bitmap, | |
3495 | enum grub_video_blit_format blit_format) | |
3496 | { | |
3497 | struct grub_video_mode_info *mode_info; | |
3498 | - unsigned int size; | |
3499 | + grub_size_t size; | |
3500 | ||
3501 | if (!bitmap) | |
3502 | return grub_error (GRUB_ERR_BUG, "invalid argument"); | |
3503 | @@ -137,19 +138,25 @@ grub_video_bitmap_create (struct grub_video_bitmap **bitmap, | |
3504 | ||
3505 | mode_info->pitch = width * mode_info->bytes_per_pixel; | |
3506 | ||
3507 | - /* Calculate size needed for the data. */ | |
3508 | - size = (width * mode_info->bytes_per_pixel) * height; | |
3509 | + /* Calculate size needed for the data. */ | |
3510 | + if (grub_mul (width, mode_info->bytes_per_pixel, &size) || | |
3511 | + grub_mul (size, height, &size)) | |
3512 | + { | |
3513 | + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); | |
3514 | + goto fail; | |
3515 | + } | |
3516 | ||
3517 | (*bitmap)->data = grub_zalloc (size); | |
3518 | if (! (*bitmap)->data) | |
3519 | - { | |
3520 | - grub_free (*bitmap); | |
3521 | - *bitmap = 0; | |
3522 | - | |
3523 | - return grub_errno; | |
3524 | - } | |
3525 | + goto fail; | |
3526 | ||
3527 | return GRUB_ERR_NONE; | |
3528 | + | |
3529 | + fail: | |
3530 | + grub_free (*bitmap); | |
3531 | + *bitmap = NULL; | |
3532 | + | |
3533 | + return grub_errno; | |
3534 | } | |
3535 | ||
3536 | /* Frees all resources allocated by bitmap. */ | |
3537 | diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c | |
3538 | index 61bd64537..0157ff742 100644 | |
3539 | --- a/grub-core/video/readers/png.c | |
3540 | +++ b/grub-core/video/readers/png.c | |
3541 | @@ -23,6 +23,7 @@ | |
3542 | #include <grub/mm.h> | |
3543 | #include <grub/misc.h> | |
3544 | #include <grub/bufio.h> | |
3545 | +#include <grub/safemath.h> | |
3546 | ||
3547 | GRUB_MOD_LICENSE ("GPLv3+"); | |
3548 | ||
3549 | @@ -301,9 +302,17 @@ grub_png_decode_image_header (struct grub_png_data *data) | |
3550 | data->bpp <<= 1; | |
3551 | ||
3552 | data->color_bits = color_bits; | |
3553 | - data->row_bytes = data->image_width * data->bpp; | |
3554 | + | |
3555 | + if (grub_mul (data->image_width, data->bpp, &data->row_bytes)) | |
3556 | + return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); | |
3557 | + | |
3558 | if (data->color_bits <= 4) | |
3559 | - data->row_bytes = (data->image_width * data->color_bits + 7) / 8; | |
3560 | + { | |
3561 | + if (grub_mul (data->image_width, data->color_bits + 7, &data->row_bytes)) | |
3562 | + return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); | |
3563 | + | |
3564 | + data->row_bytes >>= 3; | |
3565 | + } | |
3566 | ||
3567 | #ifndef GRUB_CPU_WORDS_BIGENDIAN | |
3568 | if (data->is_16bit || data->is_gray || data->is_palette) | |
3569 | ||
3570 | From 99c176e216b7196ac8d2af2b9bc483070b1a170a Mon Sep 17 00:00:00 2001 | |
3571 | From: Peter Jones <pjones@redhat.com> | |
3572 | Date: Sat, 4 Jul 2020 12:25:09 -0400 | |
3573 | Subject: iso9660: Don't leak memory on realloc() failures | |
3574 | ||
3575 | Signed-off-by: Peter Jones <pjones@redhat.com> | |
3576 | Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> | |
3577 | --- | |
3578 | grub-core/fs/iso9660.c | 24 ++++++++++++++++++++---- | |
3579 | 1 file changed, 20 insertions(+), 4 deletions(-) | |
3580 | ||
3581 | diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c | |
3582 | index 7ba5b300b..5ec4433b8 100644 | |
3583 | --- a/grub-core/fs/iso9660.c | |
3584 | +++ b/grub-core/fs/iso9660.c | |
3585 | @@ -533,14 +533,20 @@ add_part (struct iterate_dir_ctx *ctx, | |
3586 | { | |
3587 | int size = ctx->symlink ? grub_strlen (ctx->symlink) : 0; | |
3588 | grub_size_t sz; | |
3589 | + char *new; | |
3590 | ||
3591 | if (grub_add (size, len2, &sz) || | |
3592 | grub_add (sz, 1, &sz)) | |
3593 | return; | |
3594 | ||
3595 | - ctx->symlink = grub_realloc (ctx->symlink, sz); | |
3596 | - if (! ctx->symlink) | |
3597 | - return; | |
3598 | + new = grub_realloc (ctx->symlink, sz); | |
3599 | + if (!new) | |
3600 | + { | |
3601 | + grub_free (ctx->symlink); | |
3602 | + ctx->symlink = NULL; | |
3603 | + return; | |
3604 | + } | |
3605 | + ctx->symlink = new; | |
3606 | ||
3607 | grub_memcpy (ctx->symlink + size, part, len2); | |
3608 | ctx->symlink[size + len2] = 0; | |
3609 | @@ -634,7 +640,12 @@ susp_iterate_dir (struct grub_iso9660_susp_entry *entry, | |
3610 | is the length. Both are part of the `Component | |
3611 | Record'. */ | |
3612 | if (ctx->symlink && !ctx->was_continue) | |
3613 | - add_part (ctx, "/", 1); | |
3614 | + { | |
3615 | + add_part (ctx, "/", 1); | |
3616 | + if (grub_errno) | |
3617 | + return grub_errno; | |
3618 | + } | |
3619 | + | |
3620 | add_part (ctx, (char *) &entry->data[pos + 2], | |
3621 | entry->data[pos + 1]); | |
3622 | ctx->was_continue = (entry->data[pos] & 1); | |
3623 | @@ -653,6 +664,11 @@ susp_iterate_dir (struct grub_iso9660_susp_entry *entry, | |
3624 | add_part (ctx, "/", 1); | |
3625 | break; | |
3626 | } | |
3627 | + | |
3628 | + /* Check if grub_realloc() failed in add_part(). */ | |
3629 | + if (grub_errno) | |
3630 | + return grub_errno; | |
3631 | + | |
3632 | /* In pos + 1 the length of the `Component Record' is | |
3633 | stored. */ | |
3634 | pos += entry->data[pos + 1] + 2; | |
3635 | ||
3636 | From fcc11dc1e68192d50cfb914314fb5e2f0504c498 Mon Sep 17 00:00:00 2001 | |
3637 | From: Daniel Kiper <daniel.kiper@oracle.com> | |
3638 | Date: Tue, 7 Jul 2020 15:36:26 +0200 | |
3639 | Subject: font: Do not load more than one NAME section | |
3640 | ||
3641 | The GRUB font file can have one NAME section only. Though if somebody | |
3642 | crafts a broken font file with many NAME sections and loads it then the | |
3643 | GRUB leaks memory. So, prevent against that by loading first NAME | |
3644 | section and failing in controlled way on following one. | |
3645 | ||
3646 | Reported-by: Chris Coulson <chris.coulson@canonical.com> | |
3647 | Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com> | |
3648 | Reviewed-by: Jan Setje-Eilers <jan.setjeeilers@oracle.com> | |
3649 | --- | |
3650 | grub-core/font/font.c | 6 ++++++ | |
3651 | 1 file changed, 6 insertions(+) | |
3652 | ||
3653 | diff --git a/grub-core/font/font.c b/grub-core/font/font.c | |
3654 | index 5edb477ac..d09bb38d8 100644 | |
3655 | --- a/grub-core/font/font.c | |
3656 | +++ b/grub-core/font/font.c | |
3657 | @@ -532,6 +532,12 @@ grub_font_load (const char *filename) | |
3658 | if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_FONT_NAME, | |
3659 | sizeof (FONT_FORMAT_SECTION_NAMES_FONT_NAME) - 1) == 0) | |
3660 | { | |
3661 | + if (font->name != NULL) | |
3662 | + { | |
3663 | + grub_error (GRUB_ERR_BAD_FONT, "invalid font file: too many NAME sections"); | |
3664 | + goto fail; | |
3665 | + } | |
3666 | + | |
3667 | font->name = read_section_as_string (§ion); | |
3668 | if (!font->name) | |
3669 | goto fail; | |
3670 | ||
3671 | From e283bb250350e8c2f7edeb344a624c57c26b042f Mon Sep 17 00:00:00 2001 | |
3672 | From: Alexey Makhalov <amakhalov@vmware.com> | |
3673 | Date: Wed, 8 Jul 2020 20:41:56 +0000 | |
3674 | Subject: gfxmenu: Fix double free in load_image() | |
3675 | ||
3676 | self->bitmap should be zeroed after free. Otherwise, there is a chance | |
3677 | to double free (USE_AFTER_FREE) it later in rescale_image(). | |
3678 | ||
3679 | Fixes: CID 292472 | |
3680 | ||
3681 | Signed-off-by: Alexey Makhalov <amakhalov@vmware.com> | |
3682 | Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> | |
3683 | --- | |
3684 | grub-core/gfxmenu/gui_image.c | 5 ++++- | |
3685 | 1 file changed, 4 insertions(+), 1 deletion(-) | |
3686 | ||
3687 | diff --git a/grub-core/gfxmenu/gui_image.c b/grub-core/gfxmenu/gui_image.c | |
3688 | index 29784ed2d..6b2e976f1 100644 | |
3689 | --- a/grub-core/gfxmenu/gui_image.c | |
3690 | +++ b/grub-core/gfxmenu/gui_image.c | |
3691 | @@ -195,7 +195,10 @@ load_image (grub_gui_image_t self, const char *path) | |
3692 | return grub_errno; | |
3693 | ||
3694 | if (self->bitmap && (self->bitmap != self->raw_bitmap)) | |
3695 | - grub_video_bitmap_destroy (self->bitmap); | |
3696 | + { | |
3697 | + grub_video_bitmap_destroy (self->bitmap); | |
3698 | + self->bitmap = 0; | |
3699 | + } | |
3700 | if (self->raw_bitmap) | |
3701 | grub_video_bitmap_destroy (self->raw_bitmap); | |
3702 | ||
3703 | ||
3704 | From 387219ffbb751afd336ebd71f1a375d9923ba416 Mon Sep 17 00:00:00 2001 | |
3705 | From: Alexey Makhalov <amakhalov@vmware.com> | |
3706 | Date: Wed, 8 Jul 2020 21:30:43 +0000 | |
3707 | Subject: xnu: Fix double free in grub_xnu_devprop_add_property() | |
3708 | ||
3709 | grub_xnu_devprop_add_property() should not free utf8 and utf16 as it get | |
3710 | allocated and freed in the caller. | |
3711 | ||
3712 | Minor improvement: do prop fields initialization after memory allocations. | |
3713 | ||
3714 | Fixes: CID 292442, CID 292457, CID 292460, CID 292466 | |
3715 | ||
3716 | Signed-off-by: Alexey Makhalov <amakhalov@vmware.com> | |
3717 | Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> | |
3718 | --- | |
3719 | grub-core/loader/i386/xnu.c | 17 ++++++++--------- | |
3720 | 1 file changed, 8 insertions(+), 9 deletions(-) | |
3721 | ||
3722 | diff --git a/grub-core/loader/i386/xnu.c b/grub-core/loader/i386/xnu.c | |
3723 | index b7d176b5d..e9e119259 100644 | |
3724 | --- a/grub-core/loader/i386/xnu.c | |
3725 | +++ b/grub-core/loader/i386/xnu.c | |
3726 | @@ -262,20 +262,19 @@ grub_xnu_devprop_add_property (struct grub_xnu_devprop_device_descriptor *dev, | |
3727 | if (!prop) | |
3728 | return grub_errno; | |
3729 | ||
3730 | - prop->name = utf8; | |
3731 | - prop->name16 = utf16; | |
3732 | - prop->name16len = utf16len; | |
3733 | - | |
3734 | - prop->length = datalen; | |
3735 | - prop->data = grub_malloc (prop->length); | |
3736 | + prop->data = grub_malloc (datalen); | |
3737 | if (!prop->data) | |
3738 | { | |
3739 | - grub_free (prop->name); | |
3740 | - grub_free (prop->name16); | |
3741 | grub_free (prop); | |
3742 | return grub_errno; | |
3743 | } | |
3744 | - grub_memcpy (prop->data, data, prop->length); | |
3745 | + grub_memcpy (prop->data, data, datalen); | |
3746 | + | |
3747 | + prop->name = utf8; | |
3748 | + prop->name16 = utf16; | |
3749 | + prop->name16len = utf16len; | |
3750 | + prop->length = datalen; | |
3751 | + | |
3752 | grub_list_push (GRUB_AS_LIST_P (&dev->properties), | |
3753 | GRUB_AS_LIST (prop)); | |
3754 | return GRUB_ERR_NONE; | |
3755 | ||
3756 | From 8b93dd5ba38c2d726a08b271b14a74e8f960d147 Mon Sep 17 00:00:00 2001 | |
3757 | From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | |
3758 | Date: Thu, 9 Jul 2020 03:05:23 +0000 | |
3759 | Subject: lzma: Make sure we don't dereference past array | |
3760 | ||
3761 | The two dimensional array p->posSlotEncoder[4][64] is being dereferenced | |
3762 | using the GetLenToPosState() macro which checks if len is less than 5, | |
3763 | and if so subtracts 2 from it. If len = 0, that is 0 - 2 = 4294967294. | |
3764 | Obviously we don't want to dereference that far out so we check if the | |
3765 | position found is greater or equal kNumLenToPosStates (4) and bail out. | |
3766 | ||
3767 | N.B.: Upstream LZMA 18.05 and later has this function completely rewritten | |
3768 | without any history. | |
3769 | ||
3770 | Fixes: CID 51526 | |
3771 | ||
3772 | Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | |
3773 | Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> | |
3774 | --- | |
3775 | grub-core/lib/LzmaEnc.c | 10 ++++++++-- | |
3776 | 1 file changed, 8 insertions(+), 2 deletions(-) | |
3777 | ||
3778 | diff --git a/grub-core/lib/LzmaEnc.c b/grub-core/lib/LzmaEnc.c | |
3779 | index f2ec04a8c..753e56a95 100644 | |
3780 | --- a/grub-core/lib/LzmaEnc.c | |
3781 | +++ b/grub-core/lib/LzmaEnc.c | |
3782 | @@ -1877,13 +1877,19 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize | |
3783 | } | |
3784 | else | |
3785 | { | |
3786 | - UInt32 posSlot; | |
3787 | + UInt32 posSlot, lenToPosState; | |
3788 | RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); | |
3789 | p->state = kMatchNextStates[p->state]; | |
3790 | LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); | |
3791 | pos -= LZMA_NUM_REPS; | |
3792 | GetPosSlot(pos, posSlot); | |
3793 | - RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot); | |
3794 | + lenToPosState = GetLenToPosState(len); | |
3795 | + if (lenToPosState >= kNumLenToPosStates) | |
3796 | + { | |
3797 | + p->result = SZ_ERROR_DATA; | |
3798 | + return CheckErrors(p); | |
3799 | + } | |
3800 | + RcTree_Encode(&p->rc, p->posSlotEncoder[lenToPosState], kNumPosSlotBits, posSlot); | |
3801 | ||
3802 | if (posSlot >= kStartPosModelIndex) | |
3803 | { | |
3804 | ||
3805 | From 2328abbe2caa2129084da04a3e19461ddc571549 Mon Sep 17 00:00:00 2001 | |
3806 | From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | |
3807 | Date: Tue, 7 Jul 2020 15:12:25 -0400 | |
3808 | Subject: term: Fix overflow on user inputs | |
3809 | ||
3810 | This requires a very weird input from the serial interface but can cause | |
3811 | an overflow in input_buf (keys) overwriting the next variable (npending) | |
3812 | with the user choice: | |
3813 | ||
3814 | (pahole output) | |
3815 | ||
3816 | struct grub_terminfo_input_state { | |
3817 | int input_buf[6]; /* 0 24 */ | |
3818 | int npending; /* 24 4 */ <- CORRUPT | |
3819 | ...snip... | |
3820 | ||
3821 | The magic string requires causing this is "ESC,O,],0,1,2,q" and we overflow | |
3822 | npending with "q" (aka increase npending to 161). The simplest fix is to | |
3823 | just to disallow overwrites input_buf, which exactly what this patch does. | |
3824 | ||
3825 | Fixes: CID 292449 | |
3826 | ||
3827 | Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | |
3828 | Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> | |
3829 | --- | |
3830 | grub-core/term/terminfo.c | 9 ++++++--- | |
3831 | 1 file changed, 6 insertions(+), 3 deletions(-) | |
3832 | ||
3833 | diff --git a/grub-core/term/terminfo.c b/grub-core/term/terminfo.c | |
3834 | index 63892ad42..aa3a108ca 100644 | |
3835 | --- a/grub-core/term/terminfo.c | |
3836 | +++ b/grub-core/term/terminfo.c | |
3837 | @@ -398,7 +398,7 @@ grub_terminfo_getwh (struct grub_term_output *term) | |
3838 | } | |
3839 | ||
3840 | static void | |
3841 | -grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len, | |
3842 | +grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len, int max_len, | |
3843 | int (*readkey) (struct grub_term_input *term)) | |
3844 | { | |
3845 | int c; | |
3846 | @@ -414,6 +414,9 @@ grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len, | |
3847 | if (c == -1) \ | |
3848 | return; \ | |
3849 | \ | |
3850 | + if (*len >= max_len) \ | |
3851 | + return; \ | |
3852 | + \ | |
3853 | keys[*len] = c; \ | |
3854 | (*len)++; \ | |
3855 | } | |
3856 | @@ -602,8 +605,8 @@ grub_terminfo_getkey (struct grub_term_input *termi) | |
3857 | return ret; | |
3858 | } | |
3859 | ||
3860 | - grub_terminfo_readkey (termi, data->input_buf, | |
3861 | - &data->npending, data->readkey); | |
3862 | + grub_terminfo_readkey (termi, data->input_buf, &data->npending, | |
3863 | + GRUB_TERMINFO_READKEY_MAX_LEN, data->readkey); | |
3864 | ||
3865 | #if defined(__powerpc__) && defined(GRUB_MACHINE_IEEE1275) | |
3866 | if (data->npending == 1 && data->input_buf[0] == GRUB_TERM_ESC | |
3867 | ||
3868 | From ba1d97845644290f03754432bcb6bbd6fefe7003 Mon Sep 17 00:00:00 2001 | |
3869 | From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | |
3870 | Date: Tue, 7 Jul 2020 22:02:31 -0400 | |
3871 | Subject: udf: Fix memory leak | |
3872 | ||
3873 | Fixes: CID 73796 | |
3874 | ||
3875 | Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | |
3876 | Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> | |
3877 | Reviewed-by: Jan Setje-Eilers <jan.setjeeilers@oracle.com> | |
3878 | --- | |
3879 | grub-core/fs/udf.c | 17 +++++++++++++---- | |
3880 | 1 file changed, 13 insertions(+), 4 deletions(-) | |
3881 | ||
3882 | diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c | |
3883 | index 21ac7f446..2ac5c1d00 100644 | |
3884 | --- a/grub-core/fs/udf.c | |
3885 | +++ b/grub-core/fs/udf.c | |
3886 | @@ -965,8 +965,10 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir, | |
3887 | return 0; | |
3888 | ||
3889 | if (grub_udf_read_icb (dir->data, &dirent.icb, child)) | |
3890 | - return 0; | |
3891 | - | |
3892 | + { | |
3893 | + grub_free (child); | |
3894 | + return 0; | |
3895 | + } | |
3896 | if (dirent.characteristics & GRUB_UDF_FID_CHAR_PARENT) | |
3897 | { | |
3898 | /* This is the parent directory. */ | |
3899 | @@ -988,11 +990,18 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir, | |
3900 | dirent.file_ident_length, | |
3901 | (char *) raw)) | |
3902 | != dirent.file_ident_length) | |
3903 | - return 0; | |
3904 | + { | |
3905 | + grub_free (child); | |
3906 | + return 0; | |
3907 | + } | |
3908 | ||
3909 | filename = read_string (raw, dirent.file_ident_length, 0); | |
3910 | if (!filename) | |
3911 | - grub_print_error (); | |
3912 | + { | |
3913 | + /* As the hook won't get called. */ | |
3914 | + grub_free (child); | |
3915 | + grub_print_error (); | |
3916 | + } | |
3917 | ||
3918 | if (filename && hook (filename, type, child, hook_data)) | |
3919 | { | |
3920 | ||
3921 | From 3b39c2023f3aa242b008385939a7394e5946e94b Mon Sep 17 00:00:00 2001 | |
3922 | From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | |
3923 | Date: Fri, 26 Jun 2020 10:51:43 -0400 | |
3924 | Subject: multiboot2: Fix memory leak if | |
3925 | grub_create_loader_cmdline() fails | |
3926 | ||
3927 | Fixes: CID 292468 | |
3928 | ||
3929 | Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | |
3930 | Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> | |
3931 | --- | |
3932 | grub-core/loader/multiboot_mbi2.c | 6 +++++- | |
3933 | 1 file changed, 5 insertions(+), 1 deletion(-) | |
3934 | ||
3935 | diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c | |
3936 | index 53da78615..0efc66062 100644 | |
3937 | --- a/grub-core/loader/multiboot_mbi2.c | |
3938 | +++ b/grub-core/loader/multiboot_mbi2.c | |
3939 | @@ -1070,7 +1070,11 @@ grub_multiboot2_add_module (grub_addr_t start, grub_size_t size, | |
3940 | err = grub_create_loader_cmdline (argc, argv, newmod->cmdline, | |
3941 | newmod->cmdline_size, GRUB_VERIFY_MODULE_CMDLINE); | |
3942 | if (err) | |
3943 | - return err; | |
3944 | + { | |
3945 | + grub_free (newmod->cmdline); | |
3946 | + grub_free (newmod); | |
3947 | + return err; | |
3948 | + } | |
3949 | ||
3950 | if (modules_last) | |
3951 | modules_last->next = newmod; | |
3952 | ||
3953 | From 7726da0d972c3996b3ced02586204334eb03d472 Mon Sep 17 00:00:00 2001 | |
3954 | From: Alexey Makhalov <amakhalov@vmware.com> | |
3955 | Date: Thu, 9 Jul 2020 08:10:40 +0000 | |
3956 | Subject: tftp: Do not use priority queue | |
3957 | ||
3958 | There is not need to reassemble the order of blocks. Per RFC 1350, | |
3959 | server must wait for the ACK, before sending next block. Data packets | |
3960 | can be served immediately without putting them to priority queue. | |
3961 | ||
3962 | Logic to handle incoming packet is this: | |
3963 | - if packet block id equal to expected block id, then | |
3964 | process the packet, | |
3965 | - if packet block id is less than expected - this is retransmit | |
3966 | of old packet, then ACK it and drop the packet, | |
3967 | - if packet block id is more than expected - that shouldn't | |
3968 | happen, just drop the packet. | |
3969 | ||
3970 | It makes the tftp receive path code simpler, smaller and faster. | |
3971 | As a benefit, this change fixes CID# 73624 and CID# 96690, caused | |
3972 | by following while loop: | |
3973 | ||
3974 | while (cmp_block (grub_be_to_cpu16 (tftph->u.data.block), data->block + 1) == 0) | |
3975 | ||
3976 | where tftph pointer is not moving from one iteration to another, causing | |
3977 | to serve same packet again. Luckily, double serving didn't happen due to | |
3978 | data->block++ during the first iteration. | |
3979 | ||
3980 | Fixes: CID 73624, CID 96690 | |
3981 | ||
3982 | Signed-off-by: Alexey Makhalov <amakhalov@vmware.com> | |
3983 | Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> | |
3984 | --- | |
3985 | grub-core/net/tftp.c | 168 ++++++++++++++----------------------------- | |
3986 | 1 file changed, 53 insertions(+), 115 deletions(-) | |
3987 | ||
3988 | diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c | |
3989 | index a0817a075..84229d03d 100644 | |
3990 | --- a/grub-core/net/tftp.c | |
3991 | +++ b/grub-core/net/tftp.c | |
3992 | @@ -25,7 +25,6 @@ | |
3993 | #include <grub/mm.h> | |
3994 | #include <grub/dl.h> | |
3995 | #include <grub/file.h> | |
3996 | -#include <grub/priority_queue.h> | |
3997 | #include <grub/i18n.h> | |
3998 | ||
3999 | GRUB_MOD_LICENSE ("GPLv3+"); | |
4000 | @@ -106,31 +105,8 @@ typedef struct tftp_data | |
4001 | int have_oack; | |
4002 | struct grub_error_saved save_err; | |
4003 | grub_net_udp_socket_t sock; | |
4004 | - grub_priority_queue_t pq; | |
4005 | } *tftp_data_t; | |
4006 | ||
4007 | -static int | |
4008 | -cmp_block (grub_uint16_t a, grub_uint16_t b) | |
4009 | -{ | |
4010 | - grub_int16_t i = (grub_int16_t) (a - b); | |
4011 | - if (i > 0) | |
4012 | - return +1; | |
4013 | - if (i < 0) | |
4014 | - return -1; | |
4015 | - return 0; | |
4016 | -} | |
4017 | - | |
4018 | -static int | |
4019 | -cmp (const void *a__, const void *b__) | |
4020 | -{ | |
4021 | - struct grub_net_buff *a_ = *(struct grub_net_buff **) a__; | |
4022 | - struct grub_net_buff *b_ = *(struct grub_net_buff **) b__; | |
4023 | - struct tftphdr *a = (struct tftphdr *) a_->data; | |
4024 | - struct tftphdr *b = (struct tftphdr *) b_->data; | |
4025 | - /* We want the first elements to be on top. */ | |
4026 | - return -cmp_block (grub_be_to_cpu16 (a->u.data.block), grub_be_to_cpu16 (b->u.data.block)); | |
4027 | -} | |
4028 | - | |
4029 | static grub_err_t | |
4030 | ack (tftp_data_t data, grub_uint64_t block) | |
4031 | { | |
4032 | @@ -207,73 +183,60 @@ tftp_receive (grub_net_udp_socket_t sock __attribute__ ((unused)), | |
4033 | return GRUB_ERR_NONE; | |
4034 | } | |
4035 | ||
4036 | - err = grub_priority_queue_push (data->pq, &nb); | |
4037 | - if (err) | |
4038 | - return err; | |
4039 | - | |
4040 | - { | |
4041 | - struct grub_net_buff **nb_top_p, *nb_top; | |
4042 | - while (1) | |
4043 | - { | |
4044 | - nb_top_p = grub_priority_queue_top (data->pq); | |
4045 | - if (!nb_top_p) | |
4046 | - return GRUB_ERR_NONE; | |
4047 | - nb_top = *nb_top_p; | |
4048 | - tftph = (struct tftphdr *) nb_top->data; | |
4049 | - if (cmp_block (grub_be_to_cpu16 (tftph->u.data.block), data->block + 1) >= 0) | |
4050 | - break; | |
4051 | - ack (data, grub_be_to_cpu16 (tftph->u.data.block)); | |
4052 | - grub_netbuff_free (nb_top); | |
4053 | - grub_priority_queue_pop (data->pq); | |
4054 | - } | |
4055 | - while (cmp_block (grub_be_to_cpu16 (tftph->u.data.block), data->block + 1) == 0) | |
4056 | - { | |
4057 | - unsigned size; | |
4058 | - | |
4059 | - grub_priority_queue_pop (data->pq); | |
4060 | - | |
4061 | - if (file->device->net->packs.count < 50) | |
4062 | + /* Ack old/retransmitted block. */ | |
4063 | + if (grub_be_to_cpu16 (tftph->u.data.block) < data->block + 1) | |
4064 | + ack (data, grub_be_to_cpu16 (tftph->u.data.block)); | |
4065 | + /* Ignore unexpected block. */ | |
4066 | + else if (grub_be_to_cpu16 (tftph->u.data.block) > data->block + 1) | |
4067 | + grub_dprintf ("tftp", "TFTP unexpected block # %d\n", tftph->u.data.block); | |
4068 | + else | |
4069 | + { | |
4070 | + unsigned size; | |
4071 | + | |
4072 | + if (file->device->net->packs.count < 50) | |
4073 | + { | |
4074 | err = ack (data, data->block + 1); | |
4075 | - else | |
4076 | - { | |
4077 | - file->device->net->stall = 1; | |
4078 | - err = 0; | |
4079 | - } | |
4080 | - if (err) | |
4081 | - return err; | |
4082 | - | |
4083 | - err = grub_netbuff_pull (nb_top, sizeof (tftph->opcode) + | |
4084 | - sizeof (tftph->u.data.block)); | |
4085 | - if (err) | |
4086 | - return err; | |
4087 | - size = nb_top->tail - nb_top->data; | |
4088 | - | |
4089 | - data->block++; | |
4090 | - if (size < data->block_size) | |
4091 | - { | |
4092 | - if (data->ack_sent < data->block) | |
4093 | - ack (data, data->block); | |
4094 | - file->device->net->eof = 1; | |
4095 | - file->device->net->stall = 1; | |
4096 | - grub_net_udp_close (data->sock); | |
4097 | - data->sock = NULL; | |
4098 | - } | |
4099 | - /* Prevent garbage in broken cards. Is it still necessary | |
4100 | - given that IP implementation has been fixed? | |
4101 | - */ | |
4102 | - if (size > data->block_size) | |
4103 | - { | |
4104 | - err = grub_netbuff_unput (nb_top, size - data->block_size); | |
4105 | - if (err) | |
4106 | - return err; | |
4107 | - } | |
4108 | - /* If there is data, puts packet in socket list. */ | |
4109 | - if ((nb_top->tail - nb_top->data) > 0) | |
4110 | - grub_net_put_packet (&file->device->net->packs, nb_top); | |
4111 | - else | |
4112 | - grub_netbuff_free (nb_top); | |
4113 | - } | |
4114 | - } | |
4115 | + if (err) | |
4116 | + return err; | |
4117 | + } | |
4118 | + else | |
4119 | + file->device->net->stall = 1; | |
4120 | + | |
4121 | + err = grub_netbuff_pull (nb, sizeof (tftph->opcode) + | |
4122 | + sizeof (tftph->u.data.block)); | |
4123 | + if (err) | |
4124 | + return err; | |
4125 | + size = nb->tail - nb->data; | |
4126 | + | |
4127 | + data->block++; | |
4128 | + if (size < data->block_size) | |
4129 | + { | |
4130 | + if (data->ack_sent < data->block) | |
4131 | + ack (data, data->block); | |
4132 | + file->device->net->eof = 1; | |
4133 | + file->device->net->stall = 1; | |
4134 | + grub_net_udp_close (data->sock); | |
4135 | + data->sock = NULL; | |
4136 | + } | |
4137 | + /* | |
4138 | + * Prevent garbage in broken cards. Is it still necessary | |
4139 | + * given that IP implementation has been fixed? | |
4140 | + */ | |
4141 | + if (size > data->block_size) | |
4142 | + { | |
4143 | + err = grub_netbuff_unput (nb, size - data->block_size); | |
4144 | + if (err) | |
4145 | + return err; | |
4146 | + } | |
4147 | + /* If there is data, puts packet in socket list. */ | |
4148 | + if ((nb->tail - nb->data) > 0) | |
4149 | + { | |
4150 | + grub_net_put_packet (&file->device->net->packs, nb); | |
4151 | + /* Do not free nb. */ | |
4152 | + return GRUB_ERR_NONE; | |
4153 | + } | |
4154 | + } | |
4155 | + grub_netbuff_free (nb); | |
4156 | return GRUB_ERR_NONE; | |
4157 | case TFTP_ERROR: | |
4158 | data->have_oack = 1; | |
4159 | @@ -287,19 +250,6 @@ tftp_receive (grub_net_udp_socket_t sock __attribute__ ((unused)), | |
4160 | } | |
4161 | } | |
4162 | ||
4163 | -static void | |
4164 | -destroy_pq (tftp_data_t data) | |
4165 | -{ | |
4166 | - struct grub_net_buff **nb_p; | |
4167 | - while ((nb_p = grub_priority_queue_top (data->pq))) | |
4168 | - { | |
4169 | - grub_netbuff_free (*nb_p); | |
4170 | - grub_priority_queue_pop (data->pq); | |
4171 | - } | |
4172 | - | |
4173 | - grub_priority_queue_destroy (data->pq); | |
4174 | -} | |
4175 | - | |
4176 | static grub_err_t | |
4177 | tftp_open (struct grub_file *file, const char *filename) | |
4178 | { | |
4179 | @@ -322,17 +322,9 @@ tftp_open (struct grub_file *file, const char *filename) | |
4180 | file->not_easily_seekable = 1; | |
4181 | file->data = data; | |
4182 | ||
4183 | - data->pq = grub_priority_queue_new (sizeof (struct grub_net_buff *), cmp); | |
4184 | - if (!data->pq) | |
4185 | - { | |
4186 | - grub_free (data); | |
4187 | - return grub_errno; | |
4188 | - } | |
4189 | - | |
4190 | err = grub_net_resolve_address (file->device->net->server, &addr); | |
4191 | if (err) | |
4192 | { | |
4193 | - destroy_pq (data); | |
4194 | grub_free (data); | |
4195 | return err; | |
4196 | } | |
4197 | @@ -396,7 +338,6 @@ tftp_open (struct grub_file *file, const char *filename) | |
4198 | file); | |
4199 | if (!data->sock) | |
4200 | { | |
4201 | - destroy_pq (data); | |
4202 | grub_free (data); | |
4203 | return grub_errno; | |
4204 | } | |
4205 | @@ -410,7 +351,6 @@ tftp_open (struct grub_file *file, const char *filename) | |
4206 | if (err) | |
4207 | { | |
4208 | grub_net_udp_close (data->sock); | |
4209 | - destroy_pq (data); | |
4210 | grub_free (data); | |
4211 | return err; | |
4212 | } | |
4213 | @@ -427,7 +367,6 @@ tftp_open (struct grub_file *file, const char *filename) | |
4214 | if (grub_errno) | |
4215 | { | |
4216 | grub_net_udp_close (data->sock); | |
4217 | - destroy_pq (data); | |
4218 | grub_free (data); | |
4219 | return grub_errno; | |
4220 | } | |
4221 | @@ -470,7 +409,6 @@ tftp_close (struct grub_file *file) | |
4222 | grub_print_error (); | |
4223 | grub_net_udp_close (data->sock); | |
4224 | } | |
4225 | - destroy_pq (data); | |
4226 | grub_free (data); | |
4227 | return GRUB_ERR_NONE; | |
4228 | } | |
4229 | ||
4230 | From f1e2fd65877424ee8d8d2bdd78ce28b420dee4d8 Mon Sep 17 00:00:00 2001 | |
4231 | From: Alexey Makhalov <amakhalov@vmware.com> | |
4232 | Date: Wed, 15 Jul 2020 06:42:37 +0000 | |
4233 | Subject: relocator: Protect grub_relocator_alloc_chunk_addr() | |
4234 | input args against integer underflow/overflow | |
4235 | ||
4236 | Use arithmetic macros from safemath.h to accomplish it. In this commit, | |
4237 | I didn't want to be too paranoid to check every possible math equation | |
4238 | for overflow/underflow. Only obvious places (with non zero chance of | |
4239 | overflow/underflow) were refactored. | |
4240 | ||
4241 | Signed-off-by: Alexey Makhalov <amakhalov@vmware.com> | |
4242 | Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> | |
4243 | --- | |
4244 | grub-core/loader/i386/linux.c | 9 +++++++-- | |
4245 | grub-core/loader/i386/pc/linux.c | 9 +++++++-- | |
4246 | grub-core/loader/i386/xen.c | 12 ++++++++++-- | |
4247 | grub-core/loader/xnu.c | 11 +++++++---- | |
4248 | 4 files changed, 31 insertions(+), 10 deletions(-) | |
4249 | ||
4250 | diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c | |
4251 | index 2eab9bb10..58d76fc0a 100644 | |
4252 | --- a/grub-core/loader/i386/linux.c | |
4253 | +++ b/grub-core/loader/i386/linux.c | |
4254 | @@ -36,6 +36,7 @@ | |
4255 | #include <grub/lib/cmdline.h> | |
4256 | #include <grub/linux.h> | |
4257 | #include <grub/machine/kernel.h> | |
4258 | +#include <grub/safemath.h> | |
4259 | ||
4260 | GRUB_MOD_LICENSE ("GPLv3+"); | |
4261 | ||
4262 | @@ -549,9 +550,13 @@ grub_linux_boot (void) | |
4263 | ||
4264 | { | |
4265 | grub_relocator_chunk_t ch; | |
4266 | + grub_size_t sz; | |
4267 | + | |
4268 | + if (grub_add (ctx.real_size, efi_mmap_size, &sz)) | |
4269 | + return GRUB_ERR_OUT_OF_RANGE; | |
4270 | + | |
4271 | err = grub_relocator_alloc_chunk_addr (relocator, &ch, | |
4272 | - ctx.real_mode_target, | |
4273 | - (ctx.real_size + efi_mmap_size)); | |
4274 | + ctx.real_mode_target, sz); | |
4275 | if (err) | |
4276 | return err; | |
4277 | real_mode_mem = get_virtual_current_address (ch); | |
4278 | diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c | |
4279 | index 47ea2945e..31f09922b 100644 | |
4280 | --- a/grub-core/loader/i386/pc/linux.c | |
4281 | +++ b/grub-core/loader/i386/pc/linux.c | |
4282 | @@ -35,6 +35,7 @@ | |
4283 | #include <grub/i386/floppy.h> | |
4284 | #include <grub/lib/cmdline.h> | |
4285 | #include <grub/linux.h> | |
4286 | +#include <grub/safemath.h> | |
4287 | ||
4288 | GRUB_MOD_LICENSE ("GPLv3+"); | |
4289 | ||
4290 | @@ -218,8 +219,12 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), | |
4291 | setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS; | |
4292 | ||
4293 | real_size = setup_sects << GRUB_DISK_SECTOR_BITS; | |
4294 | - grub_linux16_prot_size = grub_file_size (file) | |
4295 | - - real_size - GRUB_DISK_SECTOR_SIZE; | |
4296 | + if (grub_sub (grub_file_size (file), real_size, &grub_linux16_prot_size) || | |
4297 | + grub_sub (grub_linux16_prot_size, GRUB_DISK_SECTOR_SIZE, &grub_linux16_prot_size)) | |
4298 | + { | |
4299 | + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); | |
4300 | + goto fail; | |
4301 | + } | |
4302 | ||
4303 | if (! grub_linux_is_bzimage | |
4304 | && GRUB_LINUX_ZIMAGE_ADDR + grub_linux16_prot_size | |
4305 | diff --git a/grub-core/loader/i386/xen.c b/grub-core/loader/i386/xen.c | |
4306 | index 8f662c8ac..cd24874ca 100644 | |
4307 | --- a/grub-core/loader/i386/xen.c | |
4308 | +++ b/grub-core/loader/i386/xen.c | |
4309 | @@ -41,6 +41,7 @@ | |
4310 | #include <grub/linux.h> | |
4311 | #include <grub/i386/memory.h> | |
4312 | #include <grub/verify.h> | |
4313 | +#include <grub/safemath.h> | |
4314 | ||
4315 | GRUB_MOD_LICENSE ("GPLv3+"); | |
4316 | ||
4317 | @@ -636,6 +637,7 @@ grub_cmd_xen (grub_command_t cmd __attribute__ ((unused)), | |
4318 | grub_relocator_chunk_t ch; | |
4319 | grub_addr_t kern_start; | |
4320 | grub_addr_t kern_end; | |
4321 | + grub_size_t sz; | |
4322 | ||
4323 | if (argc == 0) | |
4324 | return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); | |
4325 | @@ -703,8 +705,14 @@ grub_cmd_xen (grub_command_t cmd __attribute__ ((unused)), | |
4326 | ||
4327 | xen_state.max_addr = ALIGN_UP (kern_end, PAGE_SIZE); | |
4328 | ||
4329 | - err = grub_relocator_alloc_chunk_addr (xen_state.relocator, &ch, kern_start, | |
4330 | - kern_end - kern_start); | |
4331 | + | |
4332 | + if (grub_sub (kern_end, kern_start, &sz)) | |
4333 | + { | |
4334 | + err = GRUB_ERR_OUT_OF_RANGE; | |
4335 | + goto fail; | |
4336 | + } | |
4337 | + | |
4338 | + err = grub_relocator_alloc_chunk_addr (xen_state.relocator, &ch, kern_start, sz); | |
4339 | if (err) | |
4340 | goto fail; | |
4341 | kern_chunk_src = get_virtual_current_address (ch); | |
4342 | diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c | |
4343 | index 77d7060e1..9ae4ceb35 100644 | |
4344 | --- a/grub-core/loader/xnu.c | |
4345 | +++ b/grub-core/loader/xnu.c | |
4346 | @@ -34,6 +34,7 @@ | |
4347 | #include <grub/env.h> | |
4348 | #include <grub/i18n.h> | |
4349 | #include <grub/verify.h> | |
4350 | +#include <grub/safemath.h> | |
4351 | ||
4352 | GRUB_MOD_LICENSE ("GPLv3+"); | |
4353 | ||
4354 | @@ -59,15 +60,17 @@ grub_xnu_heap_malloc (int size, void **src, grub_addr_t *target) | |
4355 | { | |
4356 | grub_err_t err; | |
4357 | grub_relocator_chunk_t ch; | |
4358 | + grub_addr_t tgt; | |
4359 | + | |
4360 | + if (grub_add (grub_xnu_heap_target_start, grub_xnu_heap_size, &tgt)) | |
4361 | + return GRUB_ERR_OUT_OF_RANGE; | |
4362 | ||
4363 | - err = grub_relocator_alloc_chunk_addr (grub_xnu_relocator, &ch, | |
4364 | - grub_xnu_heap_target_start | |
4365 | - + grub_xnu_heap_size, size); | |
4366 | + err = grub_relocator_alloc_chunk_addr (grub_xnu_relocator, &ch, tgt, size); | |
4367 | if (err) | |
4368 | return err; | |
4369 | ||
4370 | *src = get_virtual_current_address (ch); | |
4371 | - *target = grub_xnu_heap_target_start + grub_xnu_heap_size; | |
4372 | + *target = tgt; | |
4373 | grub_xnu_heap_size += size; | |
4374 | grub_dprintf ("xnu", "val=%p\n", *src); | |
4375 | return GRUB_ERR_NONE; | |
4376 | ||
4377 | From e39786ab462b1e4770fb35c736927286381ec47d Mon Sep 17 00:00:00 2001 | |
4378 | From: Alexey Makhalov <amakhalov@vmware.com> | |
4379 | Date: Wed, 8 Jul 2020 01:44:38 +0000 | |
4380 | Subject: relocator: Protect grub_relocator_alloc_chunk_align() | |
4381 | max_addr against integer underflow | |
4382 | ||
4383 | This commit introduces integer underflow mitigation in max_addr calculation | |
4384 | in grub_relocator_alloc_chunk_align() invocation. | |
4385 | ||
4386 | It consists of 2 fixes: | |
4387 | 1. Introduced grub_relocator_alloc_chunk_align_safe() wrapper function to perform | |
4388 | sanity check for min/max and size values, and to make safe invocation of | |
4389 | grub_relocator_alloc_chunk_align() with validated max_addr value. Replace all | |
4390 | invocations such as grub_relocator_alloc_chunk_align(..., min_addr, max_addr - size, size, ...) | |
4391 | by grub_relocator_alloc_chunk_align_safe(..., min_addr, max_addr, size, ...). | |
4392 | 2. Introduced UP_TO_TOP32(s) macro for the cases where max_addr is 32-bit top | |
4393 | address (0xffffffff - size + 1) or similar. | |
4394 | ||
4395 | Signed-off-by: Alexey Makhalov <amakhalov@vmware.com> | |
4396 | Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> | |
4397 | --- | |
4398 | grub-core/lib/i386/relocator.c | 28 ++++++++++---------------- | |
4399 | grub-core/lib/mips/relocator.c | 6 ++---- | |
4400 | grub-core/lib/powerpc/relocator.c | 6 ++---- | |
4401 | grub-core/lib/x86_64/efi/relocator.c | 7 +++---- | |
4402 | grub-core/loader/i386/linux.c | 5 ++--- | |
4403 | grub-core/loader/i386/multiboot_mbi.c | 7 +++---- | |
4404 | grub-core/loader/i386/pc/linux.c | 6 ++---- | |
4405 | grub-core/loader/mips/linux.c | 9 +++------ | |
4406 | grub-core/loader/multiboot.c | 2 +- | |
4407 | grub-core/loader/multiboot_elfxx.c | 10 ++++----- | |
4408 | grub-core/loader/multiboot_mbi2.c | 10 ++++----- | |
4409 | grub-core/loader/xnu_resume.c | 2 +- | |
4410 | include/grub/relocator.h | 29 +++++++++++++++++++++++++++ | |
4411 | 13 files changed, 69 insertions(+), 58 deletions(-) | |
4412 | ||
4413 | diff --git a/grub-core/lib/i386/relocator.c b/grub-core/lib/i386/relocator.c | |
4414 | index 71dd4f0ab..34cbe834f 100644 | |
4415 | --- a/grub-core/lib/i386/relocator.c | |
4416 | +++ b/grub-core/lib/i386/relocator.c | |
4417 | @@ -83,11 +83,10 @@ grub_relocator32_boot (struct grub_relocator *rel, | |
4418 | /* Specific memory range due to Global Descriptor Table for use by payload | |
4419 | that we will store in returned chunk. The address range and preference | |
4420 | are based on "THE LINUX/x86 BOOT PROTOCOL" specification. */ | |
4421 | - err = grub_relocator_alloc_chunk_align (rel, &ch, 0x1000, | |
4422 | - 0x9a000 - RELOCATOR_SIZEOF (32), | |
4423 | - RELOCATOR_SIZEOF (32), 16, | |
4424 | - GRUB_RELOCATOR_PREFERENCE_LOW, | |
4425 | - avoid_efi_bootservices); | |
4426 | + err = grub_relocator_alloc_chunk_align_safe (rel, &ch, 0x1000, 0x9a000, | |
4427 | + RELOCATOR_SIZEOF (32), 16, | |
4428 | + GRUB_RELOCATOR_PREFERENCE_LOW, | |
4429 | + avoid_efi_bootservices); | |
4430 | if (err) | |
4431 | return err; | |
4432 | ||
4433 | @@ -125,13 +124,10 @@ grub_relocator16_boot (struct grub_relocator *rel, | |
4434 | grub_relocator_chunk_t ch; | |
4435 | ||
4436 | /* Put it higher than the byte it checks for A20 check. */ | |
4437 | - err = grub_relocator_alloc_chunk_align (rel, &ch, 0x8010, | |
4438 | - 0xa0000 - RELOCATOR_SIZEOF (16) | |
4439 | - - GRUB_RELOCATOR16_STACK_SIZE, | |
4440 | - RELOCATOR_SIZEOF (16) | |
4441 | - + GRUB_RELOCATOR16_STACK_SIZE, 16, | |
4442 | - GRUB_RELOCATOR_PREFERENCE_NONE, | |
4443 | - 0); | |
4444 | + err = grub_relocator_alloc_chunk_align_safe (rel, &ch, 0x8010, 0xa0000, | |
4445 | + RELOCATOR_SIZEOF (16) + | |
4446 | + GRUB_RELOCATOR16_STACK_SIZE, 16, | |
4447 | + GRUB_RELOCATOR_PREFERENCE_NONE, 0); | |
4448 | if (err) | |
4449 | return err; | |
4450 | ||
4451 | @@ -183,11 +179,9 @@ grub_relocator64_boot (struct grub_relocator *rel, | |
4452 | void *relst; | |
4453 | grub_relocator_chunk_t ch; | |
4454 | ||
4455 | - err = grub_relocator_alloc_chunk_align (rel, &ch, min_addr, | |
4456 | - max_addr - RELOCATOR_SIZEOF (64), | |
4457 | - RELOCATOR_SIZEOF (64), 16, | |
4458 | - GRUB_RELOCATOR_PREFERENCE_NONE, | |
4459 | - 0); | |
4460 | + err = grub_relocator_alloc_chunk_align_safe (rel, &ch, min_addr, max_addr, | |
4461 | + RELOCATOR_SIZEOF (64), 16, | |
4462 | + GRUB_RELOCATOR_PREFERENCE_NONE, 0); | |
4463 | if (err) | |
4464 | return err; | |
4465 | ||
4466 | diff --git a/grub-core/lib/mips/relocator.c b/grub-core/lib/mips/relocator.c | |
4467 | index 9d5f49cb9..743b213e6 100644 | |
4468 | --- a/grub-core/lib/mips/relocator.c | |
4469 | +++ b/grub-core/lib/mips/relocator.c | |
4470 | @@ -120,10 +120,8 @@ grub_relocator32_boot (struct grub_relocator *rel, | |
4471 | unsigned i; | |
4472 | grub_addr_t vtarget; | |
4473 | ||
4474 | - err = grub_relocator_alloc_chunk_align (rel, &ch, 0, | |
4475 | - (0xffffffff - stateset_size) | |
4476 | - + 1, stateset_size, | |
4477 | - sizeof (grub_uint32_t), | |
4478 | + err = grub_relocator_alloc_chunk_align (rel, &ch, 0, UP_TO_TOP32 (stateset_size), | |
4479 | + stateset_size, sizeof (grub_uint32_t), | |
4480 | GRUB_RELOCATOR_PREFERENCE_NONE, 0); | |
4481 | if (err) | |
4482 | return err; | |
4483 | diff --git a/grub-core/lib/powerpc/relocator.c b/grub-core/lib/powerpc/relocator.c | |
4484 | index bdf2b111b..8ffb8b686 100644 | |
4485 | --- a/grub-core/lib/powerpc/relocator.c | |
4486 | +++ b/grub-core/lib/powerpc/relocator.c | |
4487 | @@ -115,10 +115,8 @@ grub_relocator32_boot (struct grub_relocator *rel, | |
4488 | unsigned i; | |
4489 | grub_relocator_chunk_t ch; | |
4490 | ||
4491 | - err = grub_relocator_alloc_chunk_align (rel, &ch, 0, | |
4492 | - (0xffffffff - stateset_size) | |
4493 | - + 1, stateset_size, | |
4494 | - sizeof (grub_uint32_t), | |
4495 | + err = grub_relocator_alloc_chunk_align (rel, &ch, 0, UP_TO_TOP32 (stateset_size), | |
4496 | + stateset_size, sizeof (grub_uint32_t), | |
4497 | GRUB_RELOCATOR_PREFERENCE_NONE, 0); | |
4498 | if (err) | |
4499 | return err; | |
4500 | diff --git a/grub-core/lib/x86_64/efi/relocator.c b/grub-core/lib/x86_64/efi/relocator.c | |
4501 | index 3caef7a40..7d200a125 100644 | |
4502 | --- a/grub-core/lib/x86_64/efi/relocator.c | |
4503 | +++ b/grub-core/lib/x86_64/efi/relocator.c | |
4504 | @@ -50,10 +50,9 @@ grub_relocator64_efi_boot (struct grub_relocator *rel, | |
4505 | * 64-bit relocator code may live above 4 GiB quite well. | |
4506 | * However, I do not want ask for problems. Just in case. | |
4507 | */ | |
4508 | - err = grub_relocator_alloc_chunk_align (rel, &ch, 0, | |
4509 | - 0x100000000 - RELOCATOR_SIZEOF (64_efi), | |
4510 | - RELOCATOR_SIZEOF (64_efi), 16, | |
4511 | - GRUB_RELOCATOR_PREFERENCE_NONE, 1); | |
4512 | + err = grub_relocator_alloc_chunk_align_safe (rel, &ch, 0, 0x100000000, | |
4513 | + RELOCATOR_SIZEOF (64_efi), 16, | |
4514 | + GRUB_RELOCATOR_PREFERENCE_NONE, 1); | |
4515 | if (err) | |
4516 | return err; | |
4517 | ||
4518 | diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c | |
4519 | index 58d76fc0a..c98fbbb37 100644 | |
4520 | --- a/grub-core/loader/i386/linux.c | |
4521 | +++ b/grub-core/loader/i386/linux.c | |
4522 | @@ -183,9 +183,8 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, | |
4523 | for (; err && *align + 1 > min_align; (*align)--) | |
4524 | { | |
4525 | grub_errno = GRUB_ERR_NONE; | |
4526 | - err = grub_relocator_alloc_chunk_align (relocator, &ch, | |
4527 | - 0x1000000, | |
4528 | - 0xffffffff & ~prot_size, | |
4529 | + err = grub_relocator_alloc_chunk_align (relocator, &ch, 0x1000000, | |
4530 | + UP_TO_TOP32 (prot_size), | |
4531 | prot_size, 1 << *align, | |
4532 | GRUB_RELOCATOR_PREFERENCE_LOW, | |
4533 | 1); | |
4534 | diff --git a/grub-core/loader/i386/multiboot_mbi.c b/grub-core/loader/i386/multiboot_mbi.c | |
4535 | index ad3cc292f..a67d9d0a8 100644 | |
4536 | --- a/grub-core/loader/i386/multiboot_mbi.c | |
4537 | +++ b/grub-core/loader/i386/multiboot_mbi.c | |
4538 | @@ -466,10 +466,9 @@ grub_multiboot_make_mbi (grub_uint32_t *target) | |
4539 | ||
4540 | bufsize = grub_multiboot_get_mbi_size (); | |
4541 | ||
4542 | - err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch, | |
4543 | - 0x10000, 0xa0000 - bufsize, | |
4544 | - bufsize, 4, | |
4545 | - GRUB_RELOCATOR_PREFERENCE_NONE, 0); | |
4546 | + err = grub_relocator_alloc_chunk_align_safe (grub_multiboot_relocator, &ch, | |
4547 | + 0x10000, 0xa0000, bufsize, 4, | |
4548 | + GRUB_RELOCATOR_PREFERENCE_NONE, 0); | |
4549 | if (err) | |
4550 | return err; | |
4551 | ptrorig = get_virtual_current_address (ch); | |
4552 | diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c | |
4553 | index 31f09922b..5fed5ffdf 100644 | |
4554 | --- a/grub-core/loader/i386/pc/linux.c | |
4555 | +++ b/grub-core/loader/i386/pc/linux.c | |
4556 | @@ -453,10 +453,8 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), | |
4557 | ||
4558 | { | |
4559 | grub_relocator_chunk_t ch; | |
4560 | - err = grub_relocator_alloc_chunk_align (relocator, &ch, | |
4561 | - addr_min, addr_max - size, | |
4562 | - size, 0x1000, | |
4563 | - GRUB_RELOCATOR_PREFERENCE_HIGH, 0); | |
4564 | + err = grub_relocator_alloc_chunk_align_safe (relocator, &ch, addr_min, addr_max, size, | |
4565 | + 0x1000, GRUB_RELOCATOR_PREFERENCE_HIGH, 0); | |
4566 | if (err) | |
4567 | return err; | |
4568 | initrd_chunk = get_virtual_current_address (ch); | |
4569 | diff --git a/grub-core/loader/mips/linux.c b/grub-core/loader/mips/linux.c | |
4570 | index 7b723bf18..e4ed95921 100644 | |
4571 | --- a/grub-core/loader/mips/linux.c | |
4572 | +++ b/grub-core/loader/mips/linux.c | |
4573 | @@ -442,12 +442,9 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), | |
4574 | { | |
4575 | grub_relocator_chunk_t ch; | |
4576 | ||
4577 | - err = grub_relocator_alloc_chunk_align (relocator, &ch, | |
4578 | - (target_addr & 0x1fffffff) | |
4579 | - + linux_size + 0x10000, | |
4580 | - (0x10000000 - size), | |
4581 | - size, 0x10000, | |
4582 | - GRUB_RELOCATOR_PREFERENCE_NONE, 0); | |
4583 | + err = grub_relocator_alloc_chunk_align_safe (relocator, &ch, (target_addr & 0x1fffffff) + | |
4584 | + linux_size + 0x10000, 0x10000000, size, | |
4585 | + 0x10000, GRUB_RELOCATOR_PREFERENCE_NONE, 0); | |
4586 | ||
4587 | if (err) | |
4588 | goto fail; | |
4589 | diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c | |
4590 | index 4a98d7082..facb13f3d 100644 | |
4591 | --- a/grub-core/loader/multiboot.c | |
4592 | +++ b/grub-core/loader/multiboot.c | |
4593 | @@ -403,7 +403,7 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)), | |
4594 | { | |
4595 | grub_relocator_chunk_t ch; | |
4596 | err = grub_relocator_alloc_chunk_align (GRUB_MULTIBOOT (relocator), &ch, | |
4597 | - lowest_addr, (0xffffffff - size) + 1, | |
4598 | + lowest_addr, UP_TO_TOP32 (size), | |
4599 | size, MULTIBOOT_MOD_ALIGN, | |
4600 | GRUB_RELOCATOR_PREFERENCE_NONE, 1); | |
4601 | if (err) | |
4602 | diff --git a/grub-core/loader/multiboot_elfxx.c b/grub-core/loader/multiboot_elfxx.c | |
4603 | index cc6853692..f2318e0d1 100644 | |
4604 | --- a/grub-core/loader/multiboot_elfxx.c | |
4605 | +++ b/grub-core/loader/multiboot_elfxx.c | |
4606 | @@ -109,10 +109,10 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) | |
4607 | if (load_size > mld->max_addr || mld->min_addr > mld->max_addr - load_size) | |
4608 | return grub_error (GRUB_ERR_BAD_OS, "invalid min/max address and/or load size"); | |
4609 | ||
4610 | - err = grub_relocator_alloc_chunk_align (GRUB_MULTIBOOT (relocator), &ch, | |
4611 | - mld->min_addr, mld->max_addr - load_size, | |
4612 | - load_size, mld->align ? mld->align : 1, | |
4613 | - mld->preference, mld->avoid_efi_boot_services); | |
4614 | + err = grub_relocator_alloc_chunk_align_safe (GRUB_MULTIBOOT (relocator), &ch, | |
4615 | + mld->min_addr, mld->max_addr, | |
4616 | + load_size, mld->align ? mld->align : 1, | |
4617 | + mld->preference, mld->avoid_efi_boot_services); | |
4618 | ||
4619 | if (err) | |
4620 | { | |
4621 | @@ -256,7 +256,7 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) | |
4622 | continue; | |
4623 | ||
4624 | err = grub_relocator_alloc_chunk_align (GRUB_MULTIBOOT (relocator), &ch, 0, | |
4625 | - (0xffffffff - sh->sh_size) + 1, | |
4626 | + UP_TO_TOP32 (sh->sh_size), | |
4627 | sh->sh_size, sh->sh_addralign, | |
4628 | GRUB_RELOCATOR_PREFERENCE_NONE, | |
4629 | mld->avoid_efi_boot_services); | |
4630 | diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c | |
4631 | index 0efc66062..03967839c 100644 | |
4632 | --- a/grub-core/loader/multiboot_mbi2.c | |
4633 | +++ b/grub-core/loader/multiboot_mbi2.c | |
4634 | @@ -295,10 +295,10 @@ grub_multiboot2_load (grub_file_t file, const char *filename) | |
4635 | return grub_error (GRUB_ERR_BAD_OS, "invalid min/max address and/or load size"); | |
4636 | } | |
4637 | ||
4638 | - err = grub_relocator_alloc_chunk_align (grub_multiboot2_relocator, &ch, | |
4639 | - mld.min_addr, mld.max_addr - code_size, | |
4640 | - code_size, mld.align ? mld.align : 1, | |
4641 | - mld.preference, keep_bs); | |
4642 | + err = grub_relocator_alloc_chunk_align_safe (grub_multiboot2_relocator, &ch, | |
4643 | + mld.min_addr, mld.max_addr, | |
4644 | + code_size, mld.align ? mld.align : 1, | |
4645 | + mld.preference, keep_bs); | |
4646 | } | |
4647 | else | |
4648 | err = grub_relocator_alloc_chunk_addr (grub_multiboot2_relocator, | |
4649 | @@ -708,7 +708,7 @@ grub_multiboot2_make_mbi (grub_uint32_t *target) | |
4650 | COMPILE_TIME_ASSERT (MULTIBOOT_TAG_ALIGN % sizeof (grub_properly_aligned_t) == 0); | |
4651 | ||
4652 | err = grub_relocator_alloc_chunk_align (grub_multiboot2_relocator, &ch, | |
4653 | - 0, 0xffffffff - bufsize, | |
4654 | + 0, UP_TO_TOP32 (bufsize), | |
4655 | bufsize, MULTIBOOT_TAG_ALIGN, | |
4656 | GRUB_RELOCATOR_PREFERENCE_NONE, 1); | |
4657 | if (err) | |
4658 | diff --git a/grub-core/loader/xnu_resume.c b/grub-core/loader/xnu_resume.c | |
4659 | index 8089804d4..d648ef0cd 100644 | |
4660 | --- a/grub-core/loader/xnu_resume.c | |
4661 | +++ b/grub-core/loader/xnu_resume.c | |
4662 | @@ -129,7 +129,7 @@ grub_xnu_resume (char *imagename) | |
4663 | { | |
4664 | grub_relocator_chunk_t ch; | |
4665 | err = grub_relocator_alloc_chunk_align (grub_xnu_relocator, &ch, 0, | |
4666 | - (0xffffffff - hibhead.image_size) + 1, | |
4667 | + UP_TO_TOP32 (hibhead.image_size), | |
4668 | hibhead.image_size, | |
4669 | GRUB_XNU_PAGESIZE, | |
4670 | GRUB_RELOCATOR_PREFERENCE_NONE, 0); | |
4671 | diff --git a/include/grub/relocator.h b/include/grub/relocator.h | |
4672 | index 24d8672d2..1b3bdd92a 100644 | |
4673 | --- a/include/grub/relocator.h | |
4674 | +++ b/include/grub/relocator.h | |
4675 | @@ -49,6 +49,35 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, | |
4676 | int preference, | |
4677 | int avoid_efi_boot_services); | |
4678 | ||
4679 | +/* | |
4680 | + * Wrapper for grub_relocator_alloc_chunk_align() with purpose of | |
4681 | + * protecting against integer underflow. | |
4682 | + * | |
4683 | + * Compare to its callee, max_addr has different meaning here. | |
4684 | + * It covers entire chunk and not just start address of the chunk. | |
4685 | + */ | |
4686 | +static inline grub_err_t | |
4687 | +grub_relocator_alloc_chunk_align_safe (struct grub_relocator *rel, | |
4688 | + grub_relocator_chunk_t *out, | |
4689 | + grub_phys_addr_t min_addr, | |
4690 | + grub_phys_addr_t max_addr, | |
4691 | + grub_size_t size, grub_size_t align, | |
4692 | + int preference, | |
4693 | + int avoid_efi_boot_services) | |
4694 | +{ | |
4695 | + /* Sanity check and ensure following equation (max_addr - size) is safe. */ | |
4696 | + if (max_addr < size || (max_addr - size) < min_addr) | |
4697 | + return GRUB_ERR_OUT_OF_RANGE; | |
4698 | + | |
4699 | + return grub_relocator_alloc_chunk_align (rel, out, min_addr, | |
4700 | + max_addr - size, | |
4701 | + size, align, preference, | |
4702 | + avoid_efi_boot_services); | |
4703 | +} | |
4704 | + | |
4705 | +/* Top 32-bit address minus s bytes and plus 1 byte. */ | |
4706 | +#define UP_TO_TOP32(s) ((~(s) & 0xffffffff) + 1) | |
4707 | + | |
4708 | #define GRUB_RELOCATOR_PREFERENCE_NONE 0 | |
4709 | #define GRUB_RELOCATOR_PREFERENCE_LOW 1 | |
4710 | #define GRUB_RELOCATOR_PREFERENCE_HIGH 2 | |
4711 | ||
4712 | From 7855b7e78de5f257fa686ec569bda27472c4f5da Mon Sep 17 00:00:00 2001 | |
4713 | From: Chris Coulson <chris.coulson@canonical.com> | |
4714 | Date: Fri, 10 Jul 2020 11:21:14 +0100 | |
4715 | Subject: script: Remove unused fields from grub_script_function | |
4716 | struct | |
4717 | ||
4718 | Signed-off-by: Chris Coulson <chris.coulson@canonical.com> | |
4719 | Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> | |
4720 | --- | |
4721 | include/grub/script_sh.h | 5 ----- | |
4722 | 1 file changed, 5 deletions(-) | |
4723 | ||
4724 | diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h | |
4725 | index 360c2be1f..b382bcf09 100644 | |
4726 | --- a/include/grub/script_sh.h | |
4727 | +++ b/include/grub/script_sh.h | |
4728 | @@ -359,13 +359,8 @@ struct grub_script_function | |
4729 | /* The script function. */ | |
4730 | struct grub_script *func; | |
4731 | ||
4732 | - /* The flags. */ | |
4733 | - unsigned flags; | |
4734 | - | |
4735 | /* The next element. */ | |
4736 | struct grub_script_function *next; | |
4737 | - | |
4738 | - int references; | |
4739 | }; | |
4740 | typedef struct grub_script_function *grub_script_function_t; | |
4741 | ||
4742 | ||
4743 | From fdc80d2460e5d3b54f5cde8657f9e171b0b9a376 Mon Sep 17 00:00:00 2001 | |
4744 | From: Chris Coulson <chris.coulson@canonical.com> | |
4745 | Date: Fri, 10 Jul 2020 14:41:45 +0100 | |
4746 | Subject: script: Avoid a use-after-free when redefining a | |
4747 | function during execution | |
4748 | ||
4749 | Defining a new function with the same name as a previously defined | |
4750 | function causes the grub_script and associated resources for the | |
4751 | previous function to be freed. If the previous function is currently | |
4752 | executing when a function with the same name is defined, this results | |
4753 | in use-after-frees when processing subsequent commands in the original | |
4754 | function. | |
4755 | ||
4756 | Instead, reject a new function definition if it has the same name as | |
4757 | a previously defined function, and that function is currently being | |
4758 | executed. Although a behavioural change, this should be backwards | |
4759 | compatible with existing configurations because they can't be | |
4760 | dependent on the current behaviour without being broken. | |
4761 | ||
4762 | Fixes: CVE-2020-15706 | |
4763 | ||
4764 | Signed-off-by: Chris Coulson <chris.coulson@canonical.com> | |
4765 | Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> | |
4766 | --- | |
4767 | grub-core/script/execute.c | 2 ++ | |
4768 | grub-core/script/function.c | 16 +++++++++++++--- | |
4769 | grub-core/script/parser.y | 3 ++- | |
4770 | include/grub/script_sh.h | 2 ++ | |
4771 | 4 files changed, 19 insertions(+), 4 deletions(-) | |
4772 | ||
4773 | diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c | |
4774 | index c8d6806fe..7e028e135 100644 | |
4775 | --- a/grub-core/script/execute.c | |
4776 | +++ b/grub-core/script/execute.c | |
4777 | @@ -838,7 +838,9 @@ grub_script_function_call (grub_script_function_t func, int argc, char **args) | |
4778 | old_scope = scope; | |
4779 | scope = &new_scope; | |
4780 | ||
4781 | + func->executing++; | |
4782 | ret = grub_script_execute (func->func); | |
4783 | + func->executing--; | |
4784 | ||
4785 | function_return = 0; | |
4786 | active_loops = loops; | |
4787 | diff --git a/grub-core/script/function.c b/grub-core/script/function.c | |
4788 | index d36655e51..3aad04bf9 100644 | |
4789 | --- a/grub-core/script/function.c | |
4790 | +++ b/grub-core/script/function.c | |
4791 | @@ -34,6 +34,7 @@ grub_script_function_create (struct grub_script_arg *functionname_arg, | |
4792 | func = (grub_script_function_t) grub_malloc (sizeof (*func)); | |
4793 | if (! func) | |
4794 | return 0; | |
4795 | + func->executing = 0; | |
4796 | ||
4797 | func->name = grub_strdup (functionname_arg->str); | |
4798 | if (! func->name) | |
4799 | @@ -60,10 +61,19 @@ grub_script_function_create (struct grub_script_arg *functionname_arg, | |
4800 | grub_script_function_t q; | |
4801 | ||
4802 | q = *p; | |
4803 | - grub_script_free (q->func); | |
4804 | - q->func = cmd; | |
4805 | grub_free (func); | |
4806 | - func = q; | |
4807 | + if (q->executing > 0) | |
4808 | + { | |
4809 | + grub_error (GRUB_ERR_BAD_ARGUMENT, | |
4810 | + N_("attempt to redefine a function being executed")); | |
4811 | + func = NULL; | |
4812 | + } | |
4813 | + else | |
4814 | + { | |
4815 | + grub_script_free (q->func); | |
4816 | + q->func = cmd; | |
4817 | + func = q; | |
4818 | + } | |
4819 | } | |
4820 | else | |
4821 | { | |
4822 | diff --git a/grub-core/script/parser.y b/grub-core/script/parser.y | |
4823 | index 4f0ab8319..f80b86b6f 100644 | |
4824 | --- a/grub-core/script/parser.y | |
4825 | +++ b/grub-core/script/parser.y | |
4826 | @@ -289,7 +289,8 @@ function: "function" "name" | |
4827 | grub_script_mem_free (state->func_mem); | |
4828 | else { | |
4829 | script->children = state->scripts; | |
4830 | - grub_script_function_create ($2, script); | |
4831 | + if (!grub_script_function_create ($2, script)) | |
4832 | + grub_script_free (script); | |
4833 | } | |
4834 | ||
4835 | state->scripts = $<scripts>3; | |
4836 | diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h | |
4837 | index b382bcf09..6c48e0751 100644 | |
4838 | --- a/include/grub/script_sh.h | |
4839 | +++ b/include/grub/script_sh.h | |
4840 | @@ -361,6 +361,8 @@ struct grub_script_function | |
4841 | ||
4842 | /* The next element. */ | |
4843 | struct grub_script_function *next; | |
4844 | + | |
4845 | + unsigned executing; | |
4846 | }; | |
4847 | typedef struct grub_script_function *grub_script_function_t; | |
4848 | ||
4849 | ||
4850 | From dcc097ac0531485f0785816469370bfcb1a29f60 Mon Sep 17 00:00:00 2001 | |
4851 | From: Alexey Makhalov <amakhalov@vmware.com> | |
4852 | Date: Fri, 17 Jul 2020 05:17:26 +0000 | |
4853 | Subject: relocator: Fix grub_relocator_alloc_chunk_align() top | |
4854 | memory allocation | |
4855 | ||
4856 | Current implementation of grub_relocator_alloc_chunk_align() | |
4857 | does not allow allocation of the top byte. | |
4858 | ||
4859 | Assuming input args are: | |
4860 | max_addr = 0xfffff000; | |
4861 | size = 0x1000; | |
4862 | ||
4863 | And this is valid. But following overflow protection will | |
4864 | unnecessarily move max_addr one byte down (to 0xffffefff): | |
4865 | if (max_addr > ~size) | |
4866 | max_addr = ~size; | |
4867 | ||
4868 | ~size + 1 will fix the situation. In addition, check size | |
4869 | for non zero to do not zero max_addr. | |
4870 | ||
4871 | Signed-off-by: Alexey Makhalov <amakhalov@vmware.com> | |
4872 | Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> | |
4873 | --- | |
4874 | grub-core/lib/relocator.c | 4 ++-- | |
4875 | 1 file changed, 2 insertions(+), 2 deletions(-) | |
4876 | ||
4877 | diff --git a/grub-core/lib/relocator.c b/grub-core/lib/relocator.c | |
4878 | index 5847aac36..f2c1944c2 100644 | |
4879 | --- a/grub-core/lib/relocator.c | |
4880 | +++ b/grub-core/lib/relocator.c | |
4881 | @@ -1386,8 +1386,8 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, | |
4882 | }; | |
4883 | grub_addr_t min_addr2 = 0, max_addr2; | |
4884 | ||
4885 | - if (max_addr > ~size) | |
4886 | - max_addr = ~size; | |
4887 | + if (size && (max_addr > ~size)) | |
4888 | + max_addr = ~size + 1; | |
4889 | ||
4890 | #ifdef GRUB_MACHINE_PCBIOS | |
4891 | if (min_addr < 0x1000) | |
4892 | ||
4893 | From 2db482b906c425aa755fc78e8e8980659b92f5a1 Mon Sep 17 00:00:00 2001 | |
4894 | From: Peter Jones <pjones@redhat.com> | |
4895 | Date: Sun, 19 Jul 2020 14:43:31 -0400 | |
4896 | Subject: hfsplus: fix two more overflows | |
4897 | ||
4898 | Both node->size and node->namelen come from the supplied filesystem, | |
4899 | which may be user-supplied. We can't trust them for the math unless we | |
4900 | know they don't overflow; making sure they go through calloc() first | |
4901 | will give us that. | |
4902 | ||
4903 | Signed-off-by: Peter Jones <pjones@redhat.com> | |
4904 | Reviewed-by: Darren Kenny <darren.kenny@oracle.com> | |
4905 | --- | |
4906 | grub-core/fs/hfsplus.c | 11 ++++++++--- | |
4907 | 1 file changed, 8 insertions(+), 3 deletions(-) | |
4908 | ||
4909 | diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c | |
4910 | index dae43becc..9c4e4c88c 100644 | |
4911 | --- a/grub-core/fs/hfsplus.c | |
4912 | +++ b/grub-core/fs/hfsplus.c | |
4913 | @@ -31,6 +31,7 @@ | |
4914 | #include <grub/hfs.h> | |
4915 | #include <grub/charset.h> | |
4916 | #include <grub/hfsplus.h> | |
4917 | +#include <grub/safemath.h> | |
4918 | ||
4919 | GRUB_MOD_LICENSE ("GPLv3+"); | |
4920 | ||
4921 | @@ -475,8 +476,12 @@ grub_hfsplus_read_symlink (grub_fshelp_node_t node) | |
4922 | { | |
4923 | char *symlink; | |
4924 | grub_ssize_t numread; | |
4925 | + grub_size_t sz = node->size; | |
4926 | ||
4927 | - symlink = grub_malloc (node->size + 1); | |
4928 | + if (grub_add (sz, 1, &sz)) | |
4929 | + return NULL; | |
4930 | + | |
4931 | + symlink = grub_malloc (sz); | |
4932 | if (!symlink) | |
4933 | return 0; | |
4934 | ||
4935 | @@ -715,8 +720,8 @@ list_nodes (void *record, void *hook_arg) | |
4936 | if (type == GRUB_FSHELP_UNKNOWN) | |
4937 | return 0; | |
4938 | ||
4939 | - filename = grub_malloc (grub_be_to_cpu16 (catkey->namelen) | |
4940 | - * GRUB_MAX_UTF8_PER_UTF16 + 1); | |
4941 | + filename = grub_calloc (grub_be_to_cpu16 (catkey->namelen), | |
4942 | + GRUB_MAX_UTF8_PER_UTF16 + 1); | |
4943 | if (! filename) | |
4944 | return 0; | |
4945 | ||
4946 | ||
4947 | From fc669c03dbffd20667f40a2375c30ef91cdc2707 Mon Sep 17 00:00:00 2001 | |
4948 | From: Peter Jones <pjones@redhat.com> | |
4949 | Date: Sun, 19 Jul 2020 15:48:20 -0400 | |
4950 | Subject: lvm: fix two more potential data-dependent alloc | |
4951 | overflows | |
4952 | ||
4953 | It appears to be possible to make a (possibly invalid) lvm PV with a | |
4954 | metadata size field that overflows our type when adding it to the | |
4955 | address we've allocated. Even if it doesn't, it may be possible to do | |
4956 | so with the math using the outcome of that as an operand. Check them | |
4957 | both. | |
4958 | ||
4959 | Signed-off-by: Peter Jones <pjones@redhat.com> | |
4960 | Signed-off-by: Darren Kenny <darren.kenny@oracle.com> | |
4961 | --- | |
4962 | grub-core/disk/lvm.c | 47 ++++++++++++++++++++++++++++++++++++-------- | |
4963 | 1 file changed, 39 insertions(+), 8 deletions(-) | |
4964 | ||
4965 | diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c | |
4966 | index d1df640b3..e1299a348 100644 | |
4967 | --- a/grub-core/disk/lvm.c | |
4968 | +++ b/grub-core/disk/lvm.c | |
4969 | @@ -25,6 +25,7 @@ | |
4970 | #include <grub/lvm.h> | |
4971 | #include <grub/partition.h> | |
4972 | #include <grub/i18n.h> | |
4973 | +#include <grub/safemath.h> | |
4974 | ||
4975 | #ifdef GRUB_UTIL | |
4976 | #include <grub/emu/misc.h> | |
4977 | @@ -102,10 +103,11 @@ grub_lvm_detect (grub_disk_t disk, | |
4978 | { | |
4979 | grub_err_t err; | |
4980 | grub_uint64_t mda_offset, mda_size; | |
4981 | + grub_size_t ptr; | |
4982 | char buf[GRUB_LVM_LABEL_SIZE]; | |
4983 | char vg_id[GRUB_LVM_ID_STRLEN+1]; | |
4984 | char pv_id[GRUB_LVM_ID_STRLEN+1]; | |
4985 | - char *metadatabuf, *p, *q, *vgname; | |
4986 | + char *metadatabuf, *p, *q, *mda_end, *vgname; | |
4987 | struct grub_lvm_label_header *lh = (struct grub_lvm_label_header *) buf; | |
4988 | struct grub_lvm_pv_header *pvh; | |
4989 | struct grub_lvm_disk_locn *dlocn; | |
4990 | @@ -205,19 +207,31 @@ grub_lvm_detect (grub_disk_t disk, | |
4991 | grub_le_to_cpu64 (rlocn->size) - | |
4992 | grub_le_to_cpu64 (mdah->size)); | |
4993 | } | |
4994 | - p = q = metadatabuf + grub_le_to_cpu64 (rlocn->offset); | |
4995 | ||
4996 | - while (*q != ' ' && q < metadatabuf + mda_size) | |
4997 | - q++; | |
4998 | - | |
4999 | - if (q == metadatabuf + mda_size) | |
5000 | + if (grub_add ((grub_size_t)metadatabuf, | |
5001 | + (grub_size_t)grub_le_to_cpu64 (rlocn->offset), | |
5002 | + &ptr)) | |
5003 | { | |
5004 | +error_parsing_metadata: | |
5005 | #ifdef GRUB_UTIL | |
5006 | grub_util_info ("error parsing metadata"); | |
5007 | #endif | |
5008 | goto fail2; | |
5009 | } | |
5010 | ||
5011 | + p = q = (char *)ptr; | |
5012 | + | |
5013 | + if (grub_add ((grub_size_t)metadatabuf, (grub_size_t)mda_size, &ptr)) | |
5014 | + goto error_parsing_metadata; | |
5015 | + | |
5016 | + mda_end = (char *)ptr; | |
5017 | + | |
5018 | + while (*q != ' ' && q < mda_end) | |
5019 | + q++; | |
5020 | + | |
5021 | + if (q == mda_end) | |
5022 | + goto error_parsing_metadata; | |
5023 | + | |
5024 | vgname_len = q - p; | |
5025 | vgname = grub_malloc (vgname_len + 1); | |
5026 | if (!vgname) | |
5027 | @@ -367,8 +381,25 @@ grub_lvm_detect (grub_disk_t disk, | |
5028 | { | |
5029 | const char *iptr; | |
5030 | char *optr; | |
5031 | - lv->fullname = grub_malloc (sizeof ("lvm/") - 1 + 2 * vgname_len | |
5032 | - + 1 + 2 * s + 1); | |
5033 | + | |
5034 | + /* this is kind of hard to read with our safe (but rather | |
5035 | + * baroque) math primatives, but it boils down to: | |
5036 | + * | |
5037 | + * sz0 = vgname_len * 2 + 1 | |
5038 | + * + s * 2 + 1 | |
5039 | + * + sizeof ("lvm/") - 1; | |
5040 | + */ | |
5041 | + grub_size_t sz0 = vgname_len, sz1 = s; | |
5042 | + | |
5043 | + if (grub_mul (sz0, 2, &sz0) || | |
5044 | + grub_add (sz0, 1, &sz0) || | |
5045 | + grub_mul (sz1, 2, &sz1) || | |
5046 | + grub_add (sz1, 1, &sz1) || | |
5047 | + grub_add (sz0, sz1, &sz0) || | |
5048 | + grub_add (sz0, sizeof ("lvm/") - 1, &sz0)) | |
5049 | + goto lvs_fail; | |
5050 | + | |
5051 | + lv->fullname = grub_malloc (sz0); | |
5052 | if (!lv->fullname) | |
5053 | goto lvs_fail; | |
5054 | ||
5055 | ||
5056 | From c0a2098a2d47a752f9416a655a7010973298f66f Mon Sep 17 00:00:00 2001 | |
5057 | From: Peter Jones <pjones@redhat.com> | |
5058 | Date: Sun, 19 Jul 2020 16:08:08 -0400 | |
5059 | Subject: emu: make grub_free(NULL) safe | |
5060 | ||
5061 | The grub_free() implementation in kern/mm.c safely handles NULL | |
5062 | pointers, and code at many places depends on this. We don't know that | |
5063 | the same is true on all host OSes, so we need to handle the same | |
5064 | behavior in grub-emu's implementation. | |
5065 | ||
5066 | Signed-off-by: Peter Jones <pjones@redhat.com> | |
5067 | Reviewed-by: Darren Kenny <darren.kenny@oracle.com> | |
5068 | --- | |
5069 | grub-core/kern/emu/mm.c | 3 ++- | |
5070 | 1 file changed, 2 insertions(+), 1 deletion(-) | |
5071 | ||
5072 | diff --git a/grub-core/kern/emu/mm.c b/grub-core/kern/emu/mm.c | |
5073 | index 145b01d37..4d1046a21 100644 | |
5074 | --- a/grub-core/kern/emu/mm.c | |
5075 | +++ b/grub-core/kern/emu/mm.c | |
5076 | @@ -60,7 +60,8 @@ grub_zalloc (grub_size_t size) | |
5077 | void | |
5078 | grub_free (void *ptr) | |
5079 | { | |
5080 | - free (ptr); | |
5081 | + if (ptr) | |
5082 | + free (ptr); | |
5083 | } | |
5084 | ||
5085 | void * | |
5086 | ||
5087 | From 9735a4b2f52caf79e5804ca3e959f0f444a8716c Mon Sep 17 00:00:00 2001 | |
5088 | From: Peter Jones <pjones@redhat.com> | |
5089 | Date: Sun, 19 Jul 2020 16:53:27 -0400 | |
5090 | Subject: efi: fix some malformed device path arithmetic errors. | |
5091 | ||
5092 | Several places we take the length of a device path and subtract 4 from | |
5093 | it, without ever checking that it's >= 4. There are also cases where | |
5094 | this kind of malformation will result in unpredictable iteration, | |
5095 | including treating the length from one dp node as the type in the next | |
5096 | node. These are all errors, no matter where the data comes from. | |
5097 | ||
5098 | This patch adds a checking macro, GRUB_EFI_DEVICE_PATH_VALID(), which | |
5099 | can be used in several places, and makes GRUB_EFI_NEXT_DEVICE_PATH() | |
5100 | return NULL and GRUB_EFI_END_ENTIRE_DEVICE_PATH() evaluate as true when | |
5101 | the length is too small. Additionally, it makes several places in the | |
5102 | code check for and return errors in these cases. | |
5103 | ||
5104 | Signed-off-by: Peter Jones <pjones@redhat.com> | |
5105 | --- | |
5106 | grub-core/kern/efi/efi.c | 67 +++++++++++++++++++++++++----- | |
5107 | grub-core/loader/efi/chainloader.c | 19 ++++++++- | |
5108 | grub-core/loader/i386/xnu.c | 9 ++-- | |
5109 | include/grub/efi/api.h | 14 ++++--- | |
5110 | 4 files changed, 88 insertions(+), 21 deletions(-) | |
5111 | ||
5112 | diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c | |
5113 | index ad170c7ce..e12261fd5 100644 | |
5114 | --- a/grub-core/kern/efi/efi.c | |
5115 | +++ b/grub-core/kern/efi/efi.c | |
5116 | @@ -360,7 +360,7 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0) | |
5117 | ||
5118 | dp = dp0; | |
5119 | ||
5120 | - while (1) | |
5121 | + while (dp) | |
5122 | { | |
5123 | grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp); | |
5124 | grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp); | |
5125 | @@ -370,9 +370,15 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0) | |
5126 | if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE | |
5127 | && subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE) | |
5128 | { | |
5129 | - grub_efi_uint16_t len; | |
5130 | - len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4) | |
5131 | - / sizeof (grub_efi_char16_t)); | |
5132 | + grub_efi_uint16_t len = GRUB_EFI_DEVICE_PATH_LENGTH (dp); | |
5133 | + | |
5134 | + if (len < 4) | |
5135 | + { | |
5136 | + grub_error (GRUB_ERR_OUT_OF_RANGE, | |
5137 | + "malformed EFI Device Path node has length=%d", len); | |
5138 | + return NULL; | |
5139 | + } | |
5140 | + len = (len - 4) / sizeof (grub_efi_char16_t); | |
5141 | filesize += GRUB_MAX_UTF8_PER_UTF16 * len + 2; | |
5142 | } | |
5143 | ||
5144 | @@ -388,7 +394,7 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0) | |
5145 | if (!name) | |
5146 | return NULL; | |
5147 | ||
5148 | - while (1) | |
5149 | + while (dp) | |
5150 | { | |
5151 | grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp); | |
5152 | grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp); | |
5153 | @@ -404,8 +410,15 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0) | |
5154 | ||
5155 | *p++ = '/'; | |
5156 | ||
5157 | - len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4) | |
5158 | - / sizeof (grub_efi_char16_t)); | |
5159 | + len = GRUB_EFI_DEVICE_PATH_LENGTH (dp); | |
5160 | + if (len < 4) | |
5161 | + { | |
5162 | + grub_error (GRUB_ERR_OUT_OF_RANGE, | |
5163 | + "malformed EFI Device Path node has length=%d", len); | |
5164 | + return NULL; | |
5165 | + } | |
5166 | + | |
5167 | + len = (len - 4) / sizeof (grub_efi_char16_t); | |
5168 | fp = (grub_efi_file_path_device_path_t *) dp; | |
5169 | /* According to EFI spec Path Name is NULL terminated */ | |
5170 | while (len > 0 && fp->path_name[len - 1] == 0) | |
5171 | @@ -480,7 +493,26 @@ grub_efi_duplicate_device_path (const grub_efi_device_path_t *dp) | |
5172 | ; | |
5173 | p = GRUB_EFI_NEXT_DEVICE_PATH (p)) | |
5174 | { | |
5175 | - total_size += GRUB_EFI_DEVICE_PATH_LENGTH (p); | |
5176 | + grub_size_t len = GRUB_EFI_DEVICE_PATH_LENGTH (p); | |
5177 | + | |
5178 | + /* | |
5179 | + * In the event that we find a node that's completely garbage, for | |
5180 | + * example if we get to 0x7f 0x01 0x02 0x00 ... (EndInstance with a size | |
5181 | + * of 2), GRUB_EFI_END_ENTIRE_DEVICE_PATH() will be true and | |
5182 | + * GRUB_EFI_NEXT_DEVICE_PATH() will return NULL, so we won't continue, | |
5183 | + * and neither should our consumers, but there won't be any error raised | |
5184 | + * even though the device path is junk. | |
5185 | + * | |
5186 | + * This keeps us from passing junk down back to our caller. | |
5187 | + */ | |
5188 | + if (len < 4) | |
5189 | + { | |
5190 | + grub_error (GRUB_ERR_OUT_OF_RANGE, | |
5191 | + "malformed EFI Device Path node has length=%d", len); | |
5192 | + return NULL; | |
5193 | + } | |
5194 | + | |
5195 | + total_size += len; | |
5196 | if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (p)) | |
5197 | break; | |
5198 | } | |
5199 | @@ -525,7 +557,7 @@ dump_vendor_path (const char *type, grub_efi_vendor_device_path_t *vendor) | |
5200 | void | |
5201 | grub_efi_print_device_path (grub_efi_device_path_t *dp) | |
5202 | { | |
5203 | - while (1) | |
5204 | + while (GRUB_EFI_DEVICE_PATH_VALID (dp)) | |
5205 | { | |
5206 | grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp); | |
5207 | grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp); | |
5208 | @@ -937,7 +969,11 @@ grub_efi_compare_device_paths (const grub_efi_device_path_t *dp1, | |
5209 | /* Return non-zero. */ | |
5210 | return 1; | |
5211 | ||
5212 | - while (1) | |
5213 | + if (dp1 == dp2) | |
5214 | + return 0; | |
5215 | + | |
5216 | + while (GRUB_EFI_DEVICE_PATH_VALID (dp1) | |
5217 | + && GRUB_EFI_DEVICE_PATH_VALID (dp2)) | |
5218 | { | |
5219 | grub_efi_uint8_t type1, type2; | |
5220 | grub_efi_uint8_t subtype1, subtype2; | |
5221 | @@ -973,5 +1009,16 @@ grub_efi_compare_device_paths (const grub_efi_device_path_t *dp1, | |
5222 | dp2 = (grub_efi_device_path_t *) ((char *) dp2 + len2); | |
5223 | } | |
5224 | ||
5225 | + /* | |
5226 | + * There's no "right" answer here, but we probably don't want to call a valid | |
5227 | + * dp and an invalid dp equal, so pick one way or the other. | |
5228 | + */ | |
5229 | + if (GRUB_EFI_DEVICE_PATH_VALID (dp1) && | |
5230 | + !GRUB_EFI_DEVICE_PATH_VALID (dp2)) | |
5231 | + return 1; | |
5232 | + else if (!GRUB_EFI_DEVICE_PATH_VALID (dp1) && | |
5233 | + GRUB_EFI_DEVICE_PATH_VALID (dp2)) | |
5234 | + return -1; | |
5235 | + | |
5236 | return 0; | |
5237 | } | |
5238 | diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c | |
5239 | index daf8c6b54..978fab002 100644 | |
5240 | --- a/grub-core/loader/efi/chainloader.c | |
5241 | +++ b/grub-core/loader/efi/chainloader.c | |
5242 | @@ -116,6 +116,12 @@ copy_file_path (grub_efi_file_path_device_path_t *fp, | |
5243 | fp->header.type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE; | |
5244 | fp->header.subtype = GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE; | |
5245 | ||
5246 | + if (!GRUB_EFI_DEVICE_PATH_VALID ((grub_efi_device_path_t *)fp)) | |
5247 | + { | |
5248 | + grub_error (GRUB_ERR_BAD_ARGUMENT, "EFI Device Path is invalid"); | |
5249 | + return; | |
5250 | + } | |
5251 | + | |
5252 | path_name = grub_calloc (len, GRUB_MAX_UTF16_PER_UTF8 * sizeof (*path_name)); | |
5253 | if (!path_name) | |
5254 | return; | |
5255 | @@ -156,9 +162,18 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename) | |
5256 | ||
5257 | size = 0; | |
5258 | d = dp; | |
5259 | - while (1) | |
5260 | + while (d) | |
5261 | { | |
5262 | - size += GRUB_EFI_DEVICE_PATH_LENGTH (d); | |
5263 | + grub_size_t len = GRUB_EFI_DEVICE_PATH_LENGTH (d); | |
5264 | + | |
5265 | + if (len < 4) | |
5266 | + { | |
5267 | + grub_error (GRUB_ERR_OUT_OF_RANGE, | |
5268 | + "malformed EFI Device Path node has length=%d", len); | |
5269 | + return NULL; | |
5270 | + } | |
5271 | + | |
5272 | + size += len; | |
5273 | if ((GRUB_EFI_END_ENTIRE_DEVICE_PATH (d))) | |
5274 | break; | |
5275 | d = GRUB_EFI_NEXT_DEVICE_PATH (d); | |
5276 | diff --git a/grub-core/loader/i386/xnu.c b/grub-core/loader/i386/xnu.c | |
5277 | index e9e119259..a70093607 100644 | |
5278 | --- a/grub-core/loader/i386/xnu.c | |
5279 | +++ b/grub-core/loader/i386/xnu.c | |
5280 | @@ -515,14 +515,15 @@ grub_cmd_devprop_load (grub_command_t cmd __attribute__ ((unused)), | |
5281 | ||
5282 | devhead = buf; | |
5283 | buf = devhead + 1; | |
5284 | - dpstart = buf; | |
5285 | + dp = dpstart = buf; | |
5286 | ||
5287 | - do | |
5288 | + while (GRUB_EFI_DEVICE_PATH_VALID (dp) && buf < bufend) | |
5289 | { | |
5290 | - dp = buf; | |
5291 | buf = (char *) buf + GRUB_EFI_DEVICE_PATH_LENGTH (dp); | |
5292 | + if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp)) | |
5293 | + break; | |
5294 | + dp = buf; | |
5295 | } | |
5296 | - while (!GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp) && buf < bufend); | |
5297 | ||
5298 | dev = grub_xnu_devprop_add_device (dpstart, (char *) buf | |
5299 | - (char *) dpstart); | |
5300 | diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h | |
5301 | index 75befd10e..a3f4df91d 100644 | |
5302 | --- a/include/grub/efi/api.h | |
5303 | +++ b/include/grub/efi/api.h | |
5304 | @@ -635,6 +635,7 @@ typedef struct grub_efi_device_path grub_efi_device_path_protocol_t; | |
5305 | #define GRUB_EFI_DEVICE_PATH_TYPE(dp) ((dp)->type & 0x7f) | |
5306 | #define GRUB_EFI_DEVICE_PATH_SUBTYPE(dp) ((dp)->subtype) | |
5307 | #define GRUB_EFI_DEVICE_PATH_LENGTH(dp) ((dp)->length) | |
5308 | +#define GRUB_EFI_DEVICE_PATH_VALID(dp) ((dp) != NULL && GRUB_EFI_DEVICE_PATH_LENGTH (dp) >= 4) | |
5309 | ||
5310 | /* The End of Device Path nodes. */ | |
5311 | #define GRUB_EFI_END_DEVICE_PATH_TYPE (0xff & 0x7f) | |
5312 | @@ -643,13 +644,16 @@ typedef struct grub_efi_device_path grub_efi_device_path_protocol_t; | |
5313 | #define GRUB_EFI_END_THIS_DEVICE_PATH_SUBTYPE 0x01 | |
5314 | ||
5315 | #define GRUB_EFI_END_ENTIRE_DEVICE_PATH(dp) \ | |
5316 | - (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_END_DEVICE_PATH_TYPE \ | |
5317 | - && (GRUB_EFI_DEVICE_PATH_SUBTYPE (dp) \ | |
5318 | - == GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE)) | |
5319 | + (!GRUB_EFI_DEVICE_PATH_VALID (dp) || \ | |
5320 | + (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_END_DEVICE_PATH_TYPE \ | |
5321 | + && (GRUB_EFI_DEVICE_PATH_SUBTYPE (dp) \ | |
5322 | + == GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE))) | |
5323 | ||
5324 | #define GRUB_EFI_NEXT_DEVICE_PATH(dp) \ | |
5325 | - ((grub_efi_device_path_t *) ((char *) (dp) \ | |
5326 | - + GRUB_EFI_DEVICE_PATH_LENGTH (dp))) | |
5327 | + (GRUB_EFI_DEVICE_PATH_VALID (dp) \ | |
5328 | + ? ((grub_efi_device_path_t *) \ | |
5329 | + ((char *) (dp) + GRUB_EFI_DEVICE_PATH_LENGTH (dp))) \ | |
5330 | + : NULL) | |
5331 | ||
5332 | /* Hardware Device Path. */ | |
5333 | #define GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE 1 | |
5334 | ||
5335 | From c5763039a630dee079f0afbd5ced9cd74efe0b71 Mon Sep 17 00:00:00 2001 | |
5336 | From: Chris Coulson <chris.coulson@canonical.com> | |
5337 | Date: Wed, 22 Jul 2020 17:06:04 +0100 | |
5338 | Subject: Fix a regression caused by "efi: fix some malformed | |
5339 | device path arithmetic errors" | |
5340 | ||
5341 | This commit introduced a bogus check inside copy_file_path to | |
5342 | determine whether the destination grub_efi_file_path_device_path_t | |
5343 | was valid before anything was copied to it. Depending on the | |
5344 | contents of the heap buffer, this check could fail which would | |
5345 | result in copy_file_path returning early. | |
5346 | ||
5347 | Without any error propagated to the caller, make_file_path would | |
5348 | then try to advance the invalid device path node with | |
5349 | GRUB_EFI_NEXT_DEVICE_PATH, which would also fail, returning a NULL | |
5350 | pointer that would subsequently be dereferenced. | |
5351 | ||
5352 | Remove the bogus check, and also propagate errors from copy_file_path. | |
5353 | --- | |
5354 | grub-core/loader/efi/chainloader.c | 25 +++++++++++++------------ | |
5355 | 1 file changed, 13 insertions(+), 12 deletions(-) | |
5356 | ||
5357 | diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c | |
5358 | index 978fab002..e9b06242a 100644 | |
5359 | --- a/grub-core/loader/efi/chainloader.c | |
5360 | +++ b/grub-core/loader/efi/chainloader.c | |
5361 | @@ -106,7 +106,7 @@ grub_chainloader_boot (void) | |
5362 | return grub_errno; | |
5363 | } | |
5364 | ||
5365 | -static void | |
5366 | +static grub_err_t | |
5367 | copy_file_path (grub_efi_file_path_device_path_t *fp, | |
5368 | const char *str, grub_efi_uint16_t len) | |
5369 | { | |
5370 | @@ -116,15 +116,9 @@ copy_file_path (grub_efi_file_path_device_path_t *fp, | |
5371 | fp->header.type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE; | |
5372 | fp->header.subtype = GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE; | |
5373 | ||
5374 | - if (!GRUB_EFI_DEVICE_PATH_VALID ((grub_efi_device_path_t *)fp)) | |
5375 | - { | |
5376 | - grub_error (GRUB_ERR_BAD_ARGUMENT, "EFI Device Path is invalid"); | |
5377 | - return; | |
5378 | - } | |
5379 | - | |
5380 | path_name = grub_calloc (len, GRUB_MAX_UTF16_PER_UTF8 * sizeof (*path_name)); | |
5381 | if (!path_name) | |
5382 | - return; | |
5383 | + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "failed to allocate path buffer"); | |
5384 | ||
5385 | size = grub_utf8_to_utf16 (path_name, len * GRUB_MAX_UTF16_PER_UTF8, | |
5386 | (const grub_uint8_t *) str, len, 0); | |
5387 | @@ -137,6 +131,7 @@ copy_file_path (grub_efi_file_path_device_path_t *fp, | |
5388 | fp->path_name[size++] = '\0'; | |
5389 | fp->header.length = size * sizeof (grub_efi_char16_t) + sizeof (*fp); | |
5390 | grub_free (path_name); | |
5391 | + return GRUB_ERR_NONE; | |
5392 | } | |
5393 | ||
5394 | static grub_efi_device_path_t * | |
5395 | @@ -195,13 +190,19 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename) | |
5396 | d = (grub_efi_device_path_t *) ((char *) file_path | |
5397 | + ((char *) d - (char *) dp)); | |
5398 | grub_efi_print_device_path (d); | |
5399 | - copy_file_path ((grub_efi_file_path_device_path_t *) d, | |
5400 | - dir_start, dir_end - dir_start); | |
5401 | + if (copy_file_path ((grub_efi_file_path_device_path_t *) d, | |
5402 | + dir_start, dir_end - dir_start) != GRUB_ERR_NONE) | |
5403 | + { | |
5404 | + fail: | |
5405 | + grub_free (file_path); | |
5406 | + return 0; | |
5407 | + } | |
5408 | ||
5409 | /* Fill the file path for the file. */ | |
5410 | d = GRUB_EFI_NEXT_DEVICE_PATH (d); | |
5411 | - copy_file_path ((grub_efi_file_path_device_path_t *) d, | |
5412 | - dir_end + 1, grub_strlen (dir_end + 1)); | |
5413 | + if (copy_file_path ((grub_efi_file_path_device_path_t *) d, | |
5414 | + dir_end + 1, grub_strlen (dir_end + 1)) != GRUB_ERR_NONE) | |
5415 | + goto fail; | |
5416 | ||
5417 | /* Fill the end of device path nodes. */ | |
5418 | d = GRUB_EFI_NEXT_DEVICE_PATH (d); | |
5419 | ||
5420 | From 3e6aa687d9a2f8d172536a67d0d0f8bc7adb3108 Mon Sep 17 00:00:00 2001 | |
5421 | From: Alexander Burmashev <alexander.burmashev@oracle.com> | |
5422 | Date: Wed, 22 Jul 2020 06:04:38 -0700 | |
5423 | Subject: update safemath with fallback code for gcc older than | |
5424 | 5.1 | |
5425 | ||
5426 | The code used in the header was taken from linux kernel commit | |
5427 | f0907827a8a9152aedac2833ed1b674a7b2a44f2. Rasmus Villemoes | |
5428 | <linux@rasmusvillemoes.dk>, the original author of the patch, was | |
5429 | contacted directly, confirmed his authorship of the code, and gave his | |
5430 | permission on treating that dual license as MIT and including into GRUB2 | |
5431 | sources | |
5432 | ||
5433 | Signed-off-by: Alex Burmashev <alexander.burmashev@oracle.com> | |
5434 | --- | |
5435 | include/grub/safemath.h | 119 +++++++++++++++++++++++++++++++++++++++- | |
5436 | 1 file changed, 118 insertions(+), 1 deletion(-) | |
5437 | ||
5438 | diff --git a/include/grub/safemath.h b/include/grub/safemath.h | |
5439 | index c17b89bba..1ccac276b 100644 | |
5440 | --- a/include/grub/safemath.h | |
5441 | +++ b/include/grub/safemath.h | |
5442 | @@ -31,7 +31,124 @@ | |
5443 | #define grub_mul(a, b, res) __builtin_mul_overflow(a, b, res) | |
5444 | ||
5445 | #else | |
5446 | -#error gcc 5.1 or newer or clang 3.8 or newer is required | |
5447 | +/* | |
5448 | + * Copyright 2020 Rasmus Villemoes | |
5449 | + * | |
5450 | + * Permission is hereby granted, free of charge, to any person obtaining a copy | |
5451 | + * of this software and associated documentation files (the "Software"), to | |
5452 | + * deal in the Software without restriction, including without limitation the | |
5453 | + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | |
5454 | + * sell copies of the Software, and to permit persons to whom the Software is | |
5455 | + * furnished to do so, subject to the following conditions: | |
5456 | + * | |
5457 | + * The above copyright notice and this permission notice shall be included in | |
5458 | + * all copies or substantial portions of the Software. | |
5459 | + | |
5460 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
5461 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
5462 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
5463 | + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
5464 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
5465 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | |
5466 | + * IN THE SOFTWARE. | |
5467 | + */ | |
5468 | +/* | |
5469 | + * The code used in this header was taken from linux kernel commit | |
5470 | + * f0907827a8a9152aedac2833ed1b674a7b2a44f2 | |
5471 | + * Rasmus Villemoes <linux@rasmusvillemoes.dk>, the original author of the | |
5472 | + * patch, was contacted directly, confirmed his authorship of the code, and | |
5473 | + * gave his permission on treating that dual license as MIT and including into | |
5474 | + * GRUB2 sources | |
5475 | + */ | |
5476 | + | |
5477 | +#include <grub/types.h> | |
5478 | +#define is_signed_type(type) (((type)(-1)) < (type)1) | |
5479 | +#define __type_half_max(type) ((type)1 << (8*sizeof(type) - 1 - is_signed_type(type))) | |
5480 | +#define type_max(T) ((T)((__type_half_max(T) - 1) + __type_half_max(T))) | |
5481 | +#define type_min(T) ((T)((T)-type_max(T)-(T)1)) | |
5482 | + | |
5483 | +#define __unsigned_add_overflow(a, b, d) ({ \ | |
5484 | + typeof(+(a)) __a = (a); \ | |
5485 | + typeof(+(b)) __b = (b); \ | |
5486 | + typeof(d) __d = (d); \ | |
5487 | + (void) (&__a == &__b); \ | |
5488 | + (void) (&__a == __d); \ | |
5489 | + *__d = __a + __b; \ | |
5490 | + *__d < __a; \ | |
5491 | +}) | |
5492 | +#define __unsigned_sub_overflow(a, b, d) ({ \ | |
5493 | + typeof(+(a)) __a = (a); \ | |
5494 | + typeof(+(b)) __b = (b); \ | |
5495 | + typeof(d) __d = (d); \ | |
5496 | + (void) (&__a == &__b); \ | |
5497 | + (void) (&__a == __d); \ | |
5498 | + *__d = __a - __b; \ | |
5499 | + __a < __b; \ | |
5500 | +}) | |
5501 | +#define __unsigned_mul_overflow(a, b, d) ({ \ | |
5502 | + typeof(+(a)) __a = (a); \ | |
5503 | + typeof(+(b)) __b = (b); \ | |
5504 | + typeof(d) __d = (d); \ | |
5505 | + (void) (&__a == &__b); \ | |
5506 | + (void) (&__a == __d); \ | |
5507 | + *__d = __a * __b; \ | |
5508 | + __builtin_constant_p(__b) ? \ | |
5509 | + __b > 0 && __a > type_max(typeof(__a)) / __b :\ | |
5510 | + __a > 0 && __b > type_max(typeof(__b)) / __a; \ | |
5511 | +}) | |
5512 | + | |
5513 | +#define __signed_add_overflow(a, b, d) ({ \ | |
5514 | + typeof(+(a)) __a = (a); \ | |
5515 | + typeof(+(b)) __b = (b); \ | |
5516 | + typeof(d) __d = (d); \ | |
5517 | + (void) (&__a == &__b); \ | |
5518 | + (void) (&__a == __d); \ | |
5519 | + *__d = (grub_uint64_t)__a + (grub_uint64_t)__b; \ | |
5520 | + (((~(__a ^ __b)) & (*__d ^ __a)) \ | |
5521 | + & type_min(typeof(__a))) != 0; \ | |
5522 | +}) | |
5523 | + | |
5524 | +#define __signed_sub_overflow(a, b, d) ({ \ | |
5525 | + typeof(+(a)) __a = (a); \ | |
5526 | + typeof(+(b)) __b = (b); \ | |
5527 | + typeof(d) __d = (d); \ | |
5528 | + (void) (&__a == &__b); \ | |
5529 | + (void) (&__a == __d); \ | |
5530 | + *__d = (grub_uint64_t)__a - (grub_uint64_t)__b; \ | |
5531 | + ((((__a ^ __b)) & (*__d ^ __a)) \ | |
5532 | + & type_min(typeof(__a))) != 0; \ | |
5533 | +}) | |
5534 | + | |
5535 | +#define __signed_mul_overflow(a, b, d) ({ \ | |
5536 | + typeof(+(a)) __a = (a); \ | |
5537 | + typeof(+(b)) __b = (b); \ | |
5538 | + typeof(d) __d = (d); \ | |
5539 | + typeof(+(a)) __tmax = type_max(typeof(+(a))); \ | |
5540 | + typeof(+(a)) __tmin = type_min(typeof(+(a))); \ | |
5541 | + (void) (&__a == &__b); \ | |
5542 | + (void) (&__a == __d); \ | |
5543 | + *__d = (grub_uint64_t)__a * (grub_uint64_t)__b; \ | |
5544 | + (__b > 0 && (__a > __tmax/__b || __a < __tmin/__b)) ||\ | |
5545 | + (__b < (typeof(__b))-1 && \ | |
5546 | + (__a > __tmin/__b || __a < __tmax/__b)) || \ | |
5547 | + (__b == (typeof(__b))-1 && __a == __tmin); \ | |
5548 | +}) | |
5549 | + | |
5550 | +#define grub_add(a, b, d) \ | |
5551 | + __builtin_choose_expr(is_signed_type(typeof(+(a))), \ | |
5552 | + __signed_add_overflow(a, b, d), \ | |
5553 | + __unsigned_add_overflow(a, b, d)) | |
5554 | + | |
5555 | +#define grub_sub(a, b, d) \ | |
5556 | + __builtin_choose_expr(is_signed_type(typeof(+(a))), \ | |
5557 | + __signed_sub_overflow(a, b, d), \ | |
5558 | + __unsigned_sub_overflow(a, b, d)) | |
5559 | + | |
5560 | +#define grub_mul(a, b, d) \ | |
5561 | + __builtin_choose_expr(is_signed_type(typeof(+(a))), \ | |
5562 | + __signed_mul_overflow(a, b, d), \ | |
5563 | + __unsigned_mul_overflow(a, b, d)) | |
5564 | + | |
5565 | #endif | |
5566 | ||
5567 | #endif /* GRUB_SAFEMATH_H */ | |
5568 | ||
5569 | From bb5fc65035e82509b0565bfe2994fbe6cc11016e Mon Sep 17 00:00:00 2001 | |
5570 | From: Alexey Makhalov <amakhalov@vmware.com> | |
5571 | Date: Mon, 20 Jul 2020 23:03:05 +0000 | |
5572 | Subject: efi: Fix use-after-free in halt/reboot path | |
5573 | ||
5574 | commit 92bfc33db984 ("efi: Free malloc regions on exit") | |
5575 | introduced memory freeing in grub_efi_fini(), which is | |
5576 | used not only by exit path but by halt/reboot one as well. | |
5577 | As result of memory freeing, code and data regions used by | |
5578 | modules, such as halt, reboot, acpi (used by halt) also got | |
5579 | freed. After return to module code, CPU executes, filled | |
5580 | by UEFI firmware (tested with edk2), 0xAFAFAFAF pattern as | |
5581 | a code. Which leads to #UD exception later. | |
5582 | ||
5583 | grub> halt | |
5584 | !!!! X64 Exception Type - 06(#UD - Invalid Opcode) CPU Apic ID - 00000000 !!!! | |
5585 | RIP - 0000000003F4EC28, CS - 0000000000000038, RFLAGS - 0000000000200246 | |
5586 | RAX - 0000000000000000, RCX - 00000000061DA188, RDX - 0A74C0854DC35D41 | |
5587 | RBX - 0000000003E10E08, RSP - 0000000007F0F860, RBP - 0000000000000000 | |
5588 | RSI - 00000000064DB768, RDI - 000000000832C5C3 | |
5589 | R8 - 0000000000000002, R9 - 0000000000000000, R10 - 00000000061E2E52 | |
5590 | R11 - 0000000000000020, R12 - 0000000003EE5C1F, R13 - 00000000061E0FF4 | |
5591 | R14 - 0000000003E10D80, R15 - 00000000061E2F60 | |
5592 | DS - 0000000000000030, ES - 0000000000000030, FS - 0000000000000030 | |
5593 | GS - 0000000000000030, SS - 0000000000000030 | |
5594 | CR0 - 0000000080010033, CR2 - 0000000000000000, CR3 - 0000000007C01000 | |
5595 | CR4 - 0000000000000668, CR8 - 0000000000000000 | |
5596 | DR0 - 0000000000000000, DR1 - 0000000000000000, DR2 - 0000000000000000 | |
5597 | DR3 - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 - 0000000000000400 | |
5598 | GDTR - 00000000079EEA98 0000000000000047, LDTR - 0000000000000000 | |
5599 | IDTR - 0000000007598018 0000000000000FFF, TR - 0000000000000000 | |
5600 | FXSAVE_STATE - 0000000007F0F4C0 | |
5601 | ||
5602 | Proposal here is to continue to free allocated memory for | |
5603 | exit boot services path but keep it for halt/reboot path | |
5604 | as it won't be much security concern here. | |
5605 | Introduced GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY | |
5606 | loader flag to be used by efi halt/reboot path. | |
5607 | ||
5608 | Signed-off-by: Alexey Makhalov <amakhalov@vmware.com> | |
5609 | Reviewed-by: Darren Kenny <darren.kenny@oracle.com> | |
5610 | --- | |
5611 | grub-core/kern/arm/efi/init.c | 3 +++ | |
5612 | grub-core/kern/arm64/efi/init.c | 3 +++ | |
5613 | grub-core/kern/efi/efi.c | 3 ++- | |
5614 | grub-core/kern/efi/init.c | 1 - | |
5615 | grub-core/kern/i386/efi/init.c | 9 +++++++-- | |
5616 | grub-core/kern/ia64/efi/init.c | 9 +++++++-- | |
5617 | grub-core/kern/riscv/efi/init.c | 3 +++ | |
5618 | grub-core/lib/efi/halt.c | 3 ++- | |
5619 | include/grub/loader.h | 1 + | |
5620 | 9 files changed, 28 insertions(+), 7 deletions(-) | |
5621 | ||
5622 | diff --git a/grub-core/kern/arm/efi/init.c b/grub-core/kern/arm/efi/init.c | |
5623 | index 06df60e2f..40c3b467f 100644 | |
5624 | --- a/grub-core/kern/arm/efi/init.c | |
5625 | +++ b/grub-core/kern/arm/efi/init.c | |
5626 | @@ -71,4 +71,7 @@ grub_machine_fini (int flags) | |
5627 | efi_call_1 (b->close_event, tmr_evt); | |
5628 | ||
5629 | grub_efi_fini (); | |
5630 | + | |
5631 | + if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY)) | |
5632 | + grub_efi_memory_fini (); | |
5633 | } | |
5634 | diff --git a/grub-core/kern/arm64/efi/init.c b/grub-core/kern/arm64/efi/init.c | |
5635 | index 6224999ec..5010caefd 100644 | |
5636 | --- a/grub-core/kern/arm64/efi/init.c | |
5637 | +++ b/grub-core/kern/arm64/efi/init.c | |
5638 | @@ -57,4 +57,7 @@ grub_machine_fini (int flags) | |
5639 | return; | |
5640 | ||
5641 | grub_efi_fini (); | |
5642 | + | |
5643 | + if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY)) | |
5644 | + grub_efi_memory_fini (); | |
5645 | } | |
5646 | diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c | |
5647 | index e12261fd5..acb38d61f 100644 | |
5648 | --- a/grub-core/kern/efi/efi.c | |
5649 | +++ b/grub-core/kern/efi/efi.c | |
5650 | @@ -157,7 +157,8 @@ grub_efi_get_loaded_image (grub_efi_handle_t image_handle) | |
5651 | void | |
5652 | grub_reboot (void) | |
5653 | { | |
5654 | - grub_machine_fini (GRUB_LOADER_FLAG_NORETURN); | |
5655 | + grub_machine_fini (GRUB_LOADER_FLAG_NORETURN | | |
5656 | + GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY); | |
5657 | efi_call_4 (grub_efi_system_table->runtime_services->reset_system, | |
5658 | GRUB_EFI_RESET_COLD, GRUB_EFI_SUCCESS, 0, NULL); | |
5659 | for (;;) ; | |
5660 | diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c | |
5661 | index 3dfdf2d22..2c31847bf 100644 | |
5662 | --- a/grub-core/kern/efi/init.c | |
5663 | +++ b/grub-core/kern/efi/init.c | |
5664 | @@ -80,5 +80,4 @@ grub_efi_fini (void) | |
5665 | { | |
5666 | grub_efidisk_fini (); | |
5667 | grub_console_fini (); | |
5668 | - grub_efi_memory_fini (); | |
5669 | } | |
5670 | diff --git a/grub-core/kern/i386/efi/init.c b/grub-core/kern/i386/efi/init.c | |
5671 | index da499aba0..deb2eacd8 100644 | |
5672 | --- a/grub-core/kern/i386/efi/init.c | |
5673 | +++ b/grub-core/kern/i386/efi/init.c | |
5674 | @@ -39,6 +39,11 @@ grub_machine_init (void) | |
5675 | void | |
5676 | grub_machine_fini (int flags) | |
5677 | { | |
5678 | - if (flags & GRUB_LOADER_FLAG_NORETURN) | |
5679 | - grub_efi_fini (); | |
5680 | + if (!(flags & GRUB_LOADER_FLAG_NORETURN)) | |
5681 | + return; | |
5682 | + | |
5683 | + grub_efi_fini (); | |
5684 | + | |
5685 | + if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY)) | |
5686 | + grub_efi_memory_fini (); | |
5687 | } | |
5688 | diff --git a/grub-core/kern/ia64/efi/init.c b/grub-core/kern/ia64/efi/init.c | |
5689 | index b5ecbd091..f1965571b 100644 | |
5690 | --- a/grub-core/kern/ia64/efi/init.c | |
5691 | +++ b/grub-core/kern/ia64/efi/init.c | |
5692 | @@ -70,6 +70,11 @@ grub_machine_init (void) | |
5693 | void | |
5694 | grub_machine_fini (int flags) | |
5695 | { | |
5696 | - if (flags & GRUB_LOADER_FLAG_NORETURN) | |
5697 | - grub_efi_fini (); | |
5698 | + if (!(flags & GRUB_LOADER_FLAG_NORETURN)) | |
5699 | + return; | |
5700 | + | |
5701 | + grub_efi_fini (); | |
5702 | + | |
5703 | + if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY)) | |
5704 | + grub_efi_memory_fini (); | |
5705 | } | |
5706 | diff --git a/grub-core/kern/riscv/efi/init.c b/grub-core/kern/riscv/efi/init.c | |
5707 | index 7eb1969d0..38795fe67 100644 | |
5708 | --- a/grub-core/kern/riscv/efi/init.c | |
5709 | +++ b/grub-core/kern/riscv/efi/init.c | |
5710 | @@ -73,4 +73,7 @@ grub_machine_fini (int flags) | |
5711 | return; | |
5712 | ||
5713 | grub_efi_fini (); | |
5714 | + | |
5715 | + if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY)) | |
5716 | + grub_efi_memory_fini (); | |
5717 | } | |
5718 | diff --git a/grub-core/lib/efi/halt.c b/grub-core/lib/efi/halt.c | |
5719 | index 5859f0498..29d413641 100644 | |
5720 | --- a/grub-core/lib/efi/halt.c | |
5721 | +++ b/grub-core/lib/efi/halt.c | |
5722 | @@ -28,7 +28,8 @@ | |
5723 | void | |
5724 | grub_halt (void) | |
5725 | { | |
5726 | - grub_machine_fini (GRUB_LOADER_FLAG_NORETURN); | |
5727 | + grub_machine_fini (GRUB_LOADER_FLAG_NORETURN | | |
5728 | + GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY); | |
5729 | #if !defined(__ia64__) && !defined(__arm__) && !defined(__aarch64__) && \ | |
5730 | !defined(__riscv) | |
5731 | grub_acpi_halt (); | |
5732 | diff --git a/include/grub/loader.h b/include/grub/loader.h | |
5733 | index 7f82a499f..b20864282 100644 | |
5734 | --- a/include/grub/loader.h | |
5735 | +++ b/include/grub/loader.h | |
5736 | @@ -33,6 +33,7 @@ enum | |
5737 | { | |
5738 | GRUB_LOADER_FLAG_NORETURN = 1, | |
5739 | GRUB_LOADER_FLAG_PXE_NOT_UNLOAD = 2, | |
5740 | + GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY = 4, | |
5741 | }; | |
5742 | ||
5743 | void EXPORT_FUNC (grub_loader_set) (grub_err_t (*boot) (void), | |
5744 | ||
5745 | From 6d438b80c4cfe75a67f619918706630ccc2252b6 Mon Sep 17 00:00:00 2001 | |
5746 | From: Peter Jones <pjones@redhat.com> | |
5747 | Date: Fri, 24 Jul 2020 13:57:27 -0400 | |
5748 | Subject: linux loader: avoid overflow on initrd size calculation | |
5749 | ||
5750 | Signed-off-by: Peter Jones <pjones@redhat.com> | |
5751 | --- | |
5752 | grub-core/loader/linux.c | 4 ++-- | |
5753 | 1 file changed, 2 insertions(+), 2 deletions(-) | |
5754 | ||
5755 | diff --git a/grub-core/loader/linux.c b/grub-core/loader/linux.c | |
5756 | index 471b214d6..25624ebc1 100644 | |
5757 | --- a/grub-core/loader/linux.c | |
5758 | +++ b/grub-core/loader/linux.c | |
5759 | @@ -151,8 +151,8 @@ grub_initrd_init (int argc, char *argv[], | |
5760 | initrd_ctx->nfiles = 0; | |
5761 | initrd_ctx->components = 0; | |
5762 | ||
5763 | - initrd_ctx->components = grub_zalloc (argc | |
5764 | - * sizeof (initrd_ctx->components[0])); | |
5765 | + initrd_ctx->components = grub_calloc (argc, | |
5766 | + sizeof (initrd_ctx->components[0])); | |
5767 | if (!initrd_ctx->components) | |
5768 | return grub_errno; | |
5769 | ||
5770 | ||
5771 | From 81fae35a346bef8f7b27ba8d186a18ae21281755 Mon Sep 17 00:00:00 2001 | |
5772 | From: Colin Watson <cjwatson@debian.org> | |
5773 | Date: Sat, 25 Jul 2020 12:15:37 +0100 | |
5774 | Subject: linux: Fix integer overflows in initrd size handling | |
5775 | ||
5776 | These could be triggered by a crafted filesystem with very large files. | |
5777 | ||
5778 | Fixes: CVE-2020-15707 | |
5779 | ||
5780 | Signed-off-by: Colin Watson <cjwatson@debian.org> | |
5781 | Reviewed-by: Jan Setje-Eilers <jan.setjeeilers@oracle.com> | |
5782 | --- | |
5783 | grub-core/loader/linux.c | 74 +++++++++++++++++++++++++++++----------- | |
5784 | 1 file changed, 54 insertions(+), 20 deletions(-) | |
5785 | ||
5786 | diff --git a/grub-core/loader/linux.c b/grub-core/loader/linux.c | |
5787 | index 25624ebc1..e9f819ee9 100644 | |
5788 | --- a/grub-core/loader/linux.c | |
5789 | +++ b/grub-core/loader/linux.c | |
5790 | @@ -4,6 +4,7 @@ | |
5791 | #include <grub/misc.h> | |
5792 | #include <grub/file.h> | |
5793 | #include <grub/mm.h> | |
5794 | +#include <grub/safemath.h> | |
5795 | ||
5796 | struct newc_head | |
5797 | { | |
5798 | @@ -98,13 +99,13 @@ free_dir (struct dir *root) | |
5799 | grub_free (root); | |
5800 | } | |
5801 | ||
5802 | -static grub_size_t | |
5803 | +static grub_err_t | |
5804 | insert_dir (const char *name, struct dir **root, | |
5805 | - grub_uint8_t *ptr) | |
5806 | + grub_uint8_t *ptr, grub_size_t *size) | |
5807 | { | |
5808 | struct dir *cur, **head = root; | |
5809 | const char *cb, *ce = name; | |
5810 | - grub_size_t size = 0; | |
5811 | + *size = 0; | |
5812 | while (1) | |
5813 | { | |
5814 | for (cb = ce; *cb == '/'; cb++); | |
5815 | @@ -130,14 +131,22 @@ insert_dir (const char *name, struct dir **root, | |
5816 | ptr = make_header (ptr, name, ce - name, | |
5817 | 040777, 0); | |
5818 | } | |
5819 | - size += ALIGN_UP ((ce - (char *) name) | |
5820 | - + sizeof (struct newc_head), 4); | |
5821 | + if (grub_add (*size, | |
5822 | + ALIGN_UP ((ce - (char *) name) | |
5823 | + + sizeof (struct newc_head), 4), | |
5824 | + size)) | |
5825 | + { | |
5826 | + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); | |
5827 | + grub_free (n->name); | |
5828 | + grub_free (n); | |
5829 | + return grub_errno; | |
5830 | + } | |
5831 | *head = n; | |
5832 | cur = n; | |
5833 | } | |
5834 | root = &cur->next; | |
5835 | } | |
5836 | - return size; | |
5837 | + return GRUB_ERR_NONE; | |
5838 | } | |
5839 | ||
5840 | grub_err_t | |
5841 | @@ -173,26 +182,33 @@ grub_initrd_init (int argc, char *argv[], | |
5842 | eptr = grub_strchr (ptr, ':'); | |
5843 | if (eptr) | |
5844 | { | |
5845 | + grub_size_t dir_size, name_len; | |
5846 | + | |
5847 | initrd_ctx->components[i].newc_name = grub_strndup (ptr, eptr - ptr); | |
5848 | - if (!initrd_ctx->components[i].newc_name) | |
5849 | + if (!initrd_ctx->components[i].newc_name || | |
5850 | + insert_dir (initrd_ctx->components[i].newc_name, &root, 0, | |
5851 | + &dir_size)) | |
5852 | { | |
5853 | grub_initrd_close (initrd_ctx); | |
5854 | return grub_errno; | |
5855 | } | |
5856 | - initrd_ctx->size | |
5857 | - += ALIGN_UP (sizeof (struct newc_head) | |
5858 | - + grub_strlen (initrd_ctx->components[i].newc_name), | |
5859 | - 4); | |
5860 | - initrd_ctx->size += insert_dir (initrd_ctx->components[i].newc_name, | |
5861 | - &root, 0); | |
5862 | + name_len = grub_strlen (initrd_ctx->components[i].newc_name); | |
5863 | + if (grub_add (initrd_ctx->size, | |
5864 | + ALIGN_UP (sizeof (struct newc_head) + name_len, 4), | |
5865 | + &initrd_ctx->size) || | |
5866 | + grub_add (initrd_ctx->size, dir_size, &initrd_ctx->size)) | |
5867 | + goto overflow; | |
5868 | newc = 1; | |
5869 | fname = eptr + 1; | |
5870 | } | |
5871 | } | |
5872 | else if (newc) | |
5873 | { | |
5874 | - initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head) | |
5875 | - + sizeof ("TRAILER!!!") - 1, 4); | |
5876 | + if (grub_add (initrd_ctx->size, | |
5877 | + ALIGN_UP (sizeof (struct newc_head) | |
5878 | + + sizeof ("TRAILER!!!") - 1, 4), | |
5879 | + &initrd_ctx->size)) | |
5880 | + goto overflow; | |
5881 | free_dir (root); | |
5882 | root = 0; | |
5883 | newc = 0; | |
5884 | @@ -208,19 +224,29 @@ grub_initrd_init (int argc, char *argv[], | |
5885 | initrd_ctx->nfiles++; | |
5886 | initrd_ctx->components[i].size | |
5887 | = grub_file_size (initrd_ctx->components[i].file); | |
5888 | - initrd_ctx->size += initrd_ctx->components[i].size; | |
5889 | + if (grub_add (initrd_ctx->size, initrd_ctx->components[i].size, | |
5890 | + &initrd_ctx->size)) | |
5891 | + goto overflow; | |
5892 | } | |
5893 | ||
5894 | if (newc) | |
5895 | { | |
5896 | initrd_ctx->size = ALIGN_UP (initrd_ctx->size, 4); | |
5897 | - initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head) | |
5898 | - + sizeof ("TRAILER!!!") - 1, 4); | |
5899 | + if (grub_add (initrd_ctx->size, | |
5900 | + ALIGN_UP (sizeof (struct newc_head) | |
5901 | + + sizeof ("TRAILER!!!") - 1, 4), | |
5902 | + &initrd_ctx->size)) | |
5903 | + goto overflow; | |
5904 | free_dir (root); | |
5905 | root = 0; | |
5906 | } | |
5907 | ||
5908 | return GRUB_ERR_NONE; | |
5909 | + | |
5910 | +overflow: | |
5911 | + free_dir (root); | |
5912 | + grub_initrd_close (initrd_ctx); | |
5913 | + return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); | |
5914 | } | |
5915 | ||
5916 | grub_size_t | |
5917 | @@ -261,8 +287,16 @@ grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx, | |
5918 | ||
5919 | if (initrd_ctx->components[i].newc_name) | |
5920 | { | |
5921 | - ptr += insert_dir (initrd_ctx->components[i].newc_name, | |
5922 | - &root, ptr); | |
5923 | + grub_size_t dir_size; | |
5924 | + | |
5925 | + if (insert_dir (initrd_ctx->components[i].newc_name, &root, ptr, | |
5926 | + &dir_size)) | |
5927 | + { | |
5928 | + free_dir (root); | |
5929 | + grub_initrd_close (initrd_ctx); | |
5930 | + return grub_errno; | |
5931 | + } | |
5932 | + ptr += dir_size; | |
5933 | ptr = make_header (ptr, initrd_ctx->components[i].newc_name, | |
5934 | grub_strlen (initrd_ctx->components[i].newc_name), | |
5935 | 0100777, | |
5936 |