Mercurial > hg > nginx
comparison src/http/modules/ngx_http_mp4_module.c @ 9322:d6f75dd66761 default tip
Mp4: added and updated sanity checks for "end" handling.
When handling incorrect data in ngx_http_mp4_crop_stsc_data(),
trak->end_chunk_samples might end up being arbitrary large, leading
to reading before the buffer in ngx_http_mp4_update_stsz_atom(). Fix
is to check that trak->end_chunk_samples corresponds to a memory within
the stsz atom data. For consistency, trak->start_chunk_samples
is checked similarly.
Similarly, trak->end_chunk might end up being smaller than trak->start_chunk,
leading to reading memory after the buffer in ngx_http_mp4_update_stco_atom()
and ngx_http_mp4_update_co64_atom(). Corresponding checks are updated
to explicitly test (trak->end_chunk - trak->start_chunk) instead of just
checking trak->end_chunk and assuming it is larger than trak->start_chunk.
This is generally in line with existing checks of
(trak->end_sample - trak->start_sample) in ngx_http_mp4_update_stsz_atom(),
where trak->end_sample might also become smaller than trak->start_sample
when handling incorrect data in ngx_http_mp4_crop_stts_data().
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Sun, 25 Aug 2024 06:35:40 +0300 |
parents | f5515e727656 |
children |
comparison
equal
deleted
inserted
replaced
9321:bfbcfaec4c06 | 9322:d6f75dd66761 |
---|---|
3417 | 3417 |
3418 entries -= trak->start_sample; | 3418 entries -= trak->start_sample; |
3419 data->pos += trak->start_sample * sizeof(uint32_t); | 3419 data->pos += trak->start_sample * sizeof(uint32_t); |
3420 end = (uint32_t *) data->pos; | 3420 end = (uint32_t *) data->pos; |
3421 | 3421 |
3422 if (trak->start_chunk_samples > trak->start_sample) { | |
3423 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
3424 "too many mp4 start chunk samples in \"%s\"", | |
3425 mp4->file.name.data); | |
3426 return NGX_ERROR; | |
3427 } | |
3428 | |
3422 for (pos = end - trak->start_chunk_samples; pos < end; pos++) { | 3429 for (pos = end - trak->start_chunk_samples; pos < end; pos++) { |
3423 trak->start_chunk_samples_size += ngx_mp4_get_32value(pos); | 3430 trak->start_chunk_samples_size += ngx_mp4_get_32value(pos); |
3424 } | 3431 } |
3425 | 3432 |
3426 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | 3433 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
3444 | 3451 |
3445 entries = trak->end_sample - trak->start_sample; | 3452 entries = trak->end_sample - trak->start_sample; |
3446 data->last = data->pos + entries * sizeof(uint32_t); | 3453 data->last = data->pos + entries * sizeof(uint32_t); |
3447 end = (uint32_t *) data->last; | 3454 end = (uint32_t *) data->last; |
3448 | 3455 |
3456 if (trak->end_chunk_samples > entries) { | |
3457 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | |
3458 "too many mp4 end chunk samples in \"%s\"", | |
3459 mp4->file.name.data); | |
3460 return NGX_ERROR; | |
3461 } | |
3462 | |
3449 for (pos = end - trak->end_chunk_samples; pos < end; pos++) { | 3463 for (pos = end - trak->end_chunk_samples; pos < end; pos++) { |
3450 trak->end_chunk_samples_size += ngx_mp4_get_32value(pos); | 3464 trak->end_chunk_samples_size += ngx_mp4_get_32value(pos); |
3451 } | 3465 } |
3452 | 3466 |
3453 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | 3467 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
3610 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | 3624 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
3611 "start chunk offset:%O", trak->start_offset); | 3625 "start chunk offset:%O", trak->start_offset); |
3612 | 3626 |
3613 if (mp4->length) { | 3627 if (mp4->length) { |
3614 | 3628 |
3615 if (trak->end_chunk > trak->chunks) { | 3629 if (trak->end_chunk - trak->start_chunk |
3630 > trak->chunks - trak->start_chunk) | |
3631 { | |
3616 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | 3632 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, |
3617 "end time is out mp4 stco chunks in \"%s\"", | 3633 "end time is out mp4 stco chunks in \"%s\"", |
3618 mp4->file.name.data); | 3634 mp4->file.name.data); |
3619 return NGX_ERROR; | 3635 return NGX_ERROR; |
3620 } | 3636 } |
3823 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, | 3839 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, |
3824 "start chunk offset:%O", trak->start_offset); | 3840 "start chunk offset:%O", trak->start_offset); |
3825 | 3841 |
3826 if (mp4->length) { | 3842 if (mp4->length) { |
3827 | 3843 |
3828 if (trak->end_chunk > trak->chunks) { | 3844 if (trak->end_chunk - trak->start_chunk |
3829 ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, | 3845 > trak->chunks - trak->start_chunk) |
3846 { | |
3847 ngx_log_error(NGX_LOG_ALERT, mp4->file.log, 0, | |
3830 "end time is out mp4 co64 chunks in \"%s\"", | 3848 "end time is out mp4 co64 chunks in \"%s\"", |
3831 mp4->file.name.data); | 3849 mp4->file.name.data); |
3832 return NGX_ERROR; | 3850 return NGX_ERROR; |
3833 } | 3851 } |
3834 | 3852 |