From e0ac126cff42abcb043365eb8d73b03fbe0bcfa5 Mon Sep 17 00:00:00 2001 From: Amrit kumar Mahto Date: Sun, 18 Jan 2026 05:37:44 +0530 Subject: [PATCH 1/2] Fix use-after-free bugs in Rust userdata handling --- src/rust/src/es/userdata.rs | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/rust/src/es/userdata.rs b/src/rust/src/es/userdata.rs index af82667e..03e684c1 100644 --- a/src/rust/src/es/userdata.rs +++ b/src/rust/src/es/userdata.rs @@ -278,7 +278,8 @@ pub unsafe fn user_data( if !proceed { debug!(msg_type = DebugMessageFlag::VERBOSE; "\rThe following payload is not properly terminated."); - dump(cc_data.to_vec().as_mut_ptr(), (cc_count * 3 + 1) as _, 0, 0); + let mut cc_data_copy = cc_data.to_vec(); + dump(cc_data_copy.as_mut_ptr(), (cc_count * 3 + 1) as _, 0, 0); } debug!(msg_type = DebugMessageFlag::VERBOSE; "Reading {} HD CC blocks", cc_count); @@ -289,10 +290,11 @@ pub unsafe fn user_data( // Please note we store the current value of the global // fts_now variable (and not get_fts()) as we are going to // re-create the timeline in process_hdcc() (Slightly ugly). + let mut cc_data_copy = cc_data.to_vec(); store_hdcc( enc_ctx, dec_ctx, - cc_data.to_vec().as_mut_ptr(), + cc_data_copy.as_mut_ptr(), cc_count as _, (*dec_ctx.timing).current_tref, (*dec_ctx.timing).fts_now, @@ -535,7 +537,8 @@ pub unsafe fn user_data( } let vbi_data = &ustream.data[ustream.pos..ustream.pos + 720]; - decode_vbi(dec_ctx, field, vbi_data.to_vec().as_mut_ptr(), 720, sub); + let mut vbi_data_copy = vbi_data.to_vec(); + decode_vbi(dec_ctx, field, vbi_data_copy.as_mut_ptr(), 720, sub); debug!(msg_type = DebugMessageFlag::VERBOSE; "GXF (vbi line {}) user data:", line_nb); } else { // Some other user data @@ -543,14 +546,8 @@ pub unsafe fn user_data( debug!(msg_type = DebugMessageFlag::VERBOSE; "Unrecognized user data:"); let udatalen = ustream.data.len() - ustream.pos; let dump_len = if udatalen > 128 { 128 } else { udatalen }; - dump( - ustream.data[ustream.pos..ustream.pos + dump_len] - .to_vec() - .as_mut_ptr(), - dump_len as _, - 0, - 0, - ); + let mut data_copy = ustream.data[ustream.pos..ustream.pos + dump_len].to_vec(); + dump(data_copy.as_mut_ptr(), dump_len as _, 0, 0); } debug!(msg_type = DebugMessageFlag::VERBOSE; "User data - processed"); From 20b194aac45156f752838c497fde4b23bd5789ba Mon Sep 17 00:00:00 2001 From: Amrit kumar Mahto Date: Sun, 18 Jan 2026 23:34:43 +0530 Subject: [PATCH 2/2] Consolidate Rust userdata fixes: UAF, bounds checks, and VBI safety --- src/rust/src/es/userdata.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/rust/src/es/userdata.rs b/src/rust/src/es/userdata.rs index 03e684c1..1e2534cc 100644 --- a/src/rust/src/es/userdata.rs +++ b/src/rust/src/es/userdata.rs @@ -342,6 +342,10 @@ pub unsafe fn user_data( let dcd_pos = ustream.pos; // dish caption data position match pattern_type { 0x02 => { + if ustream.data.len() - ustream.pos < 4 { + info!("Dish Network caption: insufficient data"); + return Ok(1); + } // Two byte caption - always on B-frame // The following 4 bytes are: // 0 : 0x09 @@ -389,6 +393,10 @@ pub unsafe fn user_data( // Ignore 3 (0x0A, followed by two unknown) bytes. } 0x04 => { + if ustream.data.len() - ustream.pos < 5 { + info!("Dish Network caption: insufficient data"); + return Ok(1); + } // Four byte caption - always on B-frame // The following 5 bytes are: // 0 : 0x09 @@ -425,6 +433,10 @@ pub unsafe fn user_data( // Ignore 4 (0x020A, followed by two unknown) bytes. } 0x05 => { + if ustream.data.len() - ustream.pos < 12 { + info!("Dish Network caption: insufficient data"); + return Ok(1); + } // Buffered caption - always on I-/P-frame // The following six bytes are: // 0 : 0x04 @@ -432,7 +444,7 @@ pub unsafe fn user_data( // 1 : prev dcd[2] // 2-3: prev dcd[3-4] // 4-5: prev dcd[5-6] - let dcd_data = &ustream.data[dcd_pos..dcd_pos + 10]; // Need more bytes for this case + let dcd_data = &ustream.data[dcd_pos..dcd_pos + 12]; // Need more bytes for this case debug!(msg_type = DebugMessageFlag::PARSE; " - {:02X} pch: {:02X} {:5} {:02X}:{:02X}", dcd_data[0], dcd_data[1], (dcd_data[2] as u32) * 256 + (dcd_data[3] as u32), @@ -534,6 +546,7 @@ pub unsafe fn user_data( if udatalen < 720 { info!("MPEG:VBI: Minimum 720 bytes in luma line required"); + return Ok(1); } let vbi_data = &ustream.data[ustream.pos..ustream.pos + 720];