From be267185599578eacf7373204a7a19cfe36d5e65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Sun, 24 May 2026 00:16:26 +0800 Subject: [PATCH] fix(runtime): 4 memory safety bugs in onnxruntime C++ code - #2848: encoder_out_lens int32/int64 type mismatch (heap-buffer-overflow) - #2845: memory leak in FunTpassInferBuffer (missing delete[] for buff/len) - #2846: buffer leak in Audio::FfmpegLoad error paths (av_freep before avio_context_free) - #2847: AudioFrame copy constructor missing data/global_start/global_end (double-free risk) --- runtime/onnxruntime/src/audio.cpp | 18 +++++++++++++++++- runtime/onnxruntime/src/funasrruntime.cpp | 4 ++++ runtime/onnxruntime/src/paraformer.cpp | 9 ++++++++- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/runtime/onnxruntime/src/audio.cpp b/runtime/onnxruntime/src/audio.cpp index 22a9ecd29..4822897d5 100644 --- a/runtime/onnxruntime/src/audio.cpp +++ b/runtime/onnxruntime/src/audio.cpp @@ -156,6 +156,14 @@ AudioFrame::AudioFrame(const AudioFrame &other) end = other.end; len = other.len; is_final = other.is_final; + global_start = other.global_start; + global_end = other.global_end; + if (other.data != nullptr && other.len > 0) { + data = (float*)malloc(other.len * sizeof(float)); + memcpy(data, other.data, other.len * sizeof(float)); + } else { + data = nullptr; + } } AudioFrame::AudioFrame(int start, int end, bool is_final):start(start),end(end),is_final(is_final){ len = end - start; @@ -470,6 +478,7 @@ bool Audio::FfmpegLoad(const char* buf, int n_file_len){ formatContext->pb = avio_ctx; if (avformat_open_input(&formatContext, "", nullptr, nullptr) != 0) { LOG(ERROR) << "Error: Could not open input file."; + av_freep(&avio_ctx->buffer); avio_context_free(&avio_ctx); avformat_close_input(&formatContext); avformat_free_context(formatContext); @@ -478,6 +487,7 @@ bool Audio::FfmpegLoad(const char* buf, int n_file_len){ if (avformat_find_stream_info(formatContext, nullptr) < 0) { LOG(ERROR) << "Error: Could not find stream information."; + av_freep(&avio_ctx->buffer); avio_context_free(&avio_ctx); avformat_close_input(&formatContext); avformat_free_context(formatContext); @@ -492,6 +502,7 @@ bool Audio::FfmpegLoad(const char* buf, int n_file_len){ AVCodecContext* codecContext = avcodec_alloc_context3(codec); if (!codecContext) { LOG(ERROR) << "Failed to allocate codec context"; + av_freep(&avio_ctx->buffer); avio_context_free(&avio_ctx); avformat_close_input(&formatContext); avformat_free_context(formatContext); @@ -499,6 +510,7 @@ bool Audio::FfmpegLoad(const char* buf, int n_file_len){ } if (avcodec_parameters_to_context(codecContext, codecParameters) != 0) { LOG(ERROR) << "Error: Could not copy codec parameters to codec context."; + av_freep(&avio_ctx->buffer); avio_context_free(&avio_ctx); avformat_close_input(&formatContext); avformat_free_context(formatContext); @@ -507,6 +519,7 @@ bool Audio::FfmpegLoad(const char* buf, int n_file_len){ } if (avcodec_open2(codecContext, codec, nullptr) < 0) { LOG(ERROR) << "Error: Could not open audio decoder."; + av_freep(&avio_ctx->buffer); avio_context_free(&avio_ctx); avformat_close_input(&formatContext); avformat_free_context(formatContext); @@ -526,6 +539,7 @@ bool Audio::FfmpegLoad(const char* buf, int n_file_len){ ); if (swr_ctx == nullptr) { LOG(ERROR) << "Could not initialize resampler"; + av_freep(&avio_ctx->buffer); avio_context_free(&avio_ctx); avformat_close_input(&formatContext); avformat_free_context(formatContext); @@ -534,6 +548,7 @@ bool Audio::FfmpegLoad(const char* buf, int n_file_len){ } if (swr_init(swr_ctx) != 0) { LOG(ERROR) << "Could not initialize resampler"; + av_freep(&avio_ctx->buffer); avio_context_free(&avio_ctx); avformat_close_input(&formatContext); avformat_free_context(formatContext); @@ -580,7 +595,8 @@ bool Audio::FfmpegLoad(const char* buf, int n_file_len){ av_packet_unref(packet); } - //avio_context_free(&avio_ctx); + //av_freep(&avio_ctx->buffer); + avio_context_free(&avio_ctx); av_freep(&avio_ctx ->buffer); av_freep(&avio_ctx); avformat_close_input(&formatContext); diff --git a/runtime/onnxruntime/src/funasrruntime.cpp b/runtime/onnxruntime/src/funasrruntime.cpp index 580c93422..a024939b0 100644 --- a/runtime/onnxruntime/src/funasrruntime.cpp +++ b/runtime/onnxruntime/src/funasrruntime.cpp @@ -548,6 +548,8 @@ }else if(mode == ASR_TWO_PASS){ p_result->msg += msg; } + delete[] buff; + delete[] len; if(frame != nullptr){ delete frame; frame = nullptr; @@ -621,6 +623,8 @@ if (!(p_result->stamp).empty()){ p_result->stamp_sents = funasr::TimestampSentence(p_result->tpass_msg, p_result->stamp); } + delete[] buff; + delete[] len; if(frame != nullptr){ delete frame; frame = nullptr; diff --git a/runtime/onnxruntime/src/paraformer.cpp b/runtime/onnxruntime/src/paraformer.cpp index 7e1fe9671..eb9c75243 100644 --- a/runtime/onnxruntime/src/paraformer.cpp +++ b/runtime/onnxruntime/src/paraformer.cpp @@ -509,7 +509,14 @@ std::vector Paraformer::Forward(float** din, int* len, bool input_f int64_t outputCount = std::accumulate(outputShape.begin(), outputShape.end(), 1, std::multiplies()); float* floatData = outputTensor[0].GetTensorMutableData(); - auto encoder_out_lens = outputTensor[1].GetTensorMutableData(); + auto enc_lens_type = outputTensor[1].GetTensorTypeAndShapeInfo().GetElementType(); + int64_t encoder_out_lens_val; + if (enc_lens_type == ONNX_TENSOR_ELEMENT_DATA_TYPE_INT32) { + encoder_out_lens_val = static_cast(*outputTensor[1].GetTensorMutableData()); + } else { + encoder_out_lens_val = *outputTensor[1].GetTensorMutableData(); + } + auto encoder_out_lens = &encoder_out_lens_val; // timestamp if(outputTensor.size() == 4){ std::vector us_alphas_shape = outputTensor[2].GetTensorTypeAndShapeInfo().GetShape();