83be9e
Backport of the upstream patch:
83be9e
83be9e
From 03fe49ab96bf65fea784cdc256507ea88267fc7c Mon Sep 17 00:00:00 2001
83be9e
From: Michael Adams <mdadams@ece.uvic.ca>
83be9e
Date: Thu, 2 Mar 2017 08:07:04 -0800
83be9e
Subject: [PATCH] Fixed some potential double-free problems in the JPC codec.
83be9e
83be9e
diff -pruN jasper-1.900.1.orig/src/libjasper/jpc/jpc_enc.c jasper-1.900.1/src/libjasper/jpc/jpc_enc.c
83be9e
--- jasper-1.900.1.orig/src/libjasper/jpc/jpc_enc.c	2017-03-30 22:53:59.000000000 +0200
83be9e
+++ jasper-1.900.1/src/libjasper/jpc/jpc_enc.c	2017-03-31 13:40:12.000000000 +0200
83be9e
@@ -1140,8 +1140,9 @@ int numgbits;
83be9e
 		tilex = tileno % cp->numhtiles;
83be9e
 		tiley = tileno / cp->numhtiles;
83be9e
 
83be9e
-		if (!(enc->curtile = jpc_enc_tile_create(enc->cp, enc->image, tileno))) {
83be9e
-			abort();
83be9e
+		if (!(enc->curtile = jpc_enc_tile_create(enc->cp, enc->image,
83be9e
+		  tileno))) {
83be9e
+			return -1;
83be9e
 		}
83be9e
 
83be9e
 		tile = enc->curtile;
83be9e
@@ -2016,6 +2017,8 @@ error:
83be9e
 	return 0;
83be9e
 }
83be9e
 
83be9e
+/* Note: I don't think that it is necessary to marked destroyed subobjects
83be9e
+as such in this function. */
83be9e
 void jpc_enc_tile_destroy(jpc_enc_tile_t *tile)
83be9e
 {
83be9e
 	jpc_enc_tcmpt_t *tcmpt;
83be9e
@@ -2027,16 +2030,21 @@ void jpc_enc_tile_destroy(jpc_enc_tile_t
83be9e
 			tcmpt_destroy(tcmpt);
83be9e
 		}
83be9e
 		jas_free(tile->tcmpts);
83be9e
+		/* tile->tcmpts = NULL; */
83be9e
 	}
83be9e
 	if (tile->lyrsizes) {
83be9e
 		jas_free(tile->lyrsizes);
83be9e
+		/* tile->lyrsizes = NULL; */
83be9e
 	}
83be9e
 	if (tile->pi) {
83be9e
 		jpc_pi_destroy(tile->pi);
83be9e
+		/* tile->pi = NULL; */
83be9e
 	}
83be9e
 	jas_free(tile);
83be9e
+	/* tile = NULL; */
83be9e
 }
83be9e
 
83be9e
+/* Note: This constructor creates the object in place. */
83be9e
 static jpc_enc_tcmpt_t *tcmpt_create(jpc_enc_tcmpt_t *tcmpt, jpc_enc_cp_t *cp,
83be9e
   jas_image_t *image, jpc_enc_tile_t *tile)
83be9e
 {
83be9e
@@ -2132,6 +2140,10 @@ error:
83be9e
 
83be9e
 }
83be9e
 
83be9e
+/* Note: Since jpc_enc_tcmpt_t objects are created in-place, they might
83be9e
+potentially be destroyed multiple times at different levels in the call
83be9e
+chain.  So, destroyed subobjects must be marked as destroyed to prevent
83be9e
+problems such as double frees. */
83be9e
 static void tcmpt_destroy(jpc_enc_tcmpt_t *tcmpt)
83be9e
 {
83be9e
 	jpc_enc_rlvl_t *rlvl;
83be9e
@@ -2143,16 +2155,20 @@ static void tcmpt_destroy(jpc_enc_tcmpt_
83be9e
 			rlvl_destroy(rlvl);
83be9e
 		}
83be9e
 		jas_free(tcmpt->rlvls);
83be9e
+		tcmpt->rlvls = NULL;
83be9e
 	}
83be9e
 
83be9e
 	if (tcmpt->data) {
83be9e
 		jas_seq2d_destroy(tcmpt->data);
83be9e
+		tcmpt->data = NULL;
83be9e
 	}
83be9e
 	if (tcmpt->tsfb) {
83be9e
 		jpc_tsfb_destroy(tcmpt->tsfb);
83be9e
+		tcmpt->tsfb = NULL;
83be9e
 	}
83be9e
 }
83be9e
 
83be9e
+/* Note: This constructor creates the object in place. */
83be9e
 static jpc_enc_rlvl_t *rlvl_create(jpc_enc_rlvl_t *rlvl, jpc_enc_cp_t *cp,
83be9e
   jpc_enc_tcmpt_t *tcmpt, jpc_tsfb_band_t *bandinfos)
83be9e
 {
83be9e
@@ -2234,6 +2250,10 @@ error:
83be9e
 	return 0;
83be9e
 }
83be9e
 
83be9e
+/* Note: Since jpc_enc_rlvl_t objects are created in-place, they might
83be9e
+potentially be destroyed multiple times at different levels in the call
83be9e
+chain.  So, destroyed subobjects must be marked as destroyed to prevent
83be9e
+problems such as double frees. */
83be9e
 static void rlvl_destroy(jpc_enc_rlvl_t *rlvl)
83be9e
 {
83be9e
 	jpc_enc_band_t *band;
83be9e
@@ -2245,9 +2265,11 @@ static void rlvl_destroy(jpc_enc_rlvl_t
83be9e
 			band_destroy(band);
83be9e
 		}
83be9e
 		jas_free(rlvl->bands);
83be9e
+		rlvl->bands = NULL;
83be9e
 	}
83be9e
 }
83be9e
 
83be9e
+/* Note: This constructor creates the object in place. */
83be9e
 static jpc_enc_band_t *band_create(jpc_enc_band_t *band, jpc_enc_cp_t *cp,
83be9e
   jpc_enc_rlvl_t *rlvl, jpc_tsfb_band_t *bandinfos)
83be9e
 {
83be9e
@@ -2315,6 +2337,10 @@ error:
83be9e
 	return 0;
83be9e
 }
83be9e
 
83be9e
+/* Note: Since jpc_enc_band_t objects are created in-place, they might
83be9e
+potentially be destroyed multiple times at different levels in the call
83be9e
+chain.  So, destroyed subobjects must be marked as destroyed to prevent
83be9e
+problems such as double frees. */
83be9e
 static void band_destroy(jpc_enc_band_t *band)
83be9e
 {
83be9e
 	jpc_enc_prc_t *prc;
83be9e
@@ -2328,12 +2354,15 @@ static void band_destroy(jpc_enc_band_t
83be9e
 			prc_destroy(prc);
83be9e
 		}
83be9e
 		jas_free(band->prcs);
83be9e
+		band->prcs = NULL;
83be9e
 	}
83be9e
 	if (band->data) {
83be9e
 		jas_seq2d_destroy(band->data);
83be9e
+		band->data = NULL;
83be9e
 	}
83be9e
 }
83be9e
 
83be9e
+/* Note: This constructor creates the object in place. */
83be9e
 static jpc_enc_prc_t *prc_create(jpc_enc_prc_t *prc, jpc_enc_cp_t *cp, jpc_enc_band_t *band)
83be9e
 {
83be9e
 	uint_fast32_t prcno;
83be9e
@@ -2459,6 +2488,10 @@ error:
83be9e
 	return 0;
83be9e
 }
83be9e
 
83be9e
+/* Note: Since jpc_enc_prc_t objects are created in-place, they might
83be9e
+potentially be destroyed multiple times at different levels in the call
83be9e
+chain.  So, destroyed subobjects must be marked as destroyed to prevent
83be9e
+problems such as double frees. */
83be9e
 static void prc_destroy(jpc_enc_prc_t *prc)
83be9e
 {
83be9e
 	jpc_enc_cblk_t *cblk;
83be9e
@@ -2470,22 +2503,29 @@ static void prc_destroy(jpc_enc_prc_t *p
83be9e
 			cblk_destroy(cblk);
83be9e
 		}
83be9e
 		jas_free(prc->cblks);
83be9e
+		prc->cblks = NULL;
83be9e
 	}
83be9e
 	if (prc->incltree) {
83be9e
 		jpc_tagtree_destroy(prc->incltree);
83be9e
+		prc->incltree = NULL;
83be9e
 	}
83be9e
 	if (prc->nlibtree) {
83be9e
 		jpc_tagtree_destroy(prc->nlibtree);
83be9e
+		prc->nlibtree = NULL;
83be9e
 	}
83be9e
 	if (prc->savincltree) {
83be9e
 		jpc_tagtree_destroy(prc->savincltree);
83be9e
+		prc->savincltree = NULL;
83be9e
 	}
83be9e
 	if (prc->savnlibtree) {
83be9e
 		jpc_tagtree_destroy(prc->savnlibtree);
83be9e
+		prc->savnlibtree = NULL;
83be9e
 	}
83be9e
 }
83be9e
 
83be9e
-static jpc_enc_cblk_t *cblk_create(jpc_enc_cblk_t *cblk, jpc_enc_cp_t *cp, jpc_enc_prc_t *prc)
83be9e
+/* Note: This constructor creates the object in place. */
83be9e
+static jpc_enc_cblk_t *cblk_create(jpc_enc_cblk_t *cblk, jpc_enc_cp_t *cp,
83be9e
+  jpc_enc_prc_t *prc)
83be9e
 {
83be9e
 	jpc_enc_band_t *band;
83be9e
 	uint_fast32_t cblktlx;
83be9e
@@ -2543,6 +2583,10 @@ error:
83be9e
 	return 0;
83be9e
 }
83be9e
 
83be9e
+/* Note: Since jpc_enc_cblk_t objects are created in-place, they might
83be9e
+potentially be destroyed multiple times at different levels in the call
83be9e
+chain.  So, destroyed subobjects must be marked as destroyed to prevent
83be9e
+problems such as double frees. */
83be9e
 static void cblk_destroy(jpc_enc_cblk_t *cblk)
83be9e
 {
83be9e
 	uint_fast16_t passno;
83be9e
@@ -2553,18 +2597,23 @@ static void cblk_destroy(jpc_enc_cblk_t
83be9e
 			pass_destroy(pass);
83be9e
 		}
83be9e
 		jas_free(cblk->passes);
83be9e
+		cblk->passes = NULL;
83be9e
 	}
83be9e
 	if (cblk->stream) {
83be9e
 		jas_stream_close(cblk->stream);
83be9e
+		cblk->stream = NULL;
83be9e
 	}
83be9e
 	if (cblk->mqenc) {
83be9e
 		jpc_mqenc_destroy(cblk->mqenc);
83be9e
+		cblk->mqenc = NULL;
83be9e
 	}
83be9e
 	if (cblk->data) {
83be9e
 		jas_seq2d_destroy(cblk->data);
83be9e
+		cblk->data = NULL;
83be9e
 	}
83be9e
 	if (cblk->flags) {
83be9e
 		jas_seq2d_destroy(cblk->flags);
83be9e
+		cblk->flags = NULL;
83be9e
 	}
83be9e
 }
83be9e