diff options
author | Yongxin Liu <yongxin.liu@windriver.com> | 2020-11-04 08:43:33 +0800 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2020-11-08 14:03:21 +0000 |
commit | bf0e7912c8a76eaeac12a4e1f523da8a10a8780d (patch) | |
tree | e3fe2039d9da6f69f70f2b2fb49d06be8eb8f53e /meta/recipes-bsp/grub/files/0005-malloc-Use-overflow-checking-primitives-where-we-do-.patch | |
parent | 81a925ac9e21af3dee8cc4f6e548dca2b29c2e88 (diff) | |
download | poky-bf0e7912c8a76eaeac12a4e1f523da8a10a8780d.tar.gz |
grub: clean up CVE patches
Clean up several patches introduced in commit 6732918498 ("grub:fix
several CVEs in grub 2.04").
1) Add CVE tags to individual patches.
2) Rename upstream patches and prefix them with CVE tags.
3) Add description of reference to upstream patch.
(From OE-Core rev: bcb8b6719beaf6625e6b703e91958fe8afba5819)
Signed-off-by: Yongxin Liu <yongxin.liu@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-bsp/grub/files/0005-malloc-Use-overflow-checking-primitives-where-we-do-.patch')
-rw-r--r-- | meta/recipes-bsp/grub/files/0005-malloc-Use-overflow-checking-primitives-where-we-do-.patch | 1326 |
1 files changed, 0 insertions, 1326 deletions
diff --git a/meta/recipes-bsp/grub/files/0005-malloc-Use-overflow-checking-primitives-where-we-do-.patch b/meta/recipes-bsp/grub/files/0005-malloc-Use-overflow-checking-primitives-where-we-do-.patch deleted file mode 100644 index 146602cd3e..0000000000 --- a/meta/recipes-bsp/grub/files/0005-malloc-Use-overflow-checking-primitives-where-we-do-.patch +++ /dev/null | |||
@@ -1,1326 +0,0 @@ | |||
1 | From eb77d1ef65e25746acff43545f62a71360b15eec Mon Sep 17 00:00:00 2001 | ||
2 | From: Peter Jones <pjones@redhat.com> | ||
3 | Date: Mon, 15 Jun 2020 12:28:27 -0400 | ||
4 | Subject: [PATCH 6/9] malloc: Use overflow checking primitives where we do | ||
5 | complex allocations | ||
6 | |||
7 | This attempts to fix the places where we do the following where | ||
8 | arithmetic_expr may include unvalidated data: | ||
9 | |||
10 | X = grub_malloc(arithmetic_expr); | ||
11 | |||
12 | It accomplishes this by doing the arithmetic ahead of time using grub_add(), | ||
13 | grub_sub(), grub_mul() and testing for overflow before proceeding. | ||
14 | |||
15 | Among other issues, this fixes: | ||
16 | - allocation of integer overflow in grub_video_bitmap_create() | ||
17 | reported by Chris Coulson, | ||
18 | - allocation of integer overflow in grub_png_decode_image_header() | ||
19 | reported by Chris Coulson, | ||
20 | - allocation of integer overflow in grub_squash_read_symlink() | ||
21 | reported by Chris Coulson, | ||
22 | - allocation of integer overflow in grub_ext2_read_symlink() | ||
23 | reported by Chris Coulson, | ||
24 | - allocation of integer overflow in read_section_as_string() | ||
25 | reported by Chris Coulson. | ||
26 | |||
27 | Fixes: CVE-2020-14309, CVE-2020-14310, CVE-2020-14311 | ||
28 | |||
29 | Upstream-Status: Backport [commit 3f05d693d1274965ffbe4ba99080dc2c570944c6 | ||
30 | from https://git.savannah.gnu.org/git/grub.git] | ||
31 | |||
32 | Signed-off-by: Peter Jones <pjones@redhat.com> | ||
33 | Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> | ||
34 | Signed-off-by: Yongxin Liu <yongxin.liu@windriver.com> | ||
35 | --- | ||
36 | grub-core/commands/legacycfg.c | 29 +++++++++++++++++++----- | ||
37 | grub-core/commands/wildcard.c | 36 ++++++++++++++++++++++++----- | ||
38 | grub-core/disk/ldm.c | 32 ++++++++++++++++++-------- | ||
39 | grub-core/font/font.c | 7 +++++- | ||
40 | grub-core/fs/btrfs.c | 28 +++++++++++++++-------- | ||
41 | grub-core/fs/ext2.c | 10 ++++++++- | ||
42 | grub-core/fs/iso9660.c | 51 +++++++++++++++++++++++++++++------------- | ||
43 | grub-core/fs/sfs.c | 27 +++++++++++++++++----- | ||
44 | grub-core/fs/squash4.c | 45 ++++++++++++++++++++++++++++--------- | ||
45 | grub-core/fs/udf.c | 41 +++++++++++++++++++++------------ | ||
46 | grub-core/fs/xfs.c | 11 +++++---- | ||
47 | grub-core/fs/zfs/zfs.c | 22 ++++++++++++------ | ||
48 | grub-core/fs/zfs/zfscrypt.c | 7 +++++- | ||
49 | grub-core/lib/arg.c | 20 +++++++++++++++-- | ||
50 | grub-core/loader/i386/bsd.c | 8 ++++++- | ||
51 | grub-core/net/dns.c | 9 +++++++- | ||
52 | grub-core/normal/charset.c | 10 +++++++-- | ||
53 | grub-core/normal/cmdline.c | 14 ++++++++++-- | ||
54 | grub-core/normal/menu_entry.c | 13 +++++++++-- | ||
55 | grub-core/script/argv.c | 16 +++++++++++-- | ||
56 | grub-core/script/lexer.c | 21 ++++++++++++++--- | ||
57 | grub-core/video/bitmap.c | 25 +++++++++++++-------- | ||
58 | grub-core/video/readers/png.c | 13 +++++++++-- | ||
59 | 23 files changed, 382 insertions(+), 113 deletions(-) | ||
60 | |||
61 | diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c | ||
62 | index 5e3ec0d..cc5971f 100644 | ||
63 | --- a/grub-core/commands/legacycfg.c | ||
64 | +++ b/grub-core/commands/legacycfg.c | ||
65 | @@ -32,6 +32,7 @@ | ||
66 | #include <grub/auth.h> | ||
67 | #include <grub/disk.h> | ||
68 | #include <grub/partition.h> | ||
69 | +#include <grub/safemath.h> | ||
70 | |||
71 | GRUB_MOD_LICENSE ("GPLv3+"); | ||
72 | |||
73 | @@ -104,13 +105,22 @@ legacy_file (const char *filename) | ||
74 | if (newsuffix) | ||
75 | { | ||
76 | char *t; | ||
77 | - | ||
78 | + grub_size_t sz; | ||
79 | + | ||
80 | + if (grub_add (grub_strlen (suffix), grub_strlen (newsuffix), &sz) || | ||
81 | + grub_add (sz, 1, &sz)) | ||
82 | + { | ||
83 | + grub_errno = GRUB_ERR_OUT_OF_RANGE; | ||
84 | + goto fail_0; | ||
85 | + } | ||
86 | + | ||
87 | t = suffix; | ||
88 | - suffix = grub_realloc (suffix, grub_strlen (suffix) | ||
89 | - + grub_strlen (newsuffix) + 1); | ||
90 | + suffix = grub_realloc (suffix, sz); | ||
91 | if (!suffix) | ||
92 | { | ||
93 | grub_free (t); | ||
94 | + | ||
95 | + fail_0: | ||
96 | grub_free (entrysrc); | ||
97 | grub_free (parsed); | ||
98 | grub_free (newsuffix); | ||
99 | @@ -154,13 +164,22 @@ legacy_file (const char *filename) | ||
100 | else | ||
101 | { | ||
102 | char *t; | ||
103 | + grub_size_t sz; | ||
104 | + | ||
105 | + if (grub_add (grub_strlen (entrysrc), grub_strlen (parsed), &sz) || | ||
106 | + grub_add (sz, 1, &sz)) | ||
107 | + { | ||
108 | + grub_errno = GRUB_ERR_OUT_OF_RANGE; | ||
109 | + goto fail_1; | ||
110 | + } | ||
111 | |||
112 | t = entrysrc; | ||
113 | - entrysrc = grub_realloc (entrysrc, grub_strlen (entrysrc) | ||
114 | - + grub_strlen (parsed) + 1); | ||
115 | + entrysrc = grub_realloc (entrysrc, sz); | ||
116 | if (!entrysrc) | ||
117 | { | ||
118 | grub_free (t); | ||
119 | + | ||
120 | + fail_1: | ||
121 | grub_free (parsed); | ||
122 | grub_free (suffix); | ||
123 | return grub_errno; | ||
124 | diff --git a/grub-core/commands/wildcard.c b/grub-core/commands/wildcard.c | ||
125 | index 4a106ca..cc32903 100644 | ||
126 | --- a/grub-core/commands/wildcard.c | ||
127 | +++ b/grub-core/commands/wildcard.c | ||
128 | @@ -23,6 +23,7 @@ | ||
129 | #include <grub/file.h> | ||
130 | #include <grub/device.h> | ||
131 | #include <grub/script_sh.h> | ||
132 | +#include <grub/safemath.h> | ||
133 | |||
134 | #include <regex.h> | ||
135 | |||
136 | @@ -48,6 +49,7 @@ merge (char **dest, char **ps) | ||
137 | int i; | ||
138 | int j; | ||
139 | char **p; | ||
140 | + grub_size_t sz; | ||
141 | |||
142 | if (! dest) | ||
143 | return ps; | ||
144 | @@ -60,7 +62,12 @@ merge (char **dest, char **ps) | ||
145 | for (j = 0; ps[j]; j++) | ||
146 | ; | ||
147 | |||
148 | - p = grub_realloc (dest, sizeof (char*) * (i + j + 1)); | ||
149 | + if (grub_add (i, j, &sz) || | ||
150 | + grub_add (sz, 1, &sz) || | ||
151 | + grub_mul (sz, sizeof (char *), &sz)) | ||
152 | + return dest; | ||
153 | + | ||
154 | + p = grub_realloc (dest, sz); | ||
155 | if (! p) | ||
156 | { | ||
157 | grub_free (dest); | ||
158 | @@ -115,8 +122,15 @@ make_regex (const char *start, const char *end, regex_t *regexp) | ||
159 | char ch; | ||
160 | int i = 0; | ||
161 | unsigned len = end - start; | ||
162 | - char *buffer = grub_malloc (len * 2 + 2 + 1); /* worst case size. */ | ||
163 | + char *buffer; | ||
164 | + grub_size_t sz; | ||
165 | |||
166 | + /* Worst case size is (len * 2 + 2 + 1). */ | ||
167 | + if (grub_mul (len, 2, &sz) || | ||
168 | + grub_add (sz, 3, &sz)) | ||
169 | + return 1; | ||
170 | + | ||
171 | + buffer = grub_malloc (sz); | ||
172 | if (! buffer) | ||
173 | return 1; | ||
174 | |||
175 | @@ -226,6 +240,7 @@ match_devices_iter (const char *name, void *data) | ||
176 | struct match_devices_ctx *ctx = data; | ||
177 | char **t; | ||
178 | char *buffer; | ||
179 | + grub_size_t sz; | ||
180 | |||
181 | /* skip partitions if asked to. */ | ||
182 | if (ctx->noparts && grub_strchr (name, ',')) | ||
183 | @@ -239,11 +254,16 @@ match_devices_iter (const char *name, void *data) | ||
184 | if (regexec (ctx->regexp, buffer, 0, 0, 0)) | ||
185 | { | ||
186 | grub_dprintf ("expand", "not matched\n"); | ||
187 | + fail: | ||
188 | grub_free (buffer); | ||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | - t = grub_realloc (ctx->devs, sizeof (char*) * (ctx->ndev + 2)); | ||
193 | + if (grub_add (ctx->ndev, 2, &sz) || | ||
194 | + grub_mul (sz, sizeof (char *), &sz)) | ||
195 | + goto fail; | ||
196 | + | ||
197 | + t = grub_realloc (ctx->devs, sz); | ||
198 | if (! t) | ||
199 | { | ||
200 | grub_free (buffer); | ||
201 | @@ -300,6 +320,7 @@ match_files_iter (const char *name, | ||
202 | struct match_files_ctx *ctx = data; | ||
203 | char **t; | ||
204 | char *buffer; | ||
205 | + grub_size_t sz; | ||
206 | |||
207 | /* skip . and .. names */ | ||
208 | if (grub_strcmp(".", name) == 0 || grub_strcmp("..", name) == 0) | ||
209 | @@ -315,9 +336,14 @@ match_files_iter (const char *name, | ||
210 | if (! buffer) | ||
211 | return 1; | ||
212 | |||
213 | - t = grub_realloc (ctx->files, sizeof (char*) * (ctx->nfile + 2)); | ||
214 | - if (! t) | ||
215 | + if (grub_add (ctx->nfile, 2, &sz) || | ||
216 | + grub_mul (sz, sizeof (char *), &sz)) | ||
217 | + goto fail; | ||
218 | + | ||
219 | + t = grub_realloc (ctx->files, sz); | ||
220 | + if (!t) | ||
221 | { | ||
222 | + fail: | ||
223 | grub_free (buffer); | ||
224 | return 1; | ||
225 | } | ||
226 | diff --git a/grub-core/disk/ldm.c b/grub-core/disk/ldm.c | ||
227 | index e632370..58f8a53 100644 | ||
228 | --- a/grub-core/disk/ldm.c | ||
229 | +++ b/grub-core/disk/ldm.c | ||
230 | @@ -25,6 +25,7 @@ | ||
231 | #include <grub/msdos_partition.h> | ||
232 | #include <grub/gpt_partition.h> | ||
233 | #include <grub/i18n.h> | ||
234 | +#include <grub/safemath.h> | ||
235 | |||
236 | #ifdef GRUB_UTIL | ||
237 | #include <grub/emu/misc.h> | ||
238 | @@ -289,6 +290,7 @@ make_vg (grub_disk_t disk, | ||
239 | struct grub_ldm_vblk vblk[GRUB_DISK_SECTOR_SIZE | ||
240 | / sizeof (struct grub_ldm_vblk)]; | ||
241 | unsigned i; | ||
242 | + grub_size_t sz; | ||
243 | err = grub_disk_read (disk, cursec, 0, | ||
244 | sizeof(vblk), &vblk); | ||
245 | if (err) | ||
246 | @@ -350,7 +352,13 @@ make_vg (grub_disk_t disk, | ||
247 | grub_free (lv); | ||
248 | goto fail2; | ||
249 | } | ||
250 | - lv->name = grub_malloc (*ptr + 1); | ||
251 | + if (grub_add (*ptr, 1, &sz)) | ||
252 | + { | ||
253 | + grub_free (lv->internal_id); | ||
254 | + grub_free (lv); | ||
255 | + goto fail2; | ||
256 | + } | ||
257 | + lv->name = grub_malloc (sz); | ||
258 | if (!lv->name) | ||
259 | { | ||
260 | grub_free (lv->internal_id); | ||
261 | @@ -599,10 +607,13 @@ make_vg (grub_disk_t disk, | ||
262 | if (lv->segments->node_alloc == lv->segments->node_count) | ||
263 | { | ||
264 | void *t; | ||
265 | - lv->segments->node_alloc *= 2; | ||
266 | - t = grub_realloc (lv->segments->nodes, | ||
267 | - sizeof (*lv->segments->nodes) | ||
268 | - * lv->segments->node_alloc); | ||
269 | + grub_size_t sz; | ||
270 | + | ||
271 | + if (grub_mul (lv->segments->node_alloc, 2, &lv->segments->node_alloc) || | ||
272 | + grub_mul (lv->segments->node_alloc, sizeof (*lv->segments->nodes), &sz)) | ||
273 | + goto fail2; | ||
274 | + | ||
275 | + t = grub_realloc (lv->segments->nodes, sz); | ||
276 | if (!t) | ||
277 | goto fail2; | ||
278 | lv->segments->nodes = t; | ||
279 | @@ -723,10 +734,13 @@ make_vg (grub_disk_t disk, | ||
280 | if (comp->segment_alloc == comp->segment_count) | ||
281 | { | ||
282 | void *t; | ||
283 | - comp->segment_alloc *= 2; | ||
284 | - t = grub_realloc (comp->segments, | ||
285 | - comp->segment_alloc | ||
286 | - * sizeof (*comp->segments)); | ||
287 | + grub_size_t sz; | ||
288 | + | ||
289 | + if (grub_mul (comp->segment_alloc, 2, &comp->segment_alloc) || | ||
290 | + grub_mul (comp->segment_alloc, sizeof (*comp->segments), &sz)) | ||
291 | + goto fail2; | ||
292 | + | ||
293 | + t = grub_realloc (comp->segments, sz); | ||
294 | if (!t) | ||
295 | goto fail2; | ||
296 | comp->segments = t; | ||
297 | diff --git a/grub-core/font/font.c b/grub-core/font/font.c | ||
298 | index 8e118b3..5edb477 100644 | ||
299 | --- a/grub-core/font/font.c | ||
300 | +++ b/grub-core/font/font.c | ||
301 | @@ -30,6 +30,7 @@ | ||
302 | #include <grub/unicode.h> | ||
303 | #include <grub/fontformat.h> | ||
304 | #include <grub/env.h> | ||
305 | +#include <grub/safemath.h> | ||
306 | |||
307 | GRUB_MOD_LICENSE ("GPLv3+"); | ||
308 | |||
309 | @@ -360,9 +361,13 @@ static char * | ||
310 | read_section_as_string (struct font_file_section *section) | ||
311 | { | ||
312 | char *str; | ||
313 | + grub_size_t sz; | ||
314 | grub_ssize_t ret; | ||
315 | |||
316 | - str = grub_malloc (section->length + 1); | ||
317 | + if (grub_add (section->length, 1, &sz)) | ||
318 | + return NULL; | ||
319 | + | ||
320 | + str = grub_malloc (sz); | ||
321 | if (!str) | ||
322 | return 0; | ||
323 | |||
324 | diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c | ||
325 | index 11272ef..2b65bd5 100644 | ||
326 | --- a/grub-core/fs/btrfs.c | ||
327 | +++ b/grub-core/fs/btrfs.c | ||
328 | @@ -40,6 +40,7 @@ | ||
329 | #include <grub/btrfs.h> | ||
330 | #include <grub/crypto.h> | ||
331 | #include <grub/diskfilter.h> | ||
332 | +#include <grub/safemath.h> | ||
333 | |||
334 | GRUB_MOD_LICENSE ("GPLv3+"); | ||
335 | |||
336 | @@ -329,9 +330,13 @@ save_ref (struct grub_btrfs_leaf_descriptor *desc, | ||
337 | if (desc->allocated < desc->depth) | ||
338 | { | ||
339 | void *newdata; | ||
340 | - desc->allocated *= 2; | ||
341 | - newdata = grub_realloc (desc->data, sizeof (desc->data[0]) | ||
342 | - * desc->allocated); | ||
343 | + grub_size_t sz; | ||
344 | + | ||
345 | + if (grub_mul (desc->allocated, 2, &desc->allocated) || | ||
346 | + grub_mul (desc->allocated, sizeof (desc->data[0]), &sz)) | ||
347 | + return GRUB_ERR_OUT_OF_RANGE; | ||
348 | + | ||
349 | + newdata = grub_realloc (desc->data, sz); | ||
350 | if (!newdata) | ||
351 | return grub_errno; | ||
352 | desc->data = newdata; | ||
353 | @@ -622,16 +627,21 @@ find_device (struct grub_btrfs_data *data, grub_uint64_t id) | ||
354 | if (data->n_devices_attached > data->n_devices_allocated) | ||
355 | { | ||
356 | void *tmp; | ||
357 | - data->n_devices_allocated = 2 * data->n_devices_attached + 1; | ||
358 | - data->devices_attached | ||
359 | - = grub_realloc (tmp = data->devices_attached, | ||
360 | - data->n_devices_allocated | ||
361 | - * sizeof (data->devices_attached[0])); | ||
362 | + grub_size_t sz; | ||
363 | + | ||
364 | + if (grub_mul (data->n_devices_attached, 2, &data->n_devices_allocated) || | ||
365 | + grub_add (data->n_devices_allocated, 1, &data->n_devices_allocated) || | ||
366 | + grub_mul (data->n_devices_allocated, sizeof (data->devices_attached[0]), &sz)) | ||
367 | + goto fail; | ||
368 | + | ||
369 | + data->devices_attached = grub_realloc (tmp = data->devices_attached, sz); | ||
370 | if (!data->devices_attached) | ||
371 | { | ||
372 | + data->devices_attached = tmp; | ||
373 | + | ||
374 | + fail: | ||
375 | if (ctx.dev_found) | ||
376 | grub_device_close (ctx.dev_found); | ||
377 | - data->devices_attached = tmp; | ||
378 | return NULL; | ||
379 | } | ||
380 | } | ||
381 | diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c | ||
382 | index 9b38980..ac33bcd 100644 | ||
383 | --- a/grub-core/fs/ext2.c | ||
384 | +++ b/grub-core/fs/ext2.c | ||
385 | @@ -46,6 +46,7 @@ | ||
386 | #include <grub/dl.h> | ||
387 | #include <grub/types.h> | ||
388 | #include <grub/fshelp.h> | ||
389 | +#include <grub/safemath.h> | ||
390 | |||
391 | GRUB_MOD_LICENSE ("GPLv3+"); | ||
392 | |||
393 | @@ -703,6 +704,7 @@ grub_ext2_read_symlink (grub_fshelp_node_t node) | ||
394 | { | ||
395 | char *symlink; | ||
396 | struct grub_fshelp_node *diro = node; | ||
397 | + grub_size_t sz; | ||
398 | |||
399 | if (! diro->inode_read) | ||
400 | { | ||
401 | @@ -717,7 +719,13 @@ grub_ext2_read_symlink (grub_fshelp_node_t node) | ||
402 | } | ||
403 | } | ||
404 | |||
405 | - symlink = grub_malloc (grub_le_to_cpu32 (diro->inode.size) + 1); | ||
406 | + if (grub_add (grub_le_to_cpu32 (diro->inode.size), 1, &sz)) | ||
407 | + { | ||
408 | + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); | ||
409 | + return NULL; | ||
410 | + } | ||
411 | + | ||
412 | + symlink = grub_malloc (sz); | ||
413 | if (! symlink) | ||
414 | return 0; | ||
415 | |||
416 | diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c | ||
417 | index 4f1b52a..7ba5b30 100644 | ||
418 | --- a/grub-core/fs/iso9660.c | ||
419 | +++ b/grub-core/fs/iso9660.c | ||
420 | @@ -28,6 +28,7 @@ | ||
421 | #include <grub/fshelp.h> | ||
422 | #include <grub/charset.h> | ||
423 | #include <grub/datetime.h> | ||
424 | +#include <grub/safemath.h> | ||
425 | |||
426 | GRUB_MOD_LICENSE ("GPLv3+"); | ||
427 | |||
428 | @@ -531,8 +532,13 @@ add_part (struct iterate_dir_ctx *ctx, | ||
429 | int len2) | ||
430 | { | ||
431 | int size = ctx->symlink ? grub_strlen (ctx->symlink) : 0; | ||
432 | + grub_size_t sz; | ||
433 | |||
434 | - ctx->symlink = grub_realloc (ctx->symlink, size + len2 + 1); | ||
435 | + if (grub_add (size, len2, &sz) || | ||
436 | + grub_add (sz, 1, &sz)) | ||
437 | + return; | ||
438 | + | ||
439 | + ctx->symlink = grub_realloc (ctx->symlink, sz); | ||
440 | if (! ctx->symlink) | ||
441 | return; | ||
442 | |||
443 | @@ -560,17 +566,24 @@ susp_iterate_dir (struct grub_iso9660_susp_entry *entry, | ||
444 | { | ||
445 | grub_size_t off = 0, csize = 1; | ||
446 | char *old; | ||
447 | + grub_size_t sz; | ||
448 | + | ||
449 | csize = entry->len - 5; | ||
450 | old = ctx->filename; | ||
451 | if (ctx->filename_alloc) | ||
452 | { | ||
453 | off = grub_strlen (ctx->filename); | ||
454 | - ctx->filename = grub_realloc (ctx->filename, csize + off + 1); | ||
455 | + if (grub_add (csize, off, &sz) || | ||
456 | + grub_add (sz, 1, &sz)) | ||
457 | + return GRUB_ERR_OUT_OF_RANGE; | ||
458 | + ctx->filename = grub_realloc (ctx->filename, sz); | ||
459 | } | ||
460 | else | ||
461 | { | ||
462 | off = 0; | ||
463 | - ctx->filename = grub_zalloc (csize + 1); | ||
464 | + if (grub_add (csize, 1, &sz)) | ||
465 | + return GRUB_ERR_OUT_OF_RANGE; | ||
466 | + ctx->filename = grub_zalloc (sz); | ||
467 | } | ||
468 | if (!ctx->filename) | ||
469 | { | ||
470 | @@ -776,14 +789,18 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, | ||
471 | if (node->have_dirents >= node->alloc_dirents) | ||
472 | { | ||
473 | struct grub_fshelp_node *new_node; | ||
474 | - node->alloc_dirents *= 2; | ||
475 | - new_node = grub_realloc (node, | ||
476 | - sizeof (struct grub_fshelp_node) | ||
477 | - + ((node->alloc_dirents | ||
478 | - - ARRAY_SIZE (node->dirents)) | ||
479 | - * sizeof (node->dirents[0]))); | ||
480 | + grub_size_t sz; | ||
481 | + | ||
482 | + if (grub_mul (node->alloc_dirents, 2, &node->alloc_dirents) || | ||
483 | + grub_sub (node->alloc_dirents, ARRAY_SIZE (node->dirents), &sz) || | ||
484 | + grub_mul (sz, sizeof (node->dirents[0]), &sz) || | ||
485 | + grub_add (sz, sizeof (struct grub_fshelp_node), &sz)) | ||
486 | + goto fail_0; | ||
487 | + | ||
488 | + new_node = grub_realloc (node, sz); | ||
489 | if (!new_node) | ||
490 | { | ||
491 | + fail_0: | ||
492 | if (ctx.filename_alloc) | ||
493 | grub_free (ctx.filename); | ||
494 | grub_free (node); | ||
495 | @@ -799,14 +816,18 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, | ||
496 | * sizeof (node->dirents[0]) < grub_strlen (ctx.symlink) + 1) | ||
497 | { | ||
498 | struct grub_fshelp_node *new_node; | ||
499 | - new_node = grub_realloc (node, | ||
500 | - sizeof (struct grub_fshelp_node) | ||
501 | - + ((node->alloc_dirents | ||
502 | - - ARRAY_SIZE (node->dirents)) | ||
503 | - * sizeof (node->dirents[0])) | ||
504 | - + grub_strlen (ctx.symlink) + 1); | ||
505 | + grub_size_t sz; | ||
506 | + | ||
507 | + if (grub_sub (node->alloc_dirents, ARRAY_SIZE (node->dirents), &sz) || | ||
508 | + grub_mul (sz, sizeof (node->dirents[0]), &sz) || | ||
509 | + grub_add (sz, sizeof (struct grub_fshelp_node) + 1, &sz) || | ||
510 | + grub_add (sz, grub_strlen (ctx.symlink), &sz)) | ||
511 | + goto fail_1; | ||
512 | + | ||
513 | + new_node = grub_realloc (node, sz); | ||
514 | if (!new_node) | ||
515 | { | ||
516 | + fail_1: | ||
517 | if (ctx.filename_alloc) | ||
518 | grub_free (ctx.filename); | ||
519 | grub_free (node); | ||
520 | diff --git a/grub-core/fs/sfs.c b/grub-core/fs/sfs.c | ||
521 | index 90f7fb3..de2b107 100644 | ||
522 | --- a/grub-core/fs/sfs.c | ||
523 | +++ b/grub-core/fs/sfs.c | ||
524 | @@ -26,6 +26,7 @@ | ||
525 | #include <grub/types.h> | ||
526 | #include <grub/fshelp.h> | ||
527 | #include <grub/charset.h> | ||
528 | +#include <grub/safemath.h> | ||
529 | |||
530 | GRUB_MOD_LICENSE ("GPLv3+"); | ||
531 | |||
532 | @@ -307,10 +308,15 @@ grub_sfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) | ||
533 | if (node->cache && node->cache_size >= node->cache_allocated) | ||
534 | { | ||
535 | struct cache_entry *e = node->cache; | ||
536 | - e = grub_realloc (node->cache,node->cache_allocated * 2 | ||
537 | - * sizeof (e[0])); | ||
538 | + grub_size_t sz; | ||
539 | + | ||
540 | + if (grub_mul (node->cache_allocated, 2 * sizeof (e[0]), &sz)) | ||
541 | + goto fail; | ||
542 | + | ||
543 | + e = grub_realloc (node->cache, sz); | ||
544 | if (!e) | ||
545 | { | ||
546 | + fail: | ||
547 | grub_errno = 0; | ||
548 | grub_free (node->cache); | ||
549 | node->cache = 0; | ||
550 | @@ -477,10 +483,16 @@ grub_sfs_create_node (struct grub_fshelp_node **node, | ||
551 | grub_size_t len = grub_strlen (name); | ||
552 | grub_uint8_t *name_u8; | ||
553 | int ret; | ||
554 | + grub_size_t sz; | ||
555 | + | ||
556 | + if (grub_mul (len, GRUB_MAX_UTF8_PER_LATIN1, &sz) || | ||
557 | + grub_add (sz, 1, &sz)) | ||
558 | + return 1; | ||
559 | + | ||
560 | *node = grub_malloc (sizeof (**node)); | ||
561 | if (!*node) | ||
562 | return 1; | ||
563 | - name_u8 = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1); | ||
564 | + name_u8 = grub_malloc (sz); | ||
565 | if (!name_u8) | ||
566 | { | ||
567 | grub_free (*node); | ||
568 | @@ -724,8 +736,13 @@ grub_sfs_label (grub_device_t device, char **label) | ||
569 | data = grub_sfs_mount (disk); | ||
570 | if (data) | ||
571 | { | ||
572 | - grub_size_t len = grub_strlen (data->label); | ||
573 | - *label = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1); | ||
574 | + grub_size_t sz, len = grub_strlen (data->label); | ||
575 | + | ||
576 | + if (grub_mul (len, GRUB_MAX_UTF8_PER_LATIN1, &sz) || | ||
577 | + grub_add (sz, 1, &sz)) | ||
578 | + return GRUB_ERR_OUT_OF_RANGE; | ||
579 | + | ||
580 | + *label = grub_malloc (sz); | ||
581 | if (*label) | ||
582 | *grub_latin1_to_utf8 ((grub_uint8_t *) *label, | ||
583 | (const grub_uint8_t *) data->label, | ||
584 | diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c | ||
585 | index 95d5c1e..7851238 100644 | ||
586 | --- a/grub-core/fs/squash4.c | ||
587 | +++ b/grub-core/fs/squash4.c | ||
588 | @@ -26,6 +26,7 @@ | ||
589 | #include <grub/types.h> | ||
590 | #include <grub/fshelp.h> | ||
591 | #include <grub/deflate.h> | ||
592 | +#include <grub/safemath.h> | ||
593 | #include <minilzo.h> | ||
594 | |||
595 | #include "xz.h" | ||
596 | @@ -459,7 +460,17 @@ grub_squash_read_symlink (grub_fshelp_node_t node) | ||
597 | { | ||
598 | char *ret; | ||
599 | grub_err_t err; | ||
600 | - ret = grub_malloc (grub_le_to_cpu32 (node->ino.symlink.namelen) + 1); | ||
601 | + grub_size_t sz; | ||
602 | + | ||
603 | + if (grub_add (grub_le_to_cpu32 (node->ino.symlink.namelen), 1, &sz)) | ||
604 | + { | ||
605 | + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); | ||
606 | + return NULL; | ||
607 | + } | ||
608 | + | ||
609 | + ret = grub_malloc (sz); | ||
610 | + if (!ret) | ||
611 | + return NULL; | ||
612 | |||
613 | err = read_chunk (node->data, ret, | ||
614 | grub_le_to_cpu32 (node->ino.symlink.namelen), | ||
615 | @@ -506,11 +517,16 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, | ||
616 | |||
617 | { | ||
618 | grub_fshelp_node_t node; | ||
619 | - node = grub_malloc (sizeof (*node) + dir->stsize * sizeof (dir->stack[0])); | ||
620 | + grub_size_t sz; | ||
621 | + | ||
622 | + if (grub_mul (dir->stsize, sizeof (dir->stack[0]), &sz) || | ||
623 | + grub_add (sz, sizeof (*node), &sz)) | ||
624 | + return 0; | ||
625 | + | ||
626 | + node = grub_malloc (sz); | ||
627 | if (!node) | ||
628 | return 0; | ||
629 | - grub_memcpy (node, dir, | ||
630 | - sizeof (*node) + dir->stsize * sizeof (dir->stack[0])); | ||
631 | + grub_memcpy (node, dir, sz); | ||
632 | if (hook (".", GRUB_FSHELP_DIR, node, hook_data)) | ||
633 | return 1; | ||
634 | |||
635 | @@ -518,12 +534,15 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, | ||
636 | { | ||
637 | grub_err_t err; | ||
638 | |||
639 | - node = grub_malloc (sizeof (*node) + dir->stsize * sizeof (dir->stack[0])); | ||
640 | + if (grub_mul (dir->stsize, sizeof (dir->stack[0]), &sz) || | ||
641 | + grub_add (sz, sizeof (*node), &sz)) | ||
642 | + return 0; | ||
643 | + | ||
644 | + node = grub_malloc (sz); | ||
645 | if (!node) | ||
646 | return 0; | ||
647 | |||
648 | - grub_memcpy (node, dir, | ||
649 | - sizeof (*node) + dir->stsize * sizeof (dir->stack[0])); | ||
650 | + grub_memcpy (node, dir, sz); | ||
651 | |||
652 | node->stsize--; | ||
653 | err = read_chunk (dir->data, &node->ino, sizeof (node->ino), | ||
654 | @@ -557,6 +576,7 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, | ||
655 | enum grub_fshelp_filetype filetype = GRUB_FSHELP_REG; | ||
656 | struct grub_squash_dirent di; | ||
657 | struct grub_squash_inode ino; | ||
658 | + grub_size_t sz; | ||
659 | |||
660 | err = read_chunk (dir->data, &di, sizeof (di), | ||
661 | grub_le_to_cpu64 (dir->data->sb.diroffset) | ||
662 | @@ -589,13 +609,16 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, | ||
663 | if (grub_le_to_cpu16 (di.type) == SQUASH_TYPE_SYMLINK) | ||
664 | filetype = GRUB_FSHELP_SYMLINK; | ||
665 | |||
666 | - node = grub_malloc (sizeof (*node) | ||
667 | - + (dir->stsize + 1) * sizeof (dir->stack[0])); | ||
668 | + if (grub_add (dir->stsize, 1, &sz) || | ||
669 | + grub_mul (sz, sizeof (dir->stack[0]), &sz) || | ||
670 | + grub_add (sz, sizeof (*node), &sz)) | ||
671 | + return 0; | ||
672 | + | ||
673 | + node = grub_malloc (sz); | ||
674 | if (! node) | ||
675 | return 0; | ||
676 | |||
677 | - grub_memcpy (node, dir, | ||
678 | - sizeof (*node) + dir->stsize * sizeof (dir->stack[0])); | ||
679 | + grub_memcpy (node, dir, sz - sizeof(dir->stack[0])); | ||
680 | |||
681 | node->ino = ino; | ||
682 | node->stack[node->stsize].ino_chunk = grub_le_to_cpu32 (dh.ino_chunk); | ||
683 | diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c | ||
684 | index a837616..21ac7f4 100644 | ||
685 | --- a/grub-core/fs/udf.c | ||
686 | +++ b/grub-core/fs/udf.c | ||
687 | @@ -28,6 +28,7 @@ | ||
688 | #include <grub/charset.h> | ||
689 | #include <grub/datetime.h> | ||
690 | #include <grub/udf.h> | ||
691 | +#include <grub/safemath.h> | ||
692 | |||
693 | GRUB_MOD_LICENSE ("GPLv3+"); | ||
694 | |||
695 | @@ -890,9 +891,19 @@ read_string (const grub_uint8_t *raw, grub_size_t sz, char *outbuf) | ||
696 | utf16[i] = (raw[2 * i + 1] << 8) | raw[2*i + 2]; | ||
697 | } | ||
698 | if (!outbuf) | ||
699 | - outbuf = grub_malloc (utf16len * GRUB_MAX_UTF8_PER_UTF16 + 1); | ||
700 | + { | ||
701 | + grub_size_t size; | ||
702 | + | ||
703 | + if (grub_mul (utf16len, GRUB_MAX_UTF8_PER_UTF16, &size) || | ||
704 | + grub_add (size, 1, &size)) | ||
705 | + goto fail; | ||
706 | + | ||
707 | + outbuf = grub_malloc (size); | ||
708 | + } | ||
709 | if (outbuf) | ||
710 | *grub_utf16_to_utf8 ((grub_uint8_t *) outbuf, utf16, utf16len) = '\0'; | ||
711 | + | ||
712 | + fail: | ||
713 | grub_free (utf16); | ||
714 | return outbuf; | ||
715 | } | ||
716 | @@ -1005,7 +1016,7 @@ grub_udf_read_symlink (grub_fshelp_node_t node) | ||
717 | grub_size_t sz = U64 (node->block.fe.file_size); | ||
718 | grub_uint8_t *raw; | ||
719 | const grub_uint8_t *ptr; | ||
720 | - char *out, *optr; | ||
721 | + char *out = NULL, *optr; | ||
722 | |||
723 | if (sz < 4) | ||
724 | return NULL; | ||
725 | @@ -1013,14 +1024,16 @@ grub_udf_read_symlink (grub_fshelp_node_t node) | ||
726 | if (!raw) | ||
727 | return NULL; | ||
728 | if (grub_udf_read_file (node, NULL, NULL, 0, sz, (char *) raw) < 0) | ||
729 | - { | ||
730 | - grub_free (raw); | ||
731 | - return NULL; | ||
732 | - } | ||
733 | + goto fail_1; | ||
734 | |||
735 | - out = grub_malloc (sz * 2 + 1); | ||
736 | + if (grub_mul (sz, 2, &sz) || | ||
737 | + grub_add (sz, 1, &sz)) | ||
738 | + goto fail_0; | ||
739 | + | ||
740 | + out = grub_malloc (sz); | ||
741 | if (!out) | ||
742 | { | ||
743 | + fail_0: | ||
744 | grub_free (raw); | ||
745 | return NULL; | ||
746 | } | ||
747 | @@ -1031,17 +1044,17 @@ grub_udf_read_symlink (grub_fshelp_node_t node) | ||
748 | { | ||
749 | grub_size_t s; | ||
750 | if ((grub_size_t) (ptr - raw + 4) > sz) | ||
751 | - goto fail; | ||
752 | + goto fail_1; | ||
753 | if (!(ptr[2] == 0 && ptr[3] == 0)) | ||
754 | - goto fail; | ||
755 | + goto fail_1; | ||
756 | s = 4 + ptr[1]; | ||
757 | if ((grub_size_t) (ptr - raw + s) > sz) | ||
758 | - goto fail; | ||
759 | + goto fail_1; | ||
760 | switch (*ptr) | ||
761 | { | ||
762 | case 1: | ||
763 | if (ptr[1]) | ||
764 | - goto fail; | ||
765 | + goto fail_1; | ||
766 | /* Fallthrough. */ | ||
767 | case 2: | ||
768 | /* in 4 bytes. out: 1 byte. */ | ||
769 | @@ -1066,11 +1079,11 @@ grub_udf_read_symlink (grub_fshelp_node_t node) | ||
770 | if (optr != out) | ||
771 | *optr++ = '/'; | ||
772 | if (!read_string (ptr + 4, s - 4, optr)) | ||
773 | - goto fail; | ||
774 | + goto fail_1; | ||
775 | optr += grub_strlen (optr); | ||
776 | break; | ||
777 | default: | ||
778 | - goto fail; | ||
779 | + goto fail_1; | ||
780 | } | ||
781 | ptr += s; | ||
782 | } | ||
783 | @@ -1078,7 +1091,7 @@ grub_udf_read_symlink (grub_fshelp_node_t node) | ||
784 | grub_free (raw); | ||
785 | return out; | ||
786 | |||
787 | - fail: | ||
788 | + fail_1: | ||
789 | grub_free (raw); | ||
790 | grub_free (out); | ||
791 | grub_error (GRUB_ERR_BAD_FS, "invalid symlink"); | ||
792 | diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c | ||
793 | index 96ffecb..ea65902 100644 | ||
794 | --- a/grub-core/fs/xfs.c | ||
795 | +++ b/grub-core/fs/xfs.c | ||
796 | @@ -25,6 +25,7 @@ | ||
797 | #include <grub/dl.h> | ||
798 | #include <grub/types.h> | ||
799 | #include <grub/fshelp.h> | ||
800 | +#include <grub/safemath.h> | ||
801 | |||
802 | GRUB_MOD_LICENSE ("GPLv3+"); | ||
803 | |||
804 | @@ -899,6 +900,7 @@ static struct grub_xfs_data * | ||
805 | grub_xfs_mount (grub_disk_t disk) | ||
806 | { | ||
807 | struct grub_xfs_data *data = 0; | ||
808 | + grub_size_t sz; | ||
809 | |||
810 | data = grub_zalloc (sizeof (struct grub_xfs_data)); | ||
811 | if (!data) | ||
812 | @@ -913,10 +915,11 @@ grub_xfs_mount (grub_disk_t disk) | ||
813 | if (!grub_xfs_sb_valid(data)) | ||
814 | goto fail; | ||
815 | |||
816 | - data = grub_realloc (data, | ||
817 | - sizeof (struct grub_xfs_data) | ||
818 | - - sizeof (struct grub_xfs_inode) | ||
819 | - + grub_xfs_inode_size(data) + 1); | ||
820 | + if (grub_add (grub_xfs_inode_size (data), | ||
821 | + sizeof (struct grub_xfs_data) - sizeof (struct grub_xfs_inode) + 1, &sz)) | ||
822 | + goto fail; | ||
823 | + | ||
824 | + data = grub_realloc (data, sz); | ||
825 | |||
826 | if (! data) | ||
827 | goto fail; | ||
828 | diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c | ||
829 | index 381dde5..36d0373 100644 | ||
830 | --- a/grub-core/fs/zfs/zfs.c | ||
831 | +++ b/grub-core/fs/zfs/zfs.c | ||
832 | @@ -55,6 +55,7 @@ | ||
833 | #include <grub/deflate.h> | ||
834 | #include <grub/crypto.h> | ||
835 | #include <grub/i18n.h> | ||
836 | +#include <grub/safemath.h> | ||
837 | |||
838 | GRUB_MOD_LICENSE ("GPLv3+"); | ||
839 | |||
840 | @@ -773,11 +774,14 @@ fill_vdev_info (struct grub_zfs_data *data, | ||
841 | if (data->n_devices_attached > data->n_devices_allocated) | ||
842 | { | ||
843 | void *tmp; | ||
844 | - data->n_devices_allocated = 2 * data->n_devices_attached + 1; | ||
845 | - data->devices_attached | ||
846 | - = grub_realloc (tmp = data->devices_attached, | ||
847 | - data->n_devices_allocated | ||
848 | - * sizeof (data->devices_attached[0])); | ||
849 | + grub_size_t sz; | ||
850 | + | ||
851 | + if (grub_mul (data->n_devices_attached, 2, &data->n_devices_allocated) || | ||
852 | + grub_add (data->n_devices_allocated, 1, &data->n_devices_allocated) || | ||
853 | + grub_mul (data->n_devices_allocated, sizeof (data->devices_attached[0]), &sz)) | ||
854 | + return GRUB_ERR_OUT_OF_RANGE; | ||
855 | + | ||
856 | + data->devices_attached = grub_realloc (tmp = data->devices_attached, sz); | ||
857 | if (!data->devices_attached) | ||
858 | { | ||
859 | data->devices_attached = tmp; | ||
860 | @@ -3468,14 +3472,18 @@ grub_zfs_nvlist_lookup_nvlist (const char *nvlist, const char *name) | ||
861 | { | ||
862 | char *nvpair; | ||
863 | char *ret; | ||
864 | - grub_size_t size; | ||
865 | + grub_size_t size, sz; | ||
866 | int found; | ||
867 | |||
868 | found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST, &nvpair, | ||
869 | &size, 0); | ||
870 | if (!found) | ||
871 | return 0; | ||
872 | - ret = grub_zalloc (size + 3 * sizeof (grub_uint32_t)); | ||
873 | + | ||
874 | + if (grub_add (size, 3 * sizeof (grub_uint32_t), &sz)) | ||
875 | + return 0; | ||
876 | + | ||
877 | + ret = grub_zalloc (sz); | ||
878 | if (!ret) | ||
879 | return 0; | ||
880 | grub_memcpy (ret, nvlist, sizeof (grub_uint32_t)); | ||
881 | diff --git a/grub-core/fs/zfs/zfscrypt.c b/grub-core/fs/zfs/zfscrypt.c | ||
882 | index 1402e0b..de3b015 100644 | ||
883 | --- a/grub-core/fs/zfs/zfscrypt.c | ||
884 | +++ b/grub-core/fs/zfs/zfscrypt.c | ||
885 | @@ -22,6 +22,7 @@ | ||
886 | #include <grub/misc.h> | ||
887 | #include <grub/disk.h> | ||
888 | #include <grub/partition.h> | ||
889 | +#include <grub/safemath.h> | ||
890 | #include <grub/dl.h> | ||
891 | #include <grub/types.h> | ||
892 | #include <grub/zfs/zfs.h> | ||
893 | @@ -82,9 +83,13 @@ grub_zfs_add_key (grub_uint8_t *key_in, | ||
894 | int passphrase) | ||
895 | { | ||
896 | struct grub_zfs_wrap_key *key; | ||
897 | + grub_size_t sz; | ||
898 | + | ||
899 | if (!passphrase && keylen > 32) | ||
900 | keylen = 32; | ||
901 | - key = grub_malloc (sizeof (*key) + keylen); | ||
902 | + if (grub_add (sizeof (*key), keylen, &sz)) | ||
903 | + return GRUB_ERR_OUT_OF_RANGE; | ||
904 | + key = grub_malloc (sz); | ||
905 | if (!key) | ||
906 | return grub_errno; | ||
907 | key->is_passphrase = passphrase; | ||
908 | diff --git a/grub-core/lib/arg.c b/grub-core/lib/arg.c | ||
909 | index fd7744a..3288609 100644 | ||
910 | --- a/grub-core/lib/arg.c | ||
911 | +++ b/grub-core/lib/arg.c | ||
912 | @@ -23,6 +23,7 @@ | ||
913 | #include <grub/term.h> | ||
914 | #include <grub/extcmd.h> | ||
915 | #include <grub/i18n.h> | ||
916 | +#include <grub/safemath.h> | ||
917 | |||
918 | /* Built-in parser for default options. */ | ||
919 | static const struct grub_arg_option help_options[] = | ||
920 | @@ -216,7 +217,13 @@ static inline grub_err_t | ||
921 | add_arg (char ***argl, int *num, char *s) | ||
922 | { | ||
923 | char **p = *argl; | ||
924 | - *argl = grub_realloc (*argl, (++(*num) + 1) * sizeof (char *)); | ||
925 | + grub_size_t sz; | ||
926 | + | ||
927 | + if (grub_add (++(*num), 1, &sz) || | ||
928 | + grub_mul (sz, sizeof (char *), &sz)) | ||
929 | + return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); | ||
930 | + | ||
931 | + *argl = grub_realloc (*argl, sz); | ||
932 | if (! *argl) | ||
933 | { | ||
934 | grub_free (p); | ||
935 | @@ -431,6 +438,7 @@ grub_arg_list_alloc(grub_extcmd_t extcmd, int argc, | ||
936 | grub_size_t argcnt; | ||
937 | struct grub_arg_list *list; | ||
938 | const struct grub_arg_option *options; | ||
939 | + grub_size_t sz0, sz1; | ||
940 | |||
941 | options = extcmd->options; | ||
942 | if (! options) | ||
943 | @@ -443,7 +451,15 @@ grub_arg_list_alloc(grub_extcmd_t extcmd, int argc, | ||
944 | argcnt += ((grub_size_t) argc + 1) / 2 + 1; /* max possible for any option */ | ||
945 | } | ||
946 | |||
947 | - list = grub_zalloc (sizeof (*list) * i + sizeof (char*) * argcnt); | ||
948 | + if (grub_mul (sizeof (*list), i, &sz0) || | ||
949 | + grub_mul (sizeof (char *), argcnt, &sz1) || | ||
950 | + grub_add (sz0, sz1, &sz0)) | ||
951 | + { | ||
952 | + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); | ||
953 | + return 0; | ||
954 | + } | ||
955 | + | ||
956 | + list = grub_zalloc (sz0); | ||
957 | if (! list) | ||
958 | return 0; | ||
959 | |||
960 | diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c | ||
961 | index 3730ed3..b92cbe9 100644 | ||
962 | --- a/grub-core/loader/i386/bsd.c | ||
963 | +++ b/grub-core/loader/i386/bsd.c | ||
964 | @@ -35,6 +35,7 @@ | ||
965 | #include <grub/ns8250.h> | ||
966 | #include <grub/bsdlabel.h> | ||
967 | #include <grub/crypto.h> | ||
968 | +#include <grub/safemath.h> | ||
969 | #include <grub/verify.h> | ||
970 | #ifdef GRUB_MACHINE_PCBIOS | ||
971 | #include <grub/machine/int.h> | ||
972 | @@ -1012,11 +1013,16 @@ grub_netbsd_add_modules (void) | ||
973 | struct grub_netbsd_btinfo_modules *mods; | ||
974 | unsigned i; | ||
975 | grub_err_t err; | ||
976 | + grub_size_t sz; | ||
977 | |||
978 | for (mod = netbsd_mods; mod; mod = mod->next) | ||
979 | modcnt++; | ||
980 | |||
981 | - mods = grub_malloc (sizeof (*mods) + sizeof (mods->mods[0]) * modcnt); | ||
982 | + if (grub_mul (modcnt, sizeof (mods->mods[0]), &sz) || | ||
983 | + grub_add (sz, sizeof (*mods), &sz)) | ||
984 | + return GRUB_ERR_OUT_OF_RANGE; | ||
985 | + | ||
986 | + mods = grub_malloc (sz); | ||
987 | if (!mods) | ||
988 | return grub_errno; | ||
989 | |||
990 | diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c | ||
991 | index e332d5e..906ec7d 100644 | ||
992 | --- a/grub-core/net/dns.c | ||
993 | +++ b/grub-core/net/dns.c | ||
994 | @@ -22,6 +22,7 @@ | ||
995 | #include <grub/i18n.h> | ||
996 | #include <grub/err.h> | ||
997 | #include <grub/time.h> | ||
998 | +#include <grub/safemath.h> | ||
999 | |||
1000 | struct dns_cache_element | ||
1001 | { | ||
1002 | @@ -51,9 +52,15 @@ grub_net_add_dns_server (const struct grub_net_network_level_address *s) | ||
1003 | { | ||
1004 | int na = dns_servers_alloc * 2; | ||
1005 | struct grub_net_network_level_address *ns; | ||
1006 | + grub_size_t sz; | ||
1007 | + | ||
1008 | if (na < 8) | ||
1009 | na = 8; | ||
1010 | - ns = grub_realloc (dns_servers, na * sizeof (ns[0])); | ||
1011 | + | ||
1012 | + if (grub_mul (na, sizeof (ns[0]), &sz)) | ||
1013 | + return GRUB_ERR_OUT_OF_RANGE; | ||
1014 | + | ||
1015 | + ns = grub_realloc (dns_servers, sz); | ||
1016 | if (!ns) | ||
1017 | return grub_errno; | ||
1018 | dns_servers_alloc = na; | ||
1019 | diff --git a/grub-core/normal/charset.c b/grub-core/normal/charset.c | ||
1020 | index d57fb72..4dfcc31 100644 | ||
1021 | --- a/grub-core/normal/charset.c | ||
1022 | +++ b/grub-core/normal/charset.c | ||
1023 | @@ -48,6 +48,7 @@ | ||
1024 | #include <grub/unicode.h> | ||
1025 | #include <grub/term.h> | ||
1026 | #include <grub/normal.h> | ||
1027 | +#include <grub/safemath.h> | ||
1028 | |||
1029 | #if HAVE_FONT_SOURCE | ||
1030 | #include "widthspec.h" | ||
1031 | @@ -464,6 +465,7 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, | ||
1032 | { | ||
1033 | struct grub_unicode_combining *n; | ||
1034 | unsigned j; | ||
1035 | + grub_size_t sz; | ||
1036 | |||
1037 | if (!haveout) | ||
1038 | continue; | ||
1039 | @@ -477,10 +479,14 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, | ||
1040 | n = out->combining_inline; | ||
1041 | else if (out->ncomb > (int) ARRAY_SIZE (out->combining_inline)) | ||
1042 | { | ||
1043 | - n = grub_realloc (out->combining_ptr, | ||
1044 | - sizeof (n[0]) * (out->ncomb + 1)); | ||
1045 | + if (grub_add (out->ncomb, 1, &sz) || | ||
1046 | + grub_mul (sz, sizeof (n[0]), &sz)) | ||
1047 | + goto fail; | ||
1048 | + | ||
1049 | + n = grub_realloc (out->combining_ptr, sz); | ||
1050 | if (!n) | ||
1051 | { | ||
1052 | + fail: | ||
1053 | grub_errno = GRUB_ERR_NONE; | ||
1054 | continue; | ||
1055 | } | ||
1056 | diff --git a/grub-core/normal/cmdline.c b/grub-core/normal/cmdline.c | ||
1057 | index c57242e..de03fe6 100644 | ||
1058 | --- a/grub-core/normal/cmdline.c | ||
1059 | +++ b/grub-core/normal/cmdline.c | ||
1060 | @@ -28,6 +28,7 @@ | ||
1061 | #include <grub/env.h> | ||
1062 | #include <grub/i18n.h> | ||
1063 | #include <grub/charset.h> | ||
1064 | +#include <grub/safemath.h> | ||
1065 | |||
1066 | static grub_uint32_t *kill_buf; | ||
1067 | |||
1068 | @@ -307,12 +308,21 @@ cl_insert (struct cmdline_term *cl_terms, unsigned nterms, | ||
1069 | if (len + (*llen) >= (*max_len)) | ||
1070 | { | ||
1071 | grub_uint32_t *nbuf; | ||
1072 | - (*max_len) *= 2; | ||
1073 | - nbuf = grub_realloc ((*buf), sizeof (grub_uint32_t) * (*max_len)); | ||
1074 | + grub_size_t sz; | ||
1075 | + | ||
1076 | + if (grub_mul (*max_len, 2, max_len) || | ||
1077 | + grub_mul (*max_len, sizeof (grub_uint32_t), &sz)) | ||
1078 | + { | ||
1079 | + grub_errno = GRUB_ERR_OUT_OF_RANGE; | ||
1080 | + goto fail; | ||
1081 | + } | ||
1082 | + | ||
1083 | + nbuf = grub_realloc ((*buf), sz); | ||
1084 | if (nbuf) | ||
1085 | (*buf) = nbuf; | ||
1086 | else | ||
1087 | { | ||
1088 | + fail: | ||
1089 | grub_print_error (); | ||
1090 | grub_errno = GRUB_ERR_NONE; | ||
1091 | (*max_len) /= 2; | ||
1092 | diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c | ||
1093 | index 1993995..50eef91 100644 | ||
1094 | --- a/grub-core/normal/menu_entry.c | ||
1095 | +++ b/grub-core/normal/menu_entry.c | ||
1096 | @@ -27,6 +27,7 @@ | ||
1097 | #include <grub/auth.h> | ||
1098 | #include <grub/i18n.h> | ||
1099 | #include <grub/charset.h> | ||
1100 | +#include <grub/safemath.h> | ||
1101 | |||
1102 | enum update_mode | ||
1103 | { | ||
1104 | @@ -113,10 +114,18 @@ ensure_space (struct line *linep, int extra) | ||
1105 | { | ||
1106 | if (linep->max_len < linep->len + extra) | ||
1107 | { | ||
1108 | - linep->max_len = 2 * (linep->len + extra); | ||
1109 | - linep->buf = grub_realloc (linep->buf, (linep->max_len + 1) * sizeof (linep->buf[0])); | ||
1110 | + grub_size_t sz0, sz1; | ||
1111 | + | ||
1112 | + if (grub_add (linep->len, extra, &sz0) || | ||
1113 | + grub_mul (sz0, 2, &sz0) || | ||
1114 | + grub_add (sz0, 1, &sz1) || | ||
1115 | + grub_mul (sz1, sizeof (linep->buf[0]), &sz1)) | ||
1116 | + return 0; | ||
1117 | + | ||
1118 | + linep->buf = grub_realloc (linep->buf, sz1); | ||
1119 | if (! linep->buf) | ||
1120 | return 0; | ||
1121 | + linep->max_len = sz0; | ||
1122 | } | ||
1123 | |||
1124 | return 1; | ||
1125 | diff --git a/grub-core/script/argv.c b/grub-core/script/argv.c | ||
1126 | index 217ec5d..5751fdd 100644 | ||
1127 | --- a/grub-core/script/argv.c | ||
1128 | +++ b/grub-core/script/argv.c | ||
1129 | @@ -20,6 +20,7 @@ | ||
1130 | #include <grub/mm.h> | ||
1131 | #include <grub/misc.h> | ||
1132 | #include <grub/script_sh.h> | ||
1133 | +#include <grub/safemath.h> | ||
1134 | |||
1135 | /* Return nearest power of two that is >= v. */ | ||
1136 | static unsigned | ||
1137 | @@ -81,11 +82,16 @@ int | ||
1138 | grub_script_argv_next (struct grub_script_argv *argv) | ||
1139 | { | ||
1140 | char **p = argv->args; | ||
1141 | + grub_size_t sz; | ||
1142 | |||
1143 | if (argv->args && argv->argc && argv->args[argv->argc - 1] == 0) | ||
1144 | return 0; | ||
1145 | |||
1146 | - p = grub_realloc (p, round_up_exp ((argv->argc + 2) * sizeof (char *))); | ||
1147 | + if (grub_add (argv->argc, 2, &sz) || | ||
1148 | + grub_mul (sz, sizeof (char *), &sz)) | ||
1149 | + return 1; | ||
1150 | + | ||
1151 | + p = grub_realloc (p, round_up_exp (sz)); | ||
1152 | if (! p) | ||
1153 | return 1; | ||
1154 | |||
1155 | @@ -105,13 +111,19 @@ grub_script_argv_append (struct grub_script_argv *argv, const char *s, | ||
1156 | { | ||
1157 | grub_size_t a; | ||
1158 | char *p = argv->args[argv->argc - 1]; | ||
1159 | + grub_size_t sz; | ||
1160 | |||
1161 | if (! s) | ||
1162 | return 0; | ||
1163 | |||
1164 | a = p ? grub_strlen (p) : 0; | ||
1165 | |||
1166 | - p = grub_realloc (p, round_up_exp ((a + slen + 1) * sizeof (char))); | ||
1167 | + if (grub_add (a, slen, &sz) || | ||
1168 | + grub_add (sz, 1, &sz) || | ||
1169 | + grub_mul (sz, sizeof (char), &sz)) | ||
1170 | + return 1; | ||
1171 | + | ||
1172 | + p = grub_realloc (p, round_up_exp (sz)); | ||
1173 | if (! p) | ||
1174 | return 1; | ||
1175 | |||
1176 | diff --git a/grub-core/script/lexer.c b/grub-core/script/lexer.c | ||
1177 | index c6bd317..5fb0cbd 100644 | ||
1178 | --- a/grub-core/script/lexer.c | ||
1179 | +++ b/grub-core/script/lexer.c | ||
1180 | @@ -24,6 +24,7 @@ | ||
1181 | #include <grub/mm.h> | ||
1182 | #include <grub/script_sh.h> | ||
1183 | #include <grub/i18n.h> | ||
1184 | +#include <grub/safemath.h> | ||
1185 | |||
1186 | #define yytext_ptr char * | ||
1187 | #include "grub_script.tab.h" | ||
1188 | @@ -110,10 +111,14 @@ grub_script_lexer_record (struct grub_parser_param *parser, char *str) | ||
1189 | old = lexer->recording; | ||
1190 | if (lexer->recordlen < len) | ||
1191 | lexer->recordlen = len; | ||
1192 | - lexer->recordlen *= 2; | ||
1193 | + | ||
1194 | + if (grub_mul (lexer->recordlen, 2, &lexer->recordlen)) | ||
1195 | + goto fail; | ||
1196 | + | ||
1197 | lexer->recording = grub_realloc (lexer->recording, lexer->recordlen); | ||
1198 | if (!lexer->recording) | ||
1199 | { | ||
1200 | + fail: | ||
1201 | grub_free (old); | ||
1202 | lexer->recordpos = 0; | ||
1203 | lexer->recordlen = 0; | ||
1204 | @@ -130,7 +135,7 @@ int | ||
1205 | grub_script_lexer_yywrap (struct grub_parser_param *parserstate, | ||
1206 | const char *input) | ||
1207 | { | ||
1208 | - grub_size_t len = 0; | ||
1209 | + grub_size_t len = 0, sz; | ||
1210 | char *p = 0; | ||
1211 | char *line = 0; | ||
1212 | YY_BUFFER_STATE buffer; | ||
1213 | @@ -168,12 +173,22 @@ grub_script_lexer_yywrap (struct grub_parser_param *parserstate, | ||
1214 | } | ||
1215 | else if (len && line[len - 1] != '\n') | ||
1216 | { | ||
1217 | - p = grub_realloc (line, len + 2); | ||
1218 | + if (grub_add (len, 2, &sz)) | ||
1219 | + { | ||
1220 | + grub_free (line); | ||
1221 | + grub_script_yyerror (parserstate, N_("overflow is detected")); | ||
1222 | + return 1; | ||
1223 | + } | ||
1224 | + | ||
1225 | + p = grub_realloc (line, sz); | ||
1226 | if (p) | ||
1227 | { | ||
1228 | p[len++] = '\n'; | ||
1229 | p[len] = '\0'; | ||
1230 | } | ||
1231 | + else | ||
1232 | + grub_free (line); | ||
1233 | + | ||
1234 | line = p; | ||
1235 | } | ||
1236 | |||
1237 | diff --git a/grub-core/video/bitmap.c b/grub-core/video/bitmap.c | ||
1238 | index b2e0315..6256e20 100644 | ||
1239 | --- a/grub-core/video/bitmap.c | ||
1240 | +++ b/grub-core/video/bitmap.c | ||
1241 | @@ -23,6 +23,7 @@ | ||
1242 | #include <grub/mm.h> | ||
1243 | #include <grub/misc.h> | ||
1244 | #include <grub/i18n.h> | ||
1245 | +#include <grub/safemath.h> | ||
1246 | |||
1247 | GRUB_MOD_LICENSE ("GPLv3+"); | ||
1248 | |||
1249 | @@ -58,7 +59,7 @@ grub_video_bitmap_create (struct grub_video_bitmap **bitmap, | ||
1250 | enum grub_video_blit_format blit_format) | ||
1251 | { | ||
1252 | struct grub_video_mode_info *mode_info; | ||
1253 | - unsigned int size; | ||
1254 | + grub_size_t size; | ||
1255 | |||
1256 | if (!bitmap) | ||
1257 | return grub_error (GRUB_ERR_BUG, "invalid argument"); | ||
1258 | @@ -137,19 +138,25 @@ grub_video_bitmap_create (struct grub_video_bitmap **bitmap, | ||
1259 | |||
1260 | mode_info->pitch = width * mode_info->bytes_per_pixel; | ||
1261 | |||
1262 | - /* Calculate size needed for the data. */ | ||
1263 | - size = (width * mode_info->bytes_per_pixel) * height; | ||
1264 | + /* Calculate size needed for the data. */ | ||
1265 | + if (grub_mul (width, mode_info->bytes_per_pixel, &size) || | ||
1266 | + grub_mul (size, height, &size)) | ||
1267 | + { | ||
1268 | + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); | ||
1269 | + goto fail; | ||
1270 | + } | ||
1271 | |||
1272 | (*bitmap)->data = grub_zalloc (size); | ||
1273 | if (! (*bitmap)->data) | ||
1274 | - { | ||
1275 | - grub_free (*bitmap); | ||
1276 | - *bitmap = 0; | ||
1277 | - | ||
1278 | - return grub_errno; | ||
1279 | - } | ||
1280 | + goto fail; | ||
1281 | |||
1282 | return GRUB_ERR_NONE; | ||
1283 | + | ||
1284 | + fail: | ||
1285 | + grub_free (*bitmap); | ||
1286 | + *bitmap = NULL; | ||
1287 | + | ||
1288 | + return grub_errno; | ||
1289 | } | ||
1290 | |||
1291 | /* Frees all resources allocated by bitmap. */ | ||
1292 | diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c | ||
1293 | index 61bd645..0157ff7 100644 | ||
1294 | --- a/grub-core/video/readers/png.c | ||
1295 | +++ b/grub-core/video/readers/png.c | ||
1296 | @@ -23,6 +23,7 @@ | ||
1297 | #include <grub/mm.h> | ||
1298 | #include <grub/misc.h> | ||
1299 | #include <grub/bufio.h> | ||
1300 | +#include <grub/safemath.h> | ||
1301 | |||
1302 | GRUB_MOD_LICENSE ("GPLv3+"); | ||
1303 | |||
1304 | @@ -301,9 +302,17 @@ grub_png_decode_image_header (struct grub_png_data *data) | ||
1305 | data->bpp <<= 1; | ||
1306 | |||
1307 | data->color_bits = color_bits; | ||
1308 | - data->row_bytes = data->image_width * data->bpp; | ||
1309 | + | ||
1310 | + if (grub_mul (data->image_width, data->bpp, &data->row_bytes)) | ||
1311 | + return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); | ||
1312 | + | ||
1313 | if (data->color_bits <= 4) | ||
1314 | - data->row_bytes = (data->image_width * data->color_bits + 7) / 8; | ||
1315 | + { | ||
1316 | + if (grub_mul (data->image_width, data->color_bits + 7, &data->row_bytes)) | ||
1317 | + return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); | ||
1318 | + | ||
1319 | + data->row_bytes >>= 3; | ||
1320 | + } | ||
1321 | |||
1322 | #ifndef GRUB_CPU_WORDS_BIGENDIAN | ||
1323 | if (data->is_16bit || data->is_gray || data->is_palette) | ||
1324 | -- | ||
1325 | 2.14.4 | ||
1326 | |||