malloc: Use overflow checking primitives where we do complex allocations
This attempts to fix the places where we do the following where arithmetic_expr may include unvalidated data: X = grub_malloc(arithmetic_expr); It accomplishes this by doing the arithmetic ahead of time using grub_add(), grub_sub(), grub_mul() and testing for overflow before proceeding. Among other issues, this fixes: - allocation of integer overflow in grub_video_bitmap_create() reported by Chris Coulson, - allocation of integer overflow in grub_png_decode_image_header() reported by Chris Coulson, - allocation of integer overflow in grub_squash_read_symlink() reported by Chris Coulson, - allocation of integer overflow in grub_ext2_read_symlink() reported by Chris Coulson, - allocation of integer overflow in read_section_as_string() reported by Chris Coulson. Fixes: CVE-2020-14309, CVE-2020-14310, CVE-2020-14311 Signed-off-by: Peter Jones <pjones@redhat.com> Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This commit is contained in:
parent
f725fa7cb2
commit
3f05d693d1
23 changed files with 382 additions and 113 deletions
|
@ -26,6 +26,7 @@
|
|||
#include <grub/types.h>
|
||||
#include <grub/fshelp.h>
|
||||
#include <grub/charset.h>
|
||||
#include <grub/safemath.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
|
@ -307,10 +308,15 @@ grub_sfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
|||
if (node->cache && node->cache_size >= node->cache_allocated)
|
||||
{
|
||||
struct cache_entry *e = node->cache;
|
||||
e = grub_realloc (node->cache,node->cache_allocated * 2
|
||||
* sizeof (e[0]));
|
||||
grub_size_t sz;
|
||||
|
||||
if (grub_mul (node->cache_allocated, 2 * sizeof (e[0]), &sz))
|
||||
goto fail;
|
||||
|
||||
e = grub_realloc (node->cache, sz);
|
||||
if (!e)
|
||||
{
|
||||
fail:
|
||||
grub_errno = 0;
|
||||
grub_free (node->cache);
|
||||
node->cache = 0;
|
||||
|
@ -477,10 +483,16 @@ grub_sfs_create_node (struct grub_fshelp_node **node,
|
|||
grub_size_t len = grub_strlen (name);
|
||||
grub_uint8_t *name_u8;
|
||||
int ret;
|
||||
grub_size_t sz;
|
||||
|
||||
if (grub_mul (len, GRUB_MAX_UTF8_PER_LATIN1, &sz) ||
|
||||
grub_add (sz, 1, &sz))
|
||||
return 1;
|
||||
|
||||
*node = grub_malloc (sizeof (**node));
|
||||
if (!*node)
|
||||
return 1;
|
||||
name_u8 = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1);
|
||||
name_u8 = grub_malloc (sz);
|
||||
if (!name_u8)
|
||||
{
|
||||
grub_free (*node);
|
||||
|
@ -724,8 +736,13 @@ grub_sfs_label (grub_device_t device, char **label)
|
|||
data = grub_sfs_mount (disk);
|
||||
if (data)
|
||||
{
|
||||
grub_size_t len = grub_strlen (data->label);
|
||||
*label = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1);
|
||||
grub_size_t sz, len = grub_strlen (data->label);
|
||||
|
||||
if (grub_mul (len, GRUB_MAX_UTF8_PER_LATIN1, &sz) ||
|
||||
grub_add (sz, 1, &sz))
|
||||
return GRUB_ERR_OUT_OF_RANGE;
|
||||
|
||||
*label = grub_malloc (sz);
|
||||
if (*label)
|
||||
*grub_latin1_to_utf8 ((grub_uint8_t *) *label,
|
||||
(const grub_uint8_t *) data->label,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue