Skip to content
Snippets Groups Projects
Commit 46533ceb authored by Stefan Schmidt's avatar Stefan Schmidt
Browse files

Merge branch 'ghassaneben-kirkstone-patch-77760' into 'kirkstone'

tiff: backport upstream fix for CVE-2022-2867, CVE-2022-2868, CVE-2022-2869

See merge request !348
parents 182728eb a40d01a8
No related branches found
No related tags found
1 merge request!348tiff: backport upstream fix for CVE-2022-2867, CVE-2022-2868, CVE-2022-2869
From: Su Laus
Date: Thu, 20 Oct 2022 12:58:24 +0200
Subject: [PATCH] tiff: Fix upstream issue #352 heap-buffer-overflow by correcting uint32_t underflow.
Fixes upstream issue #352 (closed) where a buffer overflow was generated by an uint underflow in tiffcrop.c computeInputPixelOffsets() calculating (uint32_t)(0 - 1) around line 5210. In the following tiffcrop tries to read pixels from the image at an offset far beyond the file-/buffersize.
The main region checks in computeInputPixelOffsets() are now updated to avoid uint underflow.
This update fixes also upstream issues #350 (closed) and #351 (closed).
Issue 350 is fixed by checking for not allowed zone input cases like -Z 0:0 in getCropOffsets().
Furthermore upstream issue #335 (closed) and #336 (closed) are also fixed.
Signed-off-by: Ghassane Ben El Aattar <ghassaneb.aattar@huawei.com>
CVE: CVE-2022-2867, CVE-2022-2868, CVE-2022-2869
Upstream-status: Backport [https://gitlab.com/libtiff/libtiff/-/merge_requests/294?commit_id=7d7bfa4416366ec64068ac389414241ed4730a54]
---
tools/tiffcrop.c | 83 +++++++++++++++++++++++++++++++-----------------
1 file changed, 53 insertions(+), 30 deletions(-)
diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c
index b85c2ce..e4a08ca 100644
--- a/tools/tiffcrop.c
+++ b/tools/tiffcrop.c
@@ -1177,7 +1177,6 @@ writeBufferToSeparateStrips (TIFF* out, uint8_t* buf,
tstrip_t strip = 0;
tsize_t stripsize = TIFFStripSize(out);
tsize_t rowstripsize, scanlinesize = TIFFScanlineSize(out);
- tsize_t total_bytes = 0;
tdata_t obuf;
(void) TIFFGetFieldDefaulted(out, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
@@ -1215,7 +1214,6 @@ writeBufferToSeparateStrips (TIFF* out, uint8_t* buf,
stripsize = TIFFVStripSize(out, nrows);
src = buf + (row * rowsize);
- total_bytes += stripsize;
memset (obuf, '\0', rowstripsize);
if (extractContigSamplesToBuffer(obuf, src, nrows, width, s, spp, bps, dump))
{
@@ -2710,7 +2708,7 @@ static void dump_info(FILE *dumpfile, int format, char *prefix, char *msg, ...)
static int dump_buffer (FILE* dumpfile, int format, uint32_t rows, uint32_t width,
uint32_t row, unsigned char *buff)
{
- int j, k;
+ int k;
uint32_t i;
unsigned char * dump_ptr;
@@ -2728,7 +2726,7 @@ static int dump_buffer (FILE* dumpfile, int format, uint32_t rows, uint32_t widt
"Row %4"PRIu32", %"PRIu32" bytes at offset %"PRIu32,
row + i + 1u, width, row * width);
- for (j = 0, k = width; k >= 10; j += 10, k -= 10, dump_ptr += 10)
+ for (k = width; k >= 10; k -= 10, dump_ptr += 10)
dump_data (dumpfile, format, "", dump_ptr, 10);
if (k > 0)
dump_data (dumpfile, format, "", dump_ptr, k);
@@ -5194,29 +5192,45 @@ computeInputPixelOffsets(struct crop_mask *crop, struct image_data *image,
y1 = (uint32_t) (crop->corners[i].Y1);
y2 = (uint32_t) (crop->corners[i].Y2);
}
- if (x1 < 1)
- crop->regionlist[i].x1 = 0;
- else
- crop->regionlist[i].x1 = (uint32_t) (x1 - 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) )
+ */
+ 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);
if (x2 > image->width - 1)
crop->regionlist[i].x2 = image->width - 1;
- else
- crop->regionlist[i].x2 = (uint32_t) (x2 - 1);
- zwidth = crop->regionlist[i].x2 - crop->regionlist[i].x1 + 1;
+ else if (x2 > 0)
+ crop->regionlist[i].x2 = (uint32_t)(x2 - 1);
- if (y1 < 1)
- crop->regionlist[i].y1 = 0;
- else
- crop->regionlist[i].y1 = (uint32_t) (y1 - 1);
+ zwidth = crop->regionlist[i].x2 - crop->regionlist[i].x1 + 1;
+
+ if (y1 > image->length - 1)
+ crop->regionlist[i].y1 = image->length - 1;
+ else if (y1 > 0)
+ crop->regionlist[i].y1 = (uint32_t)(y1 - 1);
if (y2 > image->length - 1)
crop->regionlist[i].y2 = image->length - 1;
- else
- crop->regionlist[i].y2 = (uint32_t) (y2 - 1);
-
- zlength = crop->regionlist[i].y2 - crop->regionlist[i].y1 + 1;
+ else if (y2 > 0)
+ crop->regionlist[i].y2 = (uint32_t)(y2 - 1);
+ zlength = crop->regionlist[i].y2 - crop->regionlist[i].y1 + 1;
if (zwidth > max_width)
max_width = zwidth;
if (zlength > max_length)
@@ -5246,7 +5260,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
@@ -5282,7 +5296,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;
@@ -5373,24 +5387,23 @@ computeInputPixelOffsets(struct crop_mask *crop, struct image_data *image,
off->endx = endx;
off->endy = endy;
- crop_width = endx - startx + 1;
- crop_length = endy - starty + 1;
-
- if (crop_width <= 0)
+ if (endx + 1 <= startx)
{
TIFFError("computeInputPixelOffsets",
"Invalid left/right margins and /or image crop width requested");
return (-1);
}
+ crop_width = endx - startx + 1;
if (crop_width > image->width)
crop_width = image->width;
- if (crop_length <= 0)
+ if (endy + 1 <= starty)
{
TIFFError("computeInputPixelOffsets",
"Invalid top/bottom margins and /or image crop length requested");
return (-1);
}
+ crop_length = endy - starty + 1;
if (crop_length > image->length)
crop_length = image->length;
@@ -5490,10 +5503,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)
{
@@ -5622,8 +5642,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 */
# SPDX-FileCopyrightText: Huawei Inc.
#
# SPDX-License-Identifier: MIT
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
SRC_URI += "file://0001-fix-upstream-issue-352-heap-buffer-overflow-by-correcting-uint32t-underflow.patch"
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment