130 lines
4.5 KiB
Diff
130 lines
4.5 KiB
Diff
|
From cca32f0d4f3dd2bd73d044bd6991ab3c764fc718 Mon Sep 17 00:00:00 2001
|
||
|
From: Su_Laus <sulau@freenet.de>
|
||
|
Date: Sun, 6 Feb 2022 17:53:53 +0100
|
||
|
Subject: [PATCH] tiffcrop.c: This update fixes also issues #350 and #351.
|
||
|
|
||
|
Issue 350 is fixed by checking for not allowed zone input cases like -Z 0:0
|
||
|
in getCropOffsets().
|
||
|
|
||
|
CVE: CVE-2022-2867
|
||
|
|
||
|
Upstream-Status: Backport
|
||
|
[https://gitlab.com/libtiff/libtiff/-/commit/7d7bfa4416366ec64068ac389414241ed4730a54?merge_request_iid=294]
|
||
|
|
||
|
Signed-off-by: Teoh Jay Shen <jay.shen.teoh@intel.com>
|
||
|
|
||
|
---
|
||
|
tools/tiffcrop.c | 58 +++++++++++++++++++++++++++++++++---------------
|
||
|
1 file changed, 40 insertions(+), 18 deletions(-)
|
||
|
|
||
|
diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c
|
||
|
index 4a4ace8..0ef5bb2 100644
|
||
|
--- a/tools/tiffcrop.c
|
||
|
+++ b/tools/tiffcrop.c
|
||
|
@@ -5194,20 +5194,33 @@ computeInputPixelOffsets(struct crop_mask *crop, struct image_data *image,
|
||
|
y1 = _TIFFClampDoubleToUInt32(crop->corners[i].Y1);
|
||
|
y2 = _TIFFClampDoubleToUInt32(crop->corners[i].Y2);
|
||
|
}
|
||
|
- /* region needs to be within image sizes 0.. width-1; 0..length-1
|
||
|
- * - be aware x,y are already casted to (uint32_t) and avoid (0 - 1)
|
||
|
+ /* a) Region needs to be within image sizes 0.. width-1; 0..length-1
|
||
|
+ * b) Corners are expected to be submitted as top-left to bottom-right.
|
||
|
+ * Therefore, check that and reorder input.
|
||
|
+ * (be aware x,y are already casted to (uint32_t) and avoid (0 - 1) )
|
||
|
*/
|
||
|
- if (x1 > image->width - 1)
|
||
|
+ uint32_t aux;
|
||
|
+ if (x1 > x2) {
|
||
|
+ aux = x1;
|
||
|
+ x1 = x2;
|
||
|
+ x2 = aux;
|
||
|
+ }
|
||
|
+ if (y1 > y2) {
|
||
|
+ aux = y1;
|
||
|
+ y1 = y2;
|
||
|
+ y2 = aux;
|
||
|
+ }
|
||
|
+ if (x1 > image->width - 1)
|
||
|
crop->regionlist[i].x1 = image->width - 1;
|
||
|
- else if (x1 > 0)
|
||
|
- crop->regionlist[i].x1 = (uint32_t) (x1 - 1);
|
||
|
+ else if (x1 > 0)
|
||
|
+ crop->regionlist[i].x1 = (uint32_t)(x1 - 1);
|
||
|
|
||
|
- if (x2 > image->width - 1)
|
||
|
- crop->regionlist[i].x2 = image->width - 1;
|
||
|
- else if (x2 > 0)
|
||
|
- crop->regionlist[i].x2 = (uint32_t)(x2 - 1);
|
||
|
+ if (x2 > image->width - 1)
|
||
|
+ crop->regionlist[i].x2 = image->width - 1;
|
||
|
+ else if (x2 > 0)
|
||
|
+ crop->regionlist[i].x2 = (uint32_t)(x2 - 1);
|
||
|
|
||
|
- zwidth = crop->regionlist[i].x2 - crop->regionlist[i].x1 + 1;
|
||
|
+ zwidth = crop->regionlist[i].x2 - crop->regionlist[i].x1 + 1;
|
||
|
|
||
|
if (y1 > image->length - 1)
|
||
|
crop->regionlist[i].y1 = image->length - 1;
|
||
|
@@ -5219,8 +5232,7 @@ computeInputPixelOffsets(struct crop_mask *crop, struct image_data *image,
|
||
|
else if (y2 > 0)
|
||
|
crop->regionlist[i].y2 = (uint32_t)(y2 - 1);
|
||
|
|
||
|
- zlength = crop->regionlist[i].y2 - crop->regionlist[i].y1 + 1;
|
||
|
-
|
||
|
+ zlength = crop->regionlist[i].y2 - crop->regionlist[i].y1 + 1;
|
||
|
if (zwidth > max_width)
|
||
|
max_width = zwidth;
|
||
|
if (zlength > max_length)
|
||
|
@@ -5250,7 +5262,7 @@ computeInputPixelOffsets(struct crop_mask *crop, struct image_data *image,
|
||
|
}
|
||
|
}
|
||
|
return (0);
|
||
|
- }
|
||
|
+ } /* crop_mode == CROP_REGIONS */
|
||
|
|
||
|
/* Convert crop margins into offsets into image
|
||
|
* Margins are expressed as pixel rows and columns, not bytes
|
||
|
@@ -5286,7 +5298,7 @@ computeInputPixelOffsets(struct crop_mask *crop, struct image_data *image,
|
||
|
bmargin = (uint32_t) 0;
|
||
|
return (-1);
|
||
|
}
|
||
|
- }
|
||
|
+ } /* crop_mode == CROP_MARGINS */
|
||
|
else
|
||
|
{ /* no margins requested */
|
||
|
tmargin = (uint32_t) 0;
|
||
|
@@ -5494,10 +5506,17 @@ getCropOffsets(struct image_data *image, struct crop_mask *crop, struct dump_opt
|
||
|
else
|
||
|
crop->selections = crop->zones;
|
||
|
|
||
|
- for (i = 0; i < crop->zones; i++)
|
||
|
+ /* Initialize regions iterator i */
|
||
|
+ i = 0;
|
||
|
+ for (int j = 0; j < crop->zones; j++)
|
||
|
{
|
||
|
- seg = crop->zonelist[i].position;
|
||
|
- total = crop->zonelist[i].total;
|
||
|
+ seg = crop->zonelist[j].position;
|
||
|
+ total = crop->zonelist[j].total;
|
||
|
+
|
||
|
+ /* check for not allowed zone cases like 0:0; 4:3; etc. and skip that input */
|
||
|
+ if (seg == 0 || total == 0 || seg > total) {
|
||
|
+ continue;
|
||
|
+ }
|
||
|
|
||
|
switch (crop->edge_ref)
|
||
|
{
|
||
|
@@ -5626,8 +5645,11 @@ getCropOffsets(struct image_data *image, struct crop_mask *crop, struct dump_opt
|
||
|
i + 1, zwidth, zlength,
|
||
|
crop->regionlist[i].x1, crop->regionlist[i].x2,
|
||
|
crop->regionlist[i].y1, crop->regionlist[i].y2);
|
||
|
+ /* increment regions iterator */
|
||
|
+ i++;
|
||
|
}
|
||
|
-
|
||
|
+ /* set number of generated regions out of given zones */
|
||
|
+ crop->selections = i;
|
||
|
return (0);
|
||
|
} /* end getCropOffsets */
|
||
|
|