Skip to content

Commit 8b0f0bb

Browse files
committed
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()
2 parents d601832 + 322a6af commit 8b0f0bb

File tree

8 files changed

+63
-59
lines changed

8 files changed

+63
-59
lines changed

fs/ext2/balloc.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,26 +77,33 @@ static int ext2_valid_block_bitmap(struct super_block *sb,
7777
ext2_grpblk_t next_zero_bit;
7878
ext2_fsblk_t bitmap_blk;
7979
ext2_fsblk_t group_first_block;
80+
ext2_grpblk_t max_bit;
8081

8182
group_first_block = ext2_group_first_block_no(sb, block_group);
83+
max_bit = ext2_group_last_block_no(sb, block_group) - group_first_block;
8284

8385
/* check whether block bitmap block number is set */
8486
bitmap_blk = le32_to_cpu(desc->bg_block_bitmap);
8587
offset = bitmap_blk - group_first_block;
86-
if (!ext2_test_bit(offset, bh->b_data))
88+
if (offset < 0 || offset > max_bit ||
89+
!ext2_test_bit(offset, bh->b_data))
8790
/* bad block bitmap */
8891
goto err_out;
8992

9093
/* check whether the inode bitmap block number is set */
9194
bitmap_blk = le32_to_cpu(desc->bg_inode_bitmap);
9295
offset = bitmap_blk - group_first_block;
93-
if (!ext2_test_bit(offset, bh->b_data))
96+
if (offset < 0 || offset > max_bit ||
97+
!ext2_test_bit(offset, bh->b_data))
9498
/* bad block bitmap */
9599
goto err_out;
96100

97101
/* check whether the inode table block number is set */
98102
bitmap_blk = le32_to_cpu(desc->bg_inode_table);
99103
offset = bitmap_blk - group_first_block;
104+
if (offset < 0 || offset > max_bit ||
105+
offset + EXT2_SB(sb)->s_itb_per_group - 1 > max_bit)
106+
goto err_out;
100107
next_zero_bit = ext2_find_next_zero_bit(bh->b_data,
101108
offset + EXT2_SB(sb)->s_itb_per_group,
102109
offset);

fs/isofs/inode.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1617,4 +1617,5 @@ static void __exit exit_iso9660_fs(void)
16171617

16181618
module_init(init_iso9660_fs)
16191619
module_exit(exit_iso9660_fs)
1620+
MODULE_DESCRIPTION("ISO 9660 CDROM file system support");
16201621
MODULE_LICENSE("GPL");

fs/jbd2/journal.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3181,6 +3181,7 @@ static void __exit journal_exit(void)
31813181
jbd2_journal_destroy_caches();
31823182
}
31833183

3184+
MODULE_DESCRIPTION("Generic filesystem journal-writing module");
31843185
MODULE_LICENSE("GPL");
31853186
module_init(journal_init);
31863187
module_exit(journal_exit);

fs/udf/balloc.c

Lines changed: 29 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "udfdecl.h"
1919

2020
#include <linux/bitops.h>
21+
#include <linux/overflow.h>
2122

2223
#include "udf_i.h"
2324
#include "udf_sb.h"
@@ -64,14 +65,18 @@ static int read_block_bitmap(struct super_block *sb,
6465
}
6566

6667
for (i = 0; i < count; i++)
67-
if (udf_test_bit(i + off, bh->b_data))
68+
if (udf_test_bit(i + off, bh->b_data)) {
69+
bitmap->s_block_bitmap[bitmap_nr] =
70+
ERR_PTR(-EFSCORRUPTED);
71+
brelse(bh);
6872
return -EFSCORRUPTED;
73+
}
6974
return 0;
7075
}
7176

72-
static int __load_block_bitmap(struct super_block *sb,
73-
struct udf_bitmap *bitmap,
74-
unsigned int block_group)
77+
static int load_block_bitmap(struct super_block *sb,
78+
struct udf_bitmap *bitmap,
79+
unsigned int block_group)
7580
{
7681
int retval = 0;
7782
int nr_groups = bitmap->s_nr_groups;
@@ -81,8 +86,15 @@ static int __load_block_bitmap(struct super_block *sb,
8186
block_group, nr_groups);
8287
}
8388

84-
if (bitmap->s_block_bitmap[block_group])
89+
if (bitmap->s_block_bitmap[block_group]) {
90+
/*
91+
* The bitmap failed verification in the past. No point in
92+
* trying again.
93+
*/
94+
if (IS_ERR(bitmap->s_block_bitmap[block_group]))
95+
return PTR_ERR(bitmap->s_block_bitmap[block_group]);
8596
return block_group;
97+
}
8698

8799
retval = read_block_bitmap(sb, bitmap, block_group, block_group);
88100
if (retval < 0)
@@ -91,23 +103,6 @@ static int __load_block_bitmap(struct super_block *sb,
91103
return block_group;
92104
}
93105

94-
static inline int load_block_bitmap(struct super_block *sb,
95-
struct udf_bitmap *bitmap,
96-
unsigned int block_group)
97-
{
98-
int slot;
99-
100-
slot = __load_block_bitmap(sb, bitmap, block_group);
101-
102-
if (slot < 0)
103-
return slot;
104-
105-
if (!bitmap->s_block_bitmap[slot])
106-
return -EIO;
107-
108-
return slot;
109-
}
110-
111106
static void udf_add_free_space(struct super_block *sb, u16 partition, u32 cnt)
112107
{
113108
struct udf_sb_info *sbi = UDF_SB(sb);
@@ -129,7 +124,6 @@ static void udf_bitmap_free_blocks(struct super_block *sb,
129124
{
130125
struct udf_sb_info *sbi = UDF_SB(sb);
131126
struct buffer_head *bh = NULL;
132-
struct udf_part_map *partmap;
133127
unsigned long block;
134128
unsigned long block_group;
135129
unsigned long bit;
@@ -138,19 +132,9 @@ static void udf_bitmap_free_blocks(struct super_block *sb,
138132
unsigned long overflow;
139133

140134
mutex_lock(&sbi->s_alloc_mutex);
141-
partmap = &sbi->s_partmaps[bloc->partitionReferenceNum];
142-
if (bloc->logicalBlockNum + count < count ||
143-
(bloc->logicalBlockNum + count) > partmap->s_partition_len) {
144-
udf_debug("%u < %d || %u + %u > %u\n",
145-
bloc->logicalBlockNum, 0,
146-
bloc->logicalBlockNum, count,
147-
partmap->s_partition_len);
148-
goto error_return;
149-
}
150-
135+
/* We make sure this cannot overflow when mounting the filesystem */
151136
block = bloc->logicalBlockNum + offset +
152137
(sizeof(struct spaceBitmapDesc) << 3);
153-
154138
do {
155139
overflow = 0;
156140
block_group = block >> (sb->s_blocksize_bits + 3);
@@ -380,7 +364,6 @@ static void udf_table_free_blocks(struct super_block *sb,
380364
uint32_t count)
381365
{
382366
struct udf_sb_info *sbi = UDF_SB(sb);
383-
struct udf_part_map *partmap;
384367
uint32_t start, end;
385368
uint32_t elen;
386369
struct kernel_lb_addr eloc;
@@ -389,16 +372,6 @@ static void udf_table_free_blocks(struct super_block *sb,
389372
struct udf_inode_info *iinfo;
390373

391374
mutex_lock(&sbi->s_alloc_mutex);
392-
partmap = &sbi->s_partmaps[bloc->partitionReferenceNum];
393-
if (bloc->logicalBlockNum + count < count ||
394-
(bloc->logicalBlockNum + count) > partmap->s_partition_len) {
395-
udf_debug("%u < %d || %u + %u > %u\n",
396-
bloc->logicalBlockNum, 0,
397-
bloc->logicalBlockNum, count,
398-
partmap->s_partition_len);
399-
goto error_return;
400-
}
401-
402375
iinfo = UDF_I(table);
403376
udf_add_free_space(sb, sbi->s_partition, count);
404377

@@ -673,6 +646,17 @@ void udf_free_blocks(struct super_block *sb, struct inode *inode,
673646
{
674647
uint16_t partition = bloc->partitionReferenceNum;
675648
struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition];
649+
uint32_t blk;
650+
651+
if (check_add_overflow(bloc->logicalBlockNum, offset, &blk) ||
652+
check_add_overflow(blk, count, &blk) ||
653+
bloc->logicalBlockNum + count > map->s_partition_len) {
654+
udf_debug("Invalid request to free blocks: (%d, %u), off %u, "
655+
"len %u, partition len %u\n",
656+
partition, bloc->logicalBlockNum, offset, count,
657+
map->s_partition_len);
658+
return;
659+
}
676660

677661
if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) {
678662
udf_bitmap_free_blocks(sb, map->s_uspace.s_bitmap,

fs/udf/file.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,9 @@ static int udf_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
232232

233233
if ((attr->ia_valid & ATTR_SIZE) &&
234234
attr->ia_size != i_size_read(inode)) {
235+
filemap_invalidate_lock(inode->i_mapping);
235236
error = udf_setsize(inode, attr->ia_size);
237+
filemap_invalidate_unlock(inode->i_mapping);
236238
if (error)
237239
return error;
238240
}

fs/udf/inode.c

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,10 +1247,7 @@ int udf_setsize(struct inode *inode, loff_t newsize)
12471247
if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
12481248
S_ISLNK(inode->i_mode)))
12491249
return -EINVAL;
1250-
if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
1251-
return -EPERM;
12521250

1253-
filemap_invalidate_lock(inode->i_mapping);
12541251
iinfo = UDF_I(inode);
12551252
if (newsize > inode->i_size) {
12561253
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
@@ -1263,11 +1260,11 @@ int udf_setsize(struct inode *inode, loff_t newsize)
12631260
}
12641261
err = udf_expand_file_adinicb(inode);
12651262
if (err)
1266-
goto out_unlock;
1263+
return err;
12671264
}
12681265
err = udf_extend_file(inode, newsize);
12691266
if (err)
1270-
goto out_unlock;
1267+
return err;
12711268
set_size:
12721269
truncate_setsize(inode, newsize);
12731270
} else {
@@ -1285,23 +1282,21 @@ int udf_setsize(struct inode *inode, loff_t newsize)
12851282
err = block_truncate_page(inode->i_mapping, newsize,
12861283
udf_get_block);
12871284
if (err)
1288-
goto out_unlock;
1285+
return err;
12891286
truncate_setsize(inode, newsize);
12901287
down_write(&iinfo->i_data_sem);
12911288
udf_clear_extent_cache(inode);
12921289
err = udf_truncate_extents(inode);
12931290
up_write(&iinfo->i_data_sem);
12941291
if (err)
1295-
goto out_unlock;
1292+
return err;
12961293
}
12971294
update_time:
12981295
inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode));
12991296
if (IS_SYNC(inode))
13001297
udf_sync_inode(inode);
13011298
else
13021299
mark_inode_dirty(inode);
1303-
out_unlock:
1304-
filemap_invalidate_unlock(inode->i_mapping);
13051300
return err;
13061301
}
13071302

fs/udf/namei.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -876,8 +876,6 @@ static int udf_rename(struct mnt_idmap *idmap, struct inode *old_dir,
876876
if (has_diriter) {
877877
diriter.fi.icb.extLocation =
878878
cpu_to_lelb(UDF_I(new_dir)->i_location);
879-
udf_update_tag((char *)&diriter.fi,
880-
udf_dir_entry_len(&diriter.fi));
881879
udf_fiiter_write_fi(&diriter, NULL);
882880
udf_fiiter_release(&diriter);
883881
}

fs/udf/super.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,8 @@ static void udf_sb_free_bitmap(struct udf_bitmap *bitmap)
336336
int nr_groups = bitmap->s_nr_groups;
337337

338338
for (i = 0; i < nr_groups; i++)
339-
brelse(bitmap->s_block_bitmap[i]);
339+
if (!IS_ERR_OR_NULL(bitmap->s_block_bitmap[i]))
340+
brelse(bitmap->s_block_bitmap[i]);
340341

341342
kvfree(bitmap);
342343
}
@@ -1110,12 +1111,19 @@ static int udf_fill_partdesc_info(struct super_block *sb,
11101111
struct udf_part_map *map;
11111112
struct udf_sb_info *sbi = UDF_SB(sb);
11121113
struct partitionHeaderDesc *phd;
1114+
u32 sum;
11131115
int err;
11141116

11151117
map = &sbi->s_partmaps[p_index];
11161118

11171119
map->s_partition_len = le32_to_cpu(p->partitionLength); /* blocks */
11181120
map->s_partition_root = le32_to_cpu(p->partitionStartingLocation);
1121+
if (check_add_overflow(map->s_partition_root, map->s_partition_len,
1122+
&sum)) {
1123+
udf_err(sb, "Partition %d has invalid location %u + %u\n",
1124+
p_index, map->s_partition_root, map->s_partition_len);
1125+
return -EFSCORRUPTED;
1126+
}
11191127

11201128
if (p->accessType == cpu_to_le32(PD_ACCESS_TYPE_READ_ONLY))
11211129
map->s_partition_flags |= UDF_PART_FLAG_READ_ONLY;
@@ -1171,6 +1179,14 @@ static int udf_fill_partdesc_info(struct super_block *sb,
11711179
bitmap->s_extPosition = le32_to_cpu(
11721180
phd->unallocSpaceBitmap.extPosition);
11731181
map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_BITMAP;
1182+
/* Check whether math over bitmap won't overflow. */
1183+
if (check_add_overflow(map->s_partition_len,
1184+
sizeof(struct spaceBitmapDesc) << 3,
1185+
&sum)) {
1186+
udf_err(sb, "Partition %d is too long (%u)\n", p_index,
1187+
map->s_partition_len);
1188+
return -EFSCORRUPTED;
1189+
}
11741190
udf_debug("unallocSpaceBitmap (part %d) @ %u\n",
11751191
p_index, bitmap->s_extPosition);
11761192
}

0 commit comments

Comments
 (0)