diff --git a/libntfs-3g/attrib.c b/libntfs-3g/attrib.c index d2d83ac6..f4f31cf6 100644 --- a/libntfs-3g/attrib.c +++ b/libntfs-3g/attrib.c @@ -489,6 +489,17 @@ ntfs_attr *ntfs_attr_open(ntfs_inode *ni, const ATTR_TYPES type, } if (a->non_resident) { + if (((a->flags & ATTR_COMPRESSION_MASK) + || a->compression_unit) + && (ni->vol->major_ver < 3)) { + errno = EIO; + ntfs_log_perror("Compressed inode %lld not allowed" + " on NTFS %d.%d", + (unsigned long long)ni->mft_no, + ni->vol->major_ver, + ni->vol->major_ver); + goto put_err_out; + } if ((a->flags & ATTR_COMPRESSION_MASK) && !a->compression_unit) { errno = EIO; @@ -497,6 +508,17 @@ ntfs_attr *ntfs_attr_open(ntfs_inode *ni, const ATTR_TYPES type, (unsigned long long)ni->mft_no, le32_to_cpu(type)); goto put_err_out; } + if ((a->flags & ATTR_COMPRESSION_MASK) + && (a->compression_unit + != STANDARD_COMPRESSION_UNIT)) { + errno = EIO; + ntfs_log_perror("Compressed inode %lld attr 0x%lx has " + "an unsupported compression unit %d", + (unsigned long long)ni->mft_no, + (long)le32_to_cpu(type), + (int)a->compression_unit); + goto put_err_out; + } ntfs_attr_init(na, TRUE, a->flags, a->flags & ATTR_IS_ENCRYPTED, a->flags & ATTR_IS_SPARSE, diff --git a/libntfs-3g/compress.c b/libntfs-3g/compress.c index 0c22bc9c..390b2d97 100644 --- a/libntfs-3g/compress.c +++ b/libntfs-3g/compress.c @@ -752,6 +752,12 @@ s64 ntfs_compressed_attr_pread(ntfs_attr *na, s64 pos, s64 count, void *b) /* If it is a resident attribute, simply use ntfs_attr_pread(). */ if (!NAttrNonResident(na)) return ntfs_attr_pread(na, pos, count, b); + if (na->compression_block_size < NTFS_SB_SIZE) { + ntfs_log_error("Unsupported compression block size %ld\n", + (long)na->compression_block_size); + errno = EOVERFLOW; + return (-1); + } total = total2 = 0; /* Zero out reads beyond initialized size. */ if (pos + count > na->initialized_size) { @@ -1702,6 +1708,12 @@ s64 ntfs_compressed_pwrite(ntfs_attr *na, runlist_element *wrl, s64 wpos, errno = EIO; return (-1); } + if (na->compression_block_size < NTFS_SB_SIZE) { + ntfs_log_error("Unsupported compression block size %ld\n", + (long)na->compression_block_size); + errno = EOVERFLOW; + return (-1); + } if (wrl->vcn < *update_from) *update_from = wrl->vcn; written = -1; /* default return */ @@ -1883,6 +1895,12 @@ int ntfs_compressed_close(ntfs_attr *na, runlist_element *wrl, s64 offs, errno = EIO; return (-1); } + if (na->compression_block_size < NTFS_SB_SIZE) { + ntfs_log_error("Unsupported compression block size %ld\n", + (long)na->compression_block_size); + errno = EOVERFLOW; + return (-1); + } if (wrl->vcn < *update_from) *update_from = wrl->vcn; vol = na->ni->vol;