summaryrefslogtreecommitdiffstats
path: root/libblkid
diff options
context:
space:
mode:
authorAlden Tondettar2017-01-24 07:27:59 +0100
committerKarel Zak2017-01-25 11:39:10 +0100
commit999a2ffec92fdecbc1bc85f521057215bcc5ba84 (patch)
tree4fb6dd2e5992bb19496b40c06246a9d14954afa7 /libblkid
parentlibblkid: Fix out of bounds byte swaps in ZFS handling (diff)
downloadkernel-qcow2-util-linux-999a2ffec92fdecbc1bc85f521057215bcc5ba84.tar.gz
kernel-qcow2-util-linux-999a2ffec92fdecbc1bc85f521057215bcc5ba84.tar.xz
kernel-qcow2-util-linux-999a2ffec92fdecbc1bc85f521057215bcc5ba84.zip
libblkid: Fix out of bounds reads on bad NTFS Master File Table
The NTFS prober does not validate certain fields in struct file_attribute, and could attempt to read the disk label from outside the space allocated for the Master File Table. Perform the appropriate checks. Note that one variable (attr_off) is now 64-bit, so a check for integer overflow has been removed as unneeded/confusing. Signed-off-by: Alden Tondettar <alden.tondettar@gmail.com>
Diffstat (limited to 'libblkid')
-rw-r--r--libblkid/src/superblocks/ntfs.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/libblkid/src/superblocks/ntfs.c b/libblkid/src/superblocks/ntfs.c
index 751581164..3a9d5cb01 100644
--- a/libblkid/src/superblocks/ntfs.c
+++ b/libblkid/src/superblocks/ntfs.c
@@ -84,9 +84,9 @@ static int probe_ntfs(blkid_probe pr, const struct blkid_idmag *mag)
struct ntfs_super_block *ns;
struct master_file_table_record *mft;
- uint32_t sectors_per_cluster, mft_record_size, attr_off;
+ uint32_t sectors_per_cluster, mft_record_size;
uint16_t sector_size;
- uint64_t nr_clusters, off;
+ uint64_t nr_clusters, off, attr_off;
unsigned char *buf_mft;
ns = blkid_probe_get_sb(pr, mag, struct ntfs_super_block);
@@ -175,7 +175,7 @@ static int probe_ntfs(blkid_probe pr, const struct blkid_idmag *mag)
mft = (struct master_file_table_record *) buf_mft;
attr_off = le16_to_cpu(mft->attrs_offset);
- while (attr_off < mft_record_size &&
+ while (attr_off + sizeof(struct file_attribute) <= mft_record_size &&
attr_off <= le32_to_cpu(mft->bytes_allocated)) {
uint32_t attr_len;
@@ -193,12 +193,12 @@ static int probe_ntfs(blkid_probe pr, const struct blkid_idmag *mag)
unsigned int val_len = le32_to_cpu(attr->value_len);
unsigned char *val = ((uint8_t *) attr) + val_off;
- blkid_probe_set_utf8label(pr, val, val_len, BLKID_ENC_UTF16LE);
+ if (attr_off + val_off + val_len <= mft_record_size)
+ blkid_probe_set_utf8label(pr, val, val_len,
+ BLKID_ENC_UTF16LE);
break;
}
- if (UINT_MAX - attr_len < attr_off)
- break;
attr_off += attr_len;
}