mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-26 23:41:50 +00:00
fs/squashfs: fix potential integer overflows
The length of buffers used to read inode tables, directory tables, and reading a file are calculated as: number of blocks * block size, and such plain multiplication is prone to overflowing (thus unsafe). Replace it by __builtin_mul_overflow, i.e. safe math. Signed-off-by: Joao Marcos Costa <joaomarcos.costa@bootlin.com>
This commit is contained in:
parent
5061eab96a
commit
59fd62d71c
1 changed files with 15 additions and 3 deletions
|
@ -719,6 +719,7 @@ static int sqfs_read_inode_table(unsigned char **inode_table)
|
||||||
u32 src_len, dest_offset = 0;
|
u32 src_len, dest_offset = 0;
|
||||||
unsigned long dest_len = 0;
|
unsigned long dest_len = 0;
|
||||||
bool compressed;
|
bool compressed;
|
||||||
|
size_t buf_size;
|
||||||
|
|
||||||
table_size = get_unaligned_le64(&sblk->directory_table_start) -
|
table_size = get_unaligned_le64(&sblk->directory_table_start) -
|
||||||
get_unaligned_le64(&sblk->inode_table_start);
|
get_unaligned_le64(&sblk->inode_table_start);
|
||||||
|
@ -728,7 +729,10 @@ static int sqfs_read_inode_table(unsigned char **inode_table)
|
||||||
sblk->directory_table_start, &table_offset);
|
sblk->directory_table_start, &table_offset);
|
||||||
|
|
||||||
/* Allocate a proper sized buffer (itb) to store the inode table */
|
/* Allocate a proper sized buffer (itb) to store the inode table */
|
||||||
itb = malloc_cache_aligned(n_blks * ctxt.cur_dev->blksz);
|
if (__builtin_mul_overflow(n_blks, ctxt.cur_dev->blksz, &buf_size))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
itb = malloc_cache_aligned(buf_size);
|
||||||
if (!itb)
|
if (!itb)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
@ -806,6 +810,7 @@ static int sqfs_read_directory_table(unsigned char **dir_table, u32 **pos_list)
|
||||||
u32 src_len, dest_offset = 0;
|
u32 src_len, dest_offset = 0;
|
||||||
unsigned long dest_len = 0;
|
unsigned long dest_len = 0;
|
||||||
bool compressed;
|
bool compressed;
|
||||||
|
size_t buf_size;
|
||||||
|
|
||||||
*dir_table = NULL;
|
*dir_table = NULL;
|
||||||
*pos_list = NULL;
|
*pos_list = NULL;
|
||||||
|
@ -818,7 +823,10 @@ static int sqfs_read_directory_table(unsigned char **dir_table, u32 **pos_list)
|
||||||
sblk->fragment_table_start, &table_offset);
|
sblk->fragment_table_start, &table_offset);
|
||||||
|
|
||||||
/* Allocate a proper sized buffer (dtb) to store the directory table */
|
/* Allocate a proper sized buffer (dtb) to store the directory table */
|
||||||
dtb = malloc_cache_aligned(n_blks * ctxt.cur_dev->blksz);
|
if (__builtin_mul_overflow(n_blks, ctxt.cur_dev->blksz, &buf_size))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
dtb = malloc_cache_aligned(buf_size);
|
||||||
if (!dtb)
|
if (!dtb)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
@ -1369,6 +1377,7 @@ static int sqfs_read_nest(const char *filename, void *buf, loff_t offset,
|
||||||
unsigned long dest_len;
|
unsigned long dest_len;
|
||||||
struct fs_dirent *dent;
|
struct fs_dirent *dent;
|
||||||
unsigned char *ipos;
|
unsigned char *ipos;
|
||||||
|
size_t buf_size;
|
||||||
|
|
||||||
*actread = 0;
|
*actread = 0;
|
||||||
|
|
||||||
|
@ -1573,7 +1582,10 @@ static int sqfs_read_nest(const char *filename, void *buf, loff_t offset,
|
||||||
table_offset = frag_entry.start - (start * ctxt.cur_dev->blksz);
|
table_offset = frag_entry.start - (start * ctxt.cur_dev->blksz);
|
||||||
n_blks = DIV_ROUND_UP(table_size + table_offset, ctxt.cur_dev->blksz);
|
n_blks = DIV_ROUND_UP(table_size + table_offset, ctxt.cur_dev->blksz);
|
||||||
|
|
||||||
fragment = malloc_cache_aligned(n_blks * ctxt.cur_dev->blksz);
|
if (__builtin_mul_overflow(n_blks, ctxt.cur_dev->blksz, &buf_size))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
fragment = malloc_cache_aligned(buf_size);
|
||||||
|
|
||||||
if (!fragment) {
|
if (!fragment) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
|
|
Loading…
Add table
Reference in a new issue