mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 21:21:41 +00:00
\n
-----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEq1nRK9aeMoq1VSgcnJ2qBz9kQNkFAmaX3kgACgkQnJ2qBz9k QNnvxQgAtLLYyHnK9cF0UUCyLo9BwFU7jiOBnM1NCSlUjE2Z8JTKwhDOAkQNyua5 0q5afk5hl5uopazA2DQZgc9UvRDfo94uGhH4Qz9t1cJ08z+hGglD473NHSb6jjE8 Ibc6iUFKlmZ5jAD1n+6RBY5YJTpFYtS4bxBegx7aw7WdAFQOrQAc0zfmj0xw/Pzc yQUxABw/mSIQAoGSZ3iagZ8tYWaKlTn0vm0HAcqesyZ0ruYGV4DFw8SPyBWaENvw ViAyZa/qntC4sfWCKqla0TluutnET9ZfoASttPNfY6bcYAJGGRAkueIMugQWcoCE jw2vgtaYTCiCAyCFaRHO74v7AcUSKg== =Ol3a -----END PGP SIGNATURE----- Merge tag 'fs_for_v6.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs Pull udf, ext2, isofs fixes and cleanups from Jan Kara: - A few UDF cleanups and fixes for handling corrupted filesystems - ext2 fix for handling of corrupted filesystem - isofs module description - jbd2 module description * tag 'fs_for_v6.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: ext2: Verify bitmap and itable block numbers before using them udf: prevent integer overflow in udf_bitmap_free_blocks() udf: Avoid excessive partition lengths udf: Drop load_block_bitmap() wrapper udf: Avoid using corrupted block bitmap buffer udf: Fix bogus checksum computation in udf_rename() udf: Fix lock ordering in udf_evict_inode() udf: Drop pointless IS_IMMUTABLE and IS_APPEND check isofs: add missing MODULE_DESCRIPTION() jbd2: add missing MODULE_DESCRIPTION()
This commit is contained in:
commit
8b0f0bb27c
@ -77,26 +77,33 @@ static int ext2_valid_block_bitmap(struct super_block *sb,
|
||||
ext2_grpblk_t next_zero_bit;
|
||||
ext2_fsblk_t bitmap_blk;
|
||||
ext2_fsblk_t group_first_block;
|
||||
ext2_grpblk_t max_bit;
|
||||
|
||||
group_first_block = ext2_group_first_block_no(sb, block_group);
|
||||
max_bit = ext2_group_last_block_no(sb, block_group) - group_first_block;
|
||||
|
||||
/* check whether block bitmap block number is set */
|
||||
bitmap_blk = le32_to_cpu(desc->bg_block_bitmap);
|
||||
offset = bitmap_blk - group_first_block;
|
||||
if (!ext2_test_bit(offset, bh->b_data))
|
||||
if (offset < 0 || offset > max_bit ||
|
||||
!ext2_test_bit(offset, bh->b_data))
|
||||
/* bad block bitmap */
|
||||
goto err_out;
|
||||
|
||||
/* check whether the inode bitmap block number is set */
|
||||
bitmap_blk = le32_to_cpu(desc->bg_inode_bitmap);
|
||||
offset = bitmap_blk - group_first_block;
|
||||
if (!ext2_test_bit(offset, bh->b_data))
|
||||
if (offset < 0 || offset > max_bit ||
|
||||
!ext2_test_bit(offset, bh->b_data))
|
||||
/* bad block bitmap */
|
||||
goto err_out;
|
||||
|
||||
/* check whether the inode table block number is set */
|
||||
bitmap_blk = le32_to_cpu(desc->bg_inode_table);
|
||||
offset = bitmap_blk - group_first_block;
|
||||
if (offset < 0 || offset > max_bit ||
|
||||
offset + EXT2_SB(sb)->s_itb_per_group - 1 > max_bit)
|
||||
goto err_out;
|
||||
next_zero_bit = ext2_find_next_zero_bit(bh->b_data,
|
||||
offset + EXT2_SB(sb)->s_itb_per_group,
|
||||
offset);
|
||||
|
@ -1617,4 +1617,5 @@ static void __exit exit_iso9660_fs(void)
|
||||
|
||||
module_init(init_iso9660_fs)
|
||||
module_exit(exit_iso9660_fs)
|
||||
MODULE_DESCRIPTION("ISO 9660 CDROM file system support");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -3181,6 +3181,7 @@ static void __exit journal_exit(void)
|
||||
jbd2_journal_destroy_caches();
|
||||
}
|
||||
|
||||
MODULE_DESCRIPTION("Generic filesystem journal-writing module");
|
||||
MODULE_LICENSE("GPL");
|
||||
module_init(journal_init);
|
||||
module_exit(journal_exit);
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "udfdecl.h"
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/overflow.h>
|
||||
|
||||
#include "udf_i.h"
|
||||
#include "udf_sb.h"
|
||||
@ -64,14 +65,18 @@ static int read_block_bitmap(struct super_block *sb,
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
if (udf_test_bit(i + off, bh->b_data))
|
||||
if (udf_test_bit(i + off, bh->b_data)) {
|
||||
bitmap->s_block_bitmap[bitmap_nr] =
|
||||
ERR_PTR(-EFSCORRUPTED);
|
||||
brelse(bh);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __load_block_bitmap(struct super_block *sb,
|
||||
struct udf_bitmap *bitmap,
|
||||
unsigned int block_group)
|
||||
static int load_block_bitmap(struct super_block *sb,
|
||||
struct udf_bitmap *bitmap,
|
||||
unsigned int block_group)
|
||||
{
|
||||
int retval = 0;
|
||||
int nr_groups = bitmap->s_nr_groups;
|
||||
@ -81,8 +86,15 @@ static int __load_block_bitmap(struct super_block *sb,
|
||||
block_group, nr_groups);
|
||||
}
|
||||
|
||||
if (bitmap->s_block_bitmap[block_group])
|
||||
if (bitmap->s_block_bitmap[block_group]) {
|
||||
/*
|
||||
* The bitmap failed verification in the past. No point in
|
||||
* trying again.
|
||||
*/
|
||||
if (IS_ERR(bitmap->s_block_bitmap[block_group]))
|
||||
return PTR_ERR(bitmap->s_block_bitmap[block_group]);
|
||||
return block_group;
|
||||
}
|
||||
|
||||
retval = read_block_bitmap(sb, bitmap, block_group, block_group);
|
||||
if (retval < 0)
|
||||
@ -91,23 +103,6 @@ static int __load_block_bitmap(struct super_block *sb,
|
||||
return block_group;
|
||||
}
|
||||
|
||||
static inline int load_block_bitmap(struct super_block *sb,
|
||||
struct udf_bitmap *bitmap,
|
||||
unsigned int block_group)
|
||||
{
|
||||
int slot;
|
||||
|
||||
slot = __load_block_bitmap(sb, bitmap, block_group);
|
||||
|
||||
if (slot < 0)
|
||||
return slot;
|
||||
|
||||
if (!bitmap->s_block_bitmap[slot])
|
||||
return -EIO;
|
||||
|
||||
return slot;
|
||||
}
|
||||
|
||||
static void udf_add_free_space(struct super_block *sb, u16 partition, u32 cnt)
|
||||
{
|
||||
struct udf_sb_info *sbi = UDF_SB(sb);
|
||||
@ -129,7 +124,6 @@ static void udf_bitmap_free_blocks(struct super_block *sb,
|
||||
{
|
||||
struct udf_sb_info *sbi = UDF_SB(sb);
|
||||
struct buffer_head *bh = NULL;
|
||||
struct udf_part_map *partmap;
|
||||
unsigned long block;
|
||||
unsigned long block_group;
|
||||
unsigned long bit;
|
||||
@ -138,19 +132,9 @@ static void udf_bitmap_free_blocks(struct super_block *sb,
|
||||
unsigned long overflow;
|
||||
|
||||
mutex_lock(&sbi->s_alloc_mutex);
|
||||
partmap = &sbi->s_partmaps[bloc->partitionReferenceNum];
|
||||
if (bloc->logicalBlockNum + count < count ||
|
||||
(bloc->logicalBlockNum + count) > partmap->s_partition_len) {
|
||||
udf_debug("%u < %d || %u + %u > %u\n",
|
||||
bloc->logicalBlockNum, 0,
|
||||
bloc->logicalBlockNum, count,
|
||||
partmap->s_partition_len);
|
||||
goto error_return;
|
||||
}
|
||||
|
||||
/* We make sure this cannot overflow when mounting the filesystem */
|
||||
block = bloc->logicalBlockNum + offset +
|
||||
(sizeof(struct spaceBitmapDesc) << 3);
|
||||
|
||||
do {
|
||||
overflow = 0;
|
||||
block_group = block >> (sb->s_blocksize_bits + 3);
|
||||
@ -380,7 +364,6 @@ static void udf_table_free_blocks(struct super_block *sb,
|
||||
uint32_t count)
|
||||
{
|
||||
struct udf_sb_info *sbi = UDF_SB(sb);
|
||||
struct udf_part_map *partmap;
|
||||
uint32_t start, end;
|
||||
uint32_t elen;
|
||||
struct kernel_lb_addr eloc;
|
||||
@ -389,16 +372,6 @@ static void udf_table_free_blocks(struct super_block *sb,
|
||||
struct udf_inode_info *iinfo;
|
||||
|
||||
mutex_lock(&sbi->s_alloc_mutex);
|
||||
partmap = &sbi->s_partmaps[bloc->partitionReferenceNum];
|
||||
if (bloc->logicalBlockNum + count < count ||
|
||||
(bloc->logicalBlockNum + count) > partmap->s_partition_len) {
|
||||
udf_debug("%u < %d || %u + %u > %u\n",
|
||||
bloc->logicalBlockNum, 0,
|
||||
bloc->logicalBlockNum, count,
|
||||
partmap->s_partition_len);
|
||||
goto error_return;
|
||||
}
|
||||
|
||||
iinfo = UDF_I(table);
|
||||
udf_add_free_space(sb, sbi->s_partition, count);
|
||||
|
||||
@ -673,6 +646,17 @@ void udf_free_blocks(struct super_block *sb, struct inode *inode,
|
||||
{
|
||||
uint16_t partition = bloc->partitionReferenceNum;
|
||||
struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition];
|
||||
uint32_t blk;
|
||||
|
||||
if (check_add_overflow(bloc->logicalBlockNum, offset, &blk) ||
|
||||
check_add_overflow(blk, count, &blk) ||
|
||||
bloc->logicalBlockNum + count > map->s_partition_len) {
|
||||
udf_debug("Invalid request to free blocks: (%d, %u), off %u, "
|
||||
"len %u, partition len %u\n",
|
||||
partition, bloc->logicalBlockNum, offset, count,
|
||||
map->s_partition_len);
|
||||
return;
|
||||
}
|
||||
|
||||
if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) {
|
||||
udf_bitmap_free_blocks(sb, map->s_uspace.s_bitmap,
|
||||
|
@ -232,7 +232,9 @@ static int udf_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
|
||||
|
||||
if ((attr->ia_valid & ATTR_SIZE) &&
|
||||
attr->ia_size != i_size_read(inode)) {
|
||||
filemap_invalidate_lock(inode->i_mapping);
|
||||
error = udf_setsize(inode, attr->ia_size);
|
||||
filemap_invalidate_unlock(inode->i_mapping);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
@ -1247,10 +1247,7 @@ int udf_setsize(struct inode *inode, loff_t newsize)
|
||||
if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
|
||||
S_ISLNK(inode->i_mode)))
|
||||
return -EINVAL;
|
||||
if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
|
||||
return -EPERM;
|
||||
|
||||
filemap_invalidate_lock(inode->i_mapping);
|
||||
iinfo = UDF_I(inode);
|
||||
if (newsize > inode->i_size) {
|
||||
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
|
||||
@ -1263,11 +1260,11 @@ int udf_setsize(struct inode *inode, loff_t newsize)
|
||||
}
|
||||
err = udf_expand_file_adinicb(inode);
|
||||
if (err)
|
||||
goto out_unlock;
|
||||
return err;
|
||||
}
|
||||
err = udf_extend_file(inode, newsize);
|
||||
if (err)
|
||||
goto out_unlock;
|
||||
return err;
|
||||
set_size:
|
||||
truncate_setsize(inode, newsize);
|
||||
} else {
|
||||
@ -1285,14 +1282,14 @@ set_size:
|
||||
err = block_truncate_page(inode->i_mapping, newsize,
|
||||
udf_get_block);
|
||||
if (err)
|
||||
goto out_unlock;
|
||||
return err;
|
||||
truncate_setsize(inode, newsize);
|
||||
down_write(&iinfo->i_data_sem);
|
||||
udf_clear_extent_cache(inode);
|
||||
err = udf_truncate_extents(inode);
|
||||
up_write(&iinfo->i_data_sem);
|
||||
if (err)
|
||||
goto out_unlock;
|
||||
return err;
|
||||
}
|
||||
update_time:
|
||||
inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode));
|
||||
@ -1300,8 +1297,6 @@ update_time:
|
||||
udf_sync_inode(inode);
|
||||
else
|
||||
mark_inode_dirty(inode);
|
||||
out_unlock:
|
||||
filemap_invalidate_unlock(inode->i_mapping);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -876,8 +876,6 @@ static int udf_rename(struct mnt_idmap *idmap, struct inode *old_dir,
|
||||
if (has_diriter) {
|
||||
diriter.fi.icb.extLocation =
|
||||
cpu_to_lelb(UDF_I(new_dir)->i_location);
|
||||
udf_update_tag((char *)&diriter.fi,
|
||||
udf_dir_entry_len(&diriter.fi));
|
||||
udf_fiiter_write_fi(&diriter, NULL);
|
||||
udf_fiiter_release(&diriter);
|
||||
}
|
||||
|
@ -336,7 +336,8 @@ static void udf_sb_free_bitmap(struct udf_bitmap *bitmap)
|
||||
int nr_groups = bitmap->s_nr_groups;
|
||||
|
||||
for (i = 0; i < nr_groups; i++)
|
||||
brelse(bitmap->s_block_bitmap[i]);
|
||||
if (!IS_ERR_OR_NULL(bitmap->s_block_bitmap[i]))
|
||||
brelse(bitmap->s_block_bitmap[i]);
|
||||
|
||||
kvfree(bitmap);
|
||||
}
|
||||
@ -1110,12 +1111,19 @@ static int udf_fill_partdesc_info(struct super_block *sb,
|
||||
struct udf_part_map *map;
|
||||
struct udf_sb_info *sbi = UDF_SB(sb);
|
||||
struct partitionHeaderDesc *phd;
|
||||
u32 sum;
|
||||
int err;
|
||||
|
||||
map = &sbi->s_partmaps[p_index];
|
||||
|
||||
map->s_partition_len = le32_to_cpu(p->partitionLength); /* blocks */
|
||||
map->s_partition_root = le32_to_cpu(p->partitionStartingLocation);
|
||||
if (check_add_overflow(map->s_partition_root, map->s_partition_len,
|
||||
&sum)) {
|
||||
udf_err(sb, "Partition %d has invalid location %u + %u\n",
|
||||
p_index, map->s_partition_root, map->s_partition_len);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
if (p->accessType == cpu_to_le32(PD_ACCESS_TYPE_READ_ONLY))
|
||||
map->s_partition_flags |= UDF_PART_FLAG_READ_ONLY;
|
||||
@ -1171,6 +1179,14 @@ static int udf_fill_partdesc_info(struct super_block *sb,
|
||||
bitmap->s_extPosition = le32_to_cpu(
|
||||
phd->unallocSpaceBitmap.extPosition);
|
||||
map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_BITMAP;
|
||||
/* Check whether math over bitmap won't overflow. */
|
||||
if (check_add_overflow(map->s_partition_len,
|
||||
sizeof(struct spaceBitmapDesc) << 3,
|
||||
&sum)) {
|
||||
udf_err(sb, "Partition %d is too long (%u)\n", p_index,
|
||||
map->s_partition_len);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
udf_debug("unallocSpaceBitmap (part %d) @ %u\n",
|
||||
p_index, bitmap->s_extPosition);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user