Re: [PATCH 2/6] udf: Simplify handling of Volume Descriptor Pointers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wednesday 14 February 2018 11:28:46 Jan Kara wrote:
> 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.
> 
> Signed-off-by: Jan Kara <jack@xxxxxxx>
> ---
>  fs/udf/super.c | 41 ++++++++++++++++-------------------------
>  1 file changed, 16 insertions(+), 25 deletions(-)
> 
> diff --git a/fs/udf/super.c b/fs/udf/super.c
> index 5c5d5fd513cc..f80b97173acd 100644
> --- a/fs/udf/super.c
> +++ b/fs/udf/super.c
> @@ -1615,7 +1615,6 @@ static noinline int udf_process_sequence(
>  	bool done = false;
>  	uint32_t vdsn;
>  	uint16_t ident;
> -	long next_s = 0, next_e = 0;
>  	int ret;
>  	unsigned int indirections = 0;
>  
> @@ -1647,19 +1646,22 @@ static noinline int udf_process_sequence(
>  			}
>  			break;
>  		case TAG_IDENT_VDP: /* ISO 13346 3/10.3 */
> -			curr = &vds[VDS_POS_VOL_DESC_PTR];
> -			if (vdsn >= curr->volDescSeqNum) {
> -				curr->volDescSeqNum = vdsn;
> -				curr->block = block;
> -
> -				vdp = (struct volDescPtr *)bh->b_data;
> -				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;
> +			if (++indirections > UDF_MAX_TD_NESTING) {
> +				udf_err(sb, "too many Volume Descriptor "
> +					"Pointers (max %u supported)\n",
> +					UDF_MAX_TD_NESTING);
> +				brelse(bh);
> +				return -EIO;
>  			}
> +
> +			vdp = (struct volDescPtr *)bh->b_data;
> +			block = le32_to_cpu(vdp->nextVolDescSeqExt.extLocation);

Another pathological case: disc with two (or more) VDP descriptors and
each points to another in cycle.

Seems that this would not cause infinite loop due to
UDF_MAX_TD_NESTING, but probably can cause some troubles.

> +			lastblock = le32_to_cpu(
> +				vdp->nextVolDescSeqExt.extLength) >>
> +				sb->s_blocksize_bits;
> +			lastblock += block - 1;
> +			/* For loop is going to increment 'block' again */
> +			block--;
>  			break;
>  		case TAG_IDENT_IUVD: /* ISO 13346 3/10.4 */
>  			curr = &vds[VDS_POS_IMP_USE_VOL_DESC];
> @@ -1688,19 +1690,8 @@ static noinline int udf_process_sequence(
>  			}
>  			break;
>  		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;
> -			if (next_e) {
> -				block = next_s;
> -				lastblock = next_e;
> -				next_s = next_e = 0;
> -			} else
> -				done = true;
> +			done = true;
>  			break;
>  		}
>  		brelse(bh);

-- 
Pali Rohár
pali.rohar@xxxxxxxxx

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux