An integer overflow was reported by "thelastede" on
https://github.com/thelastede/FreeImage-cve-poc/tree/master/CVE-2023-47992 against freeimage 3.18.
As described in the link above, the _MemoryReadProc() function from
Source/FreeImage/FreeImageIO.cpp doesn't correctly compare the value of remaining_bytes and size when size is > 0x80000000:
unsigned DLL_CALLCONV
_MemoryReadProc(void *buffer, unsigned size, unsigned count, fi_handle handle) {
unsigned x;
FIMEMORYHEADER *mem_header = (FIMEMORYHEADER*)(((FIMEMORY*)handle)->data);
for(x = 0; x < count; x++) {
long remaining_bytes = mem_header->file_length - mem_header->current_position;
//if there isn't size bytes left to read, set pos to eof and return a short count
if( remaining_bytes < (long)size ) {
if(remaining_bytes > 0) {
memcpy( buffer, (char *)mem_header->data + mem_header->current_position, remaining_bytes );
}
mem_header->current_position = mem_header->file_length;
break;
}
//copy size bytes count times
memcpy( buffer, (char *)mem_header->data + mem_header->current_position, size );
mem_header->current_position += size;
buffer = (char *)buffer + size;
}
return x;
}
If size > 0x80000000, it will be handled as a negative number and the second memcpy in the code block is executed, when it should be skipped:
//copy size bytes count times
memcpy( buffer, (char *)mem_header->data + mem_header->current_position, size );
According to the reporter, it is possible to construct inputs that may result in both heap out-of-bounds reads to mem_header->data and heap overflow writes to the buffer.