1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
|
From: Michael R Sweet <michael.r.sweet@gmail.com>
Date: Thu, 10 Mar 2022 15:29:36 -0500
Subject: CVE-2022-27114
Fix a potential integer overflow bug in the JPEG and PNG loaders (Issue #471)
All images are now limited to 4GiB of memory usage (37837x37837 pixels).
Origin: upstream, https://github.com/michaelrsweet/htmldoc/commit/31f780487e5ddc426888638786cdc47631687275
---
htmldoc/image.cxx | 30 ++++++++++++++++++++++++++++--
1 file changed, 28 insertions(+), 2 deletions(-)
diff --git a/htmldoc/image.cxx b/htmldoc/image.cxx
index a85f1f9..70bd23f 100644
--- a/htmldoc/image.cxx
+++ b/htmldoc/image.cxx
@@ -21,6 +21,13 @@ extern "C" { /* Workaround for JPEG header problems... */
#include <png.h> /* Portable Network Graphics (PNG) definitions */
+/*
+ * Limits...
+ */
+
+#define IMAGE_MAX_DIM 37837 // Maximum dimension - sqrt(4GiB / 3)
+
+
/*
* GIF definitions...
*/
@@ -910,7 +917,7 @@ image_load_bmp(image_t *img, /* I - Image to load into */
colors_used = (int)read_dword(fp);
read_dword(fp);
- if (img->width <= 0 || img->width > 8192 || img->height <= 0 || img->height > 8192)
+ if (img->width <= 0 || img->width > IMAGE_MAX_DIM || img->height <= 0 || img->height > IMAGE_MAX_DIM)
return (-1);
if (info_size > 40)
@@ -1262,7 +1269,7 @@ image_load_gif(image_t *img, /* I - Image pointer */
img->height = (buf[9] << 8) | buf[8];
ncolors = 2 << (buf[10] & 0x07);
- if (img->width <= 0 || img->width > 32767 || img->height <= 0 || img->height > 32767)
+ if (img->width <= 0 || img->width > IMAGE_MAX_DIM || img->height <= 0 || img->height > IMAGE_MAX_DIM)
return (-1);
// If we are writing an encrypted PDF file, bump the use count so we create
@@ -1306,6 +1313,13 @@ image_load_gif(image_t *img, /* I - Image pointer */
return (-1);
}
+ img->width = (buf[5] << 8) | buf[4];
+ img->height = (buf[7] << 8) | buf[6];
+ img->depth = gray ? 1 : 3;
+
+ if (img->width <= 0 || img->width > IMAGE_MAX_DIM || img->height <= 0 || img->height > IMAGE_MAX_DIM)
+ return (-1);
+
if (transparent >= 0)
{
/*
@@ -1422,6 +1436,12 @@ JSAMPROW row; /* Sample row pointer */
img->height = (int)cinfo.output_height;
img->depth = (int)cinfo.output_components;
+ if (img->width <= 0 || img->width > IMAGE_MAX_DIM || img->height <= 0 || img->height > IMAGE_MAX_DIM)
+ {
+ jpeg_destroy_decompress(&cinfo);
+ return (-1);
+ }
+
if (!load_data)
{
jpeg_destroy_decompress(&cinfo);
@@ -1574,6 +1594,12 @@ image_load_png(image_t *img, /* I - Image pointer */
img->width = (int)png_get_image_width(pp, info);
img->height = (int)png_get_image_height(pp, info);
+ if (img->width <= 0 || img->width > IMAGE_MAX_DIM || img->height <= 0 || img->height > IMAGE_MAX_DIM)
+ {
+ png_destroy_read_struct(&pp, &info, NULL);
+ return (-1);
+ }
+
if (color_type & PNG_COLOR_MASK_ALPHA)
{
if ((PSLevel == 0 && PDFVersion >= 14) || PSLevel == 3)
|