CVE-2021-46389 (C++, published 2022-02-07T14:15Z)
Description: value: IIPImage High Resolution Streaming Image Server prior to commit 882925b295a80ec992063deffc2a3b0d803c3195 is affected by an integer overflow in iipsrv.fcgi through malformed HTTP query parameters.
Severity: MEDIUM (CVSS v3 base score: 7.5)
Weakness: CWE-190 \u2014 Integer Overflow or Wraparound
The product performs a calculation that can
         produce an integer overflow or wraparound when the logic
         assumes that the resulting value will always be larger than
         the original value. This occurs when an integer value is
         incremented to a value that is too large to store in the
         associated representation. When this occurs, the value may
         become a very small or negative number.
Repository: https://github.com/ruven/iipsrv
Files changed:
ChangeLog
src/KakaduImage.cc
src/OpenJPEGImage.cc
src/RawTile.h
src/TileManager.cc
src/Transforms.cc
Commit message: - Modified TileManager.cc to verify that malloc() has correctly allocated memory.
- Updated numerical types to std::size_t in RawTile.h, TileManager.cc, KakaduImage.cc, OpenJPEG.cc and Transforms.cc when allocating memory via new to avoid integer overflow - fixes remaining problems identified in https://github.com/ruven/iipsrv/issues/223.


Vulnerable code:
  if( obpc == 16 ) rawtile.data = new unsigned short[w*h*channels];
  else if( obpc == 8 ) rawtile.data = new unsigned char[w*h*channels];
  rawtile.dataLength = w*h*channels*(obpc/8);
  if( obpc == 16 ) rawtile.data = new unsigned short[w * h * channels];
  else if( obpc == 8 ) rawtile.data = new unsigned char[w * h * channels];
  rawtile.dataLength = w*h*channels*(obpc/8);
  unsigned int dataLength;
    Copyright (C) 2005-2021 Ruven Pillay.
  int len = tw * th * ttt->channels * (ttt->bpc/8);
  region.dataLength = width * height * channels * (bpc/8);
  if( bpc == 8 ) region.data = new unsigned char[width*height*channels];
  else if( bpc == 16 ) region.data = new unsigned short[width*height*channels];
  else if( bpc == 32 && sampleType == FIXEDPOINT ) region.data = new int[width*height*channels];
  else if( bpc == 32 && sampleType == FLOATINGPOINT ) region.data = new float[width*height*channels];
    unsigned int buffer_index = 0;
  in.dataLength = resampled_width * resampled_height * channels * (in.bpc/8);
  in.dataLength = resampled_width * resampled_height * channels * (in.bpc/8);

Fixed code:
16/01/2022:
	- Modified TileManager.cc to verify that malloc() has correctly allocated memory.
	- Updated numerical types to std::size_t in RawTile.h, TileManager.cc, KakaduImage.cc, OpenJPEG.cc and Transforms.cc
	  when allocating memory via new to avoid integer overflow - fixes remaining problems identified in
	  https://github.com/ruven/iipsrv/issues/223.


  size_t np = (size_t) w * (size_t) h * (size_t) channels;
  if( obpc == 16 ) rawtile.data = new unsigned short[np];
  else if( obpc == 8 ) rawtile.data = new unsigned char[np];
  rawtile.dataLength = np*(obpc/8);
  size_t np = (size_t) w * (size_t) h * (size_t) channels;
  if( obpc == 16 ) rawtile.data = new unsigned short[np];
  else if( obpc == 8 ) rawtile.data = new unsigned char[np];
  rawtile.dataLength = np*(obpc/8);
  size_t dataLength;
    Copyright (C) 2005-2022 Ruven Pillay.
  unsigned int len = tw * th * ttt->channels * (ttt->bpc/8);

  // Check whether we have successfully allocated memory via malloc
  if( buffer == NULL ){
    std::bad_alloc e;
    throw e;
  }
  size_t np = (size_t) width * (size_t) height * (size_t) channels;
  region.dataLength = np * (bpc/8);
  if( bpc == 8 ) region.data = new unsigned char[np];
  else if( bpc == 16 ) region.data = new unsigned short[np];
  else if( bpc == 32 && sampleType == FIXEDPOINT ) region.data = new int[np];
  else if( bpc == 32 && sampleType == FLOATINGPOINT ) region.data = new float[np];
    unsigned long buffer_index = 0;
  in.dataLength = (size_t)resampled_width * (size_t)resampled_height * (size_t)channels * (size_t)(in.bpc/8);
  in.dataLength = (size_t)resampled_width * (size_t)resampled_height * (size_t)channels * (size_t)(in.bpc/8);