From 73b3f582caa08a976d647537346790b182bbcc10 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 5 Feb 2023 15:53:16 +0000 Subject: [PATCH] (CVE-2023-0800 CVE-2023-0801 CVE-2023-0802 CVE-2023-0803 CVE-2023-0804) tiffcrop: added check for assumption on composite images (fixes #496) Closes #501, #500, #498, #497 et #496 See merge request libtiff/libtiff!466 (cherry picked from commit 33aee1275d9d1384791d2206776eb8152d397f00) --- tools/tiffcrop.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c index 7f738d91..77923cf3 100644 --- a/tools/tiffcrop.c +++ b/tools/tiffcrop.c @@ -5235,18 +5235,40 @@ computeInputPixelOffsets(struct crop_mask *crop, struct image_data *image, crop->regionlist[i].buffsize = buffsize; crop->bufftotal += buffsize; + + /* For composite images with more than one region, the + * combined_length or combined_width always needs to be equal, + * respectively. + * Otherwise, even the first section/region copy + * action might cause buffer overrun. */ if (crop->img_mode == COMPOSITE_IMAGES) { switch (crop->edge_ref) { case EDGE_LEFT: case EDGE_RIGHT: + if (i > 0 && zlength != crop->combined_length) + { + TIFFError( + "computeInputPixelOffsets", + "Only equal length regions can be combined for " + "-E left or right"); + return (-1); + } crop->combined_length = zlength; crop->combined_width += zwidth; break; case EDGE_BOTTOM: case EDGE_TOP: /* width from left, length from top */ default: + if (i > 0 && zwidth != crop->combined_width) + { + TIFFError("computeInputPixelOffsets", + "Only equal width regions can be " + "combined for -E " + "top or bottom"); + return (-1); + } crop->combined_width = zwidth; crop->combined_length += zlength; break; @@ -6390,6 +6412,46 @@ extractCompositeRegions(struct image_data *image, struct crop_mask *crop, crop->combined_width = 0; crop->combined_length = 0; + /* If there is more than one region, check beforehand whether all the width + * and length values of the regions are the same, respectively. */ + switch (crop->edge_ref) + { + default: + case EDGE_TOP: + case EDGE_BOTTOM: + for (i = 1; i < crop->selections; i++) + { + uint32_t crop_width0 = + crop->regionlist[i - 1].x2 - crop->regionlist[i - 1].x1 + 1; + uint32_t crop_width1 = + crop->regionlist[i].x2 - crop->regionlist[i].x1 + 1; + if (crop_width0 != crop_width1) + { + TIFFError("extractCompositeRegions", + "Only equal width regions can be combined for -E " + "top or bottom"); + return (1); + } + } + break; + case EDGE_LEFT: + case EDGE_RIGHT: + for (i = 1; i < crop->selections; i++) + { + uint32_t crop_length0 = + crop->regionlist[i - 1].y2 - crop->regionlist[i - 1].y1 + 1; + uint32_t crop_length1 = + crop->regionlist[i].y2 - crop->regionlist[i].y1 + 1; + if (crop_length0 != crop_length1) + { + TIFFError("extractCompositeRegions", + "Only equal length regions can be combined for " + "-E left or right"); + return (1); + } + } + } + for (i = 0; i < crop->selections; i++) { /* rows, columns, width, length are expressed in pixels */ @@ -6414,7 +6476,8 @@ extractCompositeRegions(struct image_data *image, struct crop_mask *crop, default: case EDGE_TOP: case EDGE_BOTTOM: - if ((i > 0) && (crop_width != crop->regionlist[i - 1].width)) + if ((crop->selections > i + 1) && + (crop_width != crop->regionlist[i + 1].width)) { TIFFError ("extractCompositeRegions", "Only equal width regions can be combined for -E top or bottom"); @@ -6495,7 +6558,8 @@ extractCompositeRegions(struct image_data *image, struct crop_mask *crop, break; case EDGE_LEFT: /* splice the pieces of each row together, side by side */ case EDGE_RIGHT: - if ((i > 0) && (crop_length != crop->regionlist[i - 1].length)) + if ((crop->selections > i + 1) && + (crop_length != crop->regionlist[i + 1].length)) { TIFFError ("extractCompositeRegions", "Only equal length regions can be combined for -E left or right");