Skip to content
Permalink
Browse files

openjpeg: #1574

  • Loading branch information...
MingcongBai committed Jan 15, 2019
1 parent 3488718 commit d966fd2332e83223665f57a6ffea1294eaf365c9
@@ -0,0 +1,41 @@
diff -rupN openjpeg-2.3.0/src/bin/jp2/convert.c openjpeg-2.3.0-new/src/bin/jp2/convert.c
--- openjpeg-2.3.0/src/bin/jp2/convert.c 2017-10-05 00:23:14.000000000 +0200
+++ openjpeg-2.3.0-new/src/bin/jp2/convert.c 2018-12-20 10:51:16.454336033 +0100
@@ -2210,6 +2210,11 @@ int imagetopnm(opj_image_t * image, cons
opj_version(), wr, hr, max);

red = image->comps[compno].data;
+ if (!red) {
+ fclose(fdest);
+ continue;
+ }
+
adjustR =
(image->comps[compno].sgnd ? 1 << (image->comps[compno].prec - 1) : 0);

diff -rupN openjpeg-2.3.0/src/bin/jp3d/convert.c openjpeg-2.3.0-new/src/bin/jp3d/convert.c
--- openjpeg-2.3.0/src/bin/jp3d/convert.c 2017-10-05 00:23:14.000000000 +0200
+++ openjpeg-2.3.0-new/src/bin/jp3d/convert.c 2018-12-20 10:51:16.453336036 +0100
@@ -297,8 +297,8 @@ opj_volume_t* pgxtovolume(char *relpath,
fprintf(stdout, "[INFO] Loading %s \n", pgxfiles[pos]);

fseek(f, 0, SEEK_SET);
- fscanf(f, "PG%[ \t]%c%c%[ \t+-]%d%[ \t]%d%[ \t]%d", temp, &endian1, &endian2,
- signtmp, &prec, temp, &w, temp, &h);
+ fscanf(f, "PG%31[ \t]%c%c%31[ \t+-]%d%31[ \t]%d%31[ \t]%d", temp, &endian1,
+ &endian2, signtmp, &prec, temp, &w, temp, &h);

i = 0;
sign = '+';
diff -rupN openjpeg-2.3.0/src/bin/jpwl/convert.c openjpeg-2.3.0-new/src/bin/jpwl/convert.c
--- openjpeg-2.3.0/src/bin/jpwl/convert.c 2017-10-05 00:23:14.000000000 +0200
+++ openjpeg-2.3.0-new/src/bin/jpwl/convert.c 2018-12-20 10:51:16.453336036 +0100
@@ -1348,7 +1348,7 @@ opj_image_t* pgxtoimage(const char *file
}

fseek(f, 0, SEEK_SET);
- if (fscanf(f, "PG%[ \t]%c%c%[ \t+-]%d%[ \t]%d%[ \t]%d", temp, &endian1,
+ if (fscanf(f, "PG%31[ \t]%c%c%31[ \t+-]%d%31[ \t]%d%31[ \t]%d", temp, &endian1,
&endian2, signtmp, &prec, temp, &w, temp, &h) != 9) {
fprintf(stderr,
"ERROR: Failed to read the right number of element from the fscanf() function!\n");
@@ -0,0 +1,79 @@
From ca16fe55014c57090dd97369256c7657aeb25975 Mon Sep 17 00:00:00 2001
From: Hugo Lefeuvre <hle@debian.org>
Date: Sat, 22 Sep 2018 14:33:19 -0400
Subject: [PATCH] convertbmp: fix issues with zero bitmasks

In the case where a BMP file declares compression 3 (BI_BITFIELDS)
with header size <= 56, all bitmask values keep their initialization
value 0. This may lead to various undefined behavior later e.g. when
doing 1 << (l_comp->prec - 1).

This issue does not affect files with bit count 16 because of a check
added in 16240e2 which sets default values to the color masks if they
are all 0.

This commit adds similar checks for the 32 bit case.

Also, if a BMP file declares compression 3 with header size >= 56 and
intentional 0 bitmasks, the same issue will be triggered in both the
16 and 32 bit count case.

This commit adds checks to bmp_read_info_header() rejecting BMP files
with "intentional" 0 bitmasks. These checks might be removed in the
future when proper handling of zero bitmasks will be available in
openjpeg2.

fixes #1057 (CVE-2018-5785)
---
src/bin/jp2/convertbmp.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)

diff --git a/src/bin/jp2/convertbmp.c b/src/bin/jp2/convertbmp.c
index 084f70bb7..7fde99ab3 100644
--- a/src/bin/jp2/convertbmp.c
+++ b/src/bin/jp2/convertbmp.c
@@ -435,16 +435,31 @@ static OPJ_BOOL bmp_read_info_header(FILE* IN, OPJ_BITMAPINFOHEADER* header)
header->biRedMask |= (OPJ_UINT32)getc(IN) << 16;
header->biRedMask |= (OPJ_UINT32)getc(IN) << 24;

+ if (!header->biRedMask) {
+ fprintf(stderr, "Error, invalid red mask value %d\n", header->biRedMask);
+ return OPJ_FALSE;
+ }
+
header->biGreenMask = (OPJ_UINT32)getc(IN);
header->biGreenMask |= (OPJ_UINT32)getc(IN) << 8;
header->biGreenMask |= (OPJ_UINT32)getc(IN) << 16;
header->biGreenMask |= (OPJ_UINT32)getc(IN) << 24;

+ if (!header->biGreenMask) {
+ fprintf(stderr, "Error, invalid green mask value %d\n", header->biGreenMask);
+ return OPJ_FALSE;
+ }
+
header->biBlueMask = (OPJ_UINT32)getc(IN);
header->biBlueMask |= (OPJ_UINT32)getc(IN) << 8;
header->biBlueMask |= (OPJ_UINT32)getc(IN) << 16;
header->biBlueMask |= (OPJ_UINT32)getc(IN) << 24;

+ if (!header->biBlueMask) {
+ fprintf(stderr, "Error, invalid blue mask value %d\n", header->biBlueMask);
+ return OPJ_FALSE;
+ }
+
header->biAlphaMask = (OPJ_UINT32)getc(IN);
header->biAlphaMask |= (OPJ_UINT32)getc(IN) << 8;
header->biAlphaMask |= (OPJ_UINT32)getc(IN) << 16;
@@ -831,6 +846,12 @@ opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters)
bmpmask32toimage(pData, stride, image, 0x00FF0000U, 0x0000FF00U, 0x000000FFU,
0x00000000U);
} else if (Info_h.biBitCount == 32 && Info_h.biCompression == 3) { /* bitmask */
+ if ((Info_h.biRedMask == 0U) && (Info_h.biGreenMask == 0U) &&
+ (Info_h.biBlueMask == 0U)) {
+ Info_h.biRedMask = 0x00FF0000U;
+ Info_h.biGreenMask = 0x0000FF00U;
+ Info_h.biBlueMask = 0x000000FFU;
+ }
bmpmask32toimage(pData, stride, image, Info_h.biRedMask, Info_h.biGreenMask,
Info_h.biBlueMask, Info_h.biAlphaMask);
} else if (Info_h.biBitCount == 16 && Info_h.biCompression == 0) { /* RGBX */
@@ -0,0 +1,49 @@
diff -rupN openjpeg-2.3.0/src/bin/jp2/convertbmp.c openjpeg-2.3.0-new/src/bin/jp2/convertbmp.c
--- openjpeg-2.3.0/src/bin/jp2/convertbmp.c 2018-12-20 10:51:16.451336040 +0100
+++ openjpeg-2.3.0-new/src/bin/jp2/convertbmp.c 2018-12-20 10:51:16.491335949 +0100
@@ -534,14 +534,14 @@ static OPJ_BOOL bmp_read_raw_data(FILE*
static OPJ_BOOL bmp_read_rle8_data(FILE* IN, OPJ_UINT8* pData,
OPJ_UINT32 stride, OPJ_UINT32 width, OPJ_UINT32 height)
{
- OPJ_UINT32 x, y;
+ OPJ_UINT32 x, y, written;
OPJ_UINT8 *pix;
const OPJ_UINT8 *beyond;

beyond = pData + stride * height;
pix = pData;

- x = y = 0U;
+ x = y = written = 0U;
while (y < height) {
int c = getc(IN);
if (c == EOF) {
@@ -561,6 +561,7 @@ static OPJ_BOOL bmp_read_rle8_data(FILE*
for (j = 0; (j < c) && (x < width) &&
((OPJ_SIZE_T)pix < (OPJ_SIZE_T)beyond); j++, x++, pix++) {
*pix = c1;
+ written++;
}
} else {
c = getc(IN);
@@ -598,6 +599,7 @@ static OPJ_BOOL bmp_read_rle8_data(FILE*
}
c1 = (OPJ_UINT8)c1_int;
*pix = c1;
+ written++;
}
if ((OPJ_UINT32)c & 1U) { /* skip padding byte */
c = getc(IN);
@@ -608,6 +610,12 @@ static OPJ_BOOL bmp_read_rle8_data(FILE*
}
}
}/* while() */
+
+ if (written != width * height) {
+ fprintf(stderr, "warning, image's actual size does not match advertized one\n");
+ return OPJ_FALSE;
+ }
+
return OPJ_TRUE;
}

@@ -1,2 +1,3 @@
VER=2.3.0
REL=1
SRCTBL="https://github.com/uclouvain/openjpeg/archive/v$VER.tar.gz"

0 comments on commit d966fd2

Please sign in to comment.
You can’t perform that action at this time.