CVE-2015-8871: Use After Free (CWE-416)
value: Use-after-free vulnerability in the opj_j2k_write_mco function in j2k.c in OpenJPEG before 2.1.1 allows remote attackers to have unspecified impact via unknown vectors.
CWE description: The product reuses or references memory after it has been freed. At some point afterward, the memory may be allocated again and saved in another pointer, while the original pointer references a location somewhere within the new allocation. Any operations using the original pointer are no longer valid because the memory "belongs" to the code that operates on the new pointer.
CVSS v3 base score: 9.8
Published: 2016-09-21T14:25Z
Repository: https://github.com/uclouvain/openjpeg
Language: C
Files changed: src/lib/openjp2/j2k.c
Commit date: 2015-09-06 17:24:03 +0200
Commit message: Fix potential use-after-free in opj_j2k_write_mco function

Fixes #563

Diff: diff --git a/src/lib/openjp2/j2k.c b/src/lib/openjp2/j2k.c
index 19a48f5..d487d89 100644
--- a/src/lib/openjp2/j2k.c
+++ b/src/lib/openjp2/j2k.c
@@ -5557,12 +5557,11 @@ static OPJ_BOOL opj_j2k_write_mco(     opj_j2k_t *p_j2k,
         assert(p_j2k != 00);
         assert(p_manager != 00);
         assert(p_stream != 00);
 
         l_tcp =&(p_j2k->m_cp.tcps[p_j2k->m_current_tile_number]);
-        l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
-
+	
         l_mco_size = 5 + l_tcp->m_nb_mcc_records;
         if (l_mco_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) {
 
                 OPJ_BYTE *new_header_tile_data = (OPJ_BYTE *) opj_realloc(p_j2k->m_specific_param.m_encoder.m_header_tile_data, l_mco_size);
                 if (! new_header_tile_data) {
@@ -5573,10 +5572,12 @@ static OPJ_BOOL opj_j2k_write_mco(     opj_j2k_t *p_j2k,
                         return OPJ_FALSE;
                 }
                 p_j2k->m_specific_param.m_encoder.m_header_tile_data = new_header_tile_data;
                 p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_mco_size;
         }
+        l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data;
+
 
         opj_write_bytes(l_current_data,J2K_MS_MCO,2);                   /* MCO */
         l_current_data += 2;
 
         opj_write_bytes(l_current_data,l_mco_size-2,2);                 /* Lmco */
@@ -5584,14 +5585,13 @@ static OPJ_BOOL opj_j2k_write_mco(     opj_j2k_t *p_j2k,
 
         opj_write_bytes(l_current_data,l_tcp->m_nb_mcc_records,1);      /* Nmco : only one tranform stage*/
         ++l_current_data;
 
         l_mcc_record = l_tcp->m_mcc_records;
-        for     (i=0;i<l_tcp->m_nb_mcc_records;++i) {
+        for (i=0;i<l_tcp->m_nb_mcc_records;++i) {
                 opj_write_bytes(l_current_data,l_mcc_record->m_index,1);/* Imco -> use the mcc indicated by 1*/
                 ++l_current_data;
-
                 ++l_mcc_record;
         }
 
         if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_mco_size,p_manager) != l_mco_size) {
                 return OPJ_FALSE;

Vulnerable code:         l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data;

        for     (i=0;i<l_tcp->m_nb_mcc_records;++i) {

Fixed code: 	
        l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data;

        for (i=0;i<l_tcp->m_nb_mcc_records;++i) {