|
| 1 | +From 7362d01658b61184108c21278443910da68f93b4 Mon Sep 17 00:00:00 2001 |
| 2 | +From: Roman Arutyunyan < [email protected]> |
| 3 | +Date: Mon, 12 Aug 2024 18:20:43 +0400 |
| 4 | +Subject: [PATCH] Mp4: fixed buffer underread while updating stsz atom. |
| 5 | + |
| 6 | +While cropping an stsc atom in ngx_http_mp4_crop_stsc_data(), a 32-bit integer |
| 7 | +overflow could happen, which could result in incorrect seeking and a very large |
| 8 | +value stored in "samples". This resulted in a large invalid value of |
| 9 | +trak->end_chunk_samples. This value is further used to calculate the value of |
| 10 | +trak->end_chunk_samples_size in ngx_http_mp4_update_stsz_atom(). While doing |
| 11 | +this, a large invalid value of trak->end_chunk_samples could result in reading |
| 12 | +memory before stsz atom start. This could potentially result in a segfault. |
| 13 | +--- |
| 14 | + src/http/modules/ngx_http_mp4_module.c | 7 ++++--- |
| 15 | + 1 file changed, 4 insertions(+), 3 deletions(-) |
| 16 | + |
| 17 | +diff --git a/src/http/modules/ngx_http_mp4_module.c b/src/http/modules/ngx_http_mp4_module.c |
| 18 | +index 03175dea21..1cd017c274 100644 |
| 19 | +--- a/src/http/modules/ngx_http_mp4_module.c |
| 20 | ++++ b/src/http/modules/ngx_http_mp4_module.c |
| 21 | +@@ -3099,7 +3099,8 @@ static ngx_int_t |
| 22 | + ngx_http_mp4_crop_stsc_data(ngx_http_mp4_file_t *mp4, |
| 23 | + ngx_http_mp4_trak_t *trak, ngx_uint_t start) |
| 24 | + { |
| 25 | +- uint32_t start_sample, chunk, samples, id, next_chunk, n, |
| 26 | ++ uint64_t n; |
| 27 | ++ uint32_t start_sample, chunk, samples, id, next_chunk, |
| 28 | + prev_samples; |
| 29 | + ngx_buf_t *data, *buf; |
| 30 | + ngx_uint_t entries, target_chunk, chunk_samples; |
| 31 | +@@ -3160,7 +3161,7 @@ ngx_http_mp4_crop_stsc_data(ngx_http_mp4_file_t *mp4, |
| 32 | + "samples:%uD, id:%uD", |
| 33 | + start_sample, chunk, next_chunk - chunk, samples, id); |
| 34 | + |
| 35 | +- n = (next_chunk - chunk) * samples; |
| 36 | ++ n = (uint64_t) (next_chunk - chunk) * samples; |
| 37 | + |
| 38 | + if (start_sample < n) { |
| 39 | + goto found; |
| 40 | +@@ -3182,7 +3183,7 @@ ngx_http_mp4_crop_stsc_data(ngx_http_mp4_file_t *mp4, |
| 41 | + "sample:%uD, chunk:%uD, chunks:%uD, samples:%uD", |
| 42 | + start_sample, chunk, next_chunk - chunk, samples); |
| 43 | + |
| 44 | +- n = (next_chunk - chunk) * samples; |
| 45 | ++ n = (uint64_t) (next_chunk - chunk) * samples; |
| 46 | + |
| 47 | + if (start_sample > n) { |
| 48 | + ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
| 49 | +From 88955b1044ef38315b77ad1a509d63631a790a0f Mon Sep 17 00:00:00 2001 |
| 50 | +From: Roman Arutyunyan < [email protected]> |
| 51 | +Date: Mon, 12 Aug 2024 18:20:45 +0400 |
| 52 | +Subject: [PATCH] Mp4: rejecting unordered chunks in stsc atom. |
| 53 | + |
| 54 | +Unordered chunks could result in trak->end_chunk smaller than trak->start_chunk |
| 55 | +in ngx_http_mp4_crop_stsc_data(). Later in ngx_http_mp4_update_stco_atom() |
| 56 | +this caused buffer overread while trying to calculate trak->end_offset. |
| 57 | +--- |
| 58 | + src/http/modules/ngx_http_mp4_module.c | 7 +++++++ |
| 59 | + 1 file changed, 7 insertions(+) |
| 60 | + |
| 61 | +diff --git a/src/http/modules/ngx_http_mp4_module.c b/src/http/modules/ngx_http_mp4_module.c |
| 62 | +index 1cd017c274..041ad263b5 100644 |
| 63 | +--- a/src/http/modules/ngx_http_mp4_module.c |
| 64 | ++++ b/src/http/modules/ngx_http_mp4_module.c |
| 65 | +@@ -3156,6 +3156,13 @@ ngx_http_mp4_crop_stsc_data(ngx_http_mp4_file_t *mp4, |
| 66 | + |
| 67 | + next_chunk = ngx_mp4_get_32value(entry->chunk); |
| 68 | + |
| 69 | ++ if (next_chunk < chunk) { |
| 70 | ++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
| 71 | ++ "unordered mp4 stsc chunks in \"%s\"", |
| 72 | ++ mp4->file.name.data); |
| 73 | ++ return NGX_ERROR; |
| 74 | ++ } |
| 75 | ++ |
| 76 | + ngx_log_debug5(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
| 77 | + "sample:%uD, chunk:%uD, chunks:%uD, " |
| 78 | + "samples:%uD, id:%uD", |
0 commit comments