Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
CVE-2023-0797 CVE-2023-0798 CVE-2023-0799 CVE-2023-0800 CVE-2023-0801 CVE-2023-0802 CVE-2023-0803 CVE-2023-0804 and a null pointer dereference ok landry
- Loading branch information
tj
committed
Feb 22, 2023
1 parent
7b6a09e
commit 96602dd
Showing
3 changed files
with
353 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
TIFFClose() avoid NULL pointer dereference | ||
https://gitlab.com/libtiff/libtiff/-/commit/d63de61b1e | ||
|
||
Index: libtiff/tif_close.c | ||
--- libtiff/tif_close.c.orig | ||
+++ libtiff/tif_close.c | ||
@@ -130,9 +130,12 @@ void TIFFCleanup(TIFF *tif) | ||
|
||
void TIFFClose(TIFF *tif) | ||
{ | ||
- TIFFCloseProc closeproc = tif->tif_closeproc; | ||
- thandle_t fd = tif->tif_clientdata; | ||
+ if (tif != NULL) | ||
+ { | ||
+ TIFFCloseProc closeproc = tif->tif_closeproc; | ||
+ thandle_t fd = tif->tif_clientdata; | ||
|
||
- TIFFCleanup(tif); | ||
- (void)(*closeproc)(fd); | ||
+ TIFFCleanup(tif); | ||
+ (void)(*closeproc)(fd); | ||
+ } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,329 @@ | ||
CVE-2022-48281 | ||
https://gitlab.com/libtiff/libtiff/-/commit/97d65859bc | ||
|
||
Correctly update buffersize after rotateImage() | ||
https://gitlab.com/libtiff/libtiff/-/commit/9c22495e5e | ||
|
||
CVE-2023-0795 CVE-2023-0796 CVE-2023-0797 CVE-2023-0798 | ||
and CVE-2023-0799 | ||
https://gitlab.com/libtiff/libtiff/-/commit/69818e2f2d | ||
|
||
CVE-2023-0800 CVE-2023-0801 CVE-2023-0802 CVE-2023-0803 | ||
and CVE-2023-0804 | ||
https://gitlab.com/libtiff/libtiff/-/commit/82a7fbb1fa | ||
|
||
Index: tools/tiffcrop.c | ||
--- tools/tiffcrop.c.orig | ||
+++ 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_ | ||
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 *, 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, | ||
@@ -2920,7 +2919,10 @@ int main(int argc, char *argv[]) | ||
} | ||
} | ||
|
||
- TIFFClose(out); | ||
+ if (out != NULL) | ||
+ { | ||
+ TIFFClose(out); | ||
+ } | ||
|
||
return (0); | ||
} /* end main */ | ||
@@ -5779,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; | ||
} | ||
@@ -5932,18 +5933,40 @@ static int computeInputPixelOffsets(struct crop_mask * | ||
|
||
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; | ||
@@ -7241,9 +7264,13 @@ static int correct_orientation(struct image_data *imag | ||
(uint16_t)(image->adjustments & ROTATE_ANY)); | ||
return (-1); | ||
} | ||
- | ||
- if (rotateImage(rotation, image, &image->width, &image->length, | ||
- work_buff_ptr)) | ||
+ /* 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); | ||
@@ -7298,6 +7325,46 @@ static int extractCompositeRegions(struct image_data * | ||
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 */ | ||
@@ -7312,7 +7379,6 @@ static int extractCompositeRegions(struct image_data * | ||
/* 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); | ||
@@ -7322,7 +7388,8 @@ static int extractCompositeRegions(struct image_data * | ||
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 " | ||
@@ -7415,7 +7482,8 @@ static int extractCompositeRegions(struct image_data * | ||
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 " | ||
@@ -7573,7 +7641,6 @@ static int extractSeparateRegion(struct image_data *im | ||
|
||
crop->regionlist[region].width = crop_width; | ||
crop->regionlist[region].length = crop_length; | ||
- crop->regionlist[region].buffptr = crop_buff; | ||
|
||
src = read_buff; | ||
dst = crop_buff; | ||
@@ -8563,8 +8630,13 @@ static int processCropSelections(struct image_data *im | ||
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, | ||
+ FALSE)) | ||
{ | ||
TIFFError("processCropSelections", | ||
"Failed to rotate composite regions by %" PRIu32 | ||
@@ -8573,9 +8645,7 @@ static int processCropSelections(struct image_data *im | ||
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 */ | ||
@@ -8591,7 +8661,7 @@ static int processCropSelections(struct image_data *im | ||
cropsize + NUM_BUFF_OVERSIZE_BYTES); | ||
else | ||
{ | ||
- prev_cropsize = seg_buffs[0].size; | ||
+ prev_cropsize = seg_buffs[i].size; | ||
if (prev_cropsize < cropsize) | ||
{ | ||
next_buff = _TIFFrealloc( | ||
@@ -8686,10 +8756,14 @@ static int processCropSelections(struct image_data *im | ||
* ->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()) !! | ||
- */ | ||
+ * 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)) | ||
+ &crop->regionlist[i].length, &crop_buff, | ||
+ &rot_buf_size, FALSE)) | ||
{ | ||
TIFFError("processCropSelections", | ||
"Failed to rotate crop region by %" PRIu16 | ||
@@ -8702,10 +8776,7 @@ static int processCropSelections(struct image_data *im | ||
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 +8907,7 @@ static int createCroppedImage(struct image_data *image | ||
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, TRUE)) | ||
{ | ||
TIFFError("createCroppedImage", | ||
"Failed to rotate image or cropped selection by %" PRIu16 | ||
@@ -9552,7 +9623,8 @@ static int rotateContigSamples32bits(uint16_t rotation | ||
/* 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 rot_image_params) | ||
{ | ||
int shift_width; | ||
uint32_t bytes_per_pixel, bytes_per_sample; | ||
@@ -9610,6 +9682,8 @@ static int rotateImage(uint16_t rotation, struct 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) | ||
@@ -9768,11 +9842,15 @@ static int rotateImage(uint16_t rotation, struct 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: | ||
@@ -9855,11 +9933,15 @@ static int rotateImage(uint16_t rotation, struct 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; |