summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChristophe Grenier <grenier@cgsecurity.org>2017-07-05 13:27:24 +0200
committerChristophe Grenier <grenier@cgsecurity.org>2017-07-05 13:27:24 +0200
commit0f97d72be8db4447e4c99e851cce491d9cfa1227 (patch)
tree93d225b5dadeb703d550483f28c7dc88d4099343 /src
parent622d1eb668fd3aa7e63271b90001959c599b4756 (diff)
TestDisk: stricter check on NTFS MFT record size to avoid out of bound read
Thanks to Adel KHALDI from Blue Frost Security GmbH for reporting the problem.
Diffstat (limited to 'src')
-rw-r--r--src/ntfs.c10
-rw-r--r--src/ntfs_adv.c8
-rw-r--r--src/ntfs_fix.c8
3 files changed, 17 insertions, 9 deletions
diff --git a/src/ntfs.c b/src/ntfs.c
index c624ee2..ee47e0a 100644
--- a/src/ntfs.c
+++ b/src/ntfs.c
@@ -311,12 +311,12 @@ static void ntfs_get_volume_name(disk_t *disk_car, partition_t *partition, const
/* Record 3 = $Volume */
mft_pos+=3*mft_record_size;
#ifdef NTFS_DEBUG
- log_debug("NTFS MFT cluster = %lu\n",le64(ntfs_header->mft_lcn));
- log_debug("NTFS cluster size = %5u sectors\n",ntfs_header->sectors_per_cluster);
- log_debug("NTFS MFT_record_size = %5u bytes\n",mft_record_size);
- log_debug("NTFS sector size = %5u bytes\n", ntfs_sector_size(ntfs_header));
+ log_info("NTFS MFT cluster = %lu\n",le64(ntfs_header->mft_lcn));
+ log_info("NTFS cluster size = %5u sectors\n",ntfs_header->sectors_per_cluster);
+ log_info("NTFS MFT_record_size = %5u bytes\n",mft_record_size);
+ log_info("NTFS sector size = %5u bytes\n", ntfs_sector_size(ntfs_header));
#endif
- if(mft_record_size==0)
+ if(mft_record_size < 42)
{
log_error("Invalid MFT record size or NTFS sector size\n");
return;
diff --git a/src/ntfs_adv.c b/src/ntfs_adv.c
index 1b57fac..d248592 100644
--- a/src/ntfs_adv.c
+++ b/src/ntfs_adv.c
@@ -324,10 +324,10 @@ static int read_mft_info(disk_t *disk_car, partition_t *partition, const uint64_
return 1;
}
*mft_record_size=le32(record->bytes_allocated);
- if(*mft_record_size==0)
+ if(*mft_record_size < 42)
{
if(verbose>0)
- log_warning("read_mft_info failed: mft_record_size=0\n");
+ log_warning("read_mft_info failed: mft_record_size < 42\n");
return 2;
}
attr80=(const ntfs_attribnonresident *)ntfs_findattribute(record, 0x80, buffer+sizeof(buffer));
@@ -602,11 +602,11 @@ int rebuild_NTFS_BS(disk_t *disk_car, partition_t *partition, const int verbose,
wmove(stdscr, INTER_NTFS_Y, INTER_NTFS_X);
mftmirr_lcn=ask_number(mftmirr_lcn,0,0,"MFTMIRR LCN ");
wmove(stdscr, INTER_NTFS_Y, INTER_NTFS_X);
- mft_record_size=ask_number(mft_record_size,0,4096," mft record size ");
+ mft_record_size=ask_number(mft_record_size,42,4096," mft record size ");
}
#endif
/* TODO read_mft_info(partition,sector,*sectors_per_cluster,*mft_lcn,*mftmirr_lcn,*mft_record_size); */
- if(sectors_per_cluster>0 && mft_record_size>0 && mft_record_size <= sizeof(buffer))
+ if(sectors_per_cluster>0 && mft_record_size>=42 && mft_record_size <= sizeof(buffer))
{
// 0x90 AT_INDEX_ROOT
const ntfs_attribheader *attr90;
diff --git a/src/ntfs_fix.c b/src/ntfs_fix.c
index 0549139..4cee6c7 100644
--- a/src/ntfs_fix.c
+++ b/src/ntfs_fix.c
@@ -84,6 +84,14 @@ int repair_MFT(disk_t *disk_car, partition_t *partition, const int verbose, cons
else
mft_record_size=1<<(-ntfs_header->clusters_per_mft_record);
+ if(mft_record_size < 42)
+ {
+ display_message("Invalid NTFS MFT record size.\n");
+ log_error("Invalid NTFS MFT record size.\n");
+ free(ntfs_header);
+ return -1;
+ }
+
cluster_size=ntfs_header->sectors_per_cluster * ntfs_sector_size(ntfs_header);
mftmirr_size_bytes = td_max(cluster_size , 4 * mft_record_size);