1*4882a593SmuzhiyunFrom 6cfe933df4dbac5479801b2bd10103ef7db815ee Mon Sep 17 00:00:00 2001 2*4882a593SmuzhiyunFrom: 4ugustus <wangdw.augustus@qq.com> 3*4882a593SmuzhiyunDate: Sat, 11 Jun 2022 09:31:43 +0000 4*4882a593SmuzhiyunSubject: [PATCH] fix the FPE in tiffcrop (#415, #427, and #428) 5*4882a593Smuzhiyun 6*4882a593SmuzhiyunCVE: CVE-2022-2056 CVE-2022-2057 CVE-2022-2058 7*4882a593SmuzhiyunUpstream-Status: Backport 8*4882a593SmuzhiyunSigned-off-by: Ross Burton <ross.burton@arm.com> 9*4882a593SmuzhiyunSigned-off-by: Steve Sakoman <steve@sakoman.com> 10*4882a593Smuzhiyun 11*4882a593Smuzhiyun--- 12*4882a593Smuzhiyun libtiff/tif_aux.c | 9 +++++++ 13*4882a593Smuzhiyun libtiff/tiffiop.h | 1 + 14*4882a593Smuzhiyun tools/tiffcrop.c | 62 ++++++++++++++++++++++++++--------------------- 15*4882a593Smuzhiyun 3 files changed, 44 insertions(+), 28 deletions(-) 16*4882a593Smuzhiyun 17*4882a593Smuzhiyundiff --git a/libtiff/tif_aux.c b/libtiff/tif_aux.c 18*4882a593Smuzhiyunindex 140f26c..5b88c8d 100644 19*4882a593Smuzhiyun--- a/libtiff/tif_aux.c 20*4882a593Smuzhiyun+++ b/libtiff/tif_aux.c 21*4882a593Smuzhiyun@@ -402,6 +402,15 @@ float _TIFFClampDoubleToFloat( double val ) 22*4882a593Smuzhiyun return (float)val; 23*4882a593Smuzhiyun } 24*4882a593Smuzhiyun 25*4882a593Smuzhiyun+uint32_t _TIFFClampDoubleToUInt32(double val) 26*4882a593Smuzhiyun+{ 27*4882a593Smuzhiyun+ if( val < 0 ) 28*4882a593Smuzhiyun+ return 0; 29*4882a593Smuzhiyun+ if( val > 0xFFFFFFFFU || val != val ) 30*4882a593Smuzhiyun+ return 0xFFFFFFFFU; 31*4882a593Smuzhiyun+ return (uint32_t)val; 32*4882a593Smuzhiyun+} 33*4882a593Smuzhiyun+ 34*4882a593Smuzhiyun int _TIFFSeekOK(TIFF* tif, toff_t off) 35*4882a593Smuzhiyun { 36*4882a593Smuzhiyun /* Huge offsets, especially -1 / UINT64_MAX, can cause issues */ 37*4882a593Smuzhiyundiff --git a/libtiff/tiffiop.h b/libtiff/tiffiop.h 38*4882a593Smuzhiyunindex f1151f5..c1d0276 100644 39*4882a593Smuzhiyun--- a/libtiff/tiffiop.h 40*4882a593Smuzhiyun+++ b/libtiff/tiffiop.h 41*4882a593Smuzhiyun@@ -368,6 +368,7 @@ extern double _TIFFUInt64ToDouble(uint64_t); 42*4882a593Smuzhiyun extern float _TIFFUInt64ToFloat(uint64_t); 43*4882a593Smuzhiyun 44*4882a593Smuzhiyun extern float _TIFFClampDoubleToFloat(double); 45*4882a593Smuzhiyun+extern uint32_t _TIFFClampDoubleToUInt32(double); 46*4882a593Smuzhiyun 47*4882a593Smuzhiyun extern tmsize_t 48*4882a593Smuzhiyun _TIFFReadEncodedStripAndAllocBuffer(TIFF* tif, uint32_t strip, 49*4882a593Smuzhiyundiff --git a/tools/tiffcrop.c b/tools/tiffcrop.c 50*4882a593Smuzhiyunindex e407bf5..b9b13d8 100644 51*4882a593Smuzhiyun--- a/tools/tiffcrop.c 52*4882a593Smuzhiyun+++ b/tools/tiffcrop.c 53*4882a593Smuzhiyun@@ -5182,17 +5182,17 @@ computeInputPixelOffsets(struct crop_mask *crop, struct image_data *image, 54*4882a593Smuzhiyun { 55*4882a593Smuzhiyun if ((crop->res_unit == RESUNIT_INCH) || (crop->res_unit == RESUNIT_CENTIMETER)) 56*4882a593Smuzhiyun { 57*4882a593Smuzhiyun- x1 = (uint32_t) (crop->corners[i].X1 * scale * xres); 58*4882a593Smuzhiyun- x2 = (uint32_t) (crop->corners[i].X2 * scale * xres); 59*4882a593Smuzhiyun- y1 = (uint32_t) (crop->corners[i].Y1 * scale * yres); 60*4882a593Smuzhiyun- y2 = (uint32_t) (crop->corners[i].Y2 * scale * yres); 61*4882a593Smuzhiyun+ x1 = _TIFFClampDoubleToUInt32(crop->corners[i].X1 * scale * xres); 62*4882a593Smuzhiyun+ x2 = _TIFFClampDoubleToUInt32(crop->corners[i].X2 * scale * xres); 63*4882a593Smuzhiyun+ y1 = _TIFFClampDoubleToUInt32(crop->corners[i].Y1 * scale * yres); 64*4882a593Smuzhiyun+ y2 = _TIFFClampDoubleToUInt32(crop->corners[i].Y2 * scale * yres); 65*4882a593Smuzhiyun } 66*4882a593Smuzhiyun else 67*4882a593Smuzhiyun { 68*4882a593Smuzhiyun- x1 = (uint32_t) (crop->corners[i].X1); 69*4882a593Smuzhiyun- x2 = (uint32_t) (crop->corners[i].X2); 70*4882a593Smuzhiyun- y1 = (uint32_t) (crop->corners[i].Y1); 71*4882a593Smuzhiyun- y2 = (uint32_t) (crop->corners[i].Y2); 72*4882a593Smuzhiyun+ x1 = _TIFFClampDoubleToUInt32(crop->corners[i].X1); 73*4882a593Smuzhiyun+ x2 = _TIFFClampDoubleToUInt32(crop->corners[i].X2); 74*4882a593Smuzhiyun+ y1 = _TIFFClampDoubleToUInt32(crop->corners[i].Y1); 75*4882a593Smuzhiyun+ y2 = _TIFFClampDoubleToUInt32(crop->corners[i].Y2); 76*4882a593Smuzhiyun } 77*4882a593Smuzhiyun if (x1 < 1) 78*4882a593Smuzhiyun crop->regionlist[i].x1 = 0; 79*4882a593Smuzhiyun@@ -5255,17 +5255,17 @@ computeInputPixelOffsets(struct crop_mask *crop, struct image_data *image, 80*4882a593Smuzhiyun { 81*4882a593Smuzhiyun if (crop->res_unit != RESUNIT_INCH && crop->res_unit != RESUNIT_CENTIMETER) 82*4882a593Smuzhiyun { /* User has specified pixels as reference unit */ 83*4882a593Smuzhiyun- tmargin = (uint32_t)(crop->margins[0]); 84*4882a593Smuzhiyun- lmargin = (uint32_t)(crop->margins[1]); 85*4882a593Smuzhiyun- bmargin = (uint32_t)(crop->margins[2]); 86*4882a593Smuzhiyun- rmargin = (uint32_t)(crop->margins[3]); 87*4882a593Smuzhiyun+ tmargin = _TIFFClampDoubleToUInt32(crop->margins[0]); 88*4882a593Smuzhiyun+ lmargin = _TIFFClampDoubleToUInt32(crop->margins[1]); 89*4882a593Smuzhiyun+ bmargin = _TIFFClampDoubleToUInt32(crop->margins[2]); 90*4882a593Smuzhiyun+ rmargin = _TIFFClampDoubleToUInt32(crop->margins[3]); 91*4882a593Smuzhiyun } 92*4882a593Smuzhiyun else 93*4882a593Smuzhiyun { /* inches or centimeters specified */ 94*4882a593Smuzhiyun- tmargin = (uint32_t)(crop->margins[0] * scale * yres); 95*4882a593Smuzhiyun- lmargin = (uint32_t)(crop->margins[1] * scale * xres); 96*4882a593Smuzhiyun- bmargin = (uint32_t)(crop->margins[2] * scale * yres); 97*4882a593Smuzhiyun- rmargin = (uint32_t)(crop->margins[3] * scale * xres); 98*4882a593Smuzhiyun+ tmargin = _TIFFClampDoubleToUInt32(crop->margins[0] * scale * yres); 99*4882a593Smuzhiyun+ lmargin = _TIFFClampDoubleToUInt32(crop->margins[1] * scale * xres); 100*4882a593Smuzhiyun+ bmargin = _TIFFClampDoubleToUInt32(crop->margins[2] * scale * yres); 101*4882a593Smuzhiyun+ rmargin = _TIFFClampDoubleToUInt32(crop->margins[3] * scale * xres); 102*4882a593Smuzhiyun } 103*4882a593Smuzhiyun 104*4882a593Smuzhiyun if ((lmargin + rmargin) > image->width) 105*4882a593Smuzhiyun@@ -5295,24 +5295,24 @@ computeInputPixelOffsets(struct crop_mask *crop, struct image_data *image, 106*4882a593Smuzhiyun if (crop->res_unit != RESUNIT_INCH && crop->res_unit != RESUNIT_CENTIMETER) 107*4882a593Smuzhiyun { 108*4882a593Smuzhiyun if (crop->crop_mode & CROP_WIDTH) 109*4882a593Smuzhiyun- width = (uint32_t)crop->width; 110*4882a593Smuzhiyun+ width = _TIFFClampDoubleToUInt32(crop->width); 111*4882a593Smuzhiyun else 112*4882a593Smuzhiyun width = image->width - lmargin - rmargin; 113*4882a593Smuzhiyun 114*4882a593Smuzhiyun if (crop->crop_mode & CROP_LENGTH) 115*4882a593Smuzhiyun- length = (uint32_t)crop->length; 116*4882a593Smuzhiyun+ length = _TIFFClampDoubleToUInt32(crop->length); 117*4882a593Smuzhiyun else 118*4882a593Smuzhiyun length = image->length - tmargin - bmargin; 119*4882a593Smuzhiyun } 120*4882a593Smuzhiyun else 121*4882a593Smuzhiyun { 122*4882a593Smuzhiyun if (crop->crop_mode & CROP_WIDTH) 123*4882a593Smuzhiyun- width = (uint32_t)(crop->width * scale * image->xres); 124*4882a593Smuzhiyun+ width = _TIFFClampDoubleToUInt32(crop->width * scale * image->xres); 125*4882a593Smuzhiyun else 126*4882a593Smuzhiyun width = image->width - lmargin - rmargin; 127*4882a593Smuzhiyun 128*4882a593Smuzhiyun if (crop->crop_mode & CROP_LENGTH) 129*4882a593Smuzhiyun- length = (uint32_t)(crop->length * scale * image->yres); 130*4882a593Smuzhiyun+ length = _TIFFClampDoubleToUInt32(crop->length * scale * image->yres); 131*4882a593Smuzhiyun else 132*4882a593Smuzhiyun length = image->length - tmargin - bmargin; 133*4882a593Smuzhiyun } 134*4882a593Smuzhiyun@@ -5711,13 +5711,13 @@ computeOutputPixelOffsets (struct crop_mask *crop, struct image_data *image, 135*4882a593Smuzhiyun { 136*4882a593Smuzhiyun if (page->res_unit == RESUNIT_INCH || page->res_unit == RESUNIT_CENTIMETER) 137*4882a593Smuzhiyun { /* inches or centimeters specified */ 138*4882a593Smuzhiyun- hmargin = (uint32_t)(page->hmargin * scale * page->hres * ((image->bps + 7) / 8)); 139*4882a593Smuzhiyun- vmargin = (uint32_t)(page->vmargin * scale * page->vres * ((image->bps + 7) / 8)); 140*4882a593Smuzhiyun+ hmargin = _TIFFClampDoubleToUInt32(page->hmargin * scale * page->hres * ((image->bps + 7) / 8)); 141*4882a593Smuzhiyun+ vmargin = _TIFFClampDoubleToUInt32(page->vmargin * scale * page->vres * ((image->bps + 7) / 8)); 142*4882a593Smuzhiyun } 143*4882a593Smuzhiyun else 144*4882a593Smuzhiyun { /* Otherwise user has specified pixels as reference unit */ 145*4882a593Smuzhiyun- hmargin = (uint32_t)(page->hmargin * scale * ((image->bps + 7) / 8)); 146*4882a593Smuzhiyun- vmargin = (uint32_t)(page->vmargin * scale * ((image->bps + 7) / 8)); 147*4882a593Smuzhiyun+ hmargin = _TIFFClampDoubleToUInt32(page->hmargin * scale * ((image->bps + 7) / 8)); 148*4882a593Smuzhiyun+ vmargin = _TIFFClampDoubleToUInt32(page->vmargin * scale * ((image->bps + 7) / 8)); 149*4882a593Smuzhiyun } 150*4882a593Smuzhiyun 151*4882a593Smuzhiyun if ((hmargin * 2.0) > (pwidth * page->hres)) 152*4882a593Smuzhiyun@@ -5755,13 +5755,13 @@ computeOutputPixelOffsets (struct crop_mask *crop, struct image_data *image, 153*4882a593Smuzhiyun { 154*4882a593Smuzhiyun if (page->mode & PAGE_MODE_PAPERSIZE ) 155*4882a593Smuzhiyun { 156*4882a593Smuzhiyun- owidth = (uint32_t)((pwidth * page->hres) - (hmargin * 2)); 157*4882a593Smuzhiyun- olength = (uint32_t)((plength * page->vres) - (vmargin * 2)); 158*4882a593Smuzhiyun+ owidth = _TIFFClampDoubleToUInt32((pwidth * page->hres) - (hmargin * 2)); 159*4882a593Smuzhiyun+ olength = _TIFFClampDoubleToUInt32((plength * page->vres) - (vmargin * 2)); 160*4882a593Smuzhiyun } 161*4882a593Smuzhiyun else 162*4882a593Smuzhiyun { 163*4882a593Smuzhiyun- owidth = (uint32_t)(iwidth - (hmargin * 2 * page->hres)); 164*4882a593Smuzhiyun- olength = (uint32_t)(ilength - (vmargin * 2 * page->vres)); 165*4882a593Smuzhiyun+ owidth = _TIFFClampDoubleToUInt32(iwidth - (hmargin * 2 * page->hres)); 166*4882a593Smuzhiyun+ olength = _TIFFClampDoubleToUInt32(ilength - (vmargin * 2 * page->vres)); 167*4882a593Smuzhiyun } 168*4882a593Smuzhiyun } 169*4882a593Smuzhiyun 170*4882a593Smuzhiyun@@ -5770,6 +5770,12 @@ computeOutputPixelOffsets (struct crop_mask *crop, struct image_data *image, 171*4882a593Smuzhiyun if (olength > ilength) 172*4882a593Smuzhiyun olength = ilength; 173*4882a593Smuzhiyun 174*4882a593Smuzhiyun+ if (owidth == 0 || olength == 0) 175*4882a593Smuzhiyun+ { 176*4882a593Smuzhiyun+ TIFFError("computeOutputPixelOffsets", "Integer overflow when calculating the number of pages"); 177*4882a593Smuzhiyun+ exit(EXIT_FAILURE); 178*4882a593Smuzhiyun+ } 179*4882a593Smuzhiyun+ 180*4882a593Smuzhiyun /* Compute the number of pages required for Portrait or Landscape */ 181*4882a593Smuzhiyun switch (page->orient) 182*4882a593Smuzhiyun { 183