Vulnerability: 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.
Vulnerability ID: CVE-2015-8871
CWE: CWE-416
Severity score: 6.4
Project: https://github.com/uclouvain/openjpeg
Published: 2016-09-21
File: src/lib/openjp2/j2k.c
Commit message: Fix potential use-after-free in opj_j2k_write_mco function

Fixes #563
Commit author: mayeut

Vulnerable version (before fix):
 static OPJ_BOOL opj_j2k_write_mco(     opj_j2k_t *p_j2k,         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) {  static OPJ_BOOL opj_j2k_write_mco(     opj_j2k_t *p_j2k,                 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;         }          opj_write_bytes(l_current_data,J2K_MS_MCO,2);                   /* MCO */         l_current_data += 2; static OPJ_BOOL opj_j2k_write_mco(     opj_j2k_t *p_j2k,         ++l_current_data;          l_mcc_record = l_tcp->m_mcc_records;         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;         } 

Fixed version (after fix):
 static OPJ_BOOL opj_j2k_write_mco(     opj_j2k_t *p_j2k,         assert(p_stream != 00);          l_tcp =&(p_j2k->m_cp.tcps[p_j2k->m_current_tile_number]); 	         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) {  static OPJ_BOOL opj_j2k_write_mco(     opj_j2k_t *p_j2k,                 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; static OPJ_BOOL opj_j2k_write_mco(     opj_j2k_t *p_j2k,         ++l_current_data;          l_mcc_record = l_tcp->m_mcc_records;         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;         } 

Patch:
patch: @@ -5559,8 +5559,7 @@ static OPJ_BOOL opj_j2k_write_mco(     opj_j2k_t *p_j2k,
         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) {
 
@@ -5575,6 +5574,8 @@ static OPJ_BOOL opj_j2k_write_mco(     opj_j2k_t *p_j2k,
                 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;
@@ -5586,10 +5587,9 @@ static OPJ_BOOL opj_j2k_write_mco(     opj_j2k_t *p_j2k,
         ++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;
         }
path: src/lib/openjp2/j2k.c