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