udf: Simplify handling of Volume Descriptor Pointers

According to ECMA-167 3/8.4.2 Volume Descriptor Pointer is terminating
current extent of Volume Descriptor Sequence. Also according to ECMA-167
3/8.4.3 Volume Descriptor Sequence Number is not significant for Volume
Descriptor Pointers. Simplify the handling of Volume Descriptor Pointers
to take this into account.

Acked-by: Pali Rohár <pali.rohar@gmail.com>
Signed-off-by: Jan Kara <jack@suse.cz>
This commit is contained in:
Jan Kara 2018-02-09 13:28:41 +01:00
parent 91c9c9ec54
commit 7b568cba4f

View File

@ -1615,7 +1615,6 @@ static noinline int udf_process_sequence(
bool done = false; bool done = false;
uint32_t vdsn; uint32_t vdsn;
uint16_t ident; uint16_t ident;
long next_s = 0, next_e = 0;
int ret; int ret;
unsigned int indirections = 0; unsigned int indirections = 0;
@ -1647,19 +1646,22 @@ static noinline int udf_process_sequence(
} }
break; break;
case TAG_IDENT_VDP: /* ISO 13346 3/10.3 */ case TAG_IDENT_VDP: /* ISO 13346 3/10.3 */
curr = &vds[VDS_POS_VOL_DESC_PTR]; if (++indirections > UDF_MAX_TD_NESTING) {
if (vdsn >= curr->volDescSeqNum) { udf_err(sb, "too many Volume Descriptor "
curr->volDescSeqNum = vdsn; "Pointers (max %u supported)\n",
curr->block = block; UDF_MAX_TD_NESTING);
brelse(bh);
vdp = (struct volDescPtr *)bh->b_data; return -EIO;
next_s = le32_to_cpu(
vdp->nextVolDescSeqExt.extLocation);
next_e = le32_to_cpu(
vdp->nextVolDescSeqExt.extLength);
next_e = next_e >> sb->s_blocksize_bits;
next_e += next_s - 1;
} }
vdp = (struct volDescPtr *)bh->b_data;
block = le32_to_cpu(vdp->nextVolDescSeqExt.extLocation);
lastblock = le32_to_cpu(
vdp->nextVolDescSeqExt.extLength) >>
sb->s_blocksize_bits;
lastblock += block - 1;
/* For loop is going to increment 'block' again */
block--;
break; break;
case TAG_IDENT_IUVD: /* ISO 13346 3/10.4 */ case TAG_IDENT_IUVD: /* ISO 13346 3/10.4 */
curr = &vds[VDS_POS_IMP_USE_VOL_DESC]; curr = &vds[VDS_POS_IMP_USE_VOL_DESC];
@ -1688,19 +1690,8 @@ static noinline int udf_process_sequence(
} }
break; break;
case TAG_IDENT_TD: /* ISO 13346 3/10.9 */ case TAG_IDENT_TD: /* ISO 13346 3/10.9 */
if (++indirections > UDF_MAX_TD_NESTING) {
udf_err(sb, "too many TDs (max %u supported)\n", UDF_MAX_TD_NESTING);
brelse(bh);
return -EIO;
}
vds[VDS_POS_TERMINATING_DESC].block = block; vds[VDS_POS_TERMINATING_DESC].block = block;
if (next_e) { done = true;
block = next_s;
lastblock = next_e;
next_s = next_e = 0;
} else
done = true;
break; break;
} }
brelse(bh); brelse(bh);