From 320bc0e2e357e6540bdbb38f77f58e2ca3be5204 Mon Sep 17 00:00:00 2001 From: zhouwenpei Date: Thu, 16 Feb 2023 11:39:47 +0000 Subject: [PATCH] fix CVE-2023-0795~0804 --- ...01-CVE-2023-0795-0796-0797-0798-0799.patch | 120 +++++++++++++ ...02-CVE-2023-0795-0796-0797-0798-0799.patch | 128 ++++++++++++++ ...rt-CVE-2023-0800-0801-0802-0803-0804.patch | 162 ++++++++++++++++++ libtiff.spec | 9 +- 4 files changed, 418 insertions(+), 1 deletion(-) create mode 100644 backport-0001-CVE-2023-0795-0796-0797-0798-0799.patch create mode 100644 backport-0002-CVE-2023-0795-0796-0797-0798-0799.patch create mode 100644 backport-CVE-2023-0800-0801-0802-0803-0804.patch diff --git a/backport-0001-CVE-2023-0795-0796-0797-0798-0799.patch b/backport-0001-CVE-2023-0795-0796-0797-0798-0799.patch new file mode 100644 index 0000000..0083ccd --- /dev/null +++ b/backport-0001-CVE-2023-0795-0796-0797-0798-0799.patch @@ -0,0 +1,120 @@ +From 9c22495e5eeeae9e00a1596720c969656bb8d678 Mon Sep 17 00:00:00 2001 +From: Su_Laus +Date: Fri, 3 Feb 2023 15:31:31 +0100 +Subject: [PATCH] tiffcrop correctly update buffersize after rotateImage() + fix#520 rotateImage() set up a new buffer and calculates its size + individually. Therefore, seg_buffs[] size needs to be updated accordingly. + Before this fix, the seg_buffs buffer size was calculated with a different + formula than within rotateImage(). + +Closes #520. +--- + tools/tiffcrop.c | 36 ++++++++++++++++++++---------------- + 1 file changed, 20 insertions(+), 16 deletions(-) + +diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c +index 7db69883..f8b66188 100644 +--- a/tools/tiffcrop.c ++++ b/tools/tiffcrop.c +@@ -577,7 +577,7 @@ static int rotateContigSamples24bits(uint16_t, uint16_t, uint16_t, uint32_t, + static int rotateContigSamples32bits(uint16_t, uint16_t, uint16_t, uint32_t, + uint32_t, uint32_t, uint8_t *, uint8_t *); + static int rotateImage(uint16_t, struct image_data *, uint32_t *, uint32_t *, +- unsigned char **); ++ unsigned char **, size_t *); + static int mirrorImage(uint16_t, uint16_t, uint16_t, uint32_t, uint32_t, + unsigned char *); + static int invertImage(uint16_t, uint16_t, uint16_t, uint32_t, uint32_t, +@@ -7243,7 +7243,7 @@ static int correct_orientation(struct image_data *image, + } + + if (rotateImage(rotation, image, &image->width, &image->length, +- work_buff_ptr)) ++ work_buff_ptr, NULL)) + { + TIFFError("correct_orientation", "Unable to rotate image"); + return (-1); +@@ -8563,8 +8563,12 @@ static int processCropSelections(struct image_data *image, + if (crop->crop_mode & CROP_ROTATE) /* rotate should be last as it can + reallocate the buffer */ + { ++ /* rotateImage() set up a new buffer and calculates its size ++ * individually. Therefore, seg_buffs size needs to be updated ++ * accordingly. */ ++ size_t rot_buf_size = 0; + if (rotateImage(crop->rotation, image, &crop->combined_width, +- &crop->combined_length, &crop_buff)) ++ &crop->combined_length, &crop_buff, &rot_buf_size)) + { + TIFFError("processCropSelections", + "Failed to rotate composite regions by %" PRIu32 +@@ -8573,9 +8577,7 @@ static int processCropSelections(struct image_data *image, + return (-1); + } + seg_buffs[0].buffer = crop_buff; +- seg_buffs[0].size = +- (((crop->combined_width * image->bps + 7) / 8) * image->spp) * +- crop->combined_length; ++ seg_buffs[0].size = rot_buf_size; + } + } + else /* Separated Images */ +@@ -8686,10 +8688,13 @@ static int processCropSelections(struct image_data *image, + * ->yres, what it schouldn't do here, when more than one + * section is processed. ToDo: Therefore rotateImage() and its + * usage has to be reworked (e.g. like mirrorImage()) !! +- */ +- if (rotateImage(crop->rotation, image, +- &crop->regionlist[i].width, +- &crop->regionlist[i].length, &crop_buff)) ++ * Furthermore, rotateImage() set up a new buffer and calculates ++ * its size individually. Therefore, seg_buffs size needs to be ++ * updated accordingly. */ ++ size_t rot_buf_size = 0; ++ if (rotateImage( ++ crop->rotation, image, &crop->regionlist[i].width, ++ &crop->regionlist[i].length, &crop_buff, &rot_buf_size)) + { + TIFFError("processCropSelections", + "Failed to rotate crop region by %" PRIu16 +@@ -8702,10 +8707,7 @@ static int processCropSelections(struct image_data *image, + crop->combined_width = total_width; + crop->combined_length = total_length; + seg_buffs[i].buffer = crop_buff; +- seg_buffs[i].size = +- (((crop->regionlist[i].width * image->bps + 7) / 8) * +- image->spp) * +- crop->regionlist[i].length; ++ seg_buffs[i].size = rot_buf_size; + } + } /* for crop->selections loop */ + } /* Separated Images (else case) */ +@@ -8836,7 +8838,7 @@ static int createCroppedImage(struct image_data *image, struct crop_mask *crop, + CROP_ROTATE) /* rotate should be last as it can reallocate the buffer */ + { + if (rotateImage(crop->rotation, image, &crop->combined_width, +- &crop->combined_length, crop_buff_ptr)) ++ &crop->combined_length, crop_buff_ptr, NULL)) + { + TIFFError("createCroppedImage", + "Failed to rotate image or cropped selection by %" PRIu16 +@@ -9552,7 +9554,7 @@ static int rotateContigSamples32bits(uint16_t rotation, uint16_t spp, + /* Rotate an image by a multiple of 90 degrees clockwise */ + static int rotateImage(uint16_t rotation, struct image_data *image, + uint32_t *img_width, uint32_t *img_length, +- unsigned char **ibuff_ptr) ++ unsigned char **ibuff_ptr, size_t *rot_buf_size) + { + int shift_width; + uint32_t bytes_per_pixel, bytes_per_sample; +@@ -9610,6 +9612,8 @@ static int rotateImage(uint16_t rotation, struct image_data *image, + return (-1); + } + _TIFFmemset(rbuff, '\0', buffsize + NUM_BUFF_OVERSIZE_BYTES); ++ if (rot_buf_size != NULL) ++ *rot_buf_size = buffsize; + + ibuff = *ibuff_ptr; + switch (rotation) +-- +GitLab diff --git a/backport-0002-CVE-2023-0795-0796-0797-0798-0799.patch b/backport-0002-CVE-2023-0795-0796-0797-0798-0799.patch new file mode 100644 index 0000000..4ae4885 --- /dev/null +++ b/backport-0002-CVE-2023-0795-0796-0797-0798-0799.patch @@ -0,0 +1,128 @@ +From 82a7fbb1fa7228499ffeb3a57a1d106a9626d57c Mon Sep 17 00:00:00 2001 +From: Su Laus +Date: Sun, 5 Feb 2023 15:53:15 +0000 +Subject: [PATCH] tiffcrop: added check for assumption on composite images + (fixes #496) + +tiffcrop: 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. This is now checked before the first copy action. + +Closes #496, #497, #498, #500, #501. +--- + tools/tiffcrop.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 66 insertions(+), 2 deletions(-) + +diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c +index 84e26ac6..480b927c 100644 +--- a/tools/tiffcrop.c ++++ b/tools/tiffcrop.c +@@ -5935,18 +5935,40 @@ static int computeInputPixelOffsets(struct crop_mask *crop, + + 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; +@@ -7301,6 +7323,46 @@ static int extractCompositeRegions(struct image_data *image, + 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 */ +@@ -7325,7 +7387,8 @@ static int extractCompositeRegions(struct image_data *image, + 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 " +@@ -7418,7 +7481,8 @@ static int extractCompositeRegions(struct image_data *image, + 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 " +-- +GitLab + diff --git a/backport-CVE-2023-0800-0801-0802-0803-0804.patch b/backport-CVE-2023-0800-0801-0802-0803-0804.patch new file mode 100644 index 0000000..1368875 --- /dev/null +++ b/backport-CVE-2023-0800-0801-0802-0803-0804.patch @@ -0,0 +1,162 @@ +From 69818e2f2d246e6631ac2a2da692c3706b849c38 Mon Sep 17 00:00:00 2001 +From: Su_Laus +Date: Sun, 29 Jan 2023 11:09:26 +0100 +Subject: [PATCH] tiffcrop: Amend rotateImage() not to toggle the input (main) + image width and length parameters when only cropped image sections are + rotated. Remove buffptr from region structure because never used. + +Closes #492 #493 #494 #495 #499 #518 #519 +--- + tools/tiffcrop.c | 59 ++++++++++++++++++++++++++++-------------------- + 1 file changed, 35 insertions(+), 24 deletions(-) + +diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c +index ebea7475..519871ec 100644 +--- a/tools/tiffcrop.c ++++ b/tools/tiffcrop.c +@@ -296,7 +296,6 @@ struct region + uint32_t width; /* width in pixels */ + uint32_t length; /* length in pixels */ + uint32_t buffsize; /* size of buffer needed to hold the cropped region */ +- unsigned char *buffptr; /* address of start of the region */ + }; + + /* Cropping parameters from command line and image data +@@ -577,7 +576,7 @@ static int rotateContigSamples24bits(uint16_t, uint16_t, uint16_t, uint32_t, + static int rotateContigSamples32bits(uint16_t, uint16_t, uint16_t, uint32_t, + uint32_t, uint32_t, uint8_t *, uint8_t *); + static int rotateImage(uint16_t, struct image_data *, uint32_t *, uint32_t *, +- unsigned char **, size_t *); ++ unsigned char **, size_t *, int); + static int mirrorImage(uint16_t, uint16_t, uint16_t, uint32_t, uint32_t, + unsigned char *); + static int invertImage(uint16_t, uint16_t, uint16_t, uint32_t, uint32_t, +@@ -5782,7 +5781,6 @@ static void initCropMasks(struct crop_mask *cps) + cps->regionlist[i].width = 0; + cps->regionlist[i].length = 0; + cps->regionlist[i].buffsize = 0; +- cps->regionlist[i].buffptr = NULL; + cps->zonelist[i].position = 0; + cps->zonelist[i].total = 0; + } +@@ -7266,9 +7264,13 @@ static int correct_orientation(struct image_data *image, + (uint16_t)(image->adjustments & ROTATE_ANY)); + return (-1); + } +- +- if (rotateImage(rotation, image, &image->width, &image->length, +- work_buff_ptr, NULL)) ++ /* Dummy variable in order not to switch two times the ++ * image->width,->length within rotateImage(), ++ * but switch xres, yres there. */ ++ uint32_t width = image->width; ++ uint32_t length = image->length; ++ if (rotateImage(rotation, image, &width, &length, work_buff_ptr, NULL, ++ TRUE)) + { + TIFFError("correct_orientation", "Unable to rotate image"); + return (-1); +@@ -7377,7 +7379,6 @@ static int extractCompositeRegions(struct image_data *image, + /* These should not be needed for composite images */ + crop->regionlist[i].width = crop_width; + crop->regionlist[i].length = crop_length; +- crop->regionlist[i].buffptr = crop_buff; + + src_rowsize = ((img_width * bps * spp) + 7) / 8; + dst_rowsize = (((crop_width * bps * count) + 7) / 8); +@@ -7640,7 +7641,6 @@ static int extractSeparateRegion(struct image_data *image, + + crop->regionlist[region].width = crop_width; + crop->regionlist[region].length = crop_length; +- crop->regionlist[region].buffptr = crop_buff; + + src = read_buff; + dst = crop_buff; +@@ -8635,7 +8635,8 @@ static int processCropSelections(struct image_data *image, + * accordingly. */ + size_t rot_buf_size = 0; + if (rotateImage(crop->rotation, image, &crop->combined_width, +- &crop->combined_length, &crop_buff, &rot_buf_size)) ++ &crop->combined_length, &crop_buff, &rot_buf_size, ++ FALSE)) + { + TIFFError("processCropSelections", + "Failed to rotate composite regions by %" PRIu32 +@@ -8759,9 +8760,10 @@ static int processCropSelections(struct image_data *image, + * its size individually. Therefore, seg_buffs size needs to be + * updated accordingly. */ + size_t rot_buf_size = 0; +- if (rotateImage( +- crop->rotation, image, &crop->regionlist[i].width, +- &crop->regionlist[i].length, &crop_buff, &rot_buf_size)) ++ if (rotateImage(crop->rotation, image, ++ &crop->regionlist[i].width, ++ &crop->regionlist[i].length, &crop_buff, ++ &rot_buf_size, FALSE)) + { + TIFFError("processCropSelections", + "Failed to rotate crop region by %" PRIu16 +@@ -8905,7 +8907,7 @@ static int createCroppedImage(struct image_data *image, struct crop_mask *crop, + CROP_ROTATE) /* rotate should be last as it can reallocate the buffer */ + { + if (rotateImage(crop->rotation, image, &crop->combined_width, +- &crop->combined_length, crop_buff_ptr, NULL)) ++ &crop->combined_length, crop_buff_ptr, NULL, TRUE)) + { + TIFFError("createCroppedImage", + "Failed to rotate image or cropped selection by %" PRIu16 +@@ -9621,7 +9623,8 @@ static int rotateContigSamples32bits(uint16_t rotation, uint16_t spp, + /* Rotate an image by a multiple of 90 degrees clockwise */ + static int rotateImage(uint16_t rotation, struct image_data *image, + uint32_t *img_width, uint32_t *img_length, +- unsigned char **ibuff_ptr, size_t *rot_buf_size) ++ unsigned char **ibuff_ptr, size_t *rot_buf_size, ++ int rot_image_params) + { + int shift_width; + uint32_t bytes_per_pixel, bytes_per_sample; +@@ -9869,11 +9872,15 @@ static int rotateImage(uint16_t rotation, struct image_data *image, + + *img_width = length; + *img_length = width; +- image->width = length; +- image->length = width; +- res_temp = image->xres; +- image->xres = image->yres; +- image->yres = res_temp; ++ /* Only toggle image parameters if whole input image is rotated. */ ++ if (rot_image_params) ++ { ++ image->width = length; ++ image->length = width; ++ res_temp = image->xres; ++ image->xres = image->yres; ++ image->yres = res_temp; ++ } + break; + + case 270: +@@ -9956,11 +9963,15 @@ static int rotateImage(uint16_t rotation, struct image_data *image, + + *img_width = length; + *img_length = width; +- image->width = length; +- image->length = width; +- res_temp = image->xres; +- image->xres = image->yres; +- image->yres = res_temp; ++ /* Only toggle image parameters if whole input image is rotated. */ ++ if (rot_image_params) ++ { ++ image->width = length; ++ image->length = width; ++ res_temp = image->xres; ++ image->xres = image->yres; ++ image->yres = res_temp; ++ } + break; + default: + break; +-- +GitLab + diff --git a/libtiff.spec b/libtiff.spec index 2590b0e..ef05804 100644 --- a/libtiff.spec +++ b/libtiff.spec @@ -1,12 +1,15 @@ Name: libtiff Version: 4.5.0 -Release: 1 +Release: 2 Summary: TIFF Library and Utilities License: libtiff URL: https://www.simplesystems.org/libtiff/ Source0: https://download.osgeo.org/libtiff/tiff-%{version}.tar.gz Patch6000: backport-CVE-2022-48281.patch +Patch6001: backport-0001-CVE-2023-0795-0796-0797-0798-0799.patch +Patch6002: backport-0002-CVE-2023-0795-0796-0797-0798-0799.patch +Patch6003: backport-CVE-2023-0800-0801-0802-0803-0804.patch BuildRequires: gcc gcc-c++ zlib-devel libjpeg-devel jbigkit-devel BuildRequires: libtool automake autoconf pkgconfig libtiff @@ -129,6 +132,10 @@ find doc -name 'Makefile*' | xargs rm %exclude %{_mandir}/man1/* %changelog +* Thu Feb 16 2023 zhouwenpei - 4.5.0-2 +- fix CVE-2023-0795,CVE-2023-0796,CVE-2023-0797,CVE-2023-0798,CVE-2023-0799, +- fix CVE-2023-0800,CVE-2023-0801,CVE-2023-0802,CVE-2023-0803,CVE-2023-0804 + * Thu Feb 09 2023 zhouwenpei - 4.5.0-1 - update to 4.5.0