Fix CVE-2016-9572 and CVE-2016-9573: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-9572 https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-9573 https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2016-9572 https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2016-9573 Patch copied from 3rd-party repository: https://github.com/szukw000/openjpeg/commit/7b28bd2b723df6be09fe7791eba33147c1c47d0d From 7b28bd2b723df6be09fe7791eba33147c1c47d0d Mon Sep 17 00:00:00 2001 From: szukw000 Date: Mon, 28 Nov 2016 21:57:20 +0100 Subject: [PATCH] Changes for issues #863 and #862 --- src/bin/jp2/convert.c | 59 +++++++++++++++++++++++++++++++++++++++----- src/bin/jp2/convertbmp.c | 29 +++++++++++++++++++++- src/bin/jp2/opj_decompress.c | 2 +- src/lib/openjp2/j2k.c | 11 ++++++--- 4 files changed, 90 insertions(+), 11 deletions(-) diff --git a/src/bin/jp2/convert.c b/src/bin/jp2/convert.c index deee4f6..6a3f65b 100644 --- a/src/bin/jp2/convert.c +++ b/src/bin/jp2/convert.c @@ -906,7 +906,8 @@ int imagetotga(opj_image_t * image, const char *outfile) { for (i = 0; i < image->numcomps-1; i++) { if ((image->comps[0].dx != image->comps[i+1].dx) ||(image->comps[0].dy != image->comps[i+1].dy) - ||(image->comps[0].prec != image->comps[i+1].prec)) { + ||(image->comps[0].prec != image->comps[i+1].prec) + ||(image->comps[0].sgnd != image->comps[i+1].sgnd)) { fclose(fdest); fprintf(stderr, "Unable to create a tga file with such J2K image charateristics."); return 1; @@ -1743,7 +1744,7 @@ int imagetopnm(opj_image_t * image, const char *outfile, int force_split) int *red, *green, *blue, *alpha; int wr, hr, max; int i; - unsigned int compno, ncomp; + unsigned int compno, ncomp, ui; int adjustR, adjustG, adjustB, adjustA; int fails, two, want_gray, has_alpha, triple; int prec, v; @@ -1768,6 +1769,27 @@ int imagetopnm(opj_image_t * image, const char *outfile, int force_split) if(want_gray) ncomp = 1; + for (ui = 1; ui < ncomp; ++ui) { + if (image->comps[0].dx != image->comps[ui].dx) { + break; + } + if (image->comps[0].dy != image->comps[ui].dy) { + break; + } + if (image->comps[0].prec != image->comps[ui].prec) { + break; + } + if (image->comps[0].sgnd != image->comps[ui].sgnd) { + break; + } + } + if (ui != ncomp) { + fprintf(stderr,"imagetopnm: All components\n shall have " + "the same subsampling, same bit depth, same sign.\n" + " Aborting\n"); + return 1; + } + if ((force_split == 0) && (ncomp == 2 /* GRAYA */ || (ncomp > 2 /* RGB, RGBA */ @@ -2126,7 +2148,7 @@ static int imagetoraw_common(opj_image_t * image, const char *outfile, OPJ_BOOL { FILE *rawFile = NULL; size_t res; - unsigned int compno; + unsigned int compno, numcomps; int w, h, fails; int line, row, curr, mask; int *ptr; @@ -2139,6 +2161,31 @@ static int imagetoraw_common(opj_image_t * image, const char *outfile, OPJ_BOOL return 1; } + numcomps = image->numcomps; + + if (numcomps > 4) { + numcomps = 4; + } + for (compno = 1; compno < numcomps; ++compno) { + if (image->comps[0].dx != image->comps[compno].dx) { + break; + } + if (image->comps[0].dy != image->comps[compno].dy) { + break; + } + if (image->comps[0].prec != image->comps[compno].prec) { + break; + } + if (image->comps[0].sgnd != image->comps[compno].sgnd) { + break; + } + } + if (compno != numcomps) { + fprintf(stderr,"imagetoraw_common: All components shall have the same subsampling, same bit depth, same sign.\n"); + fprintf(stderr,"\tAborting\n"); + return 1; + } + rawFile = fopen(outfile, "wb"); if (!rawFile) { fprintf(stderr, "Failed to open %s for writing !!\n", outfile); @@ -2146,9 +2193,9 @@ static int imagetoraw_common(opj_image_t * image, const char *outfile, OPJ_BOOL } fails = 1; - fprintf(stdout,"Raw image characteristics: %d components\n", image->numcomps); + fprintf(stdout,"Raw image characteristics: %d components\n", numcomps); - for(compno = 0; compno < image->numcomps; compno++) + for(compno = 0; compno < numcomps; compno++) { fprintf(stdout,"Component %u characteristics: %dx%dx%d %s\n", compno, image->comps[compno].w, image->comps[compno].h, image->comps[compno].prec, image->comps[compno].sgnd==1 ? "signed": "unsigned"); @@ -2238,7 +2285,7 @@ static int imagetoraw_common(opj_image_t * image, const char *outfile, OPJ_BOOL } else if (image->comps[compno].prec <= 32) { - fprintf(stderr,"More than 16 bits per component no handled yet\n"); + fprintf(stderr,"More than 16 bits per component not handled yet\n"); goto fin; } else diff --git a/src/bin/jp2/convertbmp.c b/src/bin/jp2/convertbmp.c index ae83077..8017ba8 100644 --- a/src/bin/jp2/convertbmp.c +++ b/src/bin/jp2/convertbmp.c @@ -806,8 +806,35 @@ int imagetobmp(opj_image_t * image, const char *outfile) { FILE *fdest = NULL; int adjustR, adjustG, adjustB; + { + unsigned int ui, ncomp = image->numcomps; + + if (ncomp > 4) { /* RGBA in bmpmask32toimage */ + ncomp = 4; + } + for (ui = 1; ui < ncomp; ++ui) { + if (image->comps[0].dx != image->comps[ui].dx) { + break; + } + if (image->comps[0].dy != image->comps[ui].dy) { + break; + } + if (image->comps[0].prec != image->comps[ui].prec) { + break; + } + if (image->comps[0].sgnd != image->comps[ui].sgnd) { + break; + } + } + if (ui != ncomp) { + fprintf(stderr,"imagetobmp: All components shall have the same subsampling, same bit depth, same sign.\n"); + fprintf(stderr,"\tAborting\n"); + return 1; + } + + } if (image->comps[0].prec < 8) { - fprintf(stderr, "Unsupported number of components: %d\n", image->comps[0].prec); + fprintf(stderr, "imagetobmp: Unsupported precision: %d\n", image->comps[0].prec); return 1; } if (image->numcomps >= 3 && image->comps[0].dx == image->comps[1].dx diff --git a/src/bin/jp2/opj_decompress.c b/src/bin/jp2/opj_decompress.c index 83160c3..c30079b 100644 --- a/src/bin/jp2/opj_decompress.c +++ b/src/bin/jp2/opj_decompress.c @@ -1607,7 +1607,7 @@ int main(int argc, char **argv) if(dirptr->filename_buf) free(dirptr->filename_buf); free(dirptr); } - if (numDecompressedImages) { + if (numDecompressedImages && !failed) { fprintf(stdout, "decode time: %d ms\n", (int)( (tCumulative * 1000.0) / (OPJ_FLOAT64)numDecompressedImages)); } return failed ? EXIT_FAILURE : EXIT_SUCCESS; diff --git a/src/lib/openjp2/j2k.c b/src/lib/openjp2/j2k.c index 66802bb..b6daa32 100644 --- a/src/lib/openjp2/j2k.c +++ b/src/lib/openjp2/j2k.c @@ -2158,7 +2158,7 @@ static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k, i, l_img_comp->dx, l_img_comp->dy); return OPJ_FALSE; } - if( l_img_comp->prec > 38) { /* TODO openjpeg won't handle more than ? */ + if( l_img_comp->prec < 1 || l_img_comp->prec > 38) { /* TODO openjpeg won't handle more than ? */ opj_event_msg(p_manager, EVT_ERROR, "Invalid values for comp = %d : prec=%u (should be between 1 and 38 according to the JPEG2000 norm)\n", i, l_img_comp->prec); @@ -10029,7 +10029,11 @@ OPJ_BOOL opj_j2k_decode(opj_j2k_t * p_j2k, /* Move data and copy one information from codec to output image*/ for (compno = 0; compno < p_image->numcomps; compno++) { p_image->comps[compno].resno_decoded = p_j2k->m_output_image->comps[compno].resno_decoded; - p_image->comps[compno].data = p_j2k->m_output_image->comps[compno].data; + p_image->comps[compno].data = p_j2k->m_output_image->comps[compno].data; + + if(p_image->comps[compno].data == NULL) return OPJ_FALSE; + + p_j2k->m_output_image->comps[compno].data = NULL; #if 0 char fn[256]; sprintf( fn, "/tmp/%d.raw", compno ); @@ -10037,7 +10041,6 @@ OPJ_BOOL opj_j2k_decode(opj_j2k_t * p_j2k, fwrite( p_image->comps[compno].data, sizeof(OPJ_INT32), p_image->comps[compno].w * p_image->comps[compno].h, debug ); fclose( debug ); #endif - p_j2k->m_output_image->comps[compno].data = NULL; } return OPJ_TRUE; @@ -10131,6 +10134,8 @@ OPJ_BOOL opj_j2k_get_tile( opj_j2k_t *p_j2k, p_image->comps[compno].data = p_j2k->m_output_image->comps[compno].data; + if (p_image->comps[compno].data == NULL) return OPJ_FALSE; + p_j2k->m_output_image->comps[compno].data = NULL; }