CVE-2021-21833
An improper array index validation vulnerability exists in the TIF IP_planar_raster_unpack functionality of Accusoft ImageGear 19.9. A specially crafted malformed file can lead to an out-of-bounds write. An attacker can provide a malicious file to trigger this vulnerability.
Accusoft ImageGear 19.9
https://www.accusoft.com/products/imagegear-collection/
9.8 - CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
CWE-119 - Improper Restriction of Operations within the Bounds of a Memory Buffer
The ImageGear library is a document-imaging developer toolkit that offers image conversion, creation, editing, annotation and more. It supports more than 100 formats such as DICOM, PDF, Microsoft Office and others.
There is a vulnerability in the IP_planar_raster_unpack
function which occurs with a specially crafted TIF file, leading to an out-of-bounds write which can result in code execution.
Trying to load a malformed TIF file, we end up in the following situation:
This exception may be expected and handled.
eax=00000000 ebx=00000002 ecx=00000005 edx=00000004 esi=0b98d000 edi=00000004
eip=5c194b4c esp=0019f484 ebp=0019f4a0 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010246
igCore19d!IG_mpi_page_set+0x8dfc:
5c194b4c 8806 mov byte ptr [esi],al ds:002b:0b98d000=??
This is corresponding to the following pseudo code :
LINE1 undefined * __cdecl
LINE2 IP_planar_raster_unpack
LINE3 (int SamplesPerPixel,int index_up_to_sampleperpixel,dword BitsPerSample,
LINE4 int sample_per_pixel_multiply_width,void *src_buffer,void *dest_buffer,
LINE5 size_t size_memory_buffer)
LINE6
LINE7 {
[...]
LINE31 switch(BitsPerSample) {
LINE32 case 1:
LINE33 case 2:
LINE34 case 4:
LINE35 nb_bits_BitsPerSample = (int)(8 / (longlong)(int)BitsPerSample);
LINE36 index_larger_loop = 0;
LINE37 _index_larger_loop = 0;
LINE38 _mask_bitpersample = (char)(1 << ((byte)BitsPerSample & 0x1f)) + -1;
LINE39 if (0 < sample_per_pixel_multiply_width / nb_bits_BitsPerSample) {
LINE40 do {
LINE41 bVar2 = *(byte *)(_index_larger_loop + (int)src_buffer);
LINE42 if (0 < nb_bits_BitsPerSample) {
LINE43 iVar9 = (nb_bits_BitsPerSample + -1) * BitsPerSample;
LINE44 _bit_to_process = nb_bits_BitsPerSample;
LINE45 do {
LINE46 bVar4 = (byte)iVar9;
LINE47 iVar9 = iVar9 - BitsPerSample;
LINE48 *(byte *)(index_up_to_sampleperpixel + (int)dest_buffer) =
LINE49 bVar2 >> (bVar4 & 0x1f) & _mask_bitpersample;
LINE50 index_up_to_sampleperpixel = index_up_to_sampleperpixel + SamplesPerPixel;
LINE51 _bit_to_process = _bit_to_process + -1;
LINE52 } while (_bit_to_process != 0);
LINE53 }
LINE54 index_larger_loop = _index_larger_loop + 1;
LINE55 _index_larger_loop = index_larger_loop;
LINE56 } while (index_larger_loop < sample_per_pixel_multiply_width / nb_bits_BitsPerSample);
LINE57 }
LINE58 nb_bytes = (SamplesPerPixel * sample_per_pixel_multiply_width) / nb_bits_BitsPerSample;
LINE59 module_bytes = (SamplesPerPixel * sample_per_pixel_multiply_width) % nb_bits_BitsPerSample;
LINE60 if (0 < module_bytes) {
LINE61 nb_bytes = (uint)src_buffer & 0xffffff00 |
LINE62 (uint)*(byte *)(index_larger_loop + (int)src_buffer);
LINE63 if (0 < module_bytes) {
LINE64 _oobw = (byte *)(index_up_to_sampleperpixel + (int)dest_buffer);
LINE65 puVar6 = (undefined *)
LINE66 ((uint)CONCAT21((short)((ulonglong)(8 / (longlong)(int)BitsPerSample) >> 0x10),
LINE67 *(byte *)(index_larger_loop + (int)src_buffer)) << 8);
LINE68 nb_bits_BitsPerSample = (nb_bits_BitsPerSample + -1) * BitsPerSample;
LINE69 do {
LINE70 bVar2 = (byte)nb_bits_BitsPerSample;
LINE71 nb_bits_BitsPerSample = nb_bits_BitsPerSample - BitsPerSample;
LINE72 result = (byte)((uint)puVar6 >> 8) >> (bVar2 & 0x1f) & _mask_bitpersample;
LINE73 puVar6 = (undefined *)((uint)puVar6 & 0xffffff00 | (uint)result);
LINE74 *_oobw = result;
LINE75 _oobw = _oobw + SamplesPerPixel;
LINE76 module_bytes = module_bytes + -1;
LINE77 } while (module_bytes != 0);
LINE78 return puVar6;
LINE79 }
LINE80 }
LINE81 [...]
LINE174 }
and the crash is happening at LINE74
. The oobw
variable is derived from the dest_buffer
passed as an argument as you can see at LINE64
The out-of-bounds write is happening throught the loop performed between LINE69
and LINE77
controlled by the module_bytes
which in our case is 4 as this is the rest of the division in LINE59
.
The issue is there is no control against the size of _oobw
computed in LINE75
while adding the value of SamplesPerPixel
.
Now let’s see how the buffer size is computed.
When looking at the memory buffer allocated corresponding to oobw
we can see the size of ‘4’ bytes in our cases:
0:000> !heap -p -a esi
address 0b98d000 found in
_DPH_HEAP_ROOT @ 3f11000
in busy allocation ( DPH_HEAP_BLOCK: UserAddr UserSize - VirtAddr VirtSize)
9fe2104: b98cff8 4 - b98c000 2000
5ce2a8b0 verifier!AVrfDebugPageHeapAllocate+0x00000240
77dcef3e ntdll!RtlDebugAllocateHeap+0x00000039
77d37080 ntdll!RtlpAllocateHeap+0x000000f0
77d36ddc ntdll!RtlpAllocateHeapInternal+0x0000104c
77d35d7e ntdll!RtlAllocateHeap+0x0000003e
5cccdcff MSVCR110!malloc+0x00000049
5c1861de igCore19d!AF_memm_alloc+0x0000001e
5c297518 igCore19d!IG_mpi_page_set+0x0010b7c8
5c29721a igCore19d!IG_mpi_page_set+0x0010b4ca
5c29c353 igCore19d!IG_mpi_page_set+0x00110603
5c2962cb igCore19d!IG_mpi_page_set+0x0010a57b
5c1610d9 igCore19d!IG_image_savelist_get+0x00000b29
5c1a0557 igCore19d!IG_mpi_page_set+0x00014807
5c19feb9 igCore19d!IG_mpi_page_set+0x00014169
5c135777 igCore19d!IG_load_file+0x00000047
00498a3a Fuzzme!fuzzme+0x0000004a [C:\Users\etach\Documents\work\gitlab\ImageGear\Fuzzme\Fuzzme.cpp @ 282]
00498e36 Fuzzme!main+0x00000376 [C:\Users\etach\Documents\work\gitlab\ImageGear\Fuzzme\Fuzzme.cpp @ 477]
004daa53 Fuzzme!invoke_main+0x00000033 [d:\agent\_work\57\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 78]
004da8a7 Fuzzme!__scrt_common_main_seh+0x00000157 [d:\agent\_work\57\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 288]
004da73d Fuzzme!__scrt_common_main+0x0000000d [d:\agent\_work\57\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 331]
004daad8 Fuzzme!mainCRTStartup+0x00000008 [d:\agent\_work\57\s\src\vctools\crt\vcstartup\src\startup\exe_main.cpp @ 17]
75bbfa29 KERNEL32!BaseThreadInitThunk+0x00000019
77d57a4e ntdll!__RtlUserThreadStart+0x0000002f
77d57a1e ntdll!_RtlUserThreadStart+0x0000001b
The buffer corresponding to dest_buffer
is allocated in a very-large previous function named allocate_table_buffer_related_sample_per_pixel
with the following pseudo-code in LINE378
:
LINE175 int allocate_table_buffer_related_sample_per_pixel
LINE176 (mys_table_function *mys_table_function,uint kind_of_heap,mys_tags_data *mys_tags_data
LINE177 ,undefined4 some_buffer,HIGDIBINFO higdibinfo,short *ID_TIF_YCBCR_SUBSAMPLING_value)
LINE178
LINE179 {
LINE180 dest_buffer = (byte *)0x0;
LINE181 _raster_size = 0;
LINE182 local_c = 0;
LINE183 local_24 = (byte *)0x0;
LINE184 table_ptr = (int *)0x0;
LINE185 if (*(ushort *)&mys_tags_data->ID_TIF_SAMPLES_PER_PIXEL == 0) {
LINE186 AF_err_record_set("..\\..\\..\\..\\Common\\Formats\\tifread.c",0x178d,-0x80d,0,0,0,(LPCHAR)0x0);
LINE187 loop_index_temp = AF_error_check();
LINE188 return loop_index_temp;
LINE189 }
LINE190 io_buff = (io_buffer *)
LINE191 AF_memm_alloc(kind_of_heap,
LINE192 (uint)*(ushort *)&mys_tags_data->ID_TIF_SAMPLES_PER_PIXEL * 0x34);
LINE193 if (io_buff == (io_buffer *)0x0) {
LINE194 AF_err_record_set("..\\..\\..\\..\\Common\\Formats\\tifread.c",0x1793,-1000,0,0,0,(LPCHAR)0x0);
LINE195 loop_index_temp = AF_error_check();
LINE196 return loop_index_temp;
LINE197 }
LINE198 table_ptr_byte_from_file =
LINE199 (byte **)AF_memm_alloc(kind_of_heap,
LINE200 (uint)*(ushort *)&mys_tags_data->ID_TIF_SAMPLES_PER_PIXEL << 2);
LINE201 if (table_ptr_byte_from_file == (byte **)0x0) {
LINE202 _look_index = 0x179b;
LINE203 p_size_memory_buffer_00 = table_ptr_byte_from_file;
LINE204 }
LINE205 else {
LINE206 OS_memset(table_ptr_byte_from_file,0,
LINE207 (uint)*(ushort *)&mys_tags_data->ID_TIF_SAMPLES_PER_PIXEL << 2);
LINE208 p_size_memory_buffer_00 =
LINE209 (byte **)AF_memm_alloc(kind_of_heap,
LINE210 (uint)*(ushort *)&mys_tags_data->ID_TIF_SAMPLES_PER_PIXEL << 2);
LINE211 if (p_size_memory_buffer_00 != (byte **)0x0) {
LINE212 if (mys_tags_data->ID_TIF_PHOTO_INTERP == IG_TIF_PHOTO_YCBCR) {
LINE213 _look_index = (int)*ID_TIF_YCBCR_SUBSAMPLING_value;
LINE214 local_24 = (byte *)((int)((mys_tags_data->ID_TIF_IMAGE_WIDTH - 1) + _look_index) /
LINE215 _look_index);
LINE216 *p_size_memory_buffer_00 =
LINE217 (byte *)((ID_TIF_YCBCR_SUBSAMPLING_value[1] * _look_index + 2) * (int)local_24);
LINE218 _raster_size = IO_raster_size_get(higdibinfo);
LINE219 table_ptr = (int *)AF_memm_alloc(kind_of_heap,(int)ID_TIF_YCBCR_SUBSAMPLING_value[1] << 2);
LINE220 if (table_ptr != (int *)0x0) {
LINE221 num_to_alloc = 0;
LINE222 if (0 < ID_TIF_YCBCR_SUBSAMPLING_value[1]) {
LINE223 size_malloc = _raster_size + 0x80;
LINE224 do {
LINE225 _buff_mem = AF_memm_alloc(kind_of_heap,size_malloc);
LINE226 table_ptr[num_to_alloc] = (int)_buff_mem;
LINE227 if (_buff_mem == (void *)0x0) {
LINE228 table_ptr = (int *)0x0;
LINE229 _look_index = 0x17d5;
LINE230 goto error_allocate_mem;
LINE231 }
LINE232 num_to_alloc = num_to_alloc + 1;
LINE233 } while (num_to_alloc < ID_TIF_YCBCR_SUBSAMPLING_value[1]);
LINE234 }
LINE235 goto continue_process;
LINE236 }
LINE237 size_malloc = (int)ID_TIF_YCBCR_SUBSAMPLING_value[1] << 2;
LINE238 _look_index = 0x17cb;
LINE239 error_allocate_mem:
LINE240 AF_err_record_set("..\\..\\..\\..\\Common\\Formats\\tifread.c",_look_index,-1000,0,
LINE241 kind_of_heap,size_malloc,(LPCHAR)table_ptr);
LINE242 AF_memm_free(kind_of_heap,io_buff);
LINE243 AF_memm_free(kind_of_heap,table_ptr_byte_from_file);
LINE244 }
LINE245 else {
LINE246 continue_process:
LINE247 /* Planar Config = 1 */
LINE248 if (mys_tags_data->ID_TIF_PLANAR_CONFIG == 1) {
[...]
LINE340 }
LINE341 else {
LINE342 /* Planar Config = 2 */
LINE343 if (mys_tags_data->ID_TIF_PLANAR_CONFIG == 2) {
LINE344 if (mys_tags_data->ID_TIF_PHOTO_INTERP == IG_TIF_PHOTO_YCBCR) {
[...]
LINE362 }
LINE363 else {
LINE364 _look_index = 0;
LINE365 if (*(short *)&mys_tags_data->ID_TIF_SAMPLES_PER_PIXEL != 0) {
LINE366 do {
LINE367 look_index = _look_index + 1;
LINE368 value_to_store =
LINE369 (int)*(short *)((mys_tags_data->ID_TIF_BITS_PER_SAMPLE - 2) + look_index * 2)
LINE370 * mys_tags_data->ID_TIF_IMAGE_WIDTH + 7;
LINE371 p_size_memory_buffer_00[_look_index] =
LINE372 (byte *)((int)(value_to_store + (value_to_store >> 0x1f & 7U)) >> 3);
LINE373 _look_index = look_index;
LINE374 } while (look_index < (int)(uint)*(ushort *)&mys_tags_data->ID_TIF_SAMPLES_PER_PIXEL
LINE375 );
LINE376 }
LINE377 _raster_size = IO_raster_size_get(higdibinfo);
LINE378 dest_buffer = (byte *)AF_memm_alloc(kind_of_heap,_raster_size);
LINE379 if (dest_buffer == (byte *)0x0) {
LINE380 AF_err_record_set("..\\..\\..\\..\\Common\\Formats\\tifread.c",0x183d,-1000,0,
LINE381 kind_of_heap,_raster_size,(LPCHAR)0x0);
LINE382 goto LAB_10177a96;
LINE383 }
LINE384 }
LINE385 loop_index_temp = 0;
LINE386 _look_index = 0;
LINE387 _io_buff = io_buff;
LINE388 if (*(short *)&mys_tags_data->ID_TIF_SAMPLES_PER_PIXEL != 0) {
LINE389 do {
LINE390 dVar1 = IOb_init(mys_table_function,kind_of_heap,_io_buff,
LINE391 (int)p_size_memory_buffer_00[_look_index] * 5,1);
LINE392 if (0 < (int)dVar1) {
LINE393 loop_index_temp = 1;
LINE394 local_c = 1;
LINE395 break;
LINE396 }
LINE397 _look_index = _look_index + 1;
LINE398 _io_buff = (io_buffer *)&_io_buff->size_buffer;
LINE399 } while (_look_index < (int)(uint)*(ushort *)&mys_tags_data->ID_TIF_SAMPLES_PER_PIXEL)
LINE400 ;
LINE401 }
LINE402 pIVar3 = (HIGDIBINFO)0x0;
LINE403 higdibinfo = (HIGDIBINFO)0x0;
LINE404 local_18 = 0;
LINE405 while ((loop_index_temp == 0 &&
LINE406 (local_18 < (int)mys_tags_data->from_ID_TIF_STRIP_OFFSET_or_ID_TIF_TILE_OFFSETS))
LINE407 ) {
LINE408 if ((mys_tags_data->ID_TIF_TILE_OFFSETS != 0) &&
LINE409 (*(short *)&mys_tags_data->ID_TIF_SAMPLES_PER_PIXEL != 0)) {
LINE410 _look_index = 0;
LINE411 _io_buff = io_buff;
LINE412 do {
LINE413 perform_some_read_or_write_intofile
LINE414 (_io_buff,*(int *)(mys_tags_data->ID_TIF_TILE_OFFSETS +
LINE415 (mys_tags_data->
LINE416 result_strip_tile_offset_divided_sample_per_pixel *
LINE417 _look_index + local_18) * 4) +
LINE418 mys_tags_data->IFD_Offset,0,0);
LINE419 _look_index = _look_index + 1;
LINE420 _io_buff = (io_buffer *)&_io_buff->size_buffer;
LINE421 loop_index_temp = local_c;
LINE422 pIVar3 = higdibinfo;
LINE423 } while (_look_index <
LINE424 (int)(uint)*(ushort *)&mys_tags_data->ID_TIF_SAMPLES_PER_PIXEL);
LINE425 }
LINE426 strip = 0;
LINE427 if (0 < (int)mys_tags_data->ID_TIF_ROWS_PER_STRIP) {
LINE428 do {
LINE429 local_c = loop_index_temp;
LINE430 if ((int)mys_tags_data->ID_TIF_IMAGE_HEIGHT <= (int)pIVar3) break;
LINE431 _look_index = 0;
LINE432 pIVar3 = higdibinfo;
LINE433 if (mys_tags_data->ID_TIF_PHOTO_INTERP == IG_TIF_PHOTO_YCBCR) {
[...]
LINE473 }
LINE474 else {
LINE475 _io_buff = io_buff;
LINE476 if (*(short *)&mys_tags_data->ID_TIF_SAMPLES_PER_PIXEL != 0) {
LINE477 do {
LINE478 src_buff = (byte *)get_data_from_file(_io_buff,(uint)*
LINE479 p_size_memory_buffer_00);
LINE480 table_ptr_byte_from_file[_look_index] = src_buff;
LINE481 if (src_buff == (byte *)0x0) {
LINE482 AF_err_record_set("..\\..\\..\\..\\Common\\Formats\\tifread.c",0x1881,
LINE483 -0x803,0,(AT_INT)*p_size_memory_buffer_00,0,(LPCHAR)0x0)
LINE484 ;
LINE485 loop_index_temp = loop_index_temp + 1;
LINE486 break;
LINE487 }
LINE488 _look_index = _look_index + 1;
LINE489 _io_buff = (io_buffer *)&_io_buff->size_buffer;
LINE490 } while (_look_index <
LINE491 (int)(uint)*(ushort *)&mys_tags_data->ID_TIF_SAMPLES_PER_PIXEL);
LINE492 }
LINE493 local_c = loop_index_temp;
LINE494 if (loop_index_temp != 0) break;
LINE495 will_iIG_IP_planar_raster_unpack
LINE496 (mys_tags_data,some_buffer,table_ptr_byte_from_file,
LINE497 (uint *)p_size_memory_buffer_00,dest_buffer);
LINE498 loop_index_temp =
LINE499 IO_raster_set(mys_table_function,dest_buffer,higdibinfo,_raster_size);
LINE500 higdibinfo = (HIGDIBINFO)((int)&higdibinfo->igdibstd_vftable + 1);
LINE501 LAB_101777e4:
LINE502 pIVar3 = higdibinfo;
LINE503 local_c = loop_index_temp;
LINE504 if (loop_index_temp != 0) break;
LINE505 }
LINE506 strip = strip + 1;
LINE507 pIVar3 = higdibinfo;
LINE508 local_c = loop_index_temp;
LINE509 } while (strip < (int)mys_tags_data->ID_TIF_ROWS_PER_STRIP);
LINE510 }
[...]
LINE563 }
The size of dest_buffer
which is represented by _raster_size
is computed through the function IO_raster_size_get
as you can see at LINE377
LINE565 uint IO_raster_size_get(HIGDIBINFO higdibinfo)
LINE566 {
LINE567 dword bit_depth;
LINE568 uint _raster_size;
LINE569
LINE570 bit_depth = IGDIBStd::DIB_bit_depth_get(higdibinfo);
LINE571 if (bit_depth == 1) {
LINE572 /* return size_X + 0x1f >> 3 & 0xfffffffc; */
LINE573 _raster_size = DIB1bit_packed_raster_size_get(higdibinfo);
LINE574 return _raster_size;
LINE575 }
LINE576 /* indirect call to some computer_raster_size */
LINE577 _raster_size = DIBStd_raster_size_get(higdibinfo);
LINE578 return _raster_size;
LINE579 }
The _raster_size
is computed differently according to the bit_depth
of the image. In our case the bit_depth
is greater than ‘1’ and so is computed through the function call DIBStd_raster_size_get
at LINE577
. This function is a wrapper to land finally into a function named IGDIBStd::compute_raster_size
with the following pseudo-code:
LINE580 uint __thiscall IGDIBStd::compute_raster_size(HIGDIBINFO this)
LINE581 {
LINE582 longlong lVar1;
LINE583 uint uVar2;
LINE584 ulonglong uVar3;
LINE585
LINE586 lVar1 = (longlong)(int)(this->mys_struct_table_color).ptr_bits_per_channel_table *
LINE587 (longlong)(int)(this->mys_struct_table_color).ptr_channel_count;
LINE588 uVar3 = __allmul((uint)lVar1,(uint)((ulonglong)lVar1 >> 0x20),this->size_X,
LINE589 (int)this->size_X >> 0x1f);
LINE590 lVar1 = (longlong)(uVar3 + 0x1f) >> 3;
LINE591 uVar2 = (uint)lVar1 & 0xfffffffc;
LINE592 if ((-1 < lVar1) && ((0 < (int)((longlong)(uVar3 + 0x1f) >> 0x23) || (0x7ffffffe < uVar2)))) {
LINE593 wrapper_thow_exception
LINE594 ((undefined *)0xfffffe6f,(char *)0x0,(undefined *)0x0,(undefined *)0x0,
LINE595 (undefined **)0x1022fa38,(undefined *)0x29);
LINE596 }
LINE597 return uVar2;
LINE598 }
The result which lead to ‘4’ is based on values taken from directly from the file and computed along the program and finally are associated into the following variables ptr_bits_per_channel_table
, ptr_channel_count
and size_X
.
The following TIFF tags must be present:
- A planar configuration with a value of ‘2’.
- A photometric tag with some specifics values
The value written into the memory are indirectly controlled from the bytes we can have from the malformed file and the size of the allocation buffer is also controlled through the values of the files.
0:000> !analyze -v
*******************************************************************************
* *
* Exception Analysis *
* *
*******************************************************************************
KEY_VALUES_STRING: 1
Key : AV.Fault
Value: Write
Key : Analysis.CPU.mSec
Value: 2405
Key : Analysis.DebugAnalysisManager
Value: Create
Key : Analysis.Elapsed.mSec
Value: 29571
Key : Analysis.Init.CPU.mSec
Value: 3624
Key : Analysis.Init.Elapsed.mSec
Value: 32534
Key : Analysis.Memory.CommitPeak.Mb
Value: 171
Key : Timeline.OS.Boot.DeltaSec
Value: 279515
Key : Timeline.Process.Start.DeltaSec
Value: 31
Key : WER.OS.Branch
Value: vb_release
Key : WER.OS.Timestamp
Value: 2019-12-06T14:06:00Z
Key : WER.OS.Version
Value: 10.0.19041.1
Key : WER.Process.Version
Value: 1.0.1.1
NTGLOBALFLAG: 2100000
APPLICATION_VERIFIER_FLAGS: 0
APPLICATION_VERIFIER_LOADED: 1
EXCEPTION_RECORD: (.exr -1)
ExceptionAddress: 5c194b4c (igCore19d!IG_mpi_page_set+0x00008dfc)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 00000001
Parameter[1]: 0b98d000
Attempt to write to address 0b98d000
FAULTING_THREAD: 0000254c
PROCESS_NAME: Fuzzme.exe
WRITE_ADDRESS: 0b98d000
ERROR_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%p referenced memory at 0x%p. The memory could not be %s.
EXCEPTION_CODE_STR: c0000005
EXCEPTION_PARAMETER1: 00000001
EXCEPTION_PARAMETER2: 0b98d000
STACK_TEXT:
WARNING: Stack unwind information not available. Following frames may be wrong.
0019f4a0 5c142d4d 00000004 00000000 00000001 igCore19d!IG_mpi_page_set+0x8dfc
0019f4c4 5c29c17f 00000004 00000000 00000001 igCore19d!IG_thread_image_unlock+0x4b5d
0019f4f8 5c297712 0019f5c4 0b418d68 099e4ff0 igCore19d!IG_mpi_page_set+0x11042f
0019f544 5c29721a 0019fb30 10000021 12688ff0 igCore19d!IG_mpi_page_set+0x10b9c2
0019f56c 5c29c353 0019fb30 10000021 0019f5c4 igCore19d!IG_mpi_page_set+0x10b4ca
0019f594 5c2962cb 0019fb30 10000021 0b418d68 igCore19d!IG_mpi_page_set+0x110603
0019faa8 5c1610d9 0019fb30 0b418d68 00000001 igCore19d!IG_mpi_page_set+0x10a57b
0019fae0 5c1a0557 00000000 0b418d68 0019fb30 igCore19d!IG_image_savelist_get+0xb29
0019fd5c 5c19feb9 00000000 05414f88 00000001 igCore19d!IG_mpi_page_set+0x14807
0019fd7c 5c135777 00000000 05414f88 00000001 igCore19d!IG_mpi_page_set+0x14169
0019fd9c 00498a3a 05414f88 0019fe0c 004801a4 igCore19d!IG_load_file+0x47
0019fe14 00498e36 05414f88 0019fe8c 004801a4 Fuzzme!fuzzme+0x4a
0019fee4 004daa53 00000005 05354f20 0535df20 Fuzzme!main+0x376
0019ff04 004da8a7 b039b859 004801a4 004801a4 Fuzzme!invoke_main+0x33
0019ff60 004da73d 0019ff70 004daad8 0019ff80 Fuzzme!__scrt_common_main_seh+0x157
0019ff68 004daad8 0019ff80 75bbfa29 0035e000 Fuzzme!__scrt_common_main+0xd
0019ff70 75bbfa29 0035e000 75bbfa10 0019ffdc Fuzzme!mainCRTStartup+0x8
0019ff80 77d57a4e 0035e000 a98e2324 00000000 KERNEL32!BaseThreadInitThunk+0x19
0019ffdc 77d57a1e ffffffff 77d788fd 00000000 ntdll!__RtlUserThreadStart+0x2f
0019ffec 00000000 004801a4 0035e000 00000000 ntdll!_RtlUserThreadStart+0x1b
STACK_COMMAND: ~0s ; .cxr ; kb
SYMBOL_NAME: igCore19d!IG_mpi_page_set+8dfc
MODULE_NAME: igCore19d
IMAGE_NAME: igCore19d.dll
FAILURE_BUCKET_ID: INVALID_POINTER_WRITE_AVRF_c0000005_igCore19d.dll!IG_mpi_page_set
OS_VERSION: 10.0.19041.1
BUILDLAB_STR: vb_release
OSPLATFORM_TYPE: x86
OSNAME: Windows 10
IMAGE_VERSION: 19.9.0.0
FAILURE_ID_HASH: {39ff52ad-9054-81fd-3e4d-ef5d82e4b2c1}
Followup: MachineOwner
---------
2021-05-10 - Vendor Disclosure
2021-05-31 - Vendor Patched
2021-06-01 - Public Release
Discovered by Emmanuel Tacheau of Cisco Talos.