From: Saikrishna Ramdeni (sramdeni) Date: Fri, 25 Jul 2025 08:39:32 +0000 (+0000) Subject: Pull request #4814: fixed the issue of Snort 3 VBA decompression infinite loops X-Git-Tag: 3.9.3.0~18 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=fa76e1defe2df5e29c0747cf7bffa71de347d857;p=thirdparty%2Fsnort3.git Pull request #4814: fixed the issue of Snort 3 VBA decompression infinite loops Merge in SNORT/snort3 from ~SRAMDENI/snort3:bugfix/CSCwq23372_master to master Squashed commit of the following: commit 6dd2508053a4e1a6471d49d993f300788879fc0b Author: sramdeni Date: Tue Jul 15 16:10:14 2025 +0530 olefile_vba : fixed the issue of Snort 3 VBA decompression infinite loops --- diff --git a/src/decompress/file_olefile.cc b/src/decompress/file_olefile.cc index 72d90f678..c6971fd9c 100644 --- a/src/decompress/file_olefile.cc +++ b/src/decompress/file_olefile.cc @@ -68,8 +68,15 @@ void OleFile :: walk_directory_list() dir_list = new DirectoryList(); + std::unordered_set visited_dir_sectors; while (current_sector > INVALID_SECTOR) { + if (visited_dir_sectors.count(current_sector)) { + VBA_DEBUG(vba_data_trace, DEFAULT_TRACE_OPTION_ID, TRACE_ERROR_LEVEL, CURRENT_PACKET, + "Potential loop in Directory FAT sector chain at sector %d. Aborting walk_directory_list.\n", current_sector); + return; + } + visited_dir_sectors.insert(current_sector); const uint8_t* buf = file_buf; uint32_t start_offset = get_fat_offset(current_sector); @@ -300,8 +307,15 @@ void OleFile :: get_file_data(FileProperty* node, uint8_t*& file_data, uint32_t& { int32_t current_sector = starting_sector; uint16_t sector_size = header->get_sector_size(); + std::unordered_set visited_sectors; while (current_sector > INVALID_SECTOR) { + if (visited_sectors.count(current_sector)) { + VBA_DEBUG(vba_data_trace, DEFAULT_TRACE_OPTION_ID, TRACE_ERROR_LEVEL, CURRENT_PACKET, + "Potential loop in FAT sector chain at sector %d. Aborting get_file_data.\n", current_sector); + return; + } + visited_sectors.insert(current_sector); byte_offset = get_fat_offset(current_sector); if (byte_offset > buf_len) return; @@ -321,8 +335,15 @@ void OleFile :: get_file_data(FileProperty* node, uint8_t*& file_data, uint32_t& { int32_t mini_sector = node->get_starting_sector(); uint16_t mini_sector_size = header->get_mini_sector_size(); + std::unordered_set visited_mini_sectors; while (mini_sector > INVALID_SECTOR) { + if (visited_mini_sectors.count(mini_sector)) { + VBA_DEBUG(vba_data_trace, DEFAULT_TRACE_OPTION_ID, TRACE_ERROR_LEVEL, CURRENT_PACKET, + "Potential loop in Mini-FAT sector chain at sector %d. Aborting get_file_data.\n", mini_sector); + return; + } + visited_mini_sectors.insert(mini_sector); byte_offset = get_mini_fat_offset(mini_sector); if (byte_offset > buf_len) return; @@ -430,9 +451,16 @@ void OleFile :: populate_mini_fat_list() current_sector = minifat_sector; int32_t minfat_curr_cnt = 0; + std::unordered_set visited_mini_fat_sectors; while (current_sector > INVALID_SECTOR) { uint32_t sector_size = header->get_sector_size(); + if (visited_mini_fat_sectors.count(current_sector)) { + VBA_DEBUG(vba_data_trace, DEFAULT_TRACE_OPTION_ID, TRACE_ERROR_LEVEL, CURRENT_PACKET, + "Potential loop in Mini-FAT FAT sector chain at sector %d. Aborting populate_mini_fat_list.\n", current_sector); + return; + } + visited_mini_fat_sectors.insert(current_sector); uint32_t byte_offset = OLE_HEADER_LEN + (current_sector * sector_size); // Integer overflow check