From: Ashutosh Gupta (ashugup3) Date: Wed, 17 Sep 2025 10:59:20 +0000 (+0000) Subject: Pull request #4880: decompress: Fixed VBA decompression unhandled mem alloc exception X-Git-Tag: 3.9.6.0~17 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=45a01099ba9809ec8ac70d367650a72da95def0c;p=thirdparty%2Fsnort3.git Pull request #4880: decompress: Fixed VBA decompression unhandled mem alloc exception Merge in SNORT/snort3 from ~ASHUGUP3/snort3:bug_CSCwq23369 to master Squashed commit of the following: commit 8030f6c95bc15dad06a4b52d71f7a2b37f9d9603 Author: ashutosh Date: Tue Aug 26 12:28:53 2025 +0530 decompress: Fixed VBA decompression unhandled mem alloc exception --- diff --git a/src/decompress/file_olefile.cc b/src/decompress/file_olefile.cc index 53a19620b..b4659491b 100644 --- a/src/decompress/file_olefile.cc +++ b/src/decompress/file_olefile.cc @@ -301,7 +301,19 @@ void OleFile :: get_file_data(FileProperty* node, uint8_t*& file_data, uint32_t& starting_sector = node->get_starting_sector(); stream_size = node->get_stream_size(); - file_data = new uint8_t[stream_size]; + if (stream_size == 0 || stream_size > MAX_STREAM_SIZE) { + VBA_DEBUG(vba_data_trace, DEFAULT_TRACE_OPTION_ID, TRACE_ERROR_LEVEL, CURRENT_PACKET, + "Requested stream_size %u is invalid or too large (max %u). Allocation aborted.\n", stream_size, MAX_STREAM_SIZE); + file_data = nullptr; + return; + } + + file_data = new (std::nothrow) uint8_t[stream_size]; + if (!file_data) { + VBA_DEBUG(vba_data_trace, DEFAULT_TRACE_OPTION_ID, TRACE_ERROR_LEVEL, CURRENT_PACKET, + "Memory allocation failed for stream_size %u.\n", stream_size); + return; + } temp_data = file_data; if (stream_size <= header->get_minifat_cutoff()) is_fat = MINIFAT_SECTOR; @@ -381,16 +393,23 @@ void OleFile :: populate_fat_list() VBA_DEBUG(vba_data_trace, DEFAULT_TRACE_OPTION_ID, TRACE_INFO_LEVEL, CURRENT_PACKET, "Reading the FAT list array.\n"); fat_list_len = ( header->get_fat_sector_count() * header->get_sector_size() ) / 4; - if (fat_list_len < 1) + + if (fat_list_len < 1 || fat_list_len > MAX_STREAM_SIZE) { - VBA_DEBUG(vba_data_trace, DEFAULT_TRACE_OPTION_ID, TRACE_INFO_LEVEL, CURRENT_PACKET, - "FAT list array is empty.\n"); + VBA_DEBUG(vba_data_trace, DEFAULT_TRACE_OPTION_ID, TRACE_ERROR_LEVEL, CURRENT_PACKET, + "FAT list length %d is invalid or too large (max %d). Allocation aborted.\n", fat_list_len, MAX_STREAM_SIZE); + fat_list = nullptr; return; } - fat_list = new int32_t[fat_list_len]; + fat_list = new (std::nothrow) int32_t[fat_list_len]; + if (!fat_list) { + VBA_DEBUG(vba_data_trace, DEFAULT_TRACE_OPTION_ID, TRACE_ERROR_LEVEL, CURRENT_PACKET, + "Memory allocation failed for FAT list length %d.\n", fat_list_len); + return; + } - memset(fat_list, -1, fat_list_len); + memset(fat_list, -1, fat_list_len * sizeof(int32_t)); current_sector = fat_sector; while (current_sector > INVALID_SECTOR) @@ -444,16 +463,23 @@ void OleFile :: populate_mini_fat_list() VBA_DEBUG(vba_data_trace, DEFAULT_TRACE_OPTION_ID, TRACE_INFO_LEVEL, CURRENT_PACKET, "Reading the Mini-FAT list array.\n"); mini_fat_list_len = ( header->get_minifat_count() * header->get_sector_size() ) / 4; - if (mini_fat_list_len < 1) + + if (mini_fat_list_len < 1 || mini_fat_list_len > MAX_STREAM_SIZE) { - VBA_DEBUG(vba_data_trace, DEFAULT_TRACE_OPTION_ID, TRACE_INFO_LEVEL, CURRENT_PACKET, - "Mini-FAT list array is empty.\n"); + VBA_DEBUG(vba_data_trace, DEFAULT_TRACE_OPTION_ID, TRACE_ERROR_LEVEL, CURRENT_PACKET, + "Mini-FAT list length %d is invalid or too large (max %d). Allocation aborted.\n", mini_fat_list_len, MAX_STREAM_SIZE); + mini_fat_list = nullptr; return; } - mini_fat_list = new int32_t[mini_fat_list_len]; + mini_fat_list = new (std::nothrow) int32_t[mini_fat_list_len]; + if (!mini_fat_list) { + VBA_DEBUG(vba_data_trace, DEFAULT_TRACE_OPTION_ID, TRACE_ERROR_LEVEL, CURRENT_PACKET, + "Memory allocation failed for Mini-FAT list length %d.\n", mini_fat_list_len); + return; + } - memset(mini_fat_list, -1, mini_fat_list_len); + memset(mini_fat_list, -1, mini_fat_list_len * sizeof(int32_t)); current_sector = minifat_sector; int32_t minfat_curr_cnt = 0; diff --git a/src/decompress/file_olefile.h b/src/decompress/file_olefile.h index 452068f98..f69a5dbf8 100644 --- a/src/decompress/file_olefile.h +++ b/src/decompress/file_olefile.h @@ -55,6 +55,7 @@ #define DIR_STARTING_SEC_OFFSET 116 #define DIR_STREAM_SIZE_OFFSET 120 #define DIR_NEXT_ENTR_OFFSET 128 +#define MAX_STREAM_SIZE 838860 #define CURRENT_PACKET snort::DetectionEngine::get_current_packet()