1From cca32f0d4f3dd2bd73d044bd6991ab3c764fc718 Mon Sep 17 00:00:00 2001 2From: Su_Laus <sulau@freenet.de> 3Date: Sun, 6 Feb 2022 17:53:53 +0100 4Subject: [PATCH] tiffcrop.c: This update fixes also issues #350 and #351. 5 6 Issue 350 is fixed by checking for not allowed zone input cases like -Z 0:0 7 in getCropOffsets(). 8 9CVE: CVE-2022-2867 10 11Upstream-Status: Backport 12[https://gitlab.com/libtiff/libtiff/-/commit/7d7bfa4416366ec64068ac389414241ed4730a54?merge_request_iid=294] 13 14Signed-off-by: Teoh Jay Shen <jay.shen.teoh@intel.com> 15 16--- 17 tools/tiffcrop.c | 58 +++++++++++++++++++++++++++++++++--------------- 18 1 file changed, 40 insertions(+), 18 deletions(-) 19 20diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c 21index 4a4ace8..0ef5bb2 100644 22--- a/tools/tiffcrop.c 23+++ b/tools/tiffcrop.c 24@@ -5194,20 +5194,33 @@ computeInputPixelOffsets(struct crop_mask *crop, struct image_data *image, 25 y1 = _TIFFClampDoubleToUInt32(crop->corners[i].Y1); 26 y2 = _TIFFClampDoubleToUInt32(crop->corners[i].Y2); 27 } 28- /* region needs to be within image sizes 0.. width-1; 0..length-1 29- * - be aware x,y are already casted to (uint32_t) and avoid (0 - 1) 30+ /* a) Region needs to be within image sizes 0.. width-1; 0..length-1 31+ * b) Corners are expected to be submitted as top-left to bottom-right. 32+ * Therefore, check that and reorder input. 33+ * (be aware x,y are already casted to (uint32_t) and avoid (0 - 1) ) 34 */ 35- if (x1 > image->width - 1) 36+ uint32_t aux; 37+ if (x1 > x2) { 38+ aux = x1; 39+ x1 = x2; 40+ x2 = aux; 41+ } 42+ if (y1 > y2) { 43+ aux = y1; 44+ y1 = y2; 45+ y2 = aux; 46+ } 47+ if (x1 > image->width - 1) 48 crop->regionlist[i].x1 = image->width - 1; 49- else if (x1 > 0) 50- crop->regionlist[i].x1 = (uint32_t) (x1 - 1); 51+ else if (x1 > 0) 52+ crop->regionlist[i].x1 = (uint32_t)(x1 - 1); 53 54- if (x2 > image->width - 1) 55- crop->regionlist[i].x2 = image->width - 1; 56- else if (x2 > 0) 57- crop->regionlist[i].x2 = (uint32_t)(x2 - 1); 58+ if (x2 > image->width - 1) 59+ crop->regionlist[i].x2 = image->width - 1; 60+ else if (x2 > 0) 61+ crop->regionlist[i].x2 = (uint32_t)(x2 - 1); 62 63- zwidth = crop->regionlist[i].x2 - crop->regionlist[i].x1 + 1; 64+ zwidth = crop->regionlist[i].x2 - crop->regionlist[i].x1 + 1; 65 66 if (y1 > image->length - 1) 67 crop->regionlist[i].y1 = image->length - 1; 68@@ -5219,8 +5232,7 @@ computeInputPixelOffsets(struct crop_mask *crop, struct image_data *image, 69 else if (y2 > 0) 70 crop->regionlist[i].y2 = (uint32_t)(y2 - 1); 71 72- zlength = crop->regionlist[i].y2 - crop->regionlist[i].y1 + 1; 73- 74+ zlength = crop->regionlist[i].y2 - crop->regionlist[i].y1 + 1; 75 if (zwidth > max_width) 76 max_width = zwidth; 77 if (zlength > max_length) 78@@ -5250,7 +5262,7 @@ computeInputPixelOffsets(struct crop_mask *crop, struct image_data *image, 79 } 80 } 81 return (0); 82- } 83+ } /* crop_mode == CROP_REGIONS */ 84 85 /* Convert crop margins into offsets into image 86 * Margins are expressed as pixel rows and columns, not bytes 87@@ -5286,7 +5298,7 @@ computeInputPixelOffsets(struct crop_mask *crop, struct image_data *image, 88 bmargin = (uint32_t) 0; 89 return (-1); 90 } 91- } 92+ } /* crop_mode == CROP_MARGINS */ 93 else 94 { /* no margins requested */ 95 tmargin = (uint32_t) 0; 96@@ -5494,10 +5506,17 @@ getCropOffsets(struct image_data *image, struct crop_mask *crop, struct dump_opt 97 else 98 crop->selections = crop->zones; 99 100- for (i = 0; i < crop->zones; i++) 101+ /* Initialize regions iterator i */ 102+ i = 0; 103+ for (int j = 0; j < crop->zones; j++) 104 { 105- seg = crop->zonelist[i].position; 106- total = crop->zonelist[i].total; 107+ seg = crop->zonelist[j].position; 108+ total = crop->zonelist[j].total; 109+ 110+ /* check for not allowed zone cases like 0:0; 4:3; etc. and skip that input */ 111+ if (seg == 0 || total == 0 || seg > total) { 112+ continue; 113+ } 114 115 switch (crop->edge_ref) 116 { 117@@ -5626,8 +5645,11 @@ getCropOffsets(struct image_data *image, struct crop_mask *crop, struct dump_opt 118 i + 1, zwidth, zlength, 119 crop->regionlist[i].x1, crop->regionlist[i].x2, 120 crop->regionlist[i].y1, crop->regionlist[i].y2); 121+ /* increment regions iterator */ 122+ i++; 123 } 124- 125+ /* set number of generated regions out of given zones */ 126+ crop->selections = i; 127 return (0); 128 } /* end getCropOffsets */ 129 130