[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#991425: unblock: mupdf/1.17.0+ds1-2 [pre-approval]



Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

Please unblock package mupdf

[ Reason ]
To fix two CVEs
- - https://security-tracker.debian.org/tracker/CVE-2021-37220
- - https://security-tracker.debian.org/tracker/CVE-2020-19609

[ Impact ]
Potential denial of service caused by crashes or arbitrary code
execution caused by buffer overflow

[ Tests ]
I tested manually with reproducer files from upstream bug reports.
I also did some regression test with some PDF files.

[ Risks ]
Risks should be low. The changes are cherry-picked from
upstream and there weren't any other changes applied by upstream
between the two versions. The risk of faulty backport is low.

[ Checklist ]
  [x] all changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in testing

[ Other info ]
The source package src:mupdf produces the following binary packages:
- - mupdf
- - mupdf-dbgsym
- - mupdf-tools
- - mupdf-tools-dbgsym
- - libmupdf-dev

unblock mupdf/1.17.0+ds1-2


-----BEGIN PGP SIGNATURE-----

iQIzBAEBCgAdFiEE2JDTPWFH4vUeM4aHCjk1SrblfeEFAmD6g1sACgkQCjk1Srbl
feE/yQ/+KQEr5VOfJhJabt13ZZKLwE2ktpOgU4OwkfwlZy5Z5VoBC+r2WpIdL/TP
k1VbDEXgc57Yd+ZlHRe1baIYc9oiz7YnYyGpnUUVLOGrILqKqFOOtWLFpoa3fzwL
9uQu0trzUahJawdQDQq7Fp5GBkA3U/+KCtZ7+f9/33ACVioxv3S3LIsfDLnLztN3
E68ZjdasSXPX3GGWbUgkY7RG8h+47CNb3Vw+4Y50kN3zucM7PjP/8pdc6d4p6SoC
B6ad3bGyI1t9leaTwB9XRGDlCPNo1I73LcTNM1Uw9WCuPzSyavnpwL/lEATJLfuQ
nsfT3+9yNv+lgCtIEzG/UABFP6FpEqwOcna4zwCRSH78Q3UiICSULEr/nx9H/DRj
+vDwuWKXp7+Y/0CwVyJASf9YiSmcj0m2SJ/Z0GHRvytwtpQKEyRVjisYGDb9gJJ0
X/3gTyvwvox6OKY4Oh8qUgdLfPZUUeIAvwTZCRONNXss8SXKvSdopfq1RrdAnNy1
fVCvp9CvsGX34e11ZU0Fnna+9Ze+eAjFykssv3En1hgGdWoIMDNo+aSP68W9GtGb
FmxCwP2o39B4Uu7cU8WWcTPe8GgJBFNHZmqW9VBxO/zwFJNBrOM1Mz0aNbKwfsXz
X6dW7PlonVR2M0rwhlgRgYp0ir2+hK87HEiQJvbnS5gabTAFyBo=
=C38i
-----END PGP SIGNATURE-----
diff -Nru mupdf-1.17.0+ds1/debian/changelog mupdf-1.17.0+ds1/debian/changelog
--- mupdf-1.17.0+ds1/debian/changelog	2021-02-28 21:40:40.000000000 +0900
+++ mupdf-1.17.0+ds1/debian/changelog	2021-07-23 17:09:37.000000000 +0900
@@ -1,3 +1,11 @@
+mupdf (1.17.0+ds1-2) unstable; urgency=medium
+
+  * Fix buffer overrun in tiff decoder (CVE-2020-19609) (Closes: #991401)
+  * Stay within hash table max key size in cached color converter
+    (CVE-2021-37220) (Closes: #991402)
+
+ -- Kan-Ru Chen (陳侃如) <koster@debian.org>  Fri, 23 Jul 2021 17:09:37 +0900
+
 mupdf (1.17.0+ds1-1.3) unstable; urgency=medium
 
   * Non-maintainer upload.
diff -Nru mupdf-1.17.0+ds1/debian/patches/0012-tiff-Avoid-limiting-palette-colors-to-8-bits.patch mupdf-1.17.0+ds1/debian/patches/0012-tiff-Avoid-limiting-palette-colors-to-8-bits.patch
--- mupdf-1.17.0+ds1/debian/patches/0012-tiff-Avoid-limiting-palette-colors-to-8-bits.patch	1970-01-01 09:00:00.000000000 +0900
+++ mupdf-1.17.0+ds1/debian/patches/0012-tiff-Avoid-limiting-palette-colors-to-8-bits.patch	2021-07-23 16:54:49.000000000 +0900
@@ -0,0 +1,65 @@
+From: Sebastian Rasmussen <sebras@gmail.com>
+Date: Fri, 23 Jul 2021 16:32:29 +0900
+Subject: tiff: Avoid limiting palette colors to 8 bits.
+
+Previously fz_unpack_tile() could not handle >8 bit images,
+so palettized tiff colors had to be limited to 8 bits.
+Now when fz_unpack_tile() does handles >8 bit images do not
+limit the samples in the colormap to 8 bits.
+
+This fixes Coverity CID 150612.
+
+Cherry-picked-from: http://git.ghostscript.com/?p=mupdf.git;a=commitdiff;h=666c62d491ca76ade9a281dfe4c4e945cc71f8e8
+---
+ source/fitz/load-tiff.c | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+diff --git a/source/fitz/load-tiff.c b/source/fitz/load-tiff.c
+index c7c0bcf..bb69e2f 100644
+--- a/source/fitz/load-tiff.c
++++ b/source/fitz/load-tiff.c
+@@ -253,7 +253,7 @@ tiff_expand_colormap(fz_context *ctx, struct tiff *tiff)
+ 	if (tiff->imagelength > UINT_MAX / tiff->imagewidth / (tiff->samplesperpixel + 2))
+ 		fz_throw(ctx, FZ_ERROR_GENERIC, "image too large");
+ 
+-	stride = tiff->imagewidth * (tiff->samplesperpixel + 2);
++	stride = tiff->imagewidth * (tiff->samplesperpixel + 2) * 2;
+ 
+ 	samples = Memento_label(fz_malloc(ctx, stride * tiff->imagelength), "tiff_samples");
+ 
+@@ -269,25 +269,31 @@ tiff_expand_colormap(fz_context *ctx, struct tiff *tiff)
+ 				int c = tiff_getcomp(src, x * 2, tiff->bitspersample);
+ 				int a = tiff_getcomp(src, x * 2 + 1, tiff->bitspersample);
+ 				*dst++ = tiff->colormap[c + 0] >> 8;
++				*dst++ = tiff->colormap[c + 0];
+ 				*dst++ = tiff->colormap[c + maxval] >> 8;
++				*dst++ = tiff->colormap[c + maxval];
+ 				*dst++ = tiff->colormap[c + maxval * 2] >> 8;
+-				if (tiff->bitspersample <= 8)
+-					*dst++ = a << (8 - tiff->bitspersample);
++				*dst++ = tiff->colormap[c + maxval * 2];
++				if (tiff->bitspersample <= 16)
++					*dst++ = a << (16 - tiff->bitspersample);
+ 				else
+-					*dst++ = a >> (tiff->bitspersample - 8);
++					*dst++ = a >> (tiff->bitspersample - 16);
+ 			}
+ 			else
+ 			{
+ 				int c = tiff_getcomp(src, x, tiff->bitspersample);
+ 				*dst++ = tiff->colormap[c + 0] >> 8;
++				*dst++ = tiff->colormap[c + 0];
+ 				*dst++ = tiff->colormap[c + maxval] >> 8;
++				*dst++ = tiff->colormap[c + maxval];
+ 				*dst++ = tiff->colormap[c + maxval * 2] >> 8;
++				*dst++ = tiff->colormap[c + maxval * 2];
+ 			}
+ 		}
+ 	}
+ 
+ 	tiff->samplesperpixel += 2;
+-	tiff->bitspersample = 8;
++	tiff->bitspersample = 16;
+ 	tiff->stride = stride;
+ 	fz_free(ctx, tiff->samples);
+ 	tiff->samples = samples;
diff -Nru mupdf-1.17.0+ds1/debian/patches/0013-Bug-703076-Fix-buffer-overrun-in-tiff-decoder.patch mupdf-1.17.0+ds1/debian/patches/0013-Bug-703076-Fix-buffer-overrun-in-tiff-decoder.patch
--- mupdf-1.17.0+ds1/debian/patches/0013-Bug-703076-Fix-buffer-overrun-in-tiff-decoder.patch	1970-01-01 09:00:00.000000000 +0900
+++ mupdf-1.17.0+ds1/debian/patches/0013-Bug-703076-Fix-buffer-overrun-in-tiff-decoder.patch	2021-07-23 16:54:49.000000000 +0900
@@ -0,0 +1,87 @@
+From: Robin Watts <Robin.Watts@artifex.com>
+Date: Fri, 23 Jul 2021 16:35:21 +0900
+Subject: Bug 703076: Fix buffer overrun in tiff decoder.
+
+Harden tiff_expand_colormap against badly formed TIFFs.
+Correctly allocate space, and avoid overreading. Skip any excess
+input data.
+
+Cherry-picked-from: http://git.ghostscript.com/?p=mupdf.git;a=commitdiff;h=2c4f11f8dcdbd18c35a65e58cc789be0e46012a8
+---
+ source/fitz/load-tiff.c | 42 +++++++++++++++++++++---------------------
+ 1 file changed, 21 insertions(+), 21 deletions(-)
+
+diff --git a/source/fitz/load-tiff.c b/source/fitz/load-tiff.c
+index bb69e2f..40db0fe 100644
+--- a/source/fitz/load-tiff.c
++++ b/source/fitz/load-tiff.c
+@@ -236,6 +236,7 @@ tiff_expand_colormap(fz_context *ctx, struct tiff *tiff)
+ 	unsigned char *src, *dst;
+ 	unsigned int x, y;
+ 	unsigned int stride;
++	unsigned int srcstride;
+ 
+ 	/* colormap has first all red, then all green, then all blue values */
+ 	/* colormap values are 0..65535, bits is 4 or 8 */
+@@ -253,41 +254,40 @@ tiff_expand_colormap(fz_context *ctx, struct tiff *tiff)
+ 	if (tiff->imagelength > UINT_MAX / tiff->imagewidth / (tiff->samplesperpixel + 2))
+ 		fz_throw(ctx, FZ_ERROR_GENERIC, "image too large");
+ 
+-	stride = tiff->imagewidth * (tiff->samplesperpixel + 2) * 2;
++	srcstride = ((1 + tiff->extrasamples) * tiff->bitspersample + 7) & ~7;
++	if (tiff->stride < 0 || srcstride > (unsigned int)tiff->stride)
++		fz_throw(ctx, FZ_ERROR_GENERIC, "insufficient data for format");
++
++	stride = tiff->imagewidth * (3 + !!tiff->extrasamples) * 2;
+ 
+ 	samples = Memento_label(fz_malloc(ctx, stride * tiff->imagelength), "tiff_samples");
+ 
+ 	for (y = 0; y < tiff->imagelength; y++)
+ 	{
++		int s = 0;
+ 		src = tiff->samples + (unsigned int)(tiff->stride * y);
+ 		dst = samples + (unsigned int)(stride * y);
+ 
+ 		for (x = 0; x < tiff->imagewidth; x++)
+ 		{
++			int c = tiff_getcomp(src, s++, tiff->bitspersample);
++			*dst++ = tiff->colormap[c + 0] >> 8;
++			*dst++ = tiff->colormap[c + 0];
++			*dst++ = tiff->colormap[c + maxval] >> 8;
++			*dst++ = tiff->colormap[c + maxval];
++			*dst++ = tiff->colormap[c + maxval * 2] >> 8;
++			*dst++ = tiff->colormap[c + maxval * 2];
+ 			if (tiff->extrasamples)
+ 			{
+-				int c = tiff_getcomp(src, x * 2, tiff->bitspersample);
+-				int a = tiff_getcomp(src, x * 2 + 1, tiff->bitspersample);
+-				*dst++ = tiff->colormap[c + 0] >> 8;
+-				*dst++ = tiff->colormap[c + 0];
+-				*dst++ = tiff->colormap[c + maxval] >> 8;
+-				*dst++ = tiff->colormap[c + maxval];
+-				*dst++ = tiff->colormap[c + maxval * 2] >> 8;
+-				*dst++ = tiff->colormap[c + maxval * 2];
++				/* Assume the first is alpha, and skip the rest. */
++				int a = tiff_getcomp(src, s++, tiff->bitspersample);
+ 				if (tiff->bitspersample <= 16)
+-					*dst++ = a << (16 - tiff->bitspersample);
++					a = a << (16 - tiff->bitspersample);
+ 				else
+-					*dst++ = a >> (tiff->bitspersample - 16);
+-			}
+-			else
+-			{
+-				int c = tiff_getcomp(src, x, tiff->bitspersample);
+-				*dst++ = tiff->colormap[c + 0] >> 8;
+-				*dst++ = tiff->colormap[c + 0];
+-				*dst++ = tiff->colormap[c + maxval] >> 8;
+-				*dst++ = tiff->colormap[c + maxval];
+-				*dst++ = tiff->colormap[c + maxval * 2] >> 8;
+-				*dst++ = tiff->colormap[c + maxval * 2];
++					a = a >> (tiff->bitspersample - 16);
++				*dst++ = a >> 8;
++				*dst++ = a;
++				s += tiff->extrasamples-1;
+ 			}
+ 		}
+ 	}
diff -Nru mupdf-1.17.0+ds1/debian/patches/0014-Bug-703791-Stay-within-hash-table-max-key-size-in-ca.patch mupdf-1.17.0+ds1/debian/patches/0014-Bug-703791-Stay-within-hash-table-max-key-size-in-ca.patch
--- mupdf-1.17.0+ds1/debian/patches/0014-Bug-703791-Stay-within-hash-table-max-key-size-in-ca.patch	1970-01-01 09:00:00.000000000 +0900
+++ mupdf-1.17.0+ds1/debian/patches/0014-Bug-703791-Stay-within-hash-table-max-key-size-in-ca.patch	2021-07-23 16:54:49.000000000 +0900
@@ -0,0 +1,113 @@
+From: Tor Andersson <tor.andersson@artifex.com>
+Date: Fri, 23 Jul 2021 16:54:00 +0900
+Subject: Bug 703791: Stay within hash table max key size in cached color
+ converter.
+
+Cherry-picked-from: http://git.ghostscript.com/?p=mupdf.git;h=f5712c9949d026e4b891b25837edd2edc166151f
+---
+ include/mupdf/fitz/hash.h |  2 ++
+ source/fitz/colorspace.c  | 40 +++++++++++++++++++++++++---------------
+ source/fitz/hash.c        |  7 +++----
+ 3 files changed, 30 insertions(+), 19 deletions(-)
+
+diff --git a/include/mupdf/fitz/hash.h b/include/mupdf/fitz/hash.h
+index ab6159e..6a1b87f 100644
+--- a/include/mupdf/fitz/hash.h
++++ b/include/mupdf/fitz/hash.h
+@@ -5,6 +5,8 @@
+ #include "mupdf/fitz/context.h"
+ #include "mupdf/fitz/output.h"
+ 
++#define FZ_HASH_TABLE_KEY_LENGTH 48
++
+ /**
+ 	Generic hash-table with fixed-length keys.
+ 
+diff --git a/source/fitz/colorspace.c b/source/fitz/colorspace.c
+index b095a7c..200f264 100644
+--- a/source/fitz/colorspace.c
++++ b/source/fitz/colorspace.c
+@@ -990,23 +990,30 @@ typedef struct fz_cached_color_converter
+ static void fz_cached_color_convert(fz_context *ctx, fz_color_converter *cc_, const float *ss, float *ds)
+ {
+ 	fz_cached_color_converter *cc = cc_->opaque;
+-	float *val = fz_hash_find(ctx, cc->hash, ss);
+-	int n = cc->base.ds->n * sizeof(float);
+-
+-	if (val)
++	if (cc->hash)
+ 	{
+-		memcpy(ds, val, n);
+-		return;
+-	}
++		float *val = fz_hash_find(ctx, cc->hash, ss);
++		int n = cc->base.ds->n * sizeof(float);
+ 
+-	cc->base.convert(ctx, &cc->base, ss, ds);
++		if (val)
++		{
++			memcpy(ds, val, n);
++			return;
++		}
+ 
+-	val = Memento_label(fz_malloc_array(ctx, cc->base.ds->n, float), "cached_color_convert");
+-	memcpy(val, ds, n);
+-	fz_try(ctx)
+-		fz_hash_insert(ctx, cc->hash, ss, val);
+-	fz_catch(ctx)
+-		fz_free(ctx, val);
++		cc->base.convert(ctx, &cc->base, ss, ds);
++
++		val = Memento_label(fz_malloc_array(ctx, cc->base.ds->n, float), "cached_color_convert");
++		memcpy(val, ds, n);
++		fz_try(ctx)
++			fz_hash_insert(ctx, cc->hash, ss, val);
++		fz_catch(ctx)
++			fz_free(ctx, val);
++	}
++	else
++	{
++		cc->base.convert(ctx, &cc->base, ss, ds);
++	}
+ }
+ 
+ void fz_init_cached_color_converter(fz_context *ctx, fz_color_converter *cc, fz_colorspace *ss, fz_colorspace *ds, fz_colorspace *is, fz_color_params params)
+@@ -1025,7 +1032,10 @@ void fz_init_cached_color_converter(fz_context *ctx, fz_color_converter *cc, fz_
+ 	fz_try(ctx)
+ 	{
+ 		fz_find_color_converter(ctx, &cached->base, ss, ds, is, params);
+-		cached->hash = fz_new_hash_table(ctx, 256, n * sizeof(float), -1, fz_free);
++		if (n * sizeof(float) <= FZ_HASH_TABLE_KEY_LENGTH)
++			cached->hash = fz_new_hash_table(ctx, 256, n * sizeof(float), -1, fz_free);
++		else
++			fz_warn(ctx, "colorspace has too many components to be cached");
+ 	}
+ 	fz_catch(ctx)
+ 	{
+diff --git a/source/fitz/hash.c b/source/fitz/hash.c
+index c787f9e..0ff320e 100644
+--- a/source/fitz/hash.c
++++ b/source/fitz/hash.c
+@@ -11,11 +11,9 @@
+ 	and removed frequently.
+ */
+ 
+-enum { MAX_KEY_LEN = 48 };
+-
+ typedef struct
+ {
+-	unsigned char key[MAX_KEY_LEN];
++	unsigned char key[FZ_HASH_TABLE_KEY_LENGTH];
+ 	void *val;
+ } fz_hash_entry;
+ 
+@@ -50,7 +48,8 @@ fz_new_hash_table(fz_context *ctx, int initialsize, int keylen, int lock, fz_has
+ {
+ 	fz_hash_table *table;
+ 
+-	assert(keylen <= MAX_KEY_LEN);
++	if (keylen > FZ_HASH_TABLE_KEY_LENGTH)
++		fz_throw(ctx, FZ_ERROR_GENERIC, "hash table key length too large");
+ 
+ 	table = fz_malloc_struct(ctx, fz_hash_table);
+ 	table->keylen = keylen;
diff -Nru mupdf-1.17.0+ds1/debian/patches/series mupdf-1.17.0+ds1/debian/patches/series
--- mupdf-1.17.0+ds1/debian/patches/series	2021-02-28 21:40:40.000000000 +0900
+++ mupdf-1.17.0+ds1/debian/patches/series	2021-07-23 16:54:49.000000000 +0900
@@ -9,3 +9,6 @@
 0010-Prevent-thirdparty-archive-build.patch
 0011-Bug-702857-Detect-avoid-overflow-when-calculating-si.patch
 0012-Bug-703366-Fix-double-free-of-object-during-lineariz.patch
+0012-tiff-Avoid-limiting-palette-colors-to-8-bits.patch
+0013-Bug-703076-Fix-buffer-overrun-in-tiff-decoder.patch
+0014-Bug-703791-Stay-within-hash-table-max-key-size-in-ca.patch

Reply to: