From 2701739f8ad80d14c36de1e3a7a35bd792fceabb Mon Sep 17 00:00:00 2001 From: Joachim Metz Date: Wed, 28 Apr 2021 09:40:47 +0200 Subject: [PATCH] Fixed OOB reads in hfs_cat_traverse #1401 --- tsk/fs/hfs.c | 46 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/tsk/fs/hfs.c b/tsk/fs/hfs.c index 22618534ee..003db5a950 100644 --- a/tsk/fs/hfs.c +++ b/tsk/fs/hfs.c @@ -469,6 +469,16 @@ hfs_ext_find_extent_record_attr(HFS_INFO * hfs, uint32_t cnid, size_t rec_off; hfs_btree_key_ext *key; + // Make sure node is large enough, note that (rec + 1) * 2 is an offset + // relative to the end of node + if ((rec + 1) * 2 > (int) nodesize) { + tsk_error_set_errno(TSK_ERR_FS_GENFS); + tsk_error_set_errstr + ("hfs_ext_find_extent_record: offset of record %d in leaf node %d too small (%" + PRIu16 ")", rec, cur_node, nodesize); + free(node); + return 1; + } // get the record offset in the node rec_off = tsk_getu16(fs->endian, @@ -554,11 +564,21 @@ hfs_ext_find_extent_record_attr(HFS_INFO * hfs, uint32_t cnid, int keylen; TSK_FS_ATTR_RUN *attr_run; + // Make sure node is large enough, note that (rec + 1) * 2 is an offset + // relative to the end of node + if ((rec + 1) * 2 > (int) nodesize) { + tsk_error_set_errno(TSK_ERR_FS_GENFS); + tsk_error_set_errstr + ("hfs_ext_find_extent_record_attr: offset of record %d in leaf node %d too small (%" + PRIu16 ")", rec, cur_node, nodesize); + free(node); + return 1; + } // get the record offset in the node rec_off = tsk_getu16(fs->endian, &node[nodesize - (rec + 1) * 2]); - if (rec_off > nodesize) { + if (rec_off >= nodesize) { tsk_error_set_errno(TSK_ERR_FS_GENFS); tsk_error_set_errstr ("hfs_ext_find_extent_record_attr: offset of record %d in leaf node %d too large (%d vs %" @@ -821,11 +841,21 @@ hfs_cat_traverse(HFS_INFO * hfs, uint8_t retval; int keylen; + // Make sure node is large enough, note that (rec + 1) * 2 is an offset + // relative to the end of node + if ((rec + 1) * 2 > (int) nodesize) { + tsk_error_set_errno(TSK_ERR_FS_GENFS); + tsk_error_set_errstr + ("hfs_cat_traverse: offset of record %d in leaf node %d too small (%" + PRIu16 ")", rec, cur_node, nodesize); + free(node); + return 1; + } // get the record offset in the node rec_off = tsk_getu16(fs->endian, &node[nodesize - (rec + 1) * 2]); - if (rec_off > nodesize) { + if (rec_off >= nodesize) { tsk_error_set_errno(TSK_ERR_FS_GENFS); tsk_error_set_errstr ("hfs_cat_traverse: offset of record %d in index node %d too large (%d vs %" @@ -931,11 +961,21 @@ hfs_cat_traverse(HFS_INFO * hfs, uint8_t retval; int keylen; + // Make sure node is large enough, note that (rec + 1) * 2 is an offset + // relative to the end of node + if ((rec + 1) * 2 > (int) nodesize) { + tsk_error_set_errno(TSK_ERR_FS_GENFS); + tsk_error_set_errstr + ("hfs_cat_traverse: offset of record %d in leaf node %d too small (%" + PRIu16 ")", rec, cur_node, nodesize); + free(node); + return 1; + } // get the record offset in the node rec_off = tsk_getu16(fs->endian, &node[nodesize - (rec + 1) * 2]); - if (rec_off > nodesize) { + if (rec_off >= nodesize) { tsk_error_set_errno(TSK_ERR_FS_GENFS); tsk_error_set_errstr ("hfs_cat_traverse: offset of record %d in leaf node %d too large (%d vs %"