diff --git a/meta-oniro-staging/recipes-multimedia/libtiff/files/0001-fix-upstream-issue-352-heap-buffer-overflow-by-correcting-uint32t-underflow.patch b/meta-oniro-staging/recipes-multimedia/libtiff/files/0001-fix-upstream-issue-352-heap-buffer-overflow-by-correcting-uint32t-underflow.patch new file mode 100644 index 0000000000000000000000000000000000000000..f5ca2c363af4b7abfff18c1f6b0468a40a91f48b --- /dev/null +++ b/meta-oniro-staging/recipes-multimedia/libtiff/files/0001-fix-upstream-issue-352-heap-buffer-overflow-by-correcting-uint32t-underflow.patch @@ -0,0 +1,199 @@ +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 */ + diff --git a/meta-oniro-staging/recipes-multimedia/libtiff/tiff_4.3.0.bbappend b/meta-oniro-staging/recipes-multimedia/libtiff/tiff_4.3.0.bbappend new file mode 100644 index 0000000000000000000000000000000000000000..69fb8b35a298b4eb8ca5e284c24f2adbabd83f04 --- /dev/null +++ b/meta-oniro-staging/recipes-multimedia/libtiff/tiff_4.3.0.bbappend @@ -0,0 +1,8 @@ +# 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" +