summaryrefslogtreecommitdiffstats
path: root/meta/recipes-multimedia/libtiff/tiff/CVE-2022-1354.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-multimedia/libtiff/tiff/CVE-2022-1354.patch')
-rw-r--r--meta/recipes-multimedia/libtiff/tiff/CVE-2022-1354.patch212
1 files changed, 212 insertions, 0 deletions
diff --git a/meta/recipes-multimedia/libtiff/tiff/CVE-2022-1354.patch b/meta/recipes-multimedia/libtiff/tiff/CVE-2022-1354.patch
new file mode 100644
index 0000000000..71b85cac10
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/tiff/CVE-2022-1354.patch
@@ -0,0 +1,212 @@
+From 87881e093691a35c60b91cafed058ba2dd5d9807 Mon Sep 17 00:00:00 2001
+From: Even Rouault <even.rouault@spatialys.com>
+Date: Sun, 5 Dec 2021 14:37:46 +0100
+Subject: [PATCH] TIFFReadDirectory: fix OJPEG hack (fixes #319)
+
+to avoid having the size of the strip arrays inconsistent with the
+number of strips returned by TIFFNumberOfStrips(), which may cause
+out-ouf-bounds array read afterwards.
+
+One of the OJPEG hack that alters SamplesPerPixel may influence the
+number of strips. Hence compute tif_dir.td_nstrips only afterwards.
+
+CVE: CVE-2022-1354
+
+Upstream-Status: Backport
+[https://gitlab.com/libtiff/libtiff/-/commit/87f580f39011109b3bb5f6eca13fac543a542798]
+
+Signed-off-by: Yi Zhao <yi.zhao@windriver.com>
+---
+ libtiff/tif_dirread.c | 162 ++++++++++++++++++++++--------------------
+ 1 file changed, 83 insertions(+), 79 deletions(-)
+
+diff --git a/libtiff/tif_dirread.c b/libtiff/tif_dirread.c
+index 8f434ef5..14c031d1 100644
+--- a/libtiff/tif_dirread.c
++++ b/libtiff/tif_dirread.c
+@@ -3794,50 +3794,7 @@ TIFFReadDirectory(TIFF* tif)
+ MissingRequired(tif,"ImageLength");
+ goto bad;
+ }
+- /*
+- * Setup appropriate structures (by strip or by tile)
+- */
+- if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) {
+- tif->tif_dir.td_nstrips = TIFFNumberOfStrips(tif);
+- tif->tif_dir.td_tilewidth = tif->tif_dir.td_imagewidth;
+- tif->tif_dir.td_tilelength = tif->tif_dir.td_rowsperstrip;
+- tif->tif_dir.td_tiledepth = tif->tif_dir.td_imagedepth;
+- tif->tif_flags &= ~TIFF_ISTILED;
+- } else {
+- tif->tif_dir.td_nstrips = TIFFNumberOfTiles(tif);
+- tif->tif_flags |= TIFF_ISTILED;
+- }
+- if (!tif->tif_dir.td_nstrips) {
+- TIFFErrorExt(tif->tif_clientdata, module,
+- "Cannot handle zero number of %s",
+- isTiled(tif) ? "tiles" : "strips");
+- goto bad;
+- }
+- tif->tif_dir.td_stripsperimage = tif->tif_dir.td_nstrips;
+- if (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE)
+- tif->tif_dir.td_stripsperimage /= tif->tif_dir.td_samplesperpixel;
+- if (!TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) {
+-#ifdef OJPEG_SUPPORT
+- if ((tif->tif_dir.td_compression==COMPRESSION_OJPEG) &&
+- (isTiled(tif)==0) &&
+- (tif->tif_dir.td_nstrips==1)) {
+- /*
+- * XXX: OJPEG hack.
+- * If a) compression is OJPEG, b) it's not a tiled TIFF,
+- * and c) the number of strips is 1,
+- * then we tolerate the absence of stripoffsets tag,
+- * because, presumably, all required data is in the
+- * JpegInterchangeFormat stream.
+- */
+- TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
+- } else
+-#endif
+- {
+- MissingRequired(tif,
+- isTiled(tif) ? "TileOffsets" : "StripOffsets");
+- goto bad;
+- }
+- }
++
+ /*
+ * Second pass: extract other information.
+ */
+@@ -4042,41 +3999,6 @@ TIFFReadDirectory(TIFF* tif)
+ } /* -- if (!dp->tdir_ignore) */
+ } /* -- for-loop -- */
+
+- if( tif->tif_mode == O_RDWR &&
+- tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 &&
+- tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
+- tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
+- tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 &&
+- tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 &&
+- tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
+- tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
+- tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0 )
+- {
+- /* Directory typically created with TIFFDeferStrileArrayWriting() */
+- TIFFSetupStrips(tif);
+- }
+- else if( !(tif->tif_flags&TIFF_DEFERSTRILELOAD) )
+- {
+- if( tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 )
+- {
+- if (!TIFFFetchStripThing(tif,&(tif->tif_dir.td_stripoffset_entry),
+- tif->tif_dir.td_nstrips,
+- &tif->tif_dir.td_stripoffset_p))
+- {
+- goto bad;
+- }
+- }
+- if( tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 )
+- {
+- if (!TIFFFetchStripThing(tif,&(tif->tif_dir.td_stripbytecount_entry),
+- tif->tif_dir.td_nstrips,
+- &tif->tif_dir.td_stripbytecount_p))
+- {
+- goto bad;
+- }
+- }
+- }
+-
+ /*
+ * OJPEG hack:
+ * - If a) compression is OJPEG, and b) photometric tag is missing,
+@@ -4147,6 +4069,88 @@ TIFFReadDirectory(TIFF* tif)
+ }
+ }
+
++ /*
++ * Setup appropriate structures (by strip or by tile)
++ * We do that only after the above OJPEG hack which alters SamplesPerPixel
++ * and thus influences the number of strips in the separate planarconfig.
++ */
++ if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) {
++ tif->tif_dir.td_nstrips = TIFFNumberOfStrips(tif);
++ tif->tif_dir.td_tilewidth = tif->tif_dir.td_imagewidth;
++ tif->tif_dir.td_tilelength = tif->tif_dir.td_rowsperstrip;
++ tif->tif_dir.td_tiledepth = tif->tif_dir.td_imagedepth;
++ tif->tif_flags &= ~TIFF_ISTILED;
++ } else {
++ tif->tif_dir.td_nstrips = TIFFNumberOfTiles(tif);
++ tif->tif_flags |= TIFF_ISTILED;
++ }
++ if (!tif->tif_dir.td_nstrips) {
++ TIFFErrorExt(tif->tif_clientdata, module,
++ "Cannot handle zero number of %s",
++ isTiled(tif) ? "tiles" : "strips");
++ goto bad;
++ }
++ tif->tif_dir.td_stripsperimage = tif->tif_dir.td_nstrips;
++ if (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE)
++ tif->tif_dir.td_stripsperimage /= tif->tif_dir.td_samplesperpixel;
++ if (!TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) {
++#ifdef OJPEG_SUPPORT
++ if ((tif->tif_dir.td_compression==COMPRESSION_OJPEG) &&
++ (isTiled(tif)==0) &&
++ (tif->tif_dir.td_nstrips==1)) {
++ /*
++ * XXX: OJPEG hack.
++ * If a) compression is OJPEG, b) it's not a tiled TIFF,
++ * and c) the number of strips is 1,
++ * then we tolerate the absence of stripoffsets tag,
++ * because, presumably, all required data is in the
++ * JpegInterchangeFormat stream.
++ */
++ TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
++ } else
++#endif
++ {
++ MissingRequired(tif,
++ isTiled(tif) ? "TileOffsets" : "StripOffsets");
++ goto bad;
++ }
++ }
++
++ if( tif->tif_mode == O_RDWR &&
++ tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 &&
++ tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
++ tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
++ tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 &&
++ tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 &&
++ tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
++ tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
++ tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0 )
++ {
++ /* Directory typically created with TIFFDeferStrileArrayWriting() */
++ TIFFSetupStrips(tif);
++ }
++ else if( !(tif->tif_flags&TIFF_DEFERSTRILELOAD) )
++ {
++ if( tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 )
++ {
++ if (!TIFFFetchStripThing(tif,&(tif->tif_dir.td_stripoffset_entry),
++ tif->tif_dir.td_nstrips,
++ &tif->tif_dir.td_stripoffset_p))
++ {
++ goto bad;
++ }
++ }
++ if( tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 )
++ {
++ if (!TIFFFetchStripThing(tif,&(tif->tif_dir.td_stripbytecount_entry),
++ tif->tif_dir.td_nstrips,
++ &tif->tif_dir.td_stripbytecount_p))
++ {
++ goto bad;
++ }
++ }
++ }
++
+ /*
+ * Make sure all non-color channels are extrasamples.
+ * If it's not the case, define them as such.
+--
+2.25.1
+