diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c index 565bd468b893..4df618abc4ef 100644 --- a/fs/ntfs/attrib.c +++ b/fs/ntfs/attrib.c @@ -733,8 +733,12 @@ static bool ntfs_non_resident_attr_value_is_valid(const struct attr_record *a) min_len = offsetof(struct attr_record, data.non_resident.initialized_size) + sizeof(a->data.non_resident.initialized_size); - /* Sparse and compressed attributes have the extra compressed_size field */ - if (a->flags & (ATTR_IS_SPARSE | ATTR_COMPRESSION_MASK)) + /* + * Only the first extent of sparse and compressed attributes has the + * extra compressed_size field. + */ + if ((a->flags & (ATTR_IS_SPARSE | ATTR_COMPRESSION_MASK)) && + !a->data.non_resident.lowest_vcn) min_len += sizeof(a->data.non_resident.compressed_size); if (attr_len < min_len) diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index b666cdb3b102..eca0724c4358 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c @@ -1157,6 +1157,11 @@ static int ntfs_read_locked_inode(struct inode *vi) } if (a->non_resident) { NInoSetNonResident(ni); + if (a->data.non_resident.lowest_vcn) { + ntfs_error(vi->i_sb, + "First extent of $DATA attribute has non zero lowest_vcn."); + goto unm_err_out; + } if (NInoCompressed(ni) || (NInoSparse(ni) && !NInoWofCompressed(ni))) { if (NInoCompressed(ni) && a->data.non_resident.compression_unit != 4) { @@ -1205,11 +1210,6 @@ static int ntfs_read_locked_inode(struct inode *vi) ni->itype.compressed.size = le64_to_cpu( a->data.non_resident.compressed_size); } - if (a->data.non_resident.lowest_vcn) { - ntfs_error(vi->i_sb, - "First extent of $DATA attribute has non zero lowest_vcn."); - goto unm_err_out; - } if (ntfs_non_resident_sizes_inconsistent(vi, a)) goto unm_err_out; vi->i_size = ni->data_size = le64_to_cpu(a->data.non_resident.data_size); @@ -1435,6 +1435,10 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi) } } else { NInoSetNonResident(ni); + if (a->data.non_resident.lowest_vcn) { + ntfs_error(vi->i_sb, "First extent of attribute has non-zero lowest_vcn."); + goto unm_err_out; + } /* * Ensure the attribute name is placed before the mapping pairs * array. @@ -1470,10 +1474,6 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi) ni->itype.compressed.size = le64_to_cpu( a->data.non_resident.compressed_size); } - if (a->data.non_resident.lowest_vcn) { - ntfs_error(vi->i_sb, "First extent of attribute has non-zero lowest_vcn."); - goto unm_err_out; - } if (ntfs_non_resident_sizes_inconsistent(vi, a)) goto unm_err_out; vi->i_size = ni->data_size = le64_to_cpu(a->data.non_resident.data_size);