aboutsummaryrefslogtreecommitdiff
path: root/fs/udf/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/udf/super.c')
-rw-r--r--fs/udf/super.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 2217f7ed7a49..3460ecc826d1 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -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);
}
@@ -630,7 +631,7 @@ static int udf_parse_param(struct fs_context *fc, struct fs_parameter *param)
if (!uopt->nls_map) {
errorf(fc, "iocharset %s not found",
param->string);
- return -EINVAL;;
+ return -EINVAL;
}
}
break;
@@ -895,7 +896,7 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block)
int ret;
struct timestamp *ts;
- outstr = kmalloc(128, GFP_KERNEL);
+ outstr = kzalloc(128, GFP_KERNEL);
if (!outstr)
return -ENOMEM;
@@ -921,11 +922,11 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block)
ret = udf_dstrCS0toChar(sb, outstr, 31, pvoldesc->volIdent, 32);
if (ret < 0) {
- strcpy(UDF_SB(sb)->s_volume_ident, "InvalidName");
+ strscpy_pad(UDF_SB(sb)->s_volume_ident, "InvalidName");
pr_warn("incorrect volume identification, setting to "
"'InvalidName'\n");
} else {
- strncpy(UDF_SB(sb)->s_volume_ident, outstr, ret);
+ strscpy_pad(UDF_SB(sb)->s_volume_ident, outstr);
}
udf_debug("volIdent[] = '%s'\n", UDF_SB(sb)->s_volume_ident);
@@ -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);
}