Commit message: * libtiff/tif_ojpeg.c: fix leak in OJPEGReadHeaderInfoSecTablesQTable,
OJPEGReadHeaderInfoSecTablesDcTable and OJPEGReadHeaderInfoSecTablesAcTable
CVE: CVE-2017-7594
CWE: CWE-772
Vulnerability description: The OJPEGReadHeaderInfoSecTablesDcTable function in tif_ojpeg.c in LibTIFF 4.0.7 allows remote attackers to cause a denial of service (memory leak) via a crafted image.

Project: libtiff

OJPEGReadHeaderInfoSecTablesAcTable(TIFF* tif)
{
	static const char module[]="OJPEGReadHeaderInfoSecTablesAcTable";
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	uint8 m;
	uint8 n;
	uint8 o[16];
	uint32 p;
	uint32 q;
	uint32 ra;
	uint8* rb;
	if (sp->actable_offset[0]==0)
	{
		TIFFErrorExt(tif->tif_clientdata,module,"Missing JPEG tables");
		return(0);
	}
	sp->in_buffer_file_pos_log=0;
	for (m=0; m<sp->samples_per_pixel; m++)
	{
		if ((sp->actable_offset[m]!=0) && ((m==0) || (sp->actable_offset[m]!=sp->actable_offset[m-1])))
		{
			for (n=0; n<m-1; n++)
			{
				if (sp->actable_offset[m]==sp->actable_offset[n])
				{
					TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JpegAcTables tag value");
					return(0);
				}
			}
			TIFFSeekFile(tif,sp->actable_offset[m],SEEK_SET);  
			p=(uint32)TIFFReadFile(tif,o,16);
			if (p!=16)
				return(0);
			q=0;
			for (n=0; n<16; n++)
				q+=o[n];
			ra=sizeof(uint32)+21+q;
			rb=_TIFFmalloc(ra);
			if (rb==0)
			{
				TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
				return(0);
			}
			*(uint32*)rb=ra;
			rb[sizeof(uint32)]=255;
			rb[sizeof(uint32)+1]=JPEG_MARKER_DHT;
			rb[sizeof(uint32)+2]=(uint8)((19+q)>>8);
			rb[sizeof(uint32)+3]=((19+q)&255);
			rb[sizeof(uint32)+4]=(16|m);
			for (n=0; n<16; n++)
				rb[sizeof(uint32)+5+n]=o[n];
			p=(uint32)TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q);
			if (p!=q)
                        {
                                _TIFFfree(rb);
				return(0);
                        }
			sp->actable[m]=rb;
			sp->sos_tda[m]=(sp->sos_tda[m]|m);
		}
		else
			sp->sos_tda[m]=(sp->sos_tda[m]|(sp->sos_tda[m-1]&15));
	}
	return(1);
}

Project: libtiff

OJPEGReadHeaderInfoSecTablesQTable(TIFF* tif)
{
	static const char module[]="OJPEGReadHeaderInfoSecTablesQTable";
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	uint8 m;
	uint8 n;
	uint32 oa;
	uint8* ob;
	uint32 p;
	if (sp->qtable_offset[0]==0)
	{
		TIFFErrorExt(tif->tif_clientdata,module,"Missing JPEG tables");
		return(0);
	}
	sp->in_buffer_file_pos_log=0;
	for (m=0; m<sp->samples_per_pixel; m++)
	{
		if ((sp->qtable_offset[m]!=0) && ((m==0) || (sp->qtable_offset[m]!=sp->qtable_offset[m-1])))
		{
			for (n=0; n<m-1; n++)
			{
				if (sp->qtable_offset[m]==sp->qtable_offset[n])
				{
					TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JpegQTables tag value");
					return(0);
				}
			}
			oa=sizeof(uint32)+69;
			ob=_TIFFmalloc(oa);
			if (ob==0)
			{
				TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
				return(0);
			}
			*(uint32*)ob=oa;
			ob[sizeof(uint32)]=255;
			ob[sizeof(uint32)+1]=JPEG_MARKER_DQT;
			ob[sizeof(uint32)+2]=0;
			ob[sizeof(uint32)+3]=67;
			ob[sizeof(uint32)+4]=m;
			TIFFSeekFile(tif,sp->qtable_offset[m],SEEK_SET); 
			p=(uint32)TIFFReadFile(tif,&ob[sizeof(uint32)+5],64);
			if (p!=64)
                        {
                                _TIFFfree(ob);
				return(0);
                        }
			sp->qtable[m]=ob;
			sp->sof_tq[m]=m;
		}
		else
			sp->sof_tq[m]=sp->sof_tq[m-1];
	}
	return(1);
}

Project: libtiff

OJPEGReadHeaderInfoSecTablesDcTable(TIFF* tif)
{
	static const char module[]="OJPEGReadHeaderInfoSecTablesDcTable";
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	uint8 m;
	uint8 n;
	uint8 o[16];
	uint32 p;
	uint32 q;
	uint32 ra;
	uint8* rb;
	if (sp->dctable_offset[0]==0)
	{
		TIFFErrorExt(tif->tif_clientdata,module,"Missing JPEG tables");
		return(0);
	}
	sp->in_buffer_file_pos_log=0;
	for (m=0; m<sp->samples_per_pixel; m++)
	{
		if ((sp->dctable_offset[m]!=0) && ((m==0) || (sp->dctable_offset[m]!=sp->dctable_offset[m-1])))
		{
			for (n=0; n<m-1; n++)
			{
				if (sp->dctable_offset[m]==sp->dctable_offset[n])
				{
					TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JpegDcTables tag value");
					return(0);
				}
			}
			TIFFSeekFile(tif,sp->dctable_offset[m],SEEK_SET);
			p=(uint32)TIFFReadFile(tif,o,16);
			if (p!=16)
				return(0);
			q=0;
			for (n=0; n<16; n++)
				q+=o[n];
			ra=sizeof(uint32)+21+q;
			rb=_TIFFmalloc(ra);
			if (rb==0)
			{
				TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
				return(0);
			}
			*(uint32*)rb=ra;
			rb[sizeof(uint32)]=255;
			rb[sizeof(uint32)+1]=JPEG_MARKER_DHT;
			rb[sizeof(uint32)+2]=(uint8)((19+q)>>8);
			rb[sizeof(uint32)+3]=((19+q)&255);
			rb[sizeof(uint32)+4]=m;
			for (n=0; n<16; n++)
				rb[sizeof(uint32)+5+n]=o[n];
			p=(uint32)TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q);
			if (p!=q)
                        {
                                _TIFFfree(rb);
				return(0);
                        }
			sp->dctable[m]=rb;
			sp->sos_tda[m]=(m<<4);
		}
		else
			sp->sos_tda[m]=sp->sos_tda[m-1];
	}
	return(1);
}