Bug 911837 - (CVE-2014-8157) VUL-0: CVE-2014-8157, CVE-2014-8158: jasper: use after free and OOB vulnerabilities
(CVE-2014-8157)
VUL-0: CVE-2014-8157, CVE-2014-8158: jasper: use after free and OOB vulnerabi...
Status: RESOLVED FIXED
Classification: Novell Products
Product: SUSE Security Incidents
Classification: Novell Products
Component: Incidents
unspecified
Other Other
: P3 - Medium : Normal
: ---
Assigned To: Security Team bot
Security Team bot
maint:released:sle11-sp1:60509 maint:...
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2015-01-06 13:11 UTC by Victor Pereira
Modified: 2019-04-02 22:42 UTC (History)
2 users (show)

See Also:
Found By: ---
Services Priority:
Business Priority:
Blocker: ---
Marketing QA Status: ---
IT Deployment: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Victor Pereira 2015-01-06 13:11:02 UTC
Hello everybody,

we received yet another libjasper report from pyddeh@gmail.com, as done for
previous reports we are sharing it with you to see if anyone wants to
contribute CVEs and contribute/validate patches. 

Cheers

-----------------------------------------------------------------------------

Details:
Two more problems with the JasPer JPEG2000 decoder:

1) jpc_dec.c:1204:

    dec->numhtiles = JPC_CEILDIV(dec->xend - dec->tilexoff, dec->tilewidth);
    dec->numvtiles = JPC_CEILDIV(dec->yend - dec->tileyoff, dec->tileheight);
    dec->numtiles = dec->numhtiles * dec->numvtiles;
    if (!(dec->tiles = jas_malloc(dec->numtiles * sizeof(jpc_dec_tile_t)))) {
        return -1;
    }

the dec->XXX in JPC_CEILDIV are all directly from the codestream, so
dec->numtiles can be 0. In that case, the minimum-sized chunk returned by
malloc can, depending on the code stream, be used later. I think this can
cause the same problems as a use after free. Fix proposal:

    if ( dec->numtiles == 0 || !(dec->tiles = jas_malloc(dec->numtiles * sizeof(jpc_dec_tile_t)))) {
        return -1;
    }

2) in jpc_qmfb.c JasPer uses variable length arrays where the sizes are
derived from the codestream data, e.g. jpc_qmfb.c:305:

    void jpc_qmfb_split_row(jpc_fix_t *a, int numcols, int parity)
    {
    
    	int bufsize = JPC_CEILDIVPOW2(numcols, 1);
    #if !defined(HAVE_VLA)
    	jpc_fix_t splitbuf[QMFB_SPLITBUFSIZE];
    #else
    	jpc_fix_t splitbuf[bufsize];
    #endif
    	jpc_fix_t *buf = splitbuf;

Here, numcols is from the codestream, in other places its numrows. I'm not
sure how bad this is, but some broken codestreams i generated crashed there
with negative numbers, which i think is dangerous if combined with VLAs.

Fix proposal: remove the VLA code.

diff -ru jasper-1.900.1.orig/src/libjasper/jpc/jpc_qmfb.c jasper-1.900.1/src/libjasper/jpc/jpc_qmfb.c
--- jasper-1.900.1.orig/src/libjasper/jpc/jpc_qmfb.c	2007-01-19 22:43:07.000000000 +0100
+++ jasper-1.900.1/src/libjasper/jpc/jpc_qmfb.c	2015-01-04 19:59:34.963933194 +0100
@@ -306,11 +306,7 @@
 {
 
 	int bufsize = JPC_CEILDIVPOW2(numcols, 1);
-#if !defined(HAVE_VLA)
 	jpc_fix_t splitbuf[QMFB_SPLITBUFSIZE];
-#else
-	jpc_fix_t splitbuf[bufsize];
-#endif
 	jpc_fix_t *buf = splitbuf;
 	register jpc_fix_t *srcptr;
 	register jpc_fix_t *dstptr;
@@ -318,7 +314,6 @@
 	register int m;
 	int hstartcol;
 
-#if !defined(HAVE_VLA)
 	/* Get a buffer. */
 	if (bufsize > QMFB_SPLITBUFSIZE) {
 		if (!(buf = jas_malloc(bufsize * sizeof(jpc_fix_t)))) {
@@ -326,7 +321,6 @@
 			abort();
 		}
 	}
-#endif
 
 	if (numcols >= 2) {
 		hstartcol = (numcols + 1 - parity) >> 1;
@@ -360,12 +354,10 @@
 		}
 	}
 
-#if !defined(HAVE_VLA)
 	/* If the split buffer was allocated on the heap, free this memory. */
 	if (buf != splitbuf) {
 		jas_free(buf);
 	}
-#endif
 
 }
 
@@ -374,11 +366,7 @@
 {
 
 	int bufsize = JPC_CEILDIVPOW2(numrows, 1);
-#if !defined(HAVE_VLA)
 	jpc_fix_t splitbuf[QMFB_SPLITBUFSIZE];
-#else
-	jpc_fix_t splitbuf[bufsize];
-#endif
 	jpc_fix_t *buf = splitbuf;
 	register jpc_fix_t *srcptr;
 	register jpc_fix_t *dstptr;
@@ -386,7 +374,6 @@
 	register int m;
 	int hstartcol;
 
-#if !defined(HAVE_VLA)
 	/* Get a buffer. */
 	if (bufsize > QMFB_SPLITBUFSIZE) {
 		if (!(buf = jas_malloc(bufsize * sizeof(jpc_fix_t)))) {
@@ -394,7 +381,6 @@
 			abort();
 		}
 	}
-#endif
 
 	if (numrows >= 2) {
 		hstartcol = (numrows + 1 - parity) >> 1;
@@ -428,12 +414,10 @@
 		}
 	}
 
-#if !defined(HAVE_VLA)
 	/* If the split buffer was allocated on the heap, free this memory. */
 	if (buf != splitbuf) {
 		jas_free(buf);
 	}
-#endif
 
 }
 
@@ -442,11 +426,7 @@
 {
 
 	int bufsize = JPC_CEILDIVPOW2(numrows, 1);
-#if !defined(HAVE_VLA)
 	jpc_fix_t splitbuf[QMFB_SPLITBUFSIZE * JPC_QMFB_COLGRPSIZE];
-#else
-	jpc_fix_t splitbuf[bufsize * JPC_QMFB_COLGRPSIZE];
-#endif
 	jpc_fix_t *buf = splitbuf;
 	jpc_fix_t *srcptr;
 	jpc_fix_t *dstptr;
@@ -457,7 +437,6 @@
 	int m;
 	int hstartcol;
 
-#if !defined(HAVE_VLA)
 	/* Get a buffer. */
 	if (bufsize > QMFB_SPLITBUFSIZE) {
 		if (!(buf = jas_malloc(bufsize * sizeof(jpc_fix_t)))) {
@@ -465,7 +444,6 @@
 			abort();
 		}
 	}
-#endif
 
 	if (numrows >= 2) {
 		hstartcol = (numrows + 1 - parity) >> 1;
@@ -517,12 +495,10 @@
 		}
 	}
 
-#if !defined(HAVE_VLA)
 	/* If the split buffer was allocated on the heap, free this memory. */
 	if (buf != splitbuf) {
 		jas_free(buf);
 	}
-#endif
 
 }
 
@@ -531,11 +507,7 @@
 {
 
 	int bufsize = JPC_CEILDIVPOW2(numrows, 1);
-#if !defined(HAVE_VLA)
 	jpc_fix_t splitbuf[QMFB_SPLITBUFSIZE * JPC_QMFB_COLGRPSIZE];
-#else
-	jpc_fix_t splitbuf[bufsize * numcols];
-#endif
 	jpc_fix_t *buf = splitbuf;
 	jpc_fix_t *srcptr;
 	jpc_fix_t *dstptr;
@@ -546,7 +518,6 @@
 	int m;
 	int hstartcol;
 
-#if !defined(HAVE_VLA)
 	/* Get a buffer. */
 	if (bufsize > QMFB_SPLITBUFSIZE) {
 		if (!(buf = jas_malloc(bufsize * sizeof(jpc_fix_t)))) {
@@ -554,7 +525,6 @@
 			abort();
 		}
 	}
-#endif
 
 	if (numrows >= 2) {
 		hstartcol = (numrows + 1 - parity) >> 1;
@@ -606,12 +576,10 @@
 		}
 	}
 
-#if !defined(HAVE_VLA)
 	/* If the split buffer was allocated on the heap, free this memory. */
 	if (buf != splitbuf) {
 		jas_free(buf);
 	}
-#endif
 
 }
 
@@ -619,18 +587,13 @@
 {
 
 	int bufsize = JPC_CEILDIVPOW2(numcols, 1);
-#if !defined(HAVE_VLA)
 	jpc_fix_t joinbuf[QMFB_JOINBUFSIZE];
-#else
-	jpc_fix_t joinbuf[bufsize];
-#endif
 	jpc_fix_t *buf = joinbuf;
 	register jpc_fix_t *srcptr;
 	register jpc_fix_t *dstptr;
 	register int n;
 	int hstartcol;
 
-#if !defined(HAVE_VLA)
 	/* Allocate memory for the join buffer from the heap. */
 	if (bufsize > QMFB_JOINBUFSIZE) {
 		if (!(buf = jas_malloc(bufsize * sizeof(jpc_fix_t)))) {
@@ -638,7 +601,6 @@
 			abort();
 		}
 	}
-#endif
 
 	hstartcol = (numcols + 1 - parity) >> 1;
 
@@ -670,12 +632,10 @@
 		++srcptr;
 	}
 
-#if !defined(HAVE_VLA)
 	/* If the join buffer was allocated on the heap, free this memory. */
 	if (buf != joinbuf) {
 		jas_free(buf);
 	}
-#endif
 
 }
 
@@ -684,18 +644,13 @@
 {
 
 	int bufsize = JPC_CEILDIVPOW2(numrows, 1);
-#if !defined(HAVE_VLA)
 	jpc_fix_t joinbuf[QMFB_JOINBUFSIZE];
-#else
-	jpc_fix_t joinbuf[bufsize];
-#endif
 	jpc_fix_t *buf = joinbuf;
 	register jpc_fix_t *srcptr;
 	register jpc_fix_t *dstptr;
 	register int n;
 	int hstartcol;
 
-#if !defined(HAVE_VLA)
 	/* Allocate memory for the join buffer from the heap. */
 	if (bufsize > QMFB_JOINBUFSIZE) {
 		if (!(buf = jas_malloc(bufsize * sizeof(jpc_fix_t)))) {
@@ -703,7 +658,6 @@
 			abort();
 		}
 	}
-#endif
 
 	hstartcol = (numrows + 1 - parity) >> 1;
 
@@ -735,12 +689,10 @@
 		++srcptr;
 	}
 
-#if !defined(HAVE_VLA)
 	/* If the join buffer was allocated on the heap, free this memory. */
 	if (buf != joinbuf) {
 		jas_free(buf);
 	}
-#endif
 
 }
 
@@ -749,11 +701,7 @@
 {
 
 	int bufsize = JPC_CEILDIVPOW2(numrows, 1);
-#if !defined(HAVE_VLA)
 	jpc_fix_t joinbuf[QMFB_JOINBUFSIZE * JPC_QMFB_COLGRPSIZE];
-#else
-	jpc_fix_t joinbuf[bufsize * JPC_QMFB_COLGRPSIZE];
-#endif
 	jpc_fix_t *buf = joinbuf;
 	jpc_fix_t *srcptr;
 	jpc_fix_t *dstptr;
@@ -763,7 +711,6 @@
 	register int i;
 	int hstartcol;
 
-#if !defined(HAVE_VLA)
 	/* Allocate memory for the join buffer from the heap. */
 	if (bufsize > QMFB_JOINBUFSIZE) {
 		if (!(buf = jas_malloc(bufsize * JPC_QMFB_COLGRPSIZE * sizeof(jpc_fix_t)))) {
@@ -771,7 +718,6 @@
 			abort();
 		}
 	}
-#endif
 
 	hstartcol = (numrows + 1 - parity) >> 1;
 
@@ -821,12 +767,10 @@
 		srcptr += JPC_QMFB_COLGRPSIZE;
 	}
 
-#if !defined(HAVE_VLA)
 	/* If the join buffer was allocated on the heap, free this memory. */
 	if (buf != joinbuf) {
 		jas_free(buf);
 	}
-#endif
 
 }
 
@@ -835,11 +779,7 @@
 {
 
 	int bufsize = JPC_CEILDIVPOW2(numrows, 1);
-#if !defined(HAVE_VLA)
 	jpc_fix_t joinbuf[QMFB_JOINBUFSIZE * JPC_QMFB_COLGRPSIZE];
-#else
-	jpc_fix_t joinbuf[bufsize * numcols];
-#endif
 	jpc_fix_t *buf = joinbuf;
 	jpc_fix_t *srcptr;
 	jpc_fix_t *dstptr;
@@ -849,7 +789,6 @@
 	register int i;
 	int hstartcol;
 
-#if !defined(HAVE_VLA)
 	/* Allocate memory for the join buffer from the heap. */
 	if (bufsize > QMFB_JOINBUFSIZE) {
 		if (!(buf = jas_malloc(bufsize * numcols * sizeof(jpc_fix_t)))) {
@@ -857,7 +796,6 @@
 			abort();
 		}
 	}
-#endif
 
 	hstartcol = (numrows + 1 - parity) >> 1;
 
@@ -907,12 +845,10 @@
 		srcptr += numcols;
 	}
 
-#if !defined(HAVE_VLA)
 	/* If the join buffer was allocated on the heap, free this memory. */
 	if (buf != joinbuf) {
 		jas_free(buf);
 	}
-#endif
 
 }
 
Best regards,

pyddeh
Contact:
pyddeh@gmail.com

-- 
Andrea Barisani |                Founder & Project Coordinator
          oCERT | OSS Computer Security Incident Response Team

<lcars@ocert.org>                         http://www.ocert.org
 0x864C9B9E 0A76 074A 02CD E989 CE7F AC3F DA47 578E 864C 9B9E
        "Pluralitas non est ponenda sine necessitate"
Comment 1 Swamp Workflow Management 2015-01-06 23:00:52 UTC
bugbot adjusting priority
Comment 3 Vladimir Nadvornik 2015-01-14 15:32:00 UTC
SLE packages submitted
Comment 5 Johannes Segitz 2015-01-22 08:09:30 UTC
public
Comment 6 Vladimir Nadvornik 2015-01-23 14:55:31 UTC
openSUSE packages submitted
Comment 7 Bernhard Wiedemann 2015-01-23 15:00:10 UTC
This is an autogenerated message for OBS integration:
This bug (911837) was mentioned in
https://build.opensuse.org/request/show/282564 13.1 / jasper
https://build.opensuse.org/request/show/282565 13.2 / jasper
https://build.opensuse.org/request/show/282566 Factory / jasper
Comment 8 Johannes Segitz 2015-01-30 13:27:10 UTC
I want to include this into 
https://swamp.suse.de/webswamp/swamp/template/DisplayWorkflow.vm/workflowid/59884
but noticed an error in the changes file
- fixed CVE-2014-8137, CVE-2014-8137 (bnc#909474, bnc#909475)

This should be CVE-2014-8137, CVE-2014-8138. Please resubmit the fix for this bug and fix the changes file. Thank you
Comment 9 Vladimir Nadvornik 2015-01-30 15:48:56 UTC
sorry.
SLE packages resubmitted
Comment 10 Swamp Workflow Management 2015-02-03 09:05:20 UTC
openSUSE-SU-2015:0200-1: An update that fixes two vulnerabilities is now available.

Category: security (moderate)
Bug References: 911837
CVE References: CVE-2014-8157,CVE-2014-8158
Sources used:
openSUSE 13.2 (src):    jasper-1.900.1-163.13.1
openSUSE 13.1 (src):    jasper-1.900.1-160.13.1
Comment 11 Swamp Workflow Management 2015-02-12 00:05:23 UTC
SUSE-SU-2015:0258-1: An update that solves two vulnerabilities and has one errata is now available.

Category: security (moderate)
Bug References: 909474,909475,911837
CVE References: CVE-2014-8137,CVE-2014-8138
Sources used:
SUSE Linux Enterprise Software Development Kit 11 SP3 (src):    jasper-1.900.1-134.17.1
SUSE Linux Enterprise Server 11 SP3 for VMware (src):    jasper-1.900.1-134.17.1
SUSE Linux Enterprise Server 11 SP3 (src):    jasper-1.900.1-134.17.1
SUSE Linux Enterprise Desktop 11 SP3 (src):    jasper-1.900.1-134.17.1
Comment 12 Swamp Workflow Management 2015-02-16 13:05:17 UTC
SUSE-SU-2015:0288-1: An update that fixes two vulnerabilities is now available.

Category: security (moderate)
Bug References: 911837
CVE References: CVE-2014-8157,CVE-2014-8158
Sources used:
SUSE Linux Enterprise Software Development Kit 12 (src):    jasper-1.900.1-170.1
SUSE Linux Enterprise Server 12 (src):    jasper-1.900.1-170.1
SUSE Linux Enterprise Desktop 12 (src):    jasper-1.900.1-170.1
Comment 13 Marcus Meissner 2015-03-17 16:35:56 UTC
released