1From 91a3b5302d6a2467df70d3b43450991a53f9946b Mon Sep 17 00:00:00 2001 2From: Hitendra Prajapati <hprajapati@mvista.com> 3Date: Wed, 16 Nov 2022 11:24:25 +0530 4Subject: [PATCH] CVE-2022-41741, CVE-2022-41742 5 6Upstream-Status: Backport [https://github.com/nginx/nginx/commit/6b022a5556af22b6e18532e547a6ae46b0d8c6ea] 7CVE: CVE-2022-41741, CVE-2022-41742 8Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com> 9 10Mp4: disabled duplicate atoms. 11 12Most atoms should not appear more than once in a container. Previously, 13this was not enforced by the module, which could result in worker process 14crash, memory corruption and disclosure. 15--- 16 src/http/modules/ngx_http_mp4_module.c | 147 +++++++++++++++++++++++++ 17 1 file changed, 147 insertions(+) 18 19diff --git a/src/http/modules/ngx_http_mp4_module.c b/src/http/modules/ngx_http_mp4_module.c 20index 0e93fbd..4f4d89d 100644 21--- a/src/http/modules/ngx_http_mp4_module.c 22+++ b/src/http/modules/ngx_http_mp4_module.c 23@@ -1070,6 +1070,12 @@ ngx_http_mp4_read_ftyp_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) 24 return NGX_ERROR; 25 } 26 27+ if (mp4->ftyp_atom.buf) { 28+ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, 29+ "duplicate mp4 ftyp atom in \"%s\"", mp4->file.name.data); 30+ return NGX_ERROR; 31+ } 32+ 33 atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size; 34 35 ftyp_atom = ngx_palloc(mp4->request->pool, atom_size); 36@@ -1128,6 +1134,12 @@ ngx_http_mp4_read_moov_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) 37 return NGX_DECLINED; 38 } 39 40+ if (mp4->moov_atom.buf) { 41+ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, 42+ "duplicate mp4 moov atom in \"%s\"", mp4->file.name.data); 43+ return NGX_ERROR; 44+ } 45+ 46 conf = ngx_http_get_module_loc_conf(mp4->request, ngx_http_mp4_module); 47 48 if (atom_data_size > mp4->buffer_size) { 49@@ -1195,6 +1207,12 @@ ngx_http_mp4_read_mdat_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) 50 51 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 mdat atom"); 52 53+ if (mp4->mdat_atom.buf) { 54+ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, 55+ "duplicate mp4 mdat atom in \"%s\"", mp4->file.name.data); 56+ return NGX_ERROR; 57+ } 58+ 59 data = &mp4->mdat_data_buf; 60 data->file = &mp4->file; 61 data->in_file = 1; 62@@ -1321,6 +1339,12 @@ ngx_http_mp4_read_mvhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) 63 64 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 mvhd atom"); 65 66+ if (mp4->mvhd_atom.buf) { 67+ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, 68+ "duplicate mp4 mvhd atom in \"%s\"", mp4->file.name.data); 69+ return NGX_ERROR; 70+ } 71+ 72 atom_header = ngx_mp4_atom_header(mp4); 73 mvhd_atom = (ngx_mp4_mvhd_atom_t *) atom_header; 74 mvhd64_atom = (ngx_mp4_mvhd64_atom_t *) atom_header; 75@@ -1586,6 +1610,13 @@ ngx_http_mp4_read_tkhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) 76 atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size; 77 78 trak = ngx_mp4_last_trak(mp4); 79+ 80+ if (trak->out[NGX_HTTP_MP4_TKHD_ATOM].buf) { 81+ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, 82+ "duplicate mp4 tkhd atom in \"%s\"", mp4->file.name.data); 83+ return NGX_ERROR; 84+ } 85+ 86 trak->tkhd_size = atom_size; 87 88 ngx_mp4_set_32value(tkhd_atom->size, atom_size); 89@@ -1624,6 +1655,12 @@ ngx_http_mp4_read_mdia_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) 90 91 trak = ngx_mp4_last_trak(mp4); 92 93+ if (trak->out[NGX_HTTP_MP4_MDIA_ATOM].buf) { 94+ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, 95+ "duplicate mp4 mdia atom in \"%s\"", mp4->file.name.data); 96+ return NGX_ERROR; 97+ } 98+ 99 atom = &trak->mdia_atom_buf; 100 atom->temporary = 1; 101 atom->pos = atom_header; 102@@ -1747,6 +1784,13 @@ ngx_http_mp4_read_mdhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) 103 atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size; 104 105 trak = ngx_mp4_last_trak(mp4); 106+ 107+ if (trak->out[NGX_HTTP_MP4_MDHD_ATOM].buf) { 108+ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, 109+ "duplicate mp4 mdhd atom in \"%s\"", mp4->file.name.data); 110+ return NGX_ERROR; 111+ } 112+ 113 trak->mdhd_size = atom_size; 114 trak->timescale = timescale; 115 116@@ -1789,6 +1833,12 @@ ngx_http_mp4_read_hdlr_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) 117 118 trak = ngx_mp4_last_trak(mp4); 119 120+ if (trak->out[NGX_HTTP_MP4_HDLR_ATOM].buf) { 121+ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, 122+ "duplicate mp4 hdlr atom in \"%s\"", mp4->file.name.data); 123+ return NGX_ERROR; 124+ } 125+ 126 atom = &trak->hdlr_atom_buf; 127 atom->temporary = 1; 128 atom->pos = atom_header; 129@@ -1817,6 +1867,12 @@ ngx_http_mp4_read_minf_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) 130 131 trak = ngx_mp4_last_trak(mp4); 132 133+ if (trak->out[NGX_HTTP_MP4_MINF_ATOM].buf) { 134+ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, 135+ "duplicate mp4 minf atom in \"%s\"", mp4->file.name.data); 136+ return NGX_ERROR; 137+ } 138+ 139 atom = &trak->minf_atom_buf; 140 atom->temporary = 1; 141 atom->pos = atom_header; 142@@ -1860,6 +1916,15 @@ ngx_http_mp4_read_vmhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) 143 144 trak = ngx_mp4_last_trak(mp4); 145 146+ if (trak->out[NGX_HTTP_MP4_VMHD_ATOM].buf 147+ || trak->out[NGX_HTTP_MP4_SMHD_ATOM].buf) 148+ { 149+ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, 150+ "duplicate mp4 vmhd/smhd atom in \"%s\"", 151+ mp4->file.name.data); 152+ return NGX_ERROR; 153+ } 154+ 155 atom = &trak->vmhd_atom_buf; 156 atom->temporary = 1; 157 atom->pos = atom_header; 158@@ -1891,6 +1956,15 @@ ngx_http_mp4_read_smhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) 159 160 trak = ngx_mp4_last_trak(mp4); 161 162+ if (trak->out[NGX_HTTP_MP4_VMHD_ATOM].buf 163+ || trak->out[NGX_HTTP_MP4_SMHD_ATOM].buf) 164+ { 165+ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, 166+ "duplicate mp4 vmhd/smhd atom in \"%s\"", 167+ mp4->file.name.data); 168+ return NGX_ERROR; 169+ } 170+ 171 atom = &trak->smhd_atom_buf; 172 atom->temporary = 1; 173 atom->pos = atom_header; 174@@ -1922,6 +1996,12 @@ ngx_http_mp4_read_dinf_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) 175 176 trak = ngx_mp4_last_trak(mp4); 177 178+ if (trak->out[NGX_HTTP_MP4_DINF_ATOM].buf) { 179+ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, 180+ "duplicate mp4 dinf atom in \"%s\"", mp4->file.name.data); 181+ return NGX_ERROR; 182+ } 183+ 184 atom = &trak->dinf_atom_buf; 185 atom->temporary = 1; 186 atom->pos = atom_header; 187@@ -1950,6 +2030,12 @@ ngx_http_mp4_read_stbl_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) 188 189 trak = ngx_mp4_last_trak(mp4); 190 191+ if (trak->out[NGX_HTTP_MP4_STBL_ATOM].buf) { 192+ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, 193+ "duplicate mp4 stbl atom in \"%s\"", mp4->file.name.data); 194+ return NGX_ERROR; 195+ } 196+ 197 atom = &trak->stbl_atom_buf; 198 atom->temporary = 1; 199 atom->pos = atom_header; 200@@ -2018,6 +2104,12 @@ ngx_http_mp4_read_stsd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) 201 202 trak = ngx_mp4_last_trak(mp4); 203 204+ if (trak->out[NGX_HTTP_MP4_STSD_ATOM].buf) { 205+ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, 206+ "duplicate mp4 stsd atom in \"%s\"", mp4->file.name.data); 207+ return NGX_ERROR; 208+ } 209+ 210 atom = &trak->stsd_atom_buf; 211 atom->temporary = 1; 212 atom->pos = atom_header; 213@@ -2086,6 +2178,13 @@ ngx_http_mp4_read_stts_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) 214 atom_end = atom_table + entries * sizeof(ngx_mp4_stts_entry_t); 215 216 trak = ngx_mp4_last_trak(mp4); 217+ 218+ if (trak->out[NGX_HTTP_MP4_STTS_ATOM].buf) { 219+ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, 220+ "duplicate mp4 stts atom in \"%s\"", mp4->file.name.data); 221+ return NGX_ERROR; 222+ } 223+ 224 trak->time_to_sample_entries = entries; 225 226 atom = &trak->stts_atom_buf; 227@@ -2291,6 +2390,13 @@ ngx_http_mp4_read_stss_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) 228 "sync sample entries:%uD", entries); 229 230 trak = ngx_mp4_last_trak(mp4); 231+ 232+ if (trak->out[NGX_HTTP_MP4_STSS_ATOM].buf) { 233+ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, 234+ "duplicate mp4 stss atom in \"%s\"", mp4->file.name.data); 235+ return NGX_ERROR; 236+ } 237+ 238 trak->sync_samples_entries = entries; 239 240 atom_table = atom_header + sizeof(ngx_http_mp4_stss_atom_t); 241@@ -2489,6 +2595,13 @@ ngx_http_mp4_read_ctts_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) 242 "composition offset entries:%uD", entries); 243 244 trak = ngx_mp4_last_trak(mp4); 245+ 246+ if (trak->out[NGX_HTTP_MP4_CTTS_ATOM].buf) { 247+ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, 248+ "duplicate mp4 ctts atom in \"%s\"", mp4->file.name.data); 249+ return NGX_ERROR; 250+ } 251+ 252 trak->composition_offset_entries = entries; 253 254 atom_table = atom_header + sizeof(ngx_mp4_ctts_atom_t); 255@@ -2692,6 +2805,13 @@ ngx_http_mp4_read_stsc_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) 256 atom_end = atom_table + entries * sizeof(ngx_mp4_stsc_entry_t); 257 258 trak = ngx_mp4_last_trak(mp4); 259+ 260+ if (trak->out[NGX_HTTP_MP4_STSC_ATOM].buf) { 261+ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, 262+ "duplicate mp4 stsc atom in \"%s\"", mp4->file.name.data); 263+ return NGX_ERROR; 264+ } 265+ 266 trak->sample_to_chunk_entries = entries; 267 268 atom = &trak->stsc_atom_buf; 269@@ -3024,6 +3144,13 @@ ngx_http_mp4_read_stsz_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) 270 "sample uniform size:%uD, entries:%uD", size, entries); 271 272 trak = ngx_mp4_last_trak(mp4); 273+ 274+ if (trak->out[NGX_HTTP_MP4_STSZ_ATOM].buf) { 275+ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, 276+ "duplicate mp4 stsz atom in \"%s\"", mp4->file.name.data); 277+ return NGX_ERROR; 278+ } 279+ 280 trak->sample_sizes_entries = entries; 281 282 atom_table = atom_header + sizeof(ngx_mp4_stsz_atom_t); 283@@ -3207,6 +3334,16 @@ ngx_http_mp4_read_stco_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) 284 atom_end = atom_table + entries * sizeof(uint32_t); 285 286 trak = ngx_mp4_last_trak(mp4); 287+ 288+ if (trak->out[NGX_HTTP_MP4_STCO_ATOM].buf 289+ || trak->out[NGX_HTTP_MP4_CO64_ATOM].buf) 290+ { 291+ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, 292+ "duplicate mp4 stco/co64 atom in \"%s\"", 293+ mp4->file.name.data); 294+ return NGX_ERROR; 295+ } 296+ 297 trak->chunks = entries; 298 299 atom = &trak->stco_atom_buf; 300@@ -3413,6 +3550,16 @@ ngx_http_mp4_read_co64_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) 301 atom_end = atom_table + entries * sizeof(uint64_t); 302 303 trak = ngx_mp4_last_trak(mp4); 304+ 305+ if (trak->out[NGX_HTTP_MP4_STCO_ATOM].buf 306+ || trak->out[NGX_HTTP_MP4_CO64_ATOM].buf) 307+ { 308+ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, 309+ "duplicate mp4 stco/co64 atom in \"%s\"", 310+ mp4->file.name.data); 311+ return NGX_ERROR; 312+ } 313+ 314 trak->chunks = entries; 315 316 atom = &trak->co64_atom_buf; 317-- 3182.25.1 319 320