[PR #1839] [MERGED] fix(rust-ffi): Prevent dangling pointers in copy_from_rust #2596

Open
opened 2026-01-29 17:23:00 +00:00 by claunia · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/CCExtractor/ccextractor/pull/1839
Author: @cfsmp3
Created: 12/17/2025
Status: Merged
Merged: 12/17/2025
Merged by: @cfsmp3

Base: masterHead: fix/rust-ffi-dangling-pointers


📝 Commits (1)

  • ba33f75 fix(rust-ffi): Prevent dangling pointers in copy_from_rust

📊 Changes

2 files changed (+11 additions, -0 deletions)

View changed files

📝 src/lib_ccx/ccx_common_option.c (+1 -0)
📝 src/rust/src/common.rs (+10 -0)

📄 Description

Summary

  • Fixed dangling pointer bug in Rust FFI copy_from_rust() function that caused memory corruption
  • Added missing settings_dtvcc.timing = NULL initialization in C's init_options()

Problem

The to_ctype() implementations for DecoderDtvccSettings and Decoder608Settings were creating temporaries on the stack and returning pointers to them:

// In to_ctype():
report: if let Some(value) = self.report {
    &mut value.to_ctype()  // ← Creates temporary, returns dangling pointer!
} else { ... },
timing: &mut self.timing.to_ctype(),  // ← Same issue

When copy_from_rust() called to_ctype(), these dangling pointers were written to the C ccx_options struct. Later when C code tried to use settings_dtvcc.report or settings_dtvcc.timing, it accessed invalid memory.

Valgrind errors before this fix:

Invalid write of size 4
   at 0x1D44ED: dtvcc_init
   Address 0x... is on thread 1's stack, 4016 bytes below stack pointer

Invalid read of size 1
   at 0x32F426: ccx_rust::common::copy_to_rust
   Address 0x... is on thread 1's stack, 1280 bytes below stack pointer

Solution

Preserve the original C-managed pointers instead of overwriting them with dangling pointers:

// Save original C pointers
let saved_report = (*ccx_s_options).settings_dtvcc.report;
let saved_timing = (*ccx_s_options).settings_dtvcc.timing;

// Apply other fields from to_ctype()
(*ccx_s_options).settings_dtvcc = options.settings_dtvcc.to_ctype();

// Restore the C-managed pointers
(*ccx_s_options).settings_dtvcc.report = saved_report;
(*ccx_s_options).settings_dtvcc.timing = saved_timing;

Test plan

  • Verified all 21 Teletext tests pass (tests 63-83)
  • Verified test 18 and 19 pass with exit code 0
  • Verified valgrind no longer reports "Invalid read/write" errors
  • Error summary reduced from 131,099 errors (15 contexts) to 131,074 errors (4 contexts) - the remaining warnings are unrelated uninitialized memory issues

🤖 Generated with Claude Code


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/CCExtractor/ccextractor/pull/1839 **Author:** [@cfsmp3](https://github.com/cfsmp3) **Created:** 12/17/2025 **Status:** ✅ Merged **Merged:** 12/17/2025 **Merged by:** [@cfsmp3](https://github.com/cfsmp3) **Base:** `master` ← **Head:** `fix/rust-ffi-dangling-pointers` --- ### 📝 Commits (1) - [`ba33f75`](https://github.com/CCExtractor/ccextractor/commit/ba33f7572d884f91849a64b8b87c3cbbadaf78ed) fix(rust-ffi): Prevent dangling pointers in copy_from_rust ### 📊 Changes **2 files changed** (+11 additions, -0 deletions) <details> <summary>View changed files</summary> 📝 `src/lib_ccx/ccx_common_option.c` (+1 -0) 📝 `src/rust/src/common.rs` (+10 -0) </details> ### 📄 Description ## Summary - Fixed dangling pointer bug in Rust FFI `copy_from_rust()` function that caused memory corruption - Added missing `settings_dtvcc.timing = NULL` initialization in C's `init_options()` ## Problem The `to_ctype()` implementations for `DecoderDtvccSettings` and `Decoder608Settings` were creating temporaries on the stack and returning pointers to them: ```rust // In to_ctype(): report: if let Some(value) = self.report { &mut value.to_ctype() // ← Creates temporary, returns dangling pointer! } else { ... }, timing: &mut self.timing.to_ctype(), // ← Same issue ``` When `copy_from_rust()` called `to_ctype()`, these dangling pointers were written to the C `ccx_options` struct. Later when C code tried to use `settings_dtvcc.report` or `settings_dtvcc.timing`, it accessed invalid memory. ### Valgrind errors before this fix: ``` Invalid write of size 4 at 0x1D44ED: dtvcc_init Address 0x... is on thread 1's stack, 4016 bytes below stack pointer Invalid read of size 1 at 0x32F426: ccx_rust::common::copy_to_rust Address 0x... is on thread 1's stack, 1280 bytes below stack pointer ``` ## Solution Preserve the original C-managed pointers instead of overwriting them with dangling pointers: ```rust // Save original C pointers let saved_report = (*ccx_s_options).settings_dtvcc.report; let saved_timing = (*ccx_s_options).settings_dtvcc.timing; // Apply other fields from to_ctype() (*ccx_s_options).settings_dtvcc = options.settings_dtvcc.to_ctype(); // Restore the C-managed pointers (*ccx_s_options).settings_dtvcc.report = saved_report; (*ccx_s_options).settings_dtvcc.timing = saved_timing; ``` ## Test plan - [x] Verified all 21 Teletext tests pass (tests 63-83) - [x] Verified test 18 and 19 pass with exit code 0 - [x] Verified valgrind no longer reports "Invalid read/write" errors - [x] Error summary reduced from 131,099 errors (15 contexts) to 131,074 errors (4 contexts) - the remaining warnings are unrelated uninitialized memory issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
claunia added the pull-request label 2026-01-29 17:23:00 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/ccextractor#2596