From ea3c16aba2bdc9a0a4357d2153037d2892bb7bfc Mon Sep 17 00:00:00 2001 From: Ann Priestman <apriestman@basistech.com> Date: Thu, 6 Feb 2020 10:25:49 -0500 Subject: [PATCH] Moved addUnallocatedPoolBlocksToDb to addUnallocSpaceToDb. Added pool check to addUnallocVsSpaceToDb. --- tsk/auto/auto.cpp | 9 +++- tsk/auto/auto_db.cpp | 102 ++++++++++++++++++++++++++++------------- tsk/auto/tsk_auto.h | 3 +- tsk/auto/tsk_case_db.h | 9 +++- 4 files changed, 87 insertions(+), 36 deletions(-) diff --git a/tsk/auto/auto.cpp b/tsk/auto/auto.cpp index 39775dd6c..4e927ad48 100755 --- a/tsk/auto/auto.cpp +++ b/tsk/auto/auto.cpp @@ -146,6 +146,10 @@ uint8_t TskAuto::openImageHandle(TSK_IMG_INFO * a_img_info) void TskAuto::closeImage() { + for (int i = 0; i < m_poolInfos.size(); i++) { + tsk_pool_close(m_poolInfos[i]); + } + if ((m_img_info) && (m_internalOpen)) { tsk_img_close(m_img_info); } @@ -493,7 +497,10 @@ TskAuto::findFilesInPool(TSK_OFF_T start, TSK_POOL_TYPE_ENUM ptype) registerError(); return TSK_ERR; } - pool->close(pool); + + // Store the pool_info for later use. It will be closed at the end of the add image process. + m_poolInfos.push_back(pool); + return TSK_OK; } diff --git a/tsk/auto/auto_db.cpp b/tsk/auto/auto_db.cpp index 9d37865f8..49ba92602 100755 --- a/tsk/auto/auto_db.cpp +++ b/tsk/auto/auto_db.cpp @@ -316,6 +316,8 @@ TskAutoDb::filterPool(const TSK_POOL_INFO * pool_info) registerError(); return TSK_FILTER_STOP; } + // Save the parent obj ID for the pool + m_poolOffsetToParentId[pool_info->img_offset] = m_curVolId; } else { // pool doesn't live in a volume, use image as parent @@ -323,48 +325,69 @@ TskAutoDb::filterPool(const TSK_POOL_INFO * pool_info) registerError(); return TSK_FILTER_STOP; } + // Save the parent obj ID for the pool + m_poolOffsetToParentId[pool_info->img_offset] = m_curImgId; } - if (addUnallocatedPoolBlocksToDb(pool_info, poolObjId)) { - registerError(); - return TSK_FILTER_STOP; - } + // Store the volume system object ID for later use + m_poolOffsetToVsId[pool_info->img_offset] = m_curPoolVs; return TSK_FILTER_CONT; } -TSK_FILTER_ENUM -TskAutoDb::addUnallocatedPoolBlocksToDb(const TSK_POOL_INFO * pool_info, int64_t poolObjId) { - /* Only APFS pools are currently supported */ - if (pool_info->ctype != TSK_POOL_TYPE_APFS) { - return TSK_FILTER_CONT; - } +TSK_RETVAL_ENUM +TskAutoDb::addUnallocatedPoolBlocksToDb(size_t & numPool) { - // Create the volume - int64_t unallocVolObjId; - m_db->addUnallocatedPoolVolume(pool_info->num_vols, poolObjId, unallocVolObjId); + for (int i = 0; i < m_poolInfos.size(); i++) { + const TSK_POOL_INFO * pool_info = m_poolInfos[i]; + if (m_poolOffsetToVsId.find(pool_info->img_offset) == m_poolOffsetToVsId.end()) { + tsk_error_reset(); + tsk_error_set_errno(TSK_ERR_AUTO_DB); + tsk_error_set_errstr("Error addUnallocatedPoolBlocksToDb() - could not find volume system object ID for pool at offset %lld", pool_info->img_offset); + return TSK_ERR; + } + int64_t curPoolVs = m_poolOffsetToVsId[pool_info->img_offset]; - TSK_FS_ATTR_RUN * unalloc_runs = tsk_pool_unallocated_runs(pool_info); - TSK_FS_ATTR_RUN * current_run = unalloc_runs; - vector<TSK_DB_FILE_LAYOUT_RANGE> ranges; - while (current_run != NULL) { + /* Make sure the pool_info is still allocated */ + if (pool_info->tag != TSK_POOL_INFO_TAG) { + tsk_error_reset(); + tsk_error_set_errno(TSK_ERR_AUTO_DB); + tsk_error_set_errstr("Error addUnallocatedPoolBlocksToDb() - pool_info is not allocated"); + return TSK_ERR; + } - TSK_DB_FILE_LAYOUT_RANGE tempRange(current_run->addr * pool_info->block_size, current_run->len * pool_info->block_size, 0); - - ranges.push_back(tempRange); - int64_t fileObjId = 0; - if (m_db->addUnallocBlockFile(unallocVolObjId, NULL, current_run->len * pool_info->block_size, ranges, fileObjId, m_curImgId)) { - registerError(); - tsk_fs_attr_run_free(unalloc_runs); - return TSK_FILTER_STOP; + /* Only APFS pools are currently supported */ + if (pool_info->ctype != TSK_POOL_TYPE_APFS) { + continue; } + numPool++; + + // Create the volume + int64_t unallocVolObjId; + m_db->addUnallocatedPoolVolume(pool_info->num_vols, curPoolVs, unallocVolObjId); + + TSK_FS_ATTR_RUN * unalloc_runs = tsk_pool_unallocated_runs(pool_info); + TSK_FS_ATTR_RUN * current_run = unalloc_runs; + vector<TSK_DB_FILE_LAYOUT_RANGE> ranges; + while (current_run != NULL) { - current_run = current_run->next; - ranges.clear(); + TSK_DB_FILE_LAYOUT_RANGE tempRange(current_run->addr * pool_info->block_size, current_run->len * pool_info->block_size, 0); + + ranges.push_back(tempRange); + int64_t fileObjId = 0; + if (m_db->addUnallocBlockFile(unallocVolObjId, NULL, current_run->len * pool_info->block_size, ranges, fileObjId, m_curImgId)) { + registerError(); + tsk_fs_attr_run_free(unalloc_runs); + return TSK_ERR; + } + + current_run = current_run->next; + ranges.clear(); + } + tsk_fs_attr_run_free(unalloc_runs); } - tsk_fs_attr_run_free(unalloc_runs); - return TSK_FILTER_CONT; + return TSK_OK; } TSK_FILTER_ENUM @@ -1141,18 +1164,20 @@ TSK_RETVAL_ENUM TskAutoDb::addUnallocSpaceToDb() { size_t numVsP = 0; size_t numFs = 0; + size_t numPool = 0; TSK_RETVAL_ENUM retFsSpace = addUnallocFsSpaceToDb(numFs); TSK_RETVAL_ENUM retVsSpace = addUnallocVsSpaceToDb(numVsP); + TSK_RETVAL_ENUM retPoolSpace = addUnallocatedPoolBlocksToDb(numPool); - //handle case when no fs and no vs partitions + //handle case when no fs and no vs partitions or pools TSK_RETVAL_ENUM retImgFile = TSK_OK; - if (numVsP == 0 && numFs == 0) { + if (numVsP == 0 && numFs == 0 && numPool == 0) { retImgFile = addUnallocImageSpaceToDb(); } - if (retFsSpace == TSK_ERR || retVsSpace == TSK_ERR || retImgFile == TSK_ERR) + if (retFsSpace == TSK_ERR || retVsSpace == TSK_ERR || retPoolSpace == TSK_ERR || retImgFile == TSK_ERR) return TSK_ERR; else return TSK_OK; @@ -1255,6 +1280,19 @@ TSK_RETVAL_ENUM TskAutoDb::addUnallocVsSpaceToDb(size_t & numVsP) { //skip processing this vspart continue; } + + // Check if the volume contains a pool + bool hasPool = false; + for (std::map<int64_t, int64_t>::iterator iter = m_poolOffsetToParentId.begin(); iter != m_poolOffsetToParentId.end(); ++iter) { + if (iter->second == vsPart.objId) { + hasPool = true; + } + } + if (hasPool) { + // Skip processing this vspart + continue; + } + } //end checking vspart flags //get sector size and image offset from parent vs info diff --git a/tsk/auto/tsk_auto.h b/tsk/auto/tsk_auto.h index 4929854fd..0839e8360 100644 --- a/tsk/auto/tsk_auto.h +++ b/tsk/auto/tsk_auto.h @@ -262,10 +262,11 @@ class TskAuto { protected: TSK_IMG_INFO * m_img_info; + std::vector<const TSK_POOL_INFO*> m_poolInfos; + bool m_internalOpen; ///< True if m_img_info was opened in TskAuto and false if passed in bool m_stopAllProcessing; ///< True if no further processing should occur - uint8_t isNtfsSystemFiles(TSK_FS_FILE * fs_file, const char *path); uint8_t isFATSystemFiles(TSK_FS_FILE * fs_file); uint8_t isDotDir(TSK_FS_FILE * fs_file); diff --git a/tsk/auto/tsk_case_db.h b/tsk/auto/tsk_case_db.h index 25df18e09..422ca330d 100644 --- a/tsk/auto/tsk_case_db.h +++ b/tsk/auto/tsk_case_db.h @@ -154,6 +154,12 @@ class TskAutoDb:public TskAuto { bool m_foundStructure; ///< Set to true when we find either a volume or file system bool m_attributeAdded; ///< Set to true when an attribute was added by processAttributes + // These are used to write unallocated blocks for pools at the end of the add image + // process. We can't load the pool_info objects directly from the database so we will + // store info about them here. + std::map<int64_t, int64_t> m_poolOffsetToParentId; + std::map<int64_t, int64_t> m_poolOffsetToVsId; + // prevent copying until we add proper logic to handle it TskAutoDb(const TskAutoDb&); TskAutoDb & operator=(const TskAutoDb&); @@ -186,8 +192,7 @@ class TskAutoDb:public TskAuto { TSK_OFF_T offset, TSK_DADDR_T addr, char *buf, size_t size, TSK_FS_BLOCK_FLAG_ENUM a_flags, void *ptr); int md5HashAttr(unsigned char md5Hash[16], const TSK_FS_ATTR * fs_attr); - TSK_FILTER_ENUM addUnallocatedPoolBlocksToDb(const TSK_POOL_INFO * pool_info, int64_t poolObjId); - + TSK_RETVAL_ENUM addUnallocatedPoolBlocksToDb(size_t & numPool); static TSK_WALK_RET_ENUM fsWalkUnallocBlocksCb(const TSK_FS_BLOCK *a_block, void *a_ptr); TSK_RETVAL_ENUM addFsInfoUnalloc(const TSK_DB_FS_INFO & dbFsInfo); TSK_RETVAL_ENUM addUnallocFsSpaceToDb(size_t & numFs); -- GitLab