Fix control flow issues and null pointer dereferences.
Signed-off-by: Joao Marcos Costa <jmcosta944@gmail.com>
header = get_unaligned_le16(metadata_buffer + table_offset);
metadata = metadata_buffer + table_offset + SQFS_HEADER_SIZE;
header = get_unaligned_le16(metadata_buffer + table_offset);
metadata = metadata_buffer + table_offset + SQFS_HEADER_SIZE;
+ if (!metadata || !header) {
ret = -ENOMEM;
goto free_buffer;
}
ret = -ENOMEM;
goto free_buffer;
}
{
struct squashfs_super_block *sblk = ctxt.sblk;
char *path, *target, **sym_tokens, *res, *rem;
{
struct squashfs_super_block *sblk = ctxt.sblk;
char *path, *target, **sym_tokens, *res, *rem;
- struct squashfs_ldir_inode *ldir = NULL;
int j, ret, new_inode_number, offset;
struct squashfs_symlink_inode *sym;
int j, ret, new_inode_number, offset;
struct squashfs_symlink_inode *sym;
+ struct squashfs_ldir_inode *ldir;
struct squashfs_dir_inode *dir;
struct fs_dir_stream *dirsp;
struct fs_dirent *dent;
struct squashfs_dir_inode *dir;
struct fs_dir_stream *dirsp;
struct fs_dirent *dent;
table = sqfs_find_inode(dirs->inode_table, le32_to_cpu(sblk->inodes),
sblk->inodes, sblk->block_size);
table = sqfs_find_inode(dirs->inode_table, le32_to_cpu(sblk->inodes),
sblk->inodes, sblk->block_size);
- /* root is a regular directory, not an extended one */
dir = (struct squashfs_dir_inode *)table;
dir = (struct squashfs_dir_inode *)table;
+ ldir = (struct squashfs_ldir_inode *)table;
/* get directory offset in directory table */
offset = sqfs_dir_offset(table, m_list, m_count);
/* get directory offset in directory table */
offset = sqfs_dir_offset(table, m_list, m_count);
finfo->start = get_unaligned_le32(®->start_block);
finfo->frag = SQFS_IS_FRAGMENTED(get_unaligned_le32(®->fragment));
finfo->start = get_unaligned_le32(®->start_block);
finfo->frag = SQFS_IS_FRAGMENTED(get_unaligned_le32(®->fragment));
- if (finfo->size < 1 || finfo->offset < 0 || finfo->start < 0)
+ if (finfo->frag && finfo->offset == 0xFFFFFFFF)
+ return -EINVAL;
+
+ if (finfo->size < 1 || finfo->start == 0xFFFFFFFF)
return -EINVAL;
if (finfo->frag) {
return -EINVAL;
if (finfo->frag) {
if (ret < 0)
return -EINVAL;
finfo->comp = true;
if (ret < 0)
return -EINVAL;
finfo->comp = true;
- if (fentry->size < 1 || fentry->start < 0)
+ if (fentry->size < 1 || fentry->start == 0x7FFFFFFF)
return -EINVAL;
} else {
datablk_count = DIV_ROUND_UP(finfo->size, le32_to_cpu(blksz));
return -EINVAL;
} else {
datablk_count = DIV_ROUND_UP(finfo->size, le32_to_cpu(blksz));
finfo->start = get_unaligned_le64(&lreg->start_block);
finfo->frag = SQFS_IS_FRAGMENTED(get_unaligned_le32(&lreg->fragment));
finfo->start = get_unaligned_le64(&lreg->start_block);
finfo->frag = SQFS_IS_FRAGMENTED(get_unaligned_le32(&lreg->fragment));
- if (finfo->size < 1 || finfo->offset < 0 || finfo->start < 0)
+ if (finfo->frag && finfo->offset == 0xFFFFFFFF)
+ return -EINVAL;
+
+ if (finfo->size < 1 || finfo->start == 0x7FFFFFFF)
return -EINVAL;
if (finfo->frag) {
return -EINVAL;
if (finfo->frag) {
if (ret < 0)
return -EINVAL;
finfo->comp = true;
if (ret < 0)
return -EINVAL;
finfo->comp = true;
- if (fentry->size < 1 || fentry->start < 0)
+ if (fentry->size < 1 || fentry->start == 0x7FFFFFFF)
return -EINVAL;
} else {
datablk_count = DIV_ROUND_UP(finfo->size, le32_to_cpu(blksz));
return -EINVAL;
} else {
datablk_count = DIV_ROUND_UP(finfo->size, le32_to_cpu(blksz));
struct squashfs_ldir_inode *ldir;
struct squashfs_dir_inode *dir;
u32 start_block;
struct squashfs_ldir_inode *ldir;
struct squashfs_dir_inode *dir;
u32 start_block;
switch (get_unaligned_le16(&base->inode_type)) {
case SQFS_DIR_TYPE:
switch (get_unaligned_le16(&base->inode_type)) {
case SQFS_DIR_TYPE:
u16 header;
data = file_mapping + offset;
u16 header;
data = file_mapping + offset;
+ if (!data)
+ return -EFAULT;
+
header = get_unaligned((u16 *)data);
header = get_unaligned((u16 *)data);
return -EINVAL;
*compressed = SQFS_COMPRESSED_METADATA(header);
return -EINVAL;
*compressed = SQFS_COMPRESSED_METADATA(header);