From e1ba42c4713efe23d6717f393df9a6572972af7a Mon Sep 17 00:00:00 2001 From: Amrit kumar Mahto Date: Thu, 8 Jan 2026 02:13:52 +0530 Subject: [PATCH 1/3] fix: Free filebuffer to prevent 16MB memory leak in ccxr_demuxer_close --- src/rust/src/libccxr_exports/demuxer.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/rust/src/libccxr_exports/demuxer.rs b/src/rust/src/libccxr_exports/demuxer.rs index dc7ef2c59..68abcdd4e 100755 --- a/src/rust/src/libccxr_exports/demuxer.rs +++ b/src/rust/src/libccxr_exports/demuxer.rs @@ -407,6 +407,19 @@ pub unsafe extern "C" fn ccxr_demuxer_close(ctx: *mut ccx_demuxer) { c.infd = -1; activity_input_file_closed(); } + + // We allocate this buffer in Rust (init_file_buffer) but then 'forget' it so C can use it. + // If we don't bring it back and drop it here, we leak 16MB every time a demuxer closes. + if !c.filebuffer.is_null() { + use crate::file_functions::file::FILEBUFFERSIZE; + // Reclaim the pointer as a boxed slice so Rust can finally free the memory. + let _ = Box::from_raw(std::ptr::slice_from_raw_parts_mut( + c.filebuffer, + FILEBUFFERSIZE, + )); + // Null it out to prevent any double-free accidents if C tries to cleanup too. + c.filebuffer = std::ptr::null_mut(); + } } // Extern function for ccx_demuxer_isopen From 472c8bd3cd88140bb9905d0e194ec15f957a28a7 Mon Sep 17 00:00:00 2001 From: Amrit kumar Mahto Date: Thu, 15 Jan 2026 04:51:25 +0530 Subject: [PATCH 2/3] fix Free Rust filebuffer in ccxr_demuxer_delete to prevent memory leak and UB --- src/lib_ccx/ccx_demuxer.c | 14 ++++++++++++++ src/rust/src/libccxr_exports/demuxer.rs | 16 ++++++++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/lib_ccx/ccx_demuxer.c b/src/lib_ccx/ccx_demuxer.c index 8fbcdd50e..f87e99584 100644 --- a/src/lib_ccx/ccx_demuxer.c +++ b/src/lib_ccx/ccx_demuxer.c @@ -6,6 +6,7 @@ #ifndef DISABLE_RUST void ccxr_demuxer_reset(struct ccx_demuxer *ctx); void ccxr_demuxer_close(struct ccx_demuxer *ctx); +void ccxr_demuxer_delete(struct ccx_demuxer *ctx); int ccxr_demuxer_isopen(const struct ccx_demuxer *ctx); int ccxr_demuxer_open(struct ccx_demuxer *ctx, const char *file); LLONG ccxr_demuxer_get_file_size(struct ccx_demuxer *ctx); @@ -304,6 +305,12 @@ void ccx_demuxer_delete(struct ccx_demuxer **ctx) { struct ccx_demuxer *lctx = *ctx; int i; + +#ifndef DISABLE_RUST + // Let Rust free any memory it allocated + ccxr_demuxer_delete(lctx); +#endif + dinit_cap(lctx); freep(&lctx->last_pat_payload); for (i = 0; i < MAX_PSI_PID; i++) @@ -322,7 +329,14 @@ void ccx_demuxer_delete(struct ccx_demuxer **ctx) freep(lctx->PIDs_programs + i); } +#ifdef DISABLE_RUST + // Only free filebuffer in pure C mode - Rust handles its own memory freep(&lctx->filebuffer); +#else + // Rust already freed this in ccxr_demuxer_delete, just clear the pointer + lctx->filebuffer = NULL; +#endif + freep(ctx); } diff --git a/src/rust/src/libccxr_exports/demuxer.rs b/src/rust/src/libccxr_exports/demuxer.rs index 68abcdd4e..09cb41936 100755 --- a/src/rust/src/libccxr_exports/demuxer.rs +++ b/src/rust/src/libccxr_exports/demuxer.rs @@ -407,17 +407,25 @@ pub unsafe extern "C" fn ccxr_demuxer_close(ctx: *mut ccx_demuxer) { c.infd = -1; activity_input_file_closed(); } +} + +/// # Safety +/// This function must be called before the C code frees the demuxer struct. +/// It frees Rust-allocated resources that C cannot safely free. +#[no_mangle] +pub unsafe extern "C" fn ccxr_demuxer_delete(ctx: *mut ccx_demuxer) { + if ctx.is_null() { + return; + } + let c = &mut *ctx; - // We allocate this buffer in Rust (init_file_buffer) but then 'forget' it so C can use it. - // If we don't bring it back and drop it here, we leak 16MB every time a demuxer closes. + // Free Rust-allocated filebuffer if !c.filebuffer.is_null() { use crate::file_functions::file::FILEBUFFERSIZE; - // Reclaim the pointer as a boxed slice so Rust can finally free the memory. let _ = Box::from_raw(std::ptr::slice_from_raw_parts_mut( c.filebuffer, FILEBUFFERSIZE, )); - // Null it out to prevent any double-free accidents if C tries to cleanup too. c.filebuffer = std::ptr::null_mut(); } } From 70d325f55808714c8f7daa2674a68c24af6058db Mon Sep 17 00:00:00 2001 From: Amrit kumar Mahto Date: Tue, 27 Jan 2026 21:16:52 +0530 Subject: [PATCH 3/3] re run checks