CVE-2020-35535 (C++, published 2022-09-01T18:15Z)
Description: value: In LibRaw, there is an out-of-bounds read vulnerability within the "LibRaw::parseSonySRF()" function (libraw\src\metadata\sony.cpp) when processing srf files.
Severity: nan (CVSS v3 base score: 5.5)
Weakness: CWE-125 \u2014 Out-of-bounds Read
The product reads data past the end, or before the beginning, of the intended buffer.
Repository: https://github.com/LibRaw/LibRaw
Files changed:
src/metadata/sony.cpp
Commit message: additional checks in parseSonySRF

parseSonySR2: buffer size check


Vulnerable code:
          FORC4 cblack[c] = sget2(cbuf_SR2 + tag_dataoffset + tag_dataunitlen * c);
          FORC4 cam_mul[GRBG_2_RGBG(c)] = sget2(cbuf_SR2 + tag_dataoffset + tag_dataunitlen * c);
          FORC4 cblack[RGGB_2_RGBG(c)] = sget2(cbuf_SR2 + tag_dataoffset + tag_dataunitlen * c);
          FORC4 cam_mul[RGGB_2_RGBG(c)] = sget2(cbuf_SR2 + tag_dataoffset + tag_dataunitlen * c);
          ilm.MaxAp4MaxFocal = sgetreal(tag_type, cbuf_SR2 + tag_dataoffset);
          ilm.MaxAp4MinFocal = sgetreal(tag_type, cbuf_SR2 + tag_dataoffset);
          ilm.MaxFocal = sgetreal(tag_type, cbuf_SR2 + tag_dataoffset);
          ilm.MinFocal = sgetreal(tag_type, cbuf_SR2 + tag_dataoffset);
          for (i = 0; i < 3; i++)
            FORC3 imgdata.color.linear_max[c] = sget2(cbuf_SR2 + tag_dataoffset + tag_dataunitlen * c);
            imgdata.color.linear_max[0] = imgdata.color.linear_max[1] =
            FORC3 icWBCCTC[WBCTC_count][c + 1] = sget2(cbuf_SR2 + tag_dataoffset + tag_dataunitlen * c);
            FORC3 icWBC[Sony_SR2_wb_list[i]][c] = sget2(cbuf_SR2 + tag_dataoffset + tag_dataunitlen * c);
            FORC3 icWBCCTC[WBCTC_count][c + 1] = sget2(cbuf_SR2 + tag_dataoffset + tag_dataunitlen * c);
            FORC3 icWBC[Sony_SR2_wb_list1[i]][c] = sget2(cbuf_SR2 + tag_dataoffset + tag_dataunitlen * c);
          FORC4 icWBC[LIBRAW_WBI_Auto][GRBG_2_RGBG(c)] = sget2(cbuf_SR2 + tag_dataoffset + tag_dataunitlen * c);
          FORC4 icWBC[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = sget2(cbuf_SR2 + tag_dataoffset + tag_dataunitlen * c);
  short entries;
  srf_buf = (uchar *)malloc(len);
        SRF2Key = sget4(srf_buf + tag_dataoffset);
        RawDataKey = sget4(srf_buf + tag_dataoffset);
    if (tiff_sget (save, srf_buf, len,
        icWBC[Sony_SRF_wb_list[nWB]][i] = sget4(srf_buf + tag_dataoffset);
        cam_mul[i] = sget4(srf_buf + tag_dataoffset);
        ilm.MaxAp4MaxFocal = sgetreal(tag_type, srf_buf + tag_dataoffset);
         ilm.MaxAp4MinFocal = sgetreal(tag_type, srf_buf + tag_dataoffset);
        ilm.MinFocal = sgetreal(tag_type, srf_buf + tag_dataoffset);
        ilm.MaxFocal = sgetreal(tag_type, srf_buf + tag_dataoffset);

Fixed code:
#define CHECKBUFFER_N(offset,N)                                     \
  do                                                                \
  {                                                                 \
    if ((((offset) + (N)) > SR2SubIFDLength) || ((offset) < 0))     \
      return;														\
  } while (0)

  CHECKBUFFER_N(0, 2);
			CHECKBUFFER_N(tag_dataoffset + tag_dataunitlen * 4,0);
			FORC4 cblack[c] = sget2(cbuf_SR2 + tag_dataoffset + tag_dataunitlen * c);
			CHECKBUFFER_N(tag_dataoffset + tag_dataunitlen * 4, 0);
			FORC4 cam_mul[GRBG_2_RGBG(c)] = sget2(cbuf_SR2 + tag_dataoffset + tag_dataunitlen * c);
			CHECKBUFFER_N(tag_dataoffset + tag_dataunitlen * 4, 0);
			FORC4 cblack[RGGB_2_RGBG(c)] = sget2(cbuf_SR2 + tag_dataoffset + tag_dataunitlen * c);
			CHECKBUFFER_N(tag_dataoffset + tag_dataunitlen * 4, 0);
			FORC4 cam_mul[RGGB_2_RGBG(c)] = sget2(cbuf_SR2 + tag_dataoffset + tag_dataunitlen * c);
			CHECKBUFFER_N(tag_dataoffset, 4);
			ilm.MaxAp4MaxFocal = sgetreal(tag_type, cbuf_SR2 + tag_dataoffset);
			CHECKBUFFER_N(tag_dataoffset, 4);
			ilm.MaxAp4MinFocal = sgetreal(tag_type, cbuf_SR2 + tag_dataoffset);
			CHECKBUFFER_N(tag_dataoffset, 4);
			ilm.MaxFocal = sgetreal(tag_type, cbuf_SR2 + tag_dataoffset);
			CHECKBUFFER_N(tag_dataoffset, 4);
			ilm.MinFocal = sgetreal(tag_type, cbuf_SR2 + tag_dataoffset);
			CHECKBUFFER_N(tag_dataoffset + tag_dataunitlen * 8, 2);
		  for (i = 0; i < 3; i++)
			  CHECKBUFFER_N(tag_dataoffset + tag_dataunitlen * 2, 2);
			  FORC3 imgdata.color.linear_max[c] = sget2(cbuf_SR2 + tag_dataoffset + tag_dataunitlen * c);
			  CHECKBUFFER_N(tag_dataoffset, 2);
			  imgdata.color.linear_max[0] = imgdata.color.linear_max[1] =
			CHECKBUFFER_N(tag_dataoffset + tag_dataunitlen * 2, 2);
			FORC3 icWBCCTC[WBCTC_count][c + 1] = sget2(cbuf_SR2 + tag_dataoffset + tag_dataunitlen * c);
			  CHECKBUFFER_N(tag_dataoffset + tag_dataunitlen * 2, 2);
			  FORC3 icWBC[Sony_SR2_wb_list[i]][c] = sget2(cbuf_SR2 + tag_dataoffset + tag_dataunitlen * c);
			CHECKBUFFER_N(tag_dataoffset + tag_dataunitlen * 2, 2);
			FORC3 icWBCCTC[WBCTC_count][c + 1] = sget2(cbuf_SR2 + tag_dataoffset + tag_dataunitlen * c);
			  CHECKBUFFER_N(tag_dataoffset + tag_dataunitlen * 2, 2);
			  FORC3 icWBC[Sony_SR2_wb_list1[i]][c] = sget2(cbuf_SR2 + tag_dataoffset + tag_dataunitlen * c);
			CHECKBUFFER_N(tag_dataoffset + tag_dataunitlen * 3, 2);
			FORC4 icWBC[LIBRAW_WBI_Auto][GRBG_2_RGBG(c)] = sget2(cbuf_SR2 + tag_dataoffset + tag_dataunitlen * c);
			CHECKBUFFER_N(tag_dataoffset + tag_dataunitlen * 3, 2);
			FORC4 icWBC[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = sget2(cbuf_SR2 + tag_dataoffset + tag_dataunitlen * c);
#undef CHECKBUFFER_N
  ushort entries;
  srf_buf = (uchar *)malloc(len+64);
		  CHECKBUFFER_SGET4(tag_dataoffset);
		  SRF2Key = sget4(srf_buf + tag_dataoffset);
		  CHECKBUFFER_SGET4(tag_dataoffset);
		  RawDataKey = sget4(srf_buf + tag_dataoffset);
	  if (tiff_sget(save, srf_buf, len,
		CHECKBUFFER_SGET4(tag_dataoffset);
		icWBC[Sony_SRF_wb_list[nWB]][i] = sget4(srf_buf + tag_dataoffset);
		CHECKBUFFER_SGET4(tag_dataoffset);
		cam_mul[i] = sget4(srf_buf + tag_dataoffset);
		  CHECKBUFFER_SGET4(tag_dataoffset); // need to add extra space
		  ilm.MaxAp4MaxFocal = sgetreal(tag_type, srf_buf + tag_dataoffset);
		  CHECKBUFFER_SGET4(tag_dataoffset);
		  ilm.MaxAp4MinFocal = sgetreal(tag_type, srf_buf + tag_dataoffset);
		  CHECKBUFFER_SGET4(tag_dataoffset);
		  ilm.MinFocal = sgetreal(tag_type, srf_buf + tag_dataoffset);
		  CHECKBUFFER_SGET4(tag_dataoffset);
		  ilm.MaxFocal = sgetreal(tag_type, srf_buf + tag_dataoffset);