From 97a0b0fbaea0e98e973e0e3ca69ebdea0a0f61e8 Mon Sep 17 00:00:00 2001 From: Dragos Oancea <dragos@signalwire.com> Date: Fri, 13 Mar 2020 18:42:43 +0000 Subject: [PATCH] [mod_opusfile] protect ogg data buff --- src/mod/formats/mod_opusfile/mod_opusfile.c | 7 ++++--- src/mod/formats/mod_opusfile/test/test_opusfile.c | 11 +++++++++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/mod/formats/mod_opusfile/mod_opusfile.c b/src/mod/formats/mod_opusfile/mod_opusfile.c index ea932ed0ff..38f5d1f442 100644 --- a/src/mod/formats/mod_opusfile/mod_opusfile.c +++ b/src/mod/formats/mod_opusfile/mod_opusfile.c @@ -976,6 +976,7 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[OGG/OPUS Stream Decode] read_stream_thread(): switch_thread_self(): 0x%lx\n", switch_thread_self()); } switch_thread_rwlock_rdlock(context->rwlock); + switch_mutex_lock(context->ogg_mutex); if ((buffered_ogg_bytes = switch_buffer_inuse(context->ogg_buffer))) { if (buffered_ogg_bytes <= OGG_MAX_PAGE_SIZE) { @@ -1021,6 +1022,7 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void } } + switch_mutex_unlock(context->ogg_mutex); switch_thread_rwlock_unlock(context->rwlock); return NULL; } @@ -1071,9 +1073,9 @@ static switch_status_t switch_opusstream_decode(switch_codec_t *codec, #endif switch_thread_rwlock_rdlock(context->rwlock); + switch_mutex_lock(context->ogg_mutex); memset(context->ogg_data, 0, sizeof(context->ogg_data)); if (encoded_data_len <= SWITCH_RECOMMENDED_BUFFER_SIZE) { - switch_mutex_lock(context->ogg_mutex); switch_buffer_write(context->ogg_buffer, encode_buf, encoded_data_len); if ((buffered_ogg_bytes = switch_buffer_inuse(context->ogg_buffer)) >= ogg_bytes) { @@ -1089,12 +1091,10 @@ static switch_status_t switch_opusstream_decode(switch_codec_t *codec, switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "[OGG/OPUS Stream Decode] buffered ogg data bigger than max OGG page size, will flush\n"); *decoded_data_len = 0; switch_buffer_zero(context->ogg_buffer); - switch_mutex_unlock(context->ogg_mutex); switch_goto_status(SWITCH_STATUS_SUCCESS, end); } } - switch_mutex_unlock(context->ogg_mutex); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "[OGG/OPUS Stream Decode] too much data to buffer, flushing buffer!\n"); *decoded_data_len = 0; @@ -1134,6 +1134,7 @@ static switch_status_t switch_opusstream_decode(switch_codec_t *codec, end: switch_thread_rwlock_unlock(context->rwlock); + switch_mutex_unlock(context->ogg_mutex); return status; } diff --git a/src/mod/formats/mod_opusfile/test/test_opusfile.c b/src/mod/formats/mod_opusfile/test/test_opusfile.c index f21738bdb7..feb74619e5 100644 --- a/src/mod/formats/mod_opusfile/test/test_opusfile.c +++ b/src/mod/formats/mod_opusfile/test/test_opusfile.c @@ -170,6 +170,7 @@ FST_CORE_BEGIN(".") uint32_t decoded_len; size_t write_len; unsigned char decbuf[SWITCH_RECOMMENDED_BUFFER_SIZE] = { 0 }; + switch_stream_handle_t stream = { 0 }; #ifdef HAVE_OPUSFILE_ENCODE switch_file_handle_t fh = { 0 }; unsigned char encbuf[SWITCH_RECOMMENDED_BUFFER_SIZE] = { 0 }; @@ -216,6 +217,12 @@ FST_CORE_BEGIN(".") &codec_settings, fst_pool); fst_check(status == SWITCH_STATUS_SUCCESS); + SWITCH_STANDARD_STREAM(stream); + + switch_api_execute("opusfile_debug", "on", NULL, &stream); + + switch_safe_free(stream.data); + #ifdef HAVE_OPUSFILE_ENCODE status = switch_core_codec_init(&write_codec, "OPUSSTREAM", @@ -277,12 +284,12 @@ FST_CORE_BEGIN(".") fhw.native_rate = filerate; - flen = OGG_MIN_PAGE_SIZE; + flen = 4096; while (switch_file_read(fd, &buf, &flen) == SWITCH_STATUS_SUCCESS || flen != 0) { status = SWITCH_STATUS_SUCCESS; while (status == SWITCH_STATUS_SUCCESS) { status = switch_core_codec_decode(&read_codec, NULL, &buf, flen, filerate, &decbuf, &decoded_len, &rate, &flags); - fst_requires(status == SWITCH_STATUS_SUCCESS); + fst_check(status == SWITCH_STATUS_SUCCESS); write_len = decoded_len / sizeof(int16_t); if (write_len) switch_core_file_write(&fhw, &decbuf, &write_len); else break;