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