Menu

#574 TALOS-2025-2210

3.0.25
open
None
5
2026-01-08
2026-01-08
No

This description is extracted from https://talosintelligence.com/vulnerability_reports/TALOS-2025-2210

LINE 114. /*
LINE 115.  * Sample routine for JPEG compression.  We assume that the target file name
LINE 116.  * and a compression quality factor are passed in.
LINE 117.  */
LINE 118. 
LINE 119. bool JPEGBITSCodec::InternalCode(const char* input, unsigned long len, std::ostream &os)
LINE 120. {
LINE 121.   int quality = 100; (void)len;
LINE 122.   (void)quality;
LINE 123.   JSAMPLE * image_buffer = (JSAMPLE*)(void*)const_cast<char*>(input);  /* Points to large array of R,G,B-order data */
LINE 124.   const unsigned int *dims = this->GetDimensions();
LINE 125.   int image_height = dims[1];  /* Number of rows in image */
LINE 126.   int image_width = dims[0];    /* Number of columns in image */
LINE 127. 
[...]
LINE 277.    row_stride = image_width * cinfo.input_components;  /* JSAMPLEs per row in image_buffer */
LINE 278.  
LINE 279.    if( this->GetPlanarConfiguration() == 0 )
LINE 280.      {
LINE 281.      while (cinfo.next_scanline < cinfo.image_height) {
LINE 282.        /* jpeg_write_scanlines expects an array of pointers to scanlines.
LINE 283.         * Here the array is only one element long, but you could pass
LINE 284.         * more than one scanline at a time if that's more convenient.
LINE 285.         */
LINE 286.        row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];      <---- OOBO here      
LINE 287.        (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
LINE 288.      }
LINE 289.      }
[...]
LINE 328.  }

Earlier in the code, a vulnerability can be observed at LINE 286 due to the absence of bounds checking. Specifically, the assignment to row_pointer may result in a potential out-of-bounds (OOBO) value, as there is no validation to ensure that image_buffer[cinfo.next_scanline * row_stride] stays within the bounds of image_buffer or its length (len).

This leads to two crash


CVE-2025-53618 - grayscale_convert


LINE 473. /*
LINE 474.  * Convert some rows of samples to the JPEG colorspace.
LINE 475.  * This version handles grayscale output with no conversion.
LINE 476.  * The source can be either plain grayscale or YCbCr (since Y == gray).
LINE 477.  */
LINE 478. 
LINE 479. METHODDEF(void)
LINE 480. grayscale_convert (j_compress_ptr cinfo,
LINE 481.        JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
LINE 482.        JDIMENSION output_row, int num_rows)
LINE 483. {
LINE 484.   register JSAMPROW inptr;
LINE 485.   register JSAMPROW outptr;
LINE 486.   register JDIMENSION col;
LINE 487.   JDIMENSION num_cols = cinfo->image_width;
LINE 488.   int instride = cinfo->input_components;
LINE 489. 
LINE 490.   while (--num_rows >= 0) {
LINE 491.     inptr = *input_buf++;
LINE 492.     outptr = output_buf[0][output_row];
LINE 493.     output_row++;
LINE 494.     for (col = 0; col < num_cols; col++) {
LINE 495.       outptr[col] = inptr[0];                             // <----- crashing here
LINE 496.       inptr += instride;                                  // <----- OOBO here
LINE 497.     }
LINE 498.   }
LINE 499. }

The variables cinfo->image_width, cinfo->input_components, and num_rows are directly influenced by values extracted from the malicious DICOM file. Additionally, the pointer inptr, which is obtained at LINE 491, is derived and computed from the input_buf pointer that is passed as an argument to the function. Upon analysis, we can an out-of-bounds read issue occurring at LINE 496


CVE-2025-53619 - null_convert


LINE 502. /*
LINE 503.  * Convert some rows of samples to the JPEG colorspace.
LINE 504.  * This version handles multi-component colorspaces without conversion.
LINE 505.  * We assume input_components == num_components.
LINE 506.  */
LINE 507. 
LINE 508. METHODDEF(void)
LINE 509. null_convert (j_compress_ptr cinfo,
LINE 510.         JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
LINE 511.         JDIMENSION output_row, int num_rows)
LINE 512. {
LINE 513.   register JSAMPROW inptr;
LINE 514.   register JSAMPROW outptr;
LINE 515.   register JDIMENSION col;
LINE 516.   register int ci;
LINE 517.   int nc = cinfo->num_components;
LINE 518.   JDIMENSION num_cols = cinfo->image_width;
LINE 519. 
LINE 520.   while (--num_rows >= 0) {
LINE 521.     /* It seems fastest to make a separate pass for each component. */
LINE 522.     for (ci = 0; ci < nc; ci++) {
LINE 523.       inptr = *input_buf;
LINE 524.       outptr = output_buf[ci][output_row];
LINE 525.       for (col = 0; col < num_cols; col++) {
LINE 526.         outptr[col] = inptr[ci];                             // <----- crashing here                               
LINE 527.         inptr += nc;                                         // <----- OOBO here
LINE 528.       }
LINE 529.     }
LINE 530.     input_buf++;
LINE 531.     output_row++;
LINE 532.   }
LINE 533. }

The variables cinfo->image_width, cinfo->input_components, and num_rows are directly influenced by values extracted from the malicious DICOM file. Additionally, the pointer inptr, which is obtained at LINE 523, is derived and computed from the input_buf pointer that is passed as an argument to the function. Upon analysis, we can observe an out-of-bounds read issue occurring at LINE 527

Discussion


Log in to post a comment.