Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fa5e0815 authored by Jan Kara's avatar Jan Kara
Browse files

udf: Handle VAT packed inside inode properly



We didn't handle VAT packed inside the inode - we tried to call udf_block_map()
on such file which lead to strange results at best. Add proper handling of
packed VAT as we do it with other packed files.

Signed-off-by: default avatarJan Kara <jack@suse.cz>
parent 742e1795
Loading
Loading
Loading
Loading
+7 −3
Original line number Original line Diff line number Diff line
@@ -54,11 +54,10 @@ uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block,
	struct udf_sb_info *sbi = UDF_SB(sb);
	struct udf_sb_info *sbi = UDF_SB(sb);
	struct udf_part_map *map;
	struct udf_part_map *map;
	struct udf_virtual_data *vdata;
	struct udf_virtual_data *vdata;
	struct udf_inode_info *iinfo;
	struct udf_inode_info *iinfo = UDF_I(sbi->s_vat_inode);


	map = &sbi->s_partmaps[partition];
	map = &sbi->s_partmaps[partition];
	vdata = &map->s_type_specific.s_virtual;
	vdata = &map->s_type_specific.s_virtual;
	index = (sb->s_blocksize - vdata->s_start_offset) / sizeof(uint32_t);


	if (block > vdata->s_num_entries) {
	if (block > vdata->s_num_entries) {
		udf_debug("Trying to access block beyond end of VAT "
		udf_debug("Trying to access block beyond end of VAT "
@@ -66,6 +65,11 @@ uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block,
		return 0xFFFFFFFF;
		return 0xFFFFFFFF;
	}
	}


	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
		loc = le32_to_cpu(((__le32 *)iinfo->i_ext.i_data)[block]);
		goto translate;
	}
	index = (sb->s_blocksize - vdata->s_start_offset) / sizeof(uint32_t);
	if (block >= index) {
	if (block >= index) {
		block -= index;
		block -= index;
		newblock = 1 + (block / (sb->s_blocksize / sizeof(uint32_t)));
		newblock = 1 + (block / (sb->s_blocksize / sizeof(uint32_t)));
@@ -88,7 +92,7 @@ uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block,


	brelse(bh);
	brelse(bh);


	iinfo = UDF_I(sbi->s_vat_inode);
translate:
	if (iinfo->i_location.partitionReferenceNum == partition) {
	if (iinfo->i_location.partitionReferenceNum == partition) {
		udf_debug("recursive call to udf_get_pblock!\n");
		udf_debug("recursive call to udf_get_pblock!\n");
		return 0xFFFFFFFF;
		return 0xFFFFFFFF;
+15 −9
Original line number Original line Diff line number Diff line
@@ -1107,7 +1107,10 @@ static int udf_load_vat(struct super_block *sb, int p_index, int type1_index)
	struct udf_sb_info *sbi = UDF_SB(sb);
	struct udf_sb_info *sbi = UDF_SB(sb);
	struct udf_part_map *map = &sbi->s_partmaps[p_index];
	struct udf_part_map *map = &sbi->s_partmaps[p_index];
	kernel_lb_addr ino;
	kernel_lb_addr ino;
	struct buffer_head *bh;
	struct buffer_head *bh = NULL;
	struct udf_inode_info *vati;
	uint32_t pos;
	struct virtualAllocationTable20 *vat20;


	/* VAT file entry is in the last recorded block */
	/* VAT file entry is in the last recorded block */
	ino.partitionReferenceNum = type1_index;
	ino.partitionReferenceNum = type1_index;
@@ -1122,15 +1125,18 @@ static int udf_load_vat(struct super_block *sb, int p_index, int type1_index)
		map->s_type_specific.s_virtual.s_num_entries =
		map->s_type_specific.s_virtual.s_num_entries =
			(sbi->s_vat_inode->i_size - 36) >> 2;
			(sbi->s_vat_inode->i_size - 36) >> 2;
	} else if (map->s_partition_type == UDF_VIRTUAL_MAP20) {
	} else if (map->s_partition_type == UDF_VIRTUAL_MAP20) {
		uint32_t pos;
		vati = UDF_I(sbi->s_vat_inode);
		struct virtualAllocationTable20 *vat20;
		if (vati->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) {

			pos = udf_block_map(sbi->s_vat_inode, 0);
			pos = udf_block_map(sbi->s_vat_inode, 0);
			bh = sb_bread(sb, pos);
			bh = sb_bread(sb, pos);
			if (!bh)
			if (!bh)
				return 1;
				return 1;
		vat20 = (struct virtualAllocationTable20 *)bh->b_data +
			vat20 = (struct virtualAllocationTable20 *)bh->b_data;
				udf_ext0_offset(sbi->s_vat_inode);
		} else {
			vat20 = (struct virtualAllocationTable20 *)
							vati->i_ext.i_data;
		}

		map->s_type_specific.s_virtual.s_start_offset =
		map->s_type_specific.s_virtual.s_start_offset =
			le16_to_cpu(vat20->lengthHeader) +
			le16_to_cpu(vat20->lengthHeader) +
			udf_ext0_offset(sbi->s_vat_inode);
			udf_ext0_offset(sbi->s_vat_inode);