Skip to main content

memscope_rs/analysis/
unsafe_ffi_tracker.rs

1//! Enhanced memory tracking for unsafe Rust and FFI operations
2//!
3//!
4//! This module extends the basic memory tracking to handle:
5//! - Unsafe Rust memory operations (std::alloc::alloc, raw pointers)
6//! - FFI memory operations (malloc, free from C libraries)
7//! - Cross-boundary memory transfers
8//! - Safety violation detection
9
10use crate::analysis::ffi_function_resolver::{get_global_ffi_resolver, ResolvedFfiFunction};
11use crate::capture::types::{AllocationInfo, TrackingError, TrackingResult};
12use crate::core::{get_global_call_stack_normalizer, CallStackRef};
13use serde::{Deserialize, Serialize};
14use std::collections::HashMap;
15use std::sync::{Arc, Mutex, OnceLock};
16
17/// Enhanced allocation source tracking
18#[derive(Debug, Clone, Serialize, Deserialize)]
19pub enum AllocationSource {
20    /// Safe Rust allocation (through normal allocator)
21    RustSafe,
22    /// Unsafe Rust allocation with location info
23    UnsafeRust {
24        /// Location of the unsafe block in source code
25        unsafe_block_location: String,
26        /// Call stack at the time of allocation
27        call_stack: CallStackRef,
28        /// Risk assessment for this unsafe operation
29        risk_assessment: RiskAssessment,
30    },
31    /// FFI allocation from C library
32    FfiC {
33        /// Resolved FFI function information
34        resolved_function: ResolvedFfiFunction,
35        /// Call stack at the time of allocation
36        call_stack: CallStackRef,
37        /// LibC hook information
38        libc_hook_info: LibCHookInfo,
39    },
40    /// Cross-boundary memory transfer
41    CrossBoundary {
42        /// Source allocation context
43        from: Box<AllocationSource>,
44        /// Destination allocation context
45        to: Box<AllocationSource>,
46        /// Timestamp when transfer occurred
47        transfer_timestamp: u128,
48        /// Transfer metadata
49        transfer_metadata: TransferMetadata,
50    },
51}
52
53/// Stack frame information for call stack tracking
54#[derive(Debug, Clone, Serialize, Deserialize, Hash, PartialEq, Eq)]
55pub struct StackFrame {
56    /// Name of the function in this stack frame
57    pub function_name: String,
58    /// Source file name if available
59    pub file_name: Option<String>,
60    /// Line number in the source file if available
61    pub line_number: Option<u32>,
62    /// Whether this frame is in an unsafe block
63    pub is_unsafe: bool,
64}
65
66/// Safety violation types
67#[derive(Debug, Clone, Serialize, Deserialize)]
68pub enum SafetyViolation {
69    /// Double free detected
70    DoubleFree {
71        /// Call stack from the first free operation
72        first_free_stack: CallStackRef,
73        /// Call stack from the second free operation
74        second_free_stack: CallStackRef,
75        /// Timestamp when the double free was detected
76        timestamp: u128,
77    },
78    /// Invalid free (pointer not in allocation table)
79    InvalidFree {
80        /// The pointer that was attempted to be freed
81        attempted_pointer: usize,
82        /// Call stack at the time of invalid free
83        stack: CallStackRef,
84        /// Timestamp when the invalid free was attempted
85        timestamp: u128,
86    },
87    /// Potential memory leak
88    PotentialLeak {
89        /// Call stack from the original allocation
90        allocation_stack: CallStackRef,
91        /// Timestamp when the allocation occurred
92        allocation_timestamp: u128,
93        /// Timestamp when the leak was detected
94        leak_detection_timestamp: u128,
95    },
96    /// Cross-boundary risk
97    CrossBoundaryRisk {
98        /// Risk level of the cross-boundary operation
99        risk_level: RiskLevel,
100        /// Description of the risk
101        description: String,
102        /// Call stack at the time of risk detection
103        stack: CallStackRef,
104    },
105}
106
107/// Risk levels for safety violations
108#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
109pub enum RiskLevel {
110    /// Low risk - minor issues that are unlikely to cause problems
111    Low,
112    /// Medium risk - issues that could potentially cause problems
113    Medium,
114    /// High risk - serious issues that are likely to cause problems
115    High,
116    /// Critical risk - severe issues that will almost certainly cause problems
117    Critical,
118}
119
120/// Comprehensive risk assessment for unsafe operations
121#[derive(Debug, Clone, Serialize, Deserialize)]
122pub struct RiskAssessment {
123    /// Overall risk level
124    pub risk_level: RiskLevel,
125    /// Specific risk factors identified
126    pub risk_factors: Vec<RiskFactor>,
127    /// Suggested mitigation strategies
128    pub mitigation_suggestions: Vec<String>,
129    /// Confidence score of the assessment (0.0 to 1.0)
130    pub confidence_score: f64,
131    /// Timestamp when assessment was performed
132    pub assessment_timestamp: u128,
133}
134
135/// Individual risk factor in an assessment
136#[derive(Debug, Clone, Serialize, Deserialize)]
137pub struct RiskFactor {
138    /// Type of risk factor
139    pub factor_type: RiskFactorType,
140    /// Severity score (0.0 to 10.0)
141    pub severity: f64,
142    /// Human-readable description
143    pub description: String,
144    /// Source location where risk was detected
145    pub source_location: Option<String>,
146}
147
148/// Types of risk factors that can be detected
149#[derive(Debug, Clone, Serialize, Deserialize)]
150pub enum RiskFactorType {
151    /// Raw pointer dereference without bounds checking
152    RawPointerDeref,
153    /// Manual memory management (alloc/dealloc)
154    ManualMemoryManagement,
155    /// Memory transfer across language boundaries
156    CrossBoundaryTransfer,
157    /// Unchecked type casting
158    UncheckedCast,
159    /// Potential lifetime violation
160    LifetimeViolation,
161    /// Use after free potential
162    UseAfterFree,
163    /// Buffer overflow potential
164    BufferOverflow,
165    /// Data race potential
166    DataRace,
167}
168
169/// Information about LibC function hooks
170#[derive(Debug, Clone, Serialize, Deserialize)]
171pub struct LibCHookInfo {
172    /// Method used to hook the function
173    pub hook_method: HookMethod,
174    /// Original function that was hooked
175    pub original_function: String,
176    /// Timestamp when hook was installed
177    pub hook_timestamp: u128,
178    /// Metadata about the allocation
179    pub allocation_metadata: AllocationMetadata,
180    /// Performance impact of the hook
181    pub hook_overhead_ns: Option<u64>,
182}
183
184/// Methods for hooking LibC functions
185#[derive(Debug, Clone, Serialize, Deserialize)]
186pub enum HookMethod {
187    /// LD_PRELOAD mechanism (Linux/macOS)
188    LdPreload,
189    /// Dynamic linker interposition
190    DynamicLinker,
191    /// Static function interposition
192    StaticInterposition,
193    /// Runtime patching
194    RuntimePatching,
195}
196
197/// Metadata about memory allocations from LibC
198#[derive(Debug, Clone, Serialize, Deserialize)]
199pub struct AllocationMetadata {
200    /// Size requested by the caller
201    pub requested_size: usize,
202    /// Actual size allocated (may be larger due to alignment)
203    pub actual_size: usize,
204    /// Memory alignment used
205    pub alignment: usize,
206    /// Information about the allocator used
207    pub allocator_info: String,
208    /// Memory protection flags if available
209    pub protection_flags: Option<MemoryProtectionFlags>,
210}
211
212/// Memory protection flags
213#[derive(Debug, Clone, Serialize, Deserialize)]
214pub struct MemoryProtectionFlags {
215    /// Memory is readable
216    pub readable: bool,
217    /// Memory is writable
218    pub writable: bool,
219    /// Memory is executable
220    pub executable: bool,
221    /// Memory is shared
222    pub shared: bool,
223}
224
225/// Memory "passport" for tracking cross-boundary transfers
226#[derive(Debug, Clone, Serialize, Deserialize)]
227pub struct MemoryPassport {
228    /// Unique identifier for this memory passport
229    pub passport_id: String,
230    /// Original allocation context
231    pub origin: AllocationOrigin,
232    /// Journey of the memory through different contexts
233    pub journey: Vec<PassportStamp>,
234    /// Current ownership information
235    pub current_owner: OwnershipInfo,
236    /// Validity status of the passport
237    pub validity_status: ValidityStatus,
238    /// Security clearance level
239    pub security_clearance: SecurityClearance,
240}
241
242/// Information about where memory was originally allocated
243#[derive(Debug, Clone, Serialize, Deserialize)]
244pub struct AllocationOrigin {
245    /// Context where allocation occurred (Rust/FFI)
246    pub context: String,
247    /// Function that performed the allocation
248    pub allocator_function: String,
249    /// Timestamp of original allocation
250    pub timestamp: u128,
251    /// Call stack at allocation time
252    pub call_stack: CallStackRef,
253}
254
255/// A stamp in the memory passport journey
256#[derive(Debug, Clone, Serialize, Deserialize)]
257pub struct PassportStamp {
258    /// Timestamp of this checkpoint
259    pub timestamp: u128,
260    /// Location/context of the checkpoint
261    pub location: String,
262    /// Operation performed at this checkpoint
263    pub operation: String,
264    /// Authority that validated this checkpoint
265    pub authority: String,
266    /// Cryptographic hash for verification
267    pub verification_hash: String,
268}
269
270/// Current ownership information
271#[derive(Debug, Clone, Serialize, Deserialize)]
272pub struct OwnershipInfo {
273    /// Current owner context (Rust/FFI)
274    pub owner_context: String,
275    /// Function/module that owns the memory
276    pub owner_function: String,
277    /// Ownership transfer timestamp
278    pub transfer_timestamp: u128,
279    /// Expected lifetime of ownership
280    pub expected_lifetime: Option<u128>,
281}
282
283/// Validity status of a memory passport
284#[derive(Debug, Clone, Serialize, Deserialize)]
285pub enum ValidityStatus {
286    /// Passport is valid and memory is safe to use
287    Valid,
288    /// Passport is expired (memory may be freed)
289    Expired,
290    /// Passport is revoked (memory is definitely freed)
291    Revoked,
292    /// Passport validity is unknown/suspicious
293    Suspicious,
294}
295
296/// Security clearance levels for memory operations
297#[derive(Debug, Clone, Serialize, Deserialize)]
298pub enum SecurityClearance {
299    /// Public memory, safe for all operations
300    Public,
301    /// Restricted memory, limited operations allowed
302    Restricted,
303    /// Confidential memory, special handling required
304    Confidential,
305    /// Secret memory, maximum security required
306    Secret,
307}
308
309/// Metadata for cross-boundary transfers
310#[derive(Debug, Clone, Serialize, Deserialize)]
311pub struct TransferMetadata {
312    /// Reason for the transfer
313    pub transfer_reason: String,
314    /// Expected return context (if any)
315    pub expected_return: Option<String>,
316    /// Transfer validation method used
317    pub validation_method: ValidationMethod,
318    /// Performance impact of the transfer
319    pub transfer_overhead_ns: Option<u64>,
320}
321
322/// Methods for validating cross-boundary transfers
323#[derive(Debug, Clone, Serialize, Deserialize)]
324pub enum ValidationMethod {
325    /// No validation performed
326    None,
327    /// Basic pointer validation
328    PointerCheck,
329    /// Size and bounds validation
330    BoundsCheck,
331    /// Full memory integrity check
332    IntegrityCheck,
333    /// Cryptographic validation
334    CryptographicCheck,
335}
336
337/// Enhanced allocation info with unsafe/FFI tracking
338#[derive(Debug, Clone, Serialize, Deserialize)]
339pub struct EnhancedAllocationInfo {
340    /// Base allocation info
341    pub base: AllocationInfo,
342    /// Source of the allocation
343    pub source: AllocationSource,
344    /// Call stack at allocation time
345    pub call_stack: CallStackRef,
346    /// Cross-boundary events
347    pub cross_boundary_events: Vec<BoundaryEvent>,
348    /// Safety violations detected
349    pub safety_violations: Vec<SafetyViolation>,
350    /// Whether this allocation is currently being tracked by FFI
351    pub ffi_tracked: bool,
352    /// Memory passport for cross-boundary tracking
353    pub memory_passport: Option<MemoryPassport>,
354    /// Ownership transfer history
355    pub ownership_history: Option<Vec<OwnershipTransferEvent>>,
356}
357
358/// Cross-boundary memory event
359#[derive(Debug, Clone, Serialize, Deserialize)]
360pub struct BoundaryEvent {
361    /// Type of boundary crossing event
362    pub event_type: BoundaryEventType,
363    /// Timestamp when the event occurred
364    pub timestamp: u128,
365    /// Context where the crossing originated
366    pub from_context: String,
367    /// Context where the crossing ended
368    pub to_context: String,
369    /// Call stack at the time of crossing
370    pub stack: CallStackRef,
371}
372
373/// Types of boundary events
374#[derive(Debug, Clone, Serialize, Deserialize)]
375pub enum BoundaryEventType {
376    /// Memory allocated in Rust, passed to FFI
377    RustToFfi,
378    /// Memory allocated in FFI, passed to Rust
379    FfiToRust,
380    /// Memory ownership transferred
381    OwnershipTransfer,
382    /// Memory shared between contexts
383    SharedAccess,
384}
385
386/// Comprehensive analysis of a boundary event
387#[derive(Debug, Clone, Serialize, Deserialize)]
388pub struct BoundaryEventAnalysis {
389    /// Unique identifier for this event analysis
390    pub event_id: String,
391    /// Memory pointer involved in the event
392    pub ptr: usize,
393    /// Type of boundary event
394    pub event_type: BoundaryEventType,
395    /// Source context
396    pub from_context: String,
397    /// Destination context
398    pub to_context: String,
399    /// Size of memory being transferred
400    pub transfer_size: usize,
401    /// Timestamp of the event
402    pub timestamp: u128,
403    /// Risk assessment for this event
404    pub risk_assessment: BoundaryRiskAssessment,
405    /// Ownership chain history
406    pub ownership_chain: Vec<OwnershipRecord>,
407    /// Security implications
408    pub security_implications: Vec<SecurityImplication>,
409    /// Performance impact analysis
410    pub performance_impact: PerformanceImpact,
411    /// Recommended mitigation strategies
412    pub mitigation_recommendations: Vec<String>,
413}
414
415/// Risk assessment for boundary transfers
416#[derive(Debug, Clone, Serialize, Deserialize)]
417pub struct BoundaryRiskAssessment {
418    /// Overall risk level
419    pub overall_risk_level: RiskLevel,
420    /// Numerical risk score (0.0 to 100.0)
421    pub risk_score: f64,
422    /// Individual risk factors
423    pub risk_factors: Vec<BoundaryRiskFactor>,
424    /// Confidence in the assessment (0.0 to 1.0)
425    pub confidence_score: f64,
426    /// When the assessment was performed
427    pub assessment_timestamp: u128,
428}
429
430/// Individual risk factor for boundary transfers
431#[derive(Debug, Clone, Serialize, Deserialize)]
432pub struct BoundaryRiskFactor {
433    /// Type of risk factor
434    pub factor_type: BoundaryRiskFactorType,
435    /// Severity score (0.0 to 10.0)
436    pub severity: f64,
437    /// Human-readable description
438    pub description: String,
439    /// Suggested mitigation
440    pub mitigation: String,
441}
442
443/// Types of boundary risk factors
444#[derive(Debug, Clone, Serialize, Deserialize)]
445pub enum BoundaryRiskFactorType {
446    /// Transfer from Rust to foreign code
447    RustToForeignTransfer,
448    /// Transfer from foreign code to Rust
449    ForeignToRustTransfer,
450    /// Ownership transfer across boundaries
451    OwnershipTransfer,
452    /// Shared access across boundaries
453    SharedAccess,
454    /// Large memory transfer
455    LargeTransfer,
456    /// Frequent boundary crossings
457    FrequentTransfers,
458    /// Unvalidated data transfer
459    UnvalidatedTransfer,
460    /// Privilege boundary crossing
461    PrivilegeBoundary,
462}
463
464/// Ownership transfer event
465#[derive(Debug, Clone, Serialize, Deserialize)]
466pub struct OwnershipTransferEvent {
467    /// Unique identifier for this transfer
468    pub transfer_id: String,
469    /// Memory pointer being transferred
470    pub ptr: usize,
471    /// Source context
472    pub from_context: String,
473    /// Destination context
474    pub to_context: String,
475    /// When the transfer occurred
476    pub transfer_timestamp: u128,
477    /// Reason for the transfer
478    pub transfer_reason: String,
479    /// Validation status of the transfer
480    pub validation_status: OwnershipValidationStatus,
481}
482
483/// Status of ownership validation
484#[derive(Debug, Clone, Serialize, Deserialize)]
485pub enum OwnershipValidationStatus {
486    /// Transfer is valid and safe
487    Valid,
488    /// Transfer is pending validation
489    Pending,
490    /// Transfer has validation warnings
491    Warning,
492    /// Transfer is invalid or unsafe
493    Invalid,
494    /// Transfer validation failed
495    Failed,
496}
497
498/// Record in the ownership chain
499#[derive(Debug, Clone, Serialize, Deserialize)]
500pub struct OwnershipRecord {
501    /// Context that owns the memory
502    pub context: String,
503    /// When ownership was acquired
504    pub timestamp: u128,
505    /// Reason for ownership transfer
506    pub transfer_reason: String,
507    /// Validation status
508    pub validation_status: OwnershipValidationStatus,
509}
510
511/// Security implication of boundary crossing
512#[derive(Debug, Clone, Serialize, Deserialize)]
513pub struct SecurityImplication {
514    /// Type of security implication
515    pub implication_type: SecurityImplicationType,
516    /// Severity level
517    pub severity: RiskLevel,
518    /// Description of the implication
519    pub description: String,
520    /// Potential impact
521    pub potential_impact: String,
522    /// Recommended action
523    pub recommended_action: String,
524}
525
526/// Types of security implications
527#[derive(Debug, Clone, Serialize, Deserialize)]
528pub enum SecurityImplicationType {
529    /// Potential privilege escalation
530    PrivilegeEscalation,
531    /// Data exposure risk
532    DataExposure,
533    /// Code injection risk
534    InjectionRisk,
535    /// Buffer overflow risk
536    BufferOverflow,
537    /// Use after free risk
538    UseAfterFree,
539    /// Race condition risk
540    RaceCondition,
541    /// Information disclosure
542    InformationDisclosure,
543}
544
545/// Performance impact analysis
546#[derive(Debug, Clone, Serialize, Deserialize)]
547pub struct PerformanceImpact {
548    /// Overall impact level
549    pub impact_level: PerformanceImpactLevel,
550    /// Estimated overhead in nanoseconds
551    pub estimated_overhead_ns: u64,
552    /// Memory overhead in bytes
553    pub memory_overhead_bytes: usize,
554    /// CPU overhead percentage
555    pub cpu_overhead_percent: f64,
556    /// Performance optimization recommendations
557    pub recommendations: Vec<String>,
558}
559
560/// Levels of performance impact
561#[derive(Debug, Clone, Serialize, Deserialize)]
562pub enum PerformanceImpactLevel {
563    /// Minimal performance impact
564    Low,
565    /// Moderate performance impact
566    Medium,
567    /// Significant performance impact
568    High,
569    /// Critical performance impact
570    Critical,
571}
572
573/// Statistics for boundary events
574#[derive(Debug, Clone, Serialize, Deserialize)]
575pub struct BoundaryEventStatistics {
576    /// Total number of boundary events
577    pub total_events: usize,
578    /// Events grouped by type
579    pub events_by_type: std::collections::HashMap<String, usize>,
580    /// Risk level distribution
581    pub risk_distribution: std::collections::HashMap<String, usize>,
582    /// Average transfer size
583    pub average_transfer_size: f64,
584    /// Total volume of data transferred
585    pub total_transfer_volume: usize,
586    /// Most active contexts (context name, event count)
587    pub most_active_contexts: Vec<(String, usize)>,
588    /// Number of security incidents detected
589    pub security_incidents: usize,
590    /// Number of performance issues detected
591    pub performance_issues: usize,
592    /// When the statistics were generated
593    pub analysis_timestamp: u128,
594}
595
596/// Enhanced memory tracker for unsafe/FFI operations
597pub struct UnsafeFFITracker {
598    /// Enhanced allocations with source tracking
599    enhanced_allocations: Mutex<HashMap<usize, EnhancedAllocationInfo>>,
600    /// Freed pointers (for double-free detection)
601    freed_pointers: Mutex<HashMap<usize, (CallStackRef, u128)>>,
602    /// Safety violations log
603    violations: Mutex<Vec<SafetyViolation>>,
604    /// C library tracking registry
605    c_libraries: Mutex<HashMap<String, CLibraryInfo>>,
606    /// Enhanced LibC hook registry
607    libc_hooks: Mutex<HashMap<String, EnhancedLibCHookInfo>>,
608    /// Memory passport registry
609    memory_passports: Mutex<HashMap<usize, MemoryPassport>>,
610}
611
612impl UnsafeFFITracker {
613    /// Create a new enhanced tracker
614    pub fn new() -> Self {
615        Self {
616            enhanced_allocations: Mutex::new(HashMap::new()),
617            freed_pointers: Mutex::new(HashMap::new()),
618            violations: Mutex::new(Vec::new()),
619            c_libraries: Mutex::new(HashMap::new()),
620            libc_hooks: Mutex::new(HashMap::new()),
621            memory_passports: Mutex::new(HashMap::new()),
622        }
623    }
624
625    /// Create a default risk assessment for unsafe operations
626    fn create_default_unsafe_risk_assessment(&self, unsafe_location: &str) -> RiskAssessment {
627        let current_time = std::time::SystemTime::now()
628            .duration_since(std::time::UNIX_EPOCH)
629            .unwrap_or_default()
630            .as_nanos();
631
632        let risk_factors = vec![RiskFactor {
633            factor_type: RiskFactorType::ManualMemoryManagement,
634            severity: 5.0,
635            description: "Manual memory management in unsafe block".to_string(),
636            source_location: Some(unsafe_location.to_string()),
637        }];
638
639        RiskAssessment {
640            risk_level: RiskLevel::Medium,
641            risk_factors,
642            mitigation_suggestions: vec![
643                "Ensure proper memory cleanup".to_string(),
644                "Use RAII patterns where possible".to_string(),
645            ],
646            confidence_score: 0.7,
647            assessment_timestamp: current_time,
648        }
649    }
650
651    /// Create a default LibC hook info for FFI operations
652    fn create_default_libc_hook_info(&self, function_name: &str, size: usize) -> LibCHookInfo {
653        let current_time = std::time::SystemTime::now()
654            .duration_since(std::time::UNIX_EPOCH)
655            .unwrap_or_default()
656            .as_nanos();
657
658        LibCHookInfo {
659            hook_method: HookMethod::DynamicLinker,
660            original_function: function_name.to_string(),
661            hook_timestamp: current_time,
662            allocation_metadata: AllocationMetadata {
663                requested_size: size,
664                actual_size: size,
665                alignment: 8, // Default alignment
666                allocator_info: "libc malloc".to_string(),
667                protection_flags: Some(MemoryProtectionFlags {
668                    readable: true,
669                    writable: true,
670                    executable: false,
671                    shared: false,
672                }),
673            },
674            hook_overhead_ns: Some(100), // Estimated overhead
675        }
676    }
677
678    /// Create a memory passport for cross-boundary tracking
679    fn create_memory_passport(&self, ptr: usize, origin_context: &str) -> MemoryPassport {
680        let current_time = std::time::SystemTime::now()
681            .duration_since(std::time::UNIX_EPOCH)
682            .unwrap_or_default()
683            .as_nanos();
684
685        MemoryPassport {
686            passport_id: format!("passport_{ptr:x}_{current_time}"),
687            origin: AllocationOrigin {
688                context: origin_context.to_string(),
689                allocator_function: "unknown".to_string(),
690                timestamp: current_time,
691                call_stack: {
692                    let normalizer = get_global_call_stack_normalizer();
693                    let empty_frames = vec![];
694                    let id = normalizer.normalize_call_stack(&empty_frames).unwrap_or(0);
695                    CallStackRef::new(id, Some(0))
696                },
697            },
698            journey: Vec::new(),
699            current_owner: OwnershipInfo {
700                owner_context: origin_context.to_string(),
701                owner_function: "unknown".to_string(),
702                transfer_timestamp: current_time,
703                expected_lifetime: None,
704            },
705            validity_status: ValidityStatus::Valid,
706            security_clearance: SecurityClearance::Public,
707        }
708    }
709
710    /// Track an unsafe Rust allocation
711    pub fn track_unsafe_allocation(
712        &self,
713        ptr: usize,
714        size: usize,
715        unsafe_location: String,
716    ) -> TrackingResult<()> {
717        let call_stack = self.capture_call_stack()?;
718        let base_allocation = AllocationInfo::new(ptr, size);
719        let risk_assessment = self.create_default_unsafe_risk_assessment(&unsafe_location);
720
721        let enhanced = EnhancedAllocationInfo {
722            base: base_allocation,
723            source: AllocationSource::UnsafeRust {
724                unsafe_block_location: unsafe_location,
725                call_stack: call_stack.clone(),
726                risk_assessment,
727            },
728            call_stack,
729            cross_boundary_events: Vec::new(),
730            safety_violations: Vec::new(),
731            ffi_tracked: false,
732            memory_passport: None,
733            ownership_history: None,
734        };
735
736        if let Ok(mut allocations) = self.enhanced_allocations.lock() {
737            allocations.insert(ptr, enhanced);
738            tracing::info!("Tracked unsafe allocation at {:x} (size: {})", ptr, size);
739        }
740
741        Ok(())
742    }
743
744    /// Track an FFI allocation
745    pub fn track_ffi_allocation(
746        &self,
747        ptr: usize,
748        size: usize,
749        library_name: String,
750        function_name: String,
751    ) -> TrackingResult<()> {
752        let call_stack = self.capture_call_stack()?;
753        let base_allocation = AllocationInfo::new(ptr, size);
754        let libc_hook_info = self.create_default_libc_hook_info(&function_name, size);
755
756        // Resolve FFI function information
757        let resolver = get_global_ffi_resolver();
758        let resolved_function = resolver
759            .resolve_function(&function_name, Some(&library_name))
760            .unwrap_or_else(|_| {
761                tracing::warn!(
762                    "Failed to resolve FFI function: {}::{}",
763                    library_name,
764                    function_name
765                );
766                // Create fallback resolution
767                ResolvedFfiFunction {
768                    library_name: library_name.clone(),
769                    function_name: function_name.clone(),
770                    signature: None,
771                    category: crate::analysis::FfiFunctionCategory::Unknown,
772                    risk_level: crate::analysis::FfiRiskLevel::Medium,
773                    metadata: std::collections::HashMap::new(),
774                }
775            });
776
777        let enhanced = EnhancedAllocationInfo {
778            base: base_allocation,
779            source: AllocationSource::FfiC {
780                resolved_function,
781                call_stack: call_stack.clone(),
782                libc_hook_info,
783            },
784            call_stack,
785            cross_boundary_events: Vec::new(),
786            safety_violations: Vec::new(),
787            ffi_tracked: true,
788            memory_passport: None,
789            ownership_history: None,
790        };
791
792        if let Ok(mut allocations) = self.enhanced_allocations.lock() {
793            allocations.insert(ptr, enhanced);
794            tracing::info!("Tracked FFI allocation at {:x} (size: {})", ptr, size);
795        }
796
797        Ok(())
798    }
799
800    /// Track a deallocation with safety checks
801    pub fn track_enhanced_deallocation(&self, ptr: usize) -> TrackingResult<()> {
802        let call_stack = self.capture_call_stack()?;
803        let timestamp = std::time::SystemTime::now()
804            .duration_since(std::time::UNIX_EPOCH)
805            .unwrap_or_default()
806            .as_millis();
807
808        // Check for double free
809        if let Ok(freed) = self.freed_pointers.lock() {
810            if let Some((first_free_stack, _first_timestamp)) = freed.get(&ptr) {
811                let violation = SafetyViolation::DoubleFree {
812                    first_free_stack: first_free_stack.clone(),
813                    second_free_stack: call_stack.clone(),
814                    timestamp,
815                };
816
817                if let Ok(mut violations) = self.violations.lock() {
818                    violations.push(violation);
819                }
820
821                tracing::error!("Double free detected at {:x}", ptr);
822                return Err(TrackingError::MemoryCorruption(
823                    "Memory corruption detected".to_string(),
824                ));
825            }
826        }
827
828        // Check if allocation exists
829        if let Ok(mut allocations) = self.enhanced_allocations.lock() {
830            if let Some(mut allocation) = allocations.remove(&ptr) {
831                allocation.base.mark_deallocated();
832
833                // Record in freed pointers
834                if let Ok(mut freed) = self.freed_pointers.lock() {
835                    freed.insert(ptr, (call_stack, timestamp));
836                }
837
838                tracing::info!("Tracked enhanced deallocation at {:x}", ptr);
839            } else {
840                // Invalid free
841                let violation = SafetyViolation::InvalidFree {
842                    attempted_pointer: ptr,
843                    stack: call_stack,
844                    timestamp,
845                };
846
847                if let Ok(mut violations) = self.violations.lock() {
848                    violations.push(violation);
849                }
850
851                tracing::error!("Invalid free detected at {:x}", ptr);
852                return Err(TrackingError::InvalidPointer(format!(
853                    "Invalid pointer: 0x{ptr:x}"
854                )));
855            }
856        }
857
858        Ok(())
859    }
860
861    /// Record a cross-boundary event
862    pub fn record_boundary_event(
863        &self,
864        ptr: usize,
865        event_type: BoundaryEventType,
866        from_context: String,
867        to_context: String,
868    ) -> TrackingResult<()> {
869        let call_stack = self.capture_call_stack()?;
870        let timestamp = std::time::SystemTime::now()
871            .duration_since(std::time::UNIX_EPOCH)
872            .unwrap_or_default()
873            .as_millis();
874
875        let event = BoundaryEvent {
876            event_type,
877            timestamp,
878            from_context,
879            to_context,
880            stack: call_stack,
881        };
882
883        if let Ok(mut allocations) = self.enhanced_allocations.lock() {
884            if let Some(allocation) = allocations.get_mut(&ptr) {
885                allocation.cross_boundary_events.push(event);
886                tracing::info!("Recorded boundary event for {:x}", ptr);
887            }
888        }
889
890        Ok(())
891    }
892
893    /// Create or update memory passport for cross-boundary tracking
894    pub fn create_or_update_passport(
895        &self,
896        ptr: usize,
897        operation: &str,
898        context: &str,
899    ) -> TrackingResult<()> {
900        if let Ok(mut allocations) = self.enhanced_allocations.lock() {
901            if let Some(allocation) = allocations.get_mut(&ptr) {
902                let current_time = std::time::SystemTime::now()
903                    .duration_since(std::time::UNIX_EPOCH)
904                    .unwrap_or_default()
905                    .as_nanos();
906
907                if allocation.memory_passport.is_none() {
908                    allocation.memory_passport = Some(self.create_memory_passport(ptr, context));
909                }
910
911                if let Some(passport) = &mut allocation.memory_passport {
912                    let stamp = PassportStamp {
913                        timestamp: current_time,
914                        location: context.to_string(),
915                        operation: operation.to_string(),
916                        authority: "UnsafeFFITracker".to_string(),
917                        verification_hash: format!("{:x}", ptr ^ current_time as usize),
918                    };
919                    passport.journey.push(stamp);
920                }
921            }
922        }
923
924        Ok(())
925    }
926
927    /// Update ownership information for a memory allocation
928    pub fn update_ownership(
929        &self,
930        ptr: usize,
931        new_owner_context: String,
932        new_owner_function: String,
933    ) -> TrackingResult<()> {
934        if let Ok(mut allocations) = self.enhanced_allocations.lock() {
935            if let Some(allocation) = allocations.get_mut(&ptr) {
936                let current_time = std::time::SystemTime::now()
937                    .duration_since(std::time::UNIX_EPOCH)
938                    .unwrap_or_default()
939                    .as_nanos();
940
941                if let Some(passport) = &mut allocation.memory_passport {
942                    passport.current_owner = OwnershipInfo {
943                        owner_context: new_owner_context,
944                        owner_function: new_owner_function,
945                        transfer_timestamp: current_time,
946                        expected_lifetime: None,
947                    };
948                }
949            }
950        }
951
952        Ok(())
953    }
954
955    /// Validate memory passport integrity
956    pub fn validate_passport(&self, ptr: usize) -> TrackingResult<bool> {
957        if let Ok(allocations) = self.enhanced_allocations.lock() {
958            if let Some(allocation) = allocations.get(&ptr) {
959                if let Some(passport) = &allocation.memory_passport {
960                    // Basic validation: check if passport is not expired or revoked
961                    match passport.validity_status {
962                        ValidityStatus::Valid => Ok(true),
963                        ValidityStatus::Expired
964                        | ValidityStatus::Revoked
965                        | ValidityStatus::Suspicious => Ok(false),
966                    }
967                } else {
968                    Ok(false) // No passport means not validated
969                }
970            } else {
971                Ok(false) // Allocation not found
972            }
973        } else {
974            Err(TrackingError::LockError(
975                "Failed to acquire allocations lock".to_string(),
976            ))
977        }
978    }
979
980    /// Get all safety violations
981    pub fn get_safety_violations(&self) -> TrackingResult<Vec<SafetyViolation>> {
982        self.violations
983            .lock()
984            .map(|v| v.clone())
985            .map_err(|e| TrackingError::LockError(e.to_string()))
986    }
987
988    /// Get enhanced allocations
989    pub fn get_enhanced_allocations(&self) -> TrackingResult<Vec<EnhancedAllocationInfo>> {
990        self.enhanced_allocations
991            .lock()
992            .map(|allocations| allocations.values().cloned().collect())
993            .map_err(|e| TrackingError::LockError(e.to_string()))
994    }
995
996    /// Capture current call stack and normalize it
997    fn capture_call_stack(&self) -> TrackingResult<CallStackRef> {
998        // In a real implementation, this would use backtrace crate
999        // For now, return a simplified stack
1000        let frames = vec![StackFrame {
1001            function_name: "current_function".to_string(),
1002            file_name: Some("src/unsafe_ffi_tracker.rs".to_string()),
1003            line_number: Some(42),
1004            is_unsafe: true,
1005        }];
1006
1007        let normalizer = get_global_call_stack_normalizer();
1008        // Manual error handling to convert between old and new TrackingError types
1009        let id = match normalizer.normalize_call_stack(&frames) {
1010            Ok(id) => id,
1011            Err(e) => {
1012                return Err(TrackingError::AnalysisError(format!(
1013                    "Failed to normalize call stack: {}",
1014                    e
1015                )))
1016            }
1017        };
1018        Ok(CallStackRef::new(id, Some(frames.len())))
1019    }
1020
1021    /// Detect potential memory leaks
1022    pub fn detect_leaks(&self, threshold_ms: u128) -> TrackingResult<Vec<SafetyViolation>> {
1023        let current_time = std::time::SystemTime::now()
1024            .duration_since(std::time::UNIX_EPOCH)
1025            .unwrap_or_default()
1026            .as_millis();
1027
1028        let mut leaks = Vec::new();
1029
1030        if let Ok(allocations) = self.enhanced_allocations.lock() {
1031            for allocation in allocations.values() {
1032                let alloc_time = allocation.base.timestamp_alloc as u128;
1033                let age = current_time.saturating_sub(alloc_time);
1034                if age > threshold_ms && allocation.base.is_active() {
1035                    leaks.push(SafetyViolation::PotentialLeak {
1036                        allocation_stack: allocation.call_stack.clone(),
1037                        allocation_timestamp: allocation.base.timestamp_alloc as u128,
1038                        leak_detection_timestamp: current_time,
1039                    });
1040                }
1041            }
1042        }
1043
1044        Ok(leaks)
1045    }
1046}
1047
1048impl Default for UnsafeFFITracker {
1049    fn default() -> Self {
1050        Self::new()
1051    }
1052}
1053
1054/// Global instance of the enhanced tracker
1055static GLOBAL_UNSAFE_FFI_TRACKER: std::sync::OnceLock<std::sync::Arc<UnsafeFFITracker>> =
1056    std::sync::OnceLock::new();
1057
1058/// Get the global unsafe/FFI tracker instance
1059pub fn get_global_unsafe_ffi_tracker() -> std::sync::Arc<UnsafeFFITracker> {
1060    GLOBAL_UNSAFE_FFI_TRACKER
1061        .get_or_init(|| std::sync::Arc::new(UnsafeFFITracker::new()))
1062        .clone()
1063}
1064
1065/// Macro for tracking unsafe allocations
1066#[macro_export]
1067macro_rules! track_unsafe_alloc {
1068    ($ptr:expr, $size:expr) => {{
1069        let tracker = $crate::unsafe_ffi_tracker::get_global_unsafe_ffi_tracker();
1070        let location = format!("{}:{}:{}", file!(), line!(), column!());
1071        let _ = tracker.track_unsafe_allocation($ptr as usize, $size, location);
1072    }};
1073}
1074
1075/// Macro for tracking FFI allocations
1076#[macro_export]
1077macro_rules! track_ffi_alloc {
1078    ($ptr:expr, $size:expr, $lib:expr, $func:expr) => {{
1079        let tracker = $crate::unsafe_ffi_tracker::get_global_unsafe_ffi_tracker();
1080        let _ =
1081            tracker.track_ffi_allocation($ptr as usize, $size, $lib.to_string(), $func.to_string());
1082    }};
1083}
1084
1085/// Statistics for unsafe and FFI operations
1086#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1087pub struct UnsafeFFIStats {
1088    /// Total number of unsafe operations
1089    pub total_operations: usize,
1090    /// Number of unsafe blocks encountered
1091    pub unsafe_blocks: usize,
1092    /// Number of FFI calls made
1093    pub ffi_calls: usize,
1094    /// Number of raw pointer operations
1095    pub raw_pointer_operations: usize,
1096    /// Number of memory violations detected
1097    pub memory_violations: usize,
1098    /// Overall risk score (0.0 to 10.0)
1099    pub risk_score: f64,
1100    /// List of unsafe operations
1101    pub operations: Vec<UnsafeOperation>,
1102}
1103
1104/// Represents a single unsafe operation
1105#[derive(Debug, Clone, Serialize, Deserialize)]
1106pub struct UnsafeOperation {
1107    /// Type of operation
1108    pub operation_type: UnsafeOperationType,
1109    /// Location in source code
1110    pub location: String,
1111    /// Risk level of this operation
1112    pub risk_level: RiskLevel,
1113    /// Timestamp when operation occurred
1114    pub timestamp: u128,
1115    /// Description of the operation
1116    pub description: String,
1117}
1118
1119/// Types of unsafe operations
1120#[derive(Debug, Clone, Serialize, Deserialize)]
1121pub enum UnsafeOperationType {
1122    /// Raw pointer dereference operation
1123    RawPointerDeref,
1124    /// Foreign Function Interface call
1125    FfiCall,
1126    /// Unsafe block execution
1127    UnsafeBlock,
1128    /// Memory safety violation detected
1129    MemoryViolation,
1130    /// Memory transfer across safety boundaries
1131    CrossBoundaryTransfer,
1132}
1133
1134/// C Library information for detailed tracking
1135#[derive(Debug, Clone, Serialize, Deserialize)]
1136pub struct CLibraryInfo {
1137    /// Name of the C library
1138    pub library_name: String,
1139    /// Version of the library if available
1140    pub library_version: Option<String>,
1141    /// Path to the library file
1142    pub library_path: Option<String>,
1143    /// Functions from this library that have been called
1144    pub functions_called: HashMap<String, CFunctionInfo>,
1145    /// Total number of allocations from this library
1146    pub total_allocations: usize,
1147    /// Total bytes allocated from this library
1148    pub total_bytes_allocated: usize,
1149    /// Library load timestamp
1150    pub load_timestamp: u128,
1151    /// Library metadata
1152    pub metadata: LibraryMetadata,
1153}
1154
1155/// Information about a specific C function
1156#[derive(Debug, Clone, Serialize, Deserialize)]
1157pub struct CFunctionInfo {
1158    /// Function name
1159    pub function_name: String,
1160    /// Function signature if available
1161    pub function_signature: Option<String>,
1162    /// Number of times this function has been called
1163    pub call_count: usize,
1164    /// Total bytes allocated by this function
1165    pub bytes_allocated: usize,
1166    /// Average allocation size
1167    pub average_allocation_size: f64,
1168    /// Risk assessment for this function
1169    pub risk_assessment: RiskAssessment,
1170    /// Performance metrics
1171    pub performance_metrics: FunctionPerformanceMetrics,
1172    /// First call timestamp
1173    pub first_call_timestamp: u128,
1174    /// Last call timestamp
1175    pub last_call_timestamp: u128,
1176}
1177
1178/// Performance metrics for C functions
1179#[derive(Debug, Clone, Serialize, Deserialize)]
1180pub struct FunctionPerformanceMetrics {
1181    /// Average execution time in nanoseconds
1182    pub avg_execution_time_ns: u64,
1183    /// Minimum execution time in nanoseconds
1184    pub min_execution_time_ns: u64,
1185    /// Maximum execution time in nanoseconds
1186    pub max_execution_time_ns: u64,
1187    /// Total execution time in nanoseconds
1188    pub total_execution_time_ns: u64,
1189    /// Memory overhead introduced by tracking
1190    pub tracking_overhead_ns: u64,
1191}
1192
1193/// Library metadata
1194#[derive(Debug, Clone, Serialize, Deserialize)]
1195pub struct LibraryMetadata {
1196    /// Architecture (x86_64, arm64, etc.)
1197    pub architecture: String,
1198    /// Operating system
1199    pub operating_system: String,
1200    /// Compiler used to build the library
1201    pub compiler_info: Option<String>,
1202    /// Debug symbols available
1203    pub has_debug_symbols: bool,
1204    /// Security features enabled
1205    pub security_features: Vec<String>,
1206}
1207
1208/// Enhanced LibC hook information with detailed tracking
1209#[derive(Debug, Clone, Serialize, Deserialize)]
1210pub struct EnhancedLibCHookInfo {
1211    /// Base hook information
1212    pub base_info: LibCHookInfo,
1213    /// Detailed function tracking
1214    pub function_tracking: CFunctionInfo,
1215    /// Hook installation details
1216    pub installation_details: HookInstallationDetails,
1217    /// Runtime behavior analysis
1218    pub runtime_analysis: RuntimeBehaviorAnalysis,
1219    /// Security analysis
1220    pub security_analysis: SecurityAnalysis,
1221}
1222
1223/// Details about hook installation
1224#[derive(Debug, Clone, Serialize, Deserialize)]
1225pub struct HookInstallationDetails {
1226    /// Method used to install the hook
1227    pub installation_method: HookInstallationMethod,
1228    /// Success status of installation
1229    pub installation_success: bool,
1230    /// Error message if installation failed
1231    pub installation_error: Option<String>,
1232    /// Timestamp of installation attempt
1233    pub installation_timestamp: u128,
1234    /// Process ID where hook was installed
1235    pub process_id: u32,
1236    /// Thread ID where hook was installed
1237    pub thread_id: u64,
1238}
1239
1240/// Methods for installing hooks
1241#[derive(Debug, Clone, Serialize, Deserialize)]
1242pub enum HookInstallationMethod {
1243    /// Preload library method
1244    Preload,
1245    /// Runtime symbol interposition
1246    SymbolInterposition,
1247    /// Binary patching
1248    BinaryPatching,
1249    /// Debugger-based hooking
1250    DebuggerHook,
1251    /// Kernel-level hooking
1252    KernelHook,
1253}
1254
1255/// Runtime behavior analysis for hooked functions
1256#[derive(Debug, Clone, Serialize, Deserialize)]
1257pub struct RuntimeBehaviorAnalysis {
1258    /// Memory access patterns
1259    pub memory_patterns: Vec<MemoryAccessPattern>,
1260    /// Allocation size distribution
1261    pub size_distribution: SizeDistribution,
1262    /// Temporal patterns
1263    pub temporal_patterns: TemporalPatterns,
1264    /// Error patterns
1265    pub error_patterns: Vec<ErrorPattern>,
1266}
1267
1268/// Memory access pattern analysis
1269#[derive(Debug, Clone, Serialize, Deserialize)]
1270pub struct MemoryAccessPattern {
1271    /// Pattern type
1272    pub pattern_type: MemoryPatternType,
1273    /// Frequency of this pattern
1274    pub frequency: usize,
1275    /// Average size involved in this pattern
1276    pub average_size: usize,
1277    /// Risk level associated with this pattern
1278    pub risk_level: RiskLevel,
1279}
1280
1281/// Types of memory access patterns
1282#[derive(Debug, Clone, Serialize, Deserialize)]
1283pub enum MemoryPatternType {
1284    /// Sequential allocation pattern
1285    Sequential,
1286    /// Random allocation pattern
1287    Random,
1288    /// Bulk allocation pattern
1289    Bulk,
1290    /// Fragmented allocation pattern
1291    Fragmented,
1292    /// Reallocation pattern
1293    Reallocation,
1294}
1295
1296/// Size distribution analysis
1297#[derive(Debug, Clone, Serialize, Deserialize)]
1298pub struct SizeDistribution {
1299    /// Small allocations (< 1KB)
1300    pub small_allocations: usize,
1301    /// Medium allocations (1KB - 1MB)
1302    pub medium_allocations: usize,
1303    /// Large allocations (> 1MB)
1304    pub large_allocations: usize,
1305    /// Average allocation size
1306    pub average_size: f64,
1307    /// Standard deviation of sizes
1308    pub size_std_dev: f64,
1309}
1310
1311/// Temporal patterns in allocations
1312#[derive(Debug, Clone, Serialize, Deserialize)]
1313pub struct TemporalPatterns {
1314    /// Allocation rate (allocations per second)
1315    pub allocation_rate: f64,
1316    /// Peak allocation periods
1317    pub peak_periods: Vec<PeakPeriod>,
1318    /// Allocation bursts detected
1319    pub burst_count: usize,
1320    /// Average time between allocations
1321    pub avg_time_between_allocs_ms: f64,
1322}
1323
1324/// Peak allocation period
1325#[derive(Debug, Clone, Serialize, Deserialize)]
1326pub struct PeakPeriod {
1327    /// Start timestamp of peak
1328    pub start_timestamp: u128,
1329    /// End timestamp of peak
1330    pub end_timestamp: u128,
1331    /// Number of allocations during peak
1332    pub allocation_count: usize,
1333    /// Total bytes allocated during peak
1334    pub bytes_allocated: usize,
1335}
1336
1337/// Error pattern analysis
1338#[derive(Debug, Clone, Serialize, Deserialize)]
1339pub struct ErrorPattern {
1340    /// Type of error
1341    pub error_type: ErrorType,
1342    /// Frequency of this error
1343    pub frequency: usize,
1344    /// Context where error occurs
1345    pub context: String,
1346    /// Suggested mitigation
1347    pub mitigation: String,
1348}
1349
1350/// Types of errors that can be detected
1351#[derive(Debug, Clone, Serialize, Deserialize)]
1352pub enum ErrorType {
1353    /// Allocation failure
1354    AllocationFailure,
1355    /// Invalid free
1356    InvalidFree,
1357    /// Double free
1358    DoubleFree,
1359    /// Memory leak
1360    MemoryLeak,
1361    /// Buffer overflow
1362    BufferOverflow,
1363    /// Use after free
1364    UseAfterFree,
1365}
1366
1367/// Security analysis for hooked functions
1368#[derive(Debug, Clone, Serialize, Deserialize)]
1369pub struct SecurityAnalysis {
1370    /// Security vulnerabilities detected
1371    pub vulnerabilities: Vec<SecurityVulnerability>,
1372    /// Security score (0.0 to 10.0)
1373    pub security_score: f64,
1374    /// Recommended security measures
1375    pub recommendations: Vec<String>,
1376    /// Compliance status
1377    pub compliance_status: ComplianceStatus,
1378}
1379
1380/// Security vulnerability information
1381#[derive(Debug, Clone, Serialize, Deserialize)]
1382pub struct SecurityVulnerability {
1383    /// Type of vulnerability
1384    pub vulnerability_type: VulnerabilityType,
1385    /// Severity level
1386    pub severity: RiskLevel,
1387    /// Description of the vulnerability
1388    pub description: String,
1389    /// Location where vulnerability was detected
1390    pub location: String,
1391    /// Potential impact
1392    pub potential_impact: String,
1393    /// Remediation steps
1394    pub remediation: Vec<String>,
1395}
1396
1397/// Types of security vulnerabilities
1398#[derive(Debug, Clone, Serialize, Deserialize)]
1399pub enum VulnerabilityType {
1400    /// Buffer overflow vulnerability
1401    BufferOverflow,
1402    /// Use after free vulnerability
1403    UseAfterFree,
1404    /// Double free vulnerability
1405    DoubleFree,
1406    /// Memory leak vulnerability
1407    MemoryLeak,
1408    /// Integer overflow vulnerability
1409    IntegerOverflow,
1410    /// Format string vulnerability
1411    FormatString,
1412    /// Race condition vulnerability
1413    RaceCondition,
1414}
1415
1416/// Compliance status
1417#[derive(Debug, Clone, Serialize, Deserialize)]
1418pub struct ComplianceStatus {
1419    /// Memory safety compliance
1420    pub memory_safety: bool,
1421    /// Thread safety compliance
1422    pub thread_safety: bool,
1423    /// API usage compliance
1424    pub api_usage: bool,
1425    /// Security best practices compliance
1426    pub security_practices: bool,
1427    /// Overall compliance score
1428    pub overall_score: f64,
1429}
1430
1431impl UnsafeFFITracker {
1432    /// Register a C library for tracking
1433    pub fn register_c_library(
1434        &self,
1435        library_name: String,
1436        library_path: Option<String>,
1437        library_version: Option<String>,
1438    ) -> TrackingResult<()> {
1439        let current_time = std::time::SystemTime::now()
1440            .duration_since(std::time::UNIX_EPOCH)
1441            .unwrap_or_default()
1442            .as_nanos();
1443
1444        let library_info = CLibraryInfo {
1445            library_name: library_name.clone(),
1446            library_version,
1447            library_path,
1448            functions_called: HashMap::new(),
1449            total_allocations: 0,
1450            total_bytes_allocated: 0,
1451            load_timestamp: current_time,
1452            metadata: LibraryMetadata {
1453                architecture: std::env::consts::ARCH.to_string(),
1454                operating_system: std::env::consts::OS.to_string(),
1455                compiler_info: None,
1456                has_debug_symbols: false,
1457                security_features: Vec::new(),
1458            },
1459        };
1460
1461        if let Ok(mut libraries) = self.c_libraries.lock() {
1462            libraries.insert(library_name.clone(), library_info);
1463            tracing::info!("Registered C library: {}", library_name);
1464        }
1465
1466        Ok(())
1467    }
1468
1469    /// Track a C function call with detailed information
1470    pub fn track_c_function_call(
1471        &self,
1472        library_name: &str,
1473        function_name: &str,
1474        allocation_size: usize,
1475        execution_time_ns: u64,
1476    ) -> TrackingResult<()> {
1477        let current_time = std::time::SystemTime::now()
1478            .duration_since(std::time::UNIX_EPOCH)
1479            .unwrap_or_default()
1480            .as_nanos();
1481
1482        if let Ok(mut libraries) = self.c_libraries.lock() {
1483            let library = libraries
1484                .entry(library_name.to_string())
1485                .or_insert_with(|| CLibraryInfo {
1486                    library_name: library_name.to_string(),
1487                    library_version: None,
1488                    library_path: None,
1489                    functions_called: HashMap::new(),
1490                    total_allocations: 0,
1491                    total_bytes_allocated: 0,
1492                    load_timestamp: current_time,
1493                    metadata: LibraryMetadata {
1494                        architecture: std::env::consts::ARCH.to_string(),
1495                        operating_system: std::env::consts::OS.to_string(),
1496                        compiler_info: None,
1497                        has_debug_symbols: false,
1498                        security_features: Vec::new(),
1499                    },
1500                });
1501
1502            // Update library statistics
1503            library.total_allocations += 1;
1504            library.total_bytes_allocated += allocation_size;
1505
1506            // Update or create function information
1507            let function_info = library
1508                .functions_called
1509                .entry(function_name.to_string())
1510                .or_insert_with(|| CFunctionInfo {
1511                    function_name: function_name.to_string(),
1512                    function_signature: None,
1513                    call_count: 0,
1514                    bytes_allocated: 0,
1515                    average_allocation_size: 0.0,
1516                    risk_assessment: RiskAssessment {
1517                        risk_level: RiskLevel::Low,
1518                        risk_factors: Vec::new(),
1519                        mitigation_suggestions: Vec::new(),
1520                        confidence_score: 0.5,
1521                        assessment_timestamp: current_time,
1522                    },
1523                    performance_metrics: FunctionPerformanceMetrics {
1524                        avg_execution_time_ns: 0,
1525                        min_execution_time_ns: u64::MAX,
1526                        max_execution_time_ns: 0,
1527                        total_execution_time_ns: 0,
1528                        tracking_overhead_ns: 0,
1529                    },
1530                    first_call_timestamp: current_time,
1531                    last_call_timestamp: current_time,
1532                });
1533
1534            // Update function statistics
1535            function_info.call_count += 1;
1536            function_info.bytes_allocated += allocation_size;
1537            function_info.average_allocation_size =
1538                function_info.bytes_allocated as f64 / function_info.call_count as f64;
1539            function_info.last_call_timestamp = current_time;
1540
1541            // Update performance metrics
1542            let metrics = &mut function_info.performance_metrics;
1543            metrics.total_execution_time_ns += execution_time_ns;
1544            metrics.avg_execution_time_ns =
1545                metrics.total_execution_time_ns / function_info.call_count as u64;
1546            metrics.min_execution_time_ns = metrics.min_execution_time_ns.min(execution_time_ns);
1547            metrics.max_execution_time_ns = metrics.max_execution_time_ns.max(execution_time_ns);
1548
1549            tracing::debug!(
1550                "Tracked C function call: {}::{} (size: {}, time: {}ns)",
1551                library_name,
1552                function_name,
1553                allocation_size,
1554                execution_time_ns
1555            );
1556        }
1557
1558        Ok(())
1559    }
1560
1561    /// Install an enhanced LibC hook
1562    pub fn install_enhanced_libc_hook(
1563        &self,
1564        function_name: String,
1565        hook_method: HookInstallationMethod,
1566    ) -> TrackingResult<()> {
1567        let current_time = std::time::SystemTime::now()
1568            .duration_since(std::time::UNIX_EPOCH)
1569            .unwrap_or_default()
1570            .as_nanos();
1571
1572        let installation_details = HookInstallationDetails {
1573            installation_method: hook_method,
1574            installation_success: true, // Assume success for now
1575            installation_error: None,
1576            installation_timestamp: current_time,
1577            process_id: std::process::id(),
1578            thread_id: 0, // Would need platform-specific code to get thread ID
1579        };
1580
1581        let enhanced_hook = EnhancedLibCHookInfo {
1582            base_info: LibCHookInfo {
1583                hook_method: HookMethod::DynamicLinker,
1584                original_function: function_name.clone(),
1585                hook_timestamp: current_time,
1586                allocation_metadata: AllocationMetadata {
1587                    requested_size: 0,
1588                    actual_size: 0,
1589                    alignment: 8,
1590                    allocator_info: format!("hooked_{function_name}"),
1591                    protection_flags: Some(MemoryProtectionFlags {
1592                        readable: true,
1593                        writable: true,
1594                        executable: false,
1595                        shared: false,
1596                    }),
1597                },
1598                hook_overhead_ns: Some(50),
1599            },
1600            function_tracking: CFunctionInfo {
1601                function_name: function_name.clone(),
1602                function_signature: None,
1603                call_count: 0,
1604                bytes_allocated: 0,
1605                average_allocation_size: 0.0,
1606                risk_assessment: RiskAssessment {
1607                    risk_level: RiskLevel::Medium,
1608                    risk_factors: Vec::new(),
1609                    mitigation_suggestions: vec![
1610                        "Monitor for memory leaks".to_string(),
1611                        "Validate all pointer operations".to_string(),
1612                    ],
1613                    confidence_score: 0.7,
1614                    assessment_timestamp: current_time,
1615                },
1616                performance_metrics: FunctionPerformanceMetrics {
1617                    avg_execution_time_ns: 0,
1618                    min_execution_time_ns: u64::MAX,
1619                    max_execution_time_ns: 0,
1620                    total_execution_time_ns: 0,
1621                    tracking_overhead_ns: 50,
1622                },
1623                first_call_timestamp: current_time,
1624                last_call_timestamp: current_time,
1625            },
1626            installation_details,
1627            runtime_analysis: RuntimeBehaviorAnalysis {
1628                memory_patterns: Vec::new(),
1629                size_distribution: SizeDistribution {
1630                    small_allocations: 0,
1631                    medium_allocations: 0,
1632                    large_allocations: 0,
1633                    average_size: 0.0,
1634                    size_std_dev: 0.0,
1635                },
1636                temporal_patterns: TemporalPatterns {
1637                    allocation_rate: 0.0,
1638                    peak_periods: Vec::new(),
1639                    burst_count: 0,
1640                    avg_time_between_allocs_ms: 0.0,
1641                },
1642                error_patterns: Vec::new(),
1643            },
1644            security_analysis: SecurityAnalysis {
1645                vulnerabilities: Vec::new(),
1646                security_score: 5.0,
1647                recommendations: vec![
1648                    "Enable memory protection".to_string(),
1649                    "Use safe allocation patterns".to_string(),
1650                ],
1651                compliance_status: ComplianceStatus {
1652                    memory_safety: false,
1653                    thread_safety: false,
1654                    api_usage: true,
1655                    security_practices: false,
1656                    overall_score: 0.25,
1657                },
1658            },
1659        };
1660
1661        if let Ok(mut hooks) = self.libc_hooks.lock() {
1662            hooks.insert(function_name.clone(), enhanced_hook);
1663            tracing::info!("Installed enhanced LibC hook for: {}", function_name);
1664        }
1665
1666        Ok(())
1667    }
1668
1669    /// Create and register a memory passport for cross-boundary tracking
1670    pub fn create_and_register_passport(
1671        &self,
1672        ptr: usize,
1673        origin_context: &str,
1674        security_clearance: SecurityClearance,
1675    ) -> TrackingResult<String> {
1676        let passport = self.create_memory_passport(ptr, origin_context);
1677        let passport_id = passport.passport_id.clone();
1678
1679        // Set the security clearance
1680        let mut passport = passport;
1681        passport.security_clearance = security_clearance;
1682
1683        if let Ok(mut passports) = self.memory_passports.lock() {
1684            passports.insert(ptr, passport);
1685            tracing::info!("Created memory passport {} for ptr {:x}", passport_id, ptr);
1686        }
1687
1688        Ok(passport_id)
1689    }
1690
1691    /// Update memory passport with new stamp
1692    pub fn stamp_passport(
1693        &self,
1694        ptr: usize,
1695        operation: &str,
1696        location: &str,
1697        authority: &str,
1698    ) -> TrackingResult<()> {
1699        let current_time = std::time::SystemTime::now()
1700            .duration_since(std::time::UNIX_EPOCH)
1701            .unwrap_or_default()
1702            .as_nanos();
1703
1704        if let Ok(mut passports) = self.memory_passports.lock() {
1705            if let Some(passport) = passports.get_mut(&ptr) {
1706                let stamp = PassportStamp {
1707                    timestamp: current_time,
1708                    location: location.to_string(),
1709                    operation: operation.to_string(),
1710                    authority: authority.to_string(),
1711                    verification_hash: format!("{:x}", ptr ^ current_time as usize),
1712                };
1713
1714                passport.journey.push(stamp);
1715                tracing::debug!("Stamped passport for ptr {:x}: {}", ptr, operation);
1716            } else {
1717                return Err(TrackingError::InvalidPointer(format!(
1718                    "No passport found for pointer: 0x{ptr:x}",
1719                )));
1720            }
1721        }
1722
1723        Ok(())
1724    }
1725
1726    /// Transfer memory passport ownership
1727    pub fn transfer_passport_ownership(
1728        &self,
1729        ptr: usize,
1730        new_owner_context: &str,
1731        new_owner_function: &str,
1732    ) -> TrackingResult<()> {
1733        let current_time = std::time::SystemTime::now()
1734            .duration_since(std::time::UNIX_EPOCH)
1735            .unwrap_or_default()
1736            .as_nanos();
1737
1738        if let Ok(mut passports) = self.memory_passports.lock() {
1739            if let Some(passport) = passports.get_mut(&ptr) {
1740                passport.current_owner = OwnershipInfo {
1741                    owner_context: new_owner_context.to_string(),
1742                    owner_function: new_owner_function.to_string(),
1743                    transfer_timestamp: current_time,
1744                    expected_lifetime: None,
1745                };
1746
1747                // Add a stamp for the ownership transfer
1748                let stamp = PassportStamp {
1749                    timestamp: current_time,
1750                    location: new_owner_context.to_string(),
1751                    operation: "ownership_transfer".to_string(),
1752                    authority: "UnsafeFFITracker".to_string(),
1753                    verification_hash: format!("{:x}", ptr ^ current_time as usize),
1754                };
1755
1756                passport.journey.push(stamp);
1757                tracing::info!(
1758                    "Transferred passport ownership for ptr {:x} to {}::{}",
1759                    ptr,
1760                    new_owner_context,
1761                    new_owner_function
1762                );
1763            } else {
1764                return Err(TrackingError::InvalidPointer(format!(
1765                    "No passport found for pointer: 0x{ptr:x}",
1766                )));
1767            }
1768        }
1769
1770        Ok(())
1771    }
1772
1773    /// Revoke a memory passport (when memory is freed)
1774    pub fn revoke_passport(&self, ptr: usize, reason: &str) -> TrackingResult<()> {
1775        if let Ok(mut passports) = self.memory_passports.lock() {
1776            if let Some(passport) = passports.get_mut(&ptr) {
1777                passport.validity_status = ValidityStatus::Revoked;
1778
1779                // Add a final stamp
1780                let current_time = std::time::SystemTime::now()
1781                    .duration_since(std::time::UNIX_EPOCH)
1782                    .unwrap_or_default()
1783                    .as_nanos();
1784
1785                let stamp = PassportStamp {
1786                    timestamp: current_time,
1787                    location: "memory_freed".to_string(),
1788                    operation: format!("revoked: {reason}"),
1789                    authority: "UnsafeFFITracker".to_string(),
1790                    verification_hash: format!("{:x}", ptr ^ current_time as usize),
1791                };
1792
1793                passport.journey.push(stamp);
1794                tracing::info!("Revoked passport for ptr {ptr:x}: {reason}");
1795            }
1796        }
1797
1798        Ok(())
1799    }
1800
1801    /// Get C library statistics
1802    pub fn get_c_library_stats(&self) -> TrackingResult<HashMap<String, CLibraryInfo>> {
1803        self.c_libraries
1804            .lock()
1805            .map(|libs| libs.clone())
1806            .map_err(|e| TrackingError::LockError(e.to_string()))
1807    }
1808
1809    /// Get LibC hook information
1810    pub fn get_libc_hook_info(&self) -> TrackingResult<HashMap<String, EnhancedLibCHookInfo>> {
1811        self.libc_hooks
1812            .lock()
1813            .map(|hooks| hooks.clone())
1814            .map_err(|e| TrackingError::LockError(e.to_string()))
1815    }
1816
1817    /// Get memory passport information
1818    pub fn get_memory_passports(&self) -> TrackingResult<HashMap<usize, MemoryPassport>> {
1819        self.memory_passports
1820            .lock()
1821            .map(|passports| passports.clone())
1822            .map_err(|e| TrackingError::LockError(e.to_string()))
1823    }
1824
1825    /// Analyze cross-boundary risks with detailed assessment
1826    pub fn analyze_cross_boundary_risks(&self) -> TrackingResult<Vec<SafetyViolation>> {
1827        let mut risks = Vec::new();
1828
1829        if let Ok(passports) = self.memory_passports.lock() {
1830            for (ptr, passport) in passports.iter() {
1831                // Check for suspicious passport activity
1832                if passport.journey.len() > 10 {
1833                    risks.push(SafetyViolation::CrossBoundaryRisk {
1834                        risk_level: RiskLevel::Medium,
1835                        description: format!(
1836                            "Memory at {ptr:x} has crossed boundaries {} times",
1837                            passport.journey.len()
1838                        ),
1839                        stack: {
1840                            let normalizer = get_global_call_stack_normalizer();
1841                            let empty_frames = vec![];
1842                            let id = normalizer.normalize_call_stack(&empty_frames).unwrap_or(0);
1843                            CallStackRef::new(id, Some(0))
1844                        },
1845                    });
1846                }
1847
1848                // Check for expired passports
1849                if matches!(passport.validity_status, ValidityStatus::Expired) {
1850                    risks.push(SafetyViolation::CrossBoundaryRisk {
1851                        risk_level: RiskLevel::High,
1852                        description: format!("Expired passport detected for memory at {ptr:x}"),
1853                        stack: {
1854                            let normalizer = get_global_call_stack_normalizer();
1855                            let empty_frames = vec![];
1856                            let id = normalizer.normalize_call_stack(&empty_frames).unwrap_or(0);
1857                            CallStackRef::new(id, Some(0))
1858                        },
1859                    });
1860                }
1861            }
1862        }
1863
1864        Ok(risks)
1865    }
1866
1867    /// Process boundary events with comprehensive analysis
1868    pub fn process_boundary_event(
1869        &self,
1870        ptr: usize,
1871        event_type: BoundaryEventType,
1872        from_context: &str,
1873        to_context: &str,
1874        transfer_size: usize,
1875    ) -> TrackingResult<BoundaryEventAnalysis> {
1876        let current_time = std::time::SystemTime::now()
1877            .duration_since(std::time::UNIX_EPOCH)
1878            .unwrap_or_default()
1879            .as_nanos();
1880
1881        // Record the boundary event
1882        self.record_boundary_event(
1883            ptr,
1884            event_type.clone(),
1885            from_context.to_string(),
1886            to_context.to_string(),
1887        )?;
1888
1889        // Analyze the risk level for this specific transfer
1890        let risk_analysis = self.assess_boundary_transfer_risk(
1891            ptr,
1892            &event_type,
1893            from_context,
1894            to_context,
1895            transfer_size,
1896        )?;
1897
1898        // Update ownership tracking
1899        self.track_ownership_transfer(ptr, from_context, to_context)?;
1900
1901        // Create comprehensive analysis
1902        let analysis = BoundaryEventAnalysis {
1903            event_id: format!("boundary_{ptr}_{current_time}"),
1904            ptr,
1905            event_type: event_type.clone(),
1906            from_context: from_context.to_string(),
1907            to_context: to_context.to_string(),
1908            transfer_size,
1909            timestamp: current_time,
1910            risk_assessment: risk_analysis.clone(),
1911            ownership_chain: self.get_ownership_chain(ptr)?,
1912            security_implications: self.analyze_security_implications(
1913                ptr,
1914                from_context,
1915                to_context,
1916            )?,
1917            performance_impact: self.estimate_performance_impact(&event_type, transfer_size),
1918            mitigation_recommendations: self.generate_mitigation_recommendations(&risk_analysis),
1919        };
1920
1921        Ok(analysis)
1922    }
1923
1924    /// Assess risk level for boundary transfers
1925    fn assess_boundary_transfer_risk(
1926        &self,
1927        ptr: usize,
1928        event_type: &BoundaryEventType,
1929        _from_context: &str,
1930        _to_context: &str,
1931        transfer_size: usize,
1932    ) -> TrackingResult<BoundaryRiskAssessment> {
1933        let mut risk_factors = Vec::new();
1934        let mut risk_score = 0.0;
1935
1936        // Analyze transfer direction risk
1937        match event_type {
1938            BoundaryEventType::RustToFfi => {
1939                risk_factors.push(BoundaryRiskFactor {
1940                    factor_type: BoundaryRiskFactorType::RustToForeignTransfer,
1941                    severity: 6.0,
1942                    description: "Memory allocated in Rust being passed to foreign code"
1943                        .to_string(),
1944                    mitigation: "Ensure foreign code doesn't free Rust-allocated memory"
1945                        .to_string(),
1946                });
1947                risk_score += 6.0;
1948            }
1949            BoundaryEventType::FfiToRust => {
1950                risk_factors.push(BoundaryRiskFactor {
1951                    factor_type: BoundaryRiskFactorType::ForeignToRustTransfer,
1952                    severity: 7.0,
1953                    description: "Foreign-allocated memory being passed to Rust".to_string(),
1954                    mitigation: "Validate memory layout and lifetime guarantees".to_string(),
1955                });
1956                risk_score += 7.0;
1957            }
1958            BoundaryEventType::OwnershipTransfer => {
1959                risk_factors.push(BoundaryRiskFactor {
1960                    factor_type: BoundaryRiskFactorType::OwnershipTransfer,
1961                    severity: 8.0,
1962                    description: "Memory ownership being transferred across language boundary"
1963                        .to_string(),
1964                    mitigation: "Clearly document ownership transfer and cleanup responsibilities"
1965                        .to_string(),
1966                });
1967                risk_score += 8.0;
1968            }
1969            BoundaryEventType::SharedAccess => {
1970                risk_factors.push(BoundaryRiskFactor {
1971                    factor_type: BoundaryRiskFactorType::SharedAccess,
1972                    severity: 5.0,
1973                    description: "Memory being shared between Rust and foreign code".to_string(),
1974                    mitigation: "Implement proper synchronization mechanisms".to_string(),
1975                });
1976                risk_score += 5.0;
1977            }
1978        }
1979
1980        // Analyze transfer size risk
1981        if transfer_size > 1024 * 1024 {
1982            risk_factors.push(BoundaryRiskFactor {
1983                factor_type: BoundaryRiskFactorType::LargeTransfer,
1984                severity: 4.0,
1985                description: format!("Large memory transfer: {transfer_size} bytes"),
1986                mitigation: "Consider streaming or chunked transfer for large data".to_string(),
1987            });
1988            risk_score += 4.0;
1989        }
1990
1991        // Check for frequent transfers (potential performance issue)
1992        if let Ok(allocations) = self.enhanced_allocations.lock() {
1993            if let Some(allocation) = allocations.get(&ptr) {
1994                if allocation.cross_boundary_events.len() > 5 {
1995                    risk_factors.push(BoundaryRiskFactor {
1996                        factor_type: BoundaryRiskFactorType::FrequentTransfers,
1997                        severity: 3.0,
1998                        description: format!(
1999                            "Memory has crossed boundaries {} times",
2000                            allocation.cross_boundary_events.len()
2001                        ),
2002                        mitigation: "Consider reducing boundary crossings or caching".to_string(),
2003                    });
2004                    risk_score += 3.0;
2005                }
2006            }
2007        }
2008
2009        // Determine overall risk level
2010        let risk_level = if risk_score >= 15.0 {
2011            RiskLevel::Critical
2012        } else if risk_score >= 10.0 {
2013            RiskLevel::High
2014        } else if risk_score >= 5.0 {
2015            RiskLevel::Medium
2016        } else {
2017            RiskLevel::Low
2018        };
2019
2020        Ok(BoundaryRiskAssessment {
2021            overall_risk_level: risk_level,
2022            risk_score,
2023            risk_factors,
2024            confidence_score: 0.8, // High confidence in boundary risk assessment
2025            assessment_timestamp: std::time::SystemTime::now()
2026                .duration_since(std::time::UNIX_EPOCH)
2027                .unwrap_or_default()
2028                .as_nanos(),
2029        })
2030    }
2031
2032    /// Track ownership transfer across boundaries
2033    fn track_ownership_transfer(
2034        &self,
2035        ptr: usize,
2036        from_context: &str,
2037        to_context: &str,
2038    ) -> TrackingResult<()> {
2039        let current_time = std::time::SystemTime::now()
2040            .duration_since(std::time::UNIX_EPOCH)
2041            .unwrap_or_default()
2042            .as_nanos();
2043
2044        // Update memory passport ownership
2045        if let Ok(mut passports) = self.memory_passports.lock() {
2046            if let Some(passport) = passports.get_mut(&ptr) {
2047                // Record the ownership transfer in the journey
2048                let stamp = PassportStamp {
2049                    timestamp: current_time,
2050                    location: to_context.to_string(),
2051                    operation: format!("ownership_transfer_from_{from_context}"),
2052                    authority: "BoundaryEventProcessor".to_string(),
2053                    verification_hash: format!("{:x}", ptr ^ current_time as usize),
2054                };
2055                passport.journey.push(stamp);
2056
2057                // Update current owner
2058                passport.current_owner = OwnershipInfo {
2059                    owner_context: to_context.to_string(),
2060                    owner_function: "unknown".to_string(),
2061                    transfer_timestamp: current_time,
2062                    expected_lifetime: None,
2063                };
2064            }
2065        }
2066
2067        // Update allocation tracking
2068        if let Ok(mut allocations) = self.enhanced_allocations.lock() {
2069            if let Some(allocation) = allocations.get_mut(&ptr) {
2070                // Add ownership transfer event
2071                let ownership_event = OwnershipTransferEvent {
2072                    transfer_id: format!("transfer_{ptr}_{current_time}"),
2073                    ptr,
2074                    from_context: from_context.to_string(),
2075                    to_context: to_context.to_string(),
2076                    transfer_timestamp: current_time,
2077                    transfer_reason: "boundary_crossing".to_string(),
2078                    validation_status: OwnershipValidationStatus::Pending,
2079                };
2080
2081                // Store in allocation's ownership history
2082                if allocation.ownership_history.is_none() {
2083                    allocation.ownership_history = Some(Vec::new());
2084                }
2085                if let Some(ref mut history) = allocation.ownership_history {
2086                    history.push(ownership_event);
2087                }
2088            }
2089        }
2090
2091        Ok(())
2092    }
2093
2094    /// Get ownership chain for a memory allocation
2095    fn get_ownership_chain(&self, ptr: usize) -> TrackingResult<Vec<OwnershipRecord>> {
2096        let mut chain = Vec::new();
2097
2098        if let Ok(allocations) = self.enhanced_allocations.lock() {
2099            if let Some(allocation) = allocations.get(&ptr) {
2100                if let Some(ref history) = allocation.ownership_history {
2101                    for transfer in history {
2102                        chain.push(OwnershipRecord {
2103                            context: transfer.to_context.clone(),
2104                            timestamp: transfer.transfer_timestamp,
2105                            transfer_reason: transfer.transfer_reason.clone(),
2106                            validation_status: transfer.validation_status.clone(),
2107                        });
2108                    }
2109                }
2110            }
2111        }
2112
2113        Ok(chain)
2114    }
2115
2116    /// Analyze security implications of boundary crossing
2117    fn analyze_security_implications(
2118        &self,
2119        _ptr: usize,
2120        from_context: &str,
2121        to_context: &str,
2122    ) -> TrackingResult<Vec<SecurityImplication>> {
2123        let mut implications = Vec::new();
2124
2125        // Check for privilege escalation
2126        if from_context.contains("user") && to_context.contains("system") {
2127            implications.push(SecurityImplication {
2128                implication_type: SecurityImplicationType::PrivilegeEscalation,
2129                severity: RiskLevel::High,
2130                description: "Memory transfer from user context to system context".to_string(),
2131                potential_impact: "Potential privilege escalation vulnerability".to_string(),
2132                recommended_action: "Validate and sanitize all data before system context access"
2133                    .to_string(),
2134            });
2135        }
2136
2137        // Check for data exposure
2138        if from_context.contains("secure") || to_context.contains("secure") {
2139            implications.push(SecurityImplication {
2140                implication_type: SecurityImplicationType::DataExposure,
2141                severity: RiskLevel::Medium,
2142                description: "Memory transfer involving secure context".to_string(),
2143                potential_impact: "Potential sensitive data exposure".to_string(),
2144                recommended_action: "Ensure proper data sanitization and access controls"
2145                    .to_string(),
2146            });
2147        }
2148
2149        // Check for injection attacks
2150        if to_context.contains("interpreter") || to_context.contains("eval") {
2151            implications.push(SecurityImplication {
2152                implication_type: SecurityImplicationType::InjectionRisk,
2153                severity: RiskLevel::Critical,
2154                description: "Memory transfer to code interpretation context".to_string(),
2155                potential_impact: "Potential code injection vulnerability".to_string(),
2156                recommended_action: "Validate and sanitize all input data before interpretation"
2157                    .to_string(),
2158            });
2159        }
2160
2161        Ok(implications)
2162    }
2163
2164    /// Estimate performance impact of boundary crossing
2165    fn estimate_performance_impact(
2166        &self,
2167        event_type: &BoundaryEventType,
2168        transfer_size: usize,
2169    ) -> PerformanceImpact {
2170        let base_overhead_ns = match event_type {
2171            BoundaryEventType::RustToFfi => 100,
2172            BoundaryEventType::FfiToRust => 150,
2173            BoundaryEventType::OwnershipTransfer => 200,
2174            BoundaryEventType::SharedAccess => 50,
2175        };
2176
2177        let size_overhead_ns = (transfer_size / 1024) as u64 * 10; // 10ns per KB
2178        let total_overhead_ns = base_overhead_ns + size_overhead_ns;
2179
2180        let impact_level = if total_overhead_ns > 10000 {
2181            PerformanceImpactLevel::High
2182        } else if total_overhead_ns > 1000 {
2183            PerformanceImpactLevel::Medium
2184        } else {
2185            PerformanceImpactLevel::Low
2186        };
2187
2188        PerformanceImpact {
2189            impact_level,
2190            estimated_overhead_ns: total_overhead_ns,
2191            memory_overhead_bytes: transfer_size / 10, // Assume 10% memory overhead
2192            cpu_overhead_percent: if total_overhead_ns > 5000 { 5.0 } else { 1.0 },
2193            recommendations: vec![
2194                "Consider batching small transfers".to_string(),
2195                "Use memory mapping for large transfers".to_string(),
2196                "Implement caching for frequently accessed data".to_string(),
2197            ],
2198        }
2199    }
2200
2201    /// Generate mitigation recommendations based on risk assessment
2202    fn generate_mitigation_recommendations(
2203        &self,
2204        risk_assessment: &BoundaryRiskAssessment,
2205    ) -> Vec<String> {
2206        let mut recommendations = Vec::new();
2207
2208        match risk_assessment.overall_risk_level {
2209            RiskLevel::Critical => {
2210                recommendations
2211                    .push("URGENT: Review and redesign boundary crossing strategy".to_string());
2212                recommendations.push("Implement comprehensive input validation".to_string());
2213                recommendations.push("Add runtime safety checks".to_string());
2214                recommendations
2215                    .push("Consider using safer alternatives to raw pointers".to_string());
2216            }
2217            RiskLevel::High => {
2218                recommendations.push("Implement additional safety checks".to_string());
2219                recommendations.push("Add comprehensive logging and monitoring".to_string());
2220                recommendations.push("Review memory ownership patterns".to_string());
2221            }
2222            RiskLevel::Medium => {
2223                recommendations.push("Monitor boundary crossing frequency".to_string());
2224                recommendations.push("Consider performance optimizations".to_string());
2225                recommendations.push("Document ownership transfer clearly".to_string());
2226            }
2227            RiskLevel::Low => {
2228                recommendations.push("Continue current practices".to_string());
2229                recommendations.push("Periodic review recommended".to_string());
2230            }
2231        }
2232
2233        // Add specific recommendations based on risk factors
2234        for factor in &risk_assessment.risk_factors {
2235            recommendations.push(factor.mitigation.clone());
2236        }
2237
2238        recommendations.dedup();
2239        recommendations
2240    }
2241
2242    /// Get comprehensive boundary event statistics
2243    pub fn get_boundary_event_statistics(&self) -> TrackingResult<BoundaryEventStatistics> {
2244        let mut stats = BoundaryEventStatistics {
2245            total_events: 0,
2246            events_by_type: std::collections::HashMap::new(),
2247            risk_distribution: std::collections::HashMap::new(),
2248            average_transfer_size: 0.0,
2249            total_transfer_volume: 0,
2250            most_active_contexts: Vec::new(),
2251            security_incidents: 0,
2252            performance_issues: 0,
2253            analysis_timestamp: std::time::SystemTime::now()
2254                .duration_since(std::time::UNIX_EPOCH)
2255                .unwrap_or_default()
2256                .as_nanos(),
2257        };
2258
2259        if let Ok(allocations) = self.enhanced_allocations.lock() {
2260            let mut context_activity: std::collections::HashMap<String, usize> =
2261                std::collections::HashMap::new();
2262            let mut total_size = 0usize;
2263            let mut event_count = 0usize;
2264
2265            for allocation in allocations.values() {
2266                for event in &allocation.cross_boundary_events {
2267                    stats.total_events += 1;
2268                    event_count += 1;
2269
2270                    // Count by event type
2271                    *stats
2272                        .events_by_type
2273                        .entry(format!("{:?}", event.event_type))
2274                        .or_insert(0) += 1;
2275
2276                    // Track context activity
2277                    *context_activity
2278                        .entry(event.from_context.clone())
2279                        .or_insert(0) += 1;
2280                    *context_activity
2281                        .entry(event.to_context.clone())
2282                        .or_insert(0) += 1;
2283
2284                    // Estimate transfer size (would need actual size tracking)
2285                    let estimated_size = allocation.base.size;
2286                    total_size += estimated_size;
2287                }
2288            }
2289
2290            if event_count > 0 {
2291                stats.average_transfer_size = total_size as f64 / event_count as f64;
2292            }
2293            stats.total_transfer_volume = total_size;
2294
2295            // Get most active contexts
2296            let mut context_vec: Vec<_> = context_activity.into_iter().collect();
2297            context_vec.sort_by_key(|b| std::cmp::Reverse(b.1));
2298            stats.most_active_contexts = context_vec.into_iter().take(10).collect();
2299        }
2300
2301        Ok(stats)
2302    }
2303
2304    /// Get statistics for unsafe and FFI operations
2305    pub fn get_stats(&self) -> UnsafeFFIStats {
2306        let allocations = self
2307            .enhanced_allocations
2308            .lock()
2309            .unwrap_or_else(|poisoned| poisoned.into_inner());
2310        let violations = self
2311            .violations
2312            .lock()
2313            .unwrap_or_else(|poisoned| poisoned.into_inner());
2314
2315        let mut stats = UnsafeFFIStats::default();
2316
2317        // Count different types of operations
2318        for allocation in allocations.values() {
2319            match &allocation.source {
2320                AllocationSource::UnsafeRust { .. } => {
2321                    stats.unsafe_blocks += 1;
2322                    stats.total_operations += 1;
2323                }
2324                AllocationSource::FfiC { .. } => {
2325                    stats.ffi_calls += 1;
2326                    stats.total_operations += 1;
2327                }
2328                AllocationSource::CrossBoundary { .. } => {
2329                    stats.total_operations += 1;
2330                }
2331                _ => {}
2332            }
2333
2334            // Count safety violations
2335            stats.memory_violations += allocation.safety_violations.len();
2336        }
2337
2338        // Add violations from the violations log
2339        stats.memory_violations += violations.len();
2340
2341        // Calculate risk score (simplified)
2342        stats.risk_score = if stats.total_operations > 0 {
2343            let base_risk = (stats.unsafe_blocks as f64 * 1.0)
2344                + (stats.ffi_calls as f64 * 2.0)
2345                + (stats.memory_violations as f64 * 5.0);
2346            (base_risk / stats.total_operations as f64).min(10.0)
2347        } else {
2348            0.0
2349        };
2350
2351        // Create operation list (simplified)
2352        for allocation in allocations.values() {
2353            let (op_type, risk_level, description) = match &allocation.source {
2354                AllocationSource::UnsafeRust {
2355                    unsafe_block_location,
2356                    ..
2357                } => (
2358                    UnsafeOperationType::UnsafeBlock,
2359                    RiskLevel::Medium,
2360                    format!("Unsafe block at {unsafe_block_location}"),
2361                ),
2362                AllocationSource::FfiC {
2363                    resolved_function, ..
2364                } => (
2365                    UnsafeOperationType::FfiCall,
2366                    RiskLevel::High,
2367                    format!(
2368                        "FFI call to {}::{}",
2369                        resolved_function.library_name, resolved_function.function_name
2370                    ),
2371                ),
2372                AllocationSource::CrossBoundary { .. } => (
2373                    UnsafeOperationType::CrossBoundaryTransfer,
2374                    RiskLevel::Medium,
2375                    "Cross-boundary memory transfer".to_string(),
2376                ),
2377                _ => continue,
2378            };
2379
2380            stats.operations.push(UnsafeOperation {
2381                operation_type: op_type,
2382                location: "unknown".to_string(), // Could be enhanced with actual location
2383                risk_level,
2384                timestamp: allocation.base.timestamp_alloc as u128,
2385                description,
2386            });
2387        }
2388
2389        // Limit operations to avoid huge JSON
2390        stats.operations.truncate(50);
2391
2392        stats
2393    }
2394
2395    /// Integrate with SafetyAnalyzer for enhanced reporting
2396    pub fn integrate_with_safety_analyzer(
2397        &self,
2398        safety_analyzer: &crate::analysis::SafetyAnalyzer,
2399    ) -> TrackingResult<()> {
2400        // Get current violations
2401        let violations = if let Ok(violations) = self.violations.lock() {
2402            violations.clone()
2403        } else {
2404            return Err(TrackingError::LockContention(
2405                "Failed to lock violations".to_string(),
2406            ));
2407        };
2408
2409        // Get current allocations
2410        let allocations: Vec<AllocationInfo> =
2411            if let Ok(enhanced_allocations) = self.enhanced_allocations.lock() {
2412                enhanced_allocations
2413                    .values()
2414                    .map(|ea| ea.base.clone())
2415                    .collect()
2416            } else {
2417                return Err(TrackingError::LockContention(
2418                    "Failed to lock allocations".to_string(),
2419                ));
2420            };
2421
2422        // Generate unsafe reports for each violation
2423        for violation in &violations {
2424            let source = match violation {
2425                SafetyViolation::DoubleFree { .. } => crate::analysis::UnsafeSource::RawPointer {
2426                    operation: "double_free".to_string(),
2427                    location: "memory_violation".to_string(),
2428                },
2429                SafetyViolation::InvalidFree {
2430                    attempted_pointer, ..
2431                } => crate::analysis::UnsafeSource::RawPointer {
2432                    operation: "invalid_free".to_string(),
2433                    location: format!("0x{attempted_pointer:x}"),
2434                },
2435                SafetyViolation::PotentialLeak { .. } => {
2436                    crate::analysis::UnsafeSource::RawPointer {
2437                        operation: "potential_leak".to_string(),
2438                        location: "memory_leak".to_string(),
2439                    }
2440                }
2441                SafetyViolation::CrossBoundaryRisk { description, .. } => {
2442                    crate::analysis::UnsafeSource::FfiFunction {
2443                        library: "unknown".to_string(),
2444                        function: "cross_boundary".to_string(),
2445                        call_site: description.clone(),
2446                    }
2447                }
2448            };
2449
2450            let _report_id =
2451                safety_analyzer.generate_unsafe_report(source, &allocations, &violations)?;
2452        }
2453
2454        tracing::info!(
2455            "🔗 Integrated {} violations with SafetyAnalyzer",
2456            violations.len()
2457        );
2458        Ok(())
2459    }
2460
2461    /// Integrate with MemoryPassportTracker for FFI boundary tracking
2462    pub fn integrate_with_passport_tracker(
2463        &self,
2464        passport_tracker: &crate::analysis::MemoryPassportTracker,
2465    ) -> TrackingResult<()> {
2466        if let Ok(enhanced_allocations) = self.enhanced_allocations.lock() {
2467            for (ptr, allocation) in enhanced_allocations.iter() {
2468                // Create passports for FFI allocations
2469                if allocation.ffi_tracked {
2470                    // Use type inference if type_name is not available
2471                    let type_name = allocation.base.type_name.clone();
2472                    let _passport_id = if type_name.is_none()
2473                        || type_name
2474                            .as_ref()
2475                            .is_none_or(|t| t == "unknown" || t.is_empty())
2476                    {
2477                        // Use inference-based passport creation
2478                        passport_tracker.create_passport_with_inference(
2479                            *ptr,
2480                            allocation.base.size,
2481                            None,
2482                            "ffi_integration".to_string(),
2483                            allocation.base.var_name.clone(),
2484                        )?
2485                    } else {
2486                        passport_tracker.create_passport(
2487                            *ptr,
2488                            allocation.base.size,
2489                            "ffi_integration".to_string(),
2490                            type_name,
2491                            allocation.base.var_name.clone(),
2492                        )?
2493                    };
2494
2495                    // Record boundary events
2496                    for event in &allocation.cross_boundary_events {
2497                        let event_type = match event.event_type {
2498                            BoundaryEventType::RustToFfi => {
2499                                crate::analysis::PassportEventType::HandoverToFfi
2500                            }
2501                            BoundaryEventType::FfiToRust => {
2502                                crate::analysis::PassportEventType::ReclaimedByRust
2503                            }
2504                            BoundaryEventType::OwnershipTransfer => {
2505                                crate::analysis::PassportEventType::OwnershipTransfer
2506                            }
2507                            BoundaryEventType::SharedAccess => {
2508                                crate::analysis::PassportEventType::BoundaryAccess
2509                            }
2510                        };
2511
2512                        passport_tracker.record_passport_event(
2513                            *ptr,
2514                            event_type,
2515                            event.to_context.clone(),
2516                            std::collections::HashMap::new(),
2517                        )?;
2518                    }
2519                }
2520            }
2521        }
2522
2523        tracing::info!("🔗 Integrated FFI allocations with MemoryPassportTracker");
2524        Ok(())
2525    }
2526
2527    /// Perform comprehensive safety analysis using integrated components
2528    pub fn perform_comprehensive_safety_analysis(
2529        &self,
2530    ) -> TrackingResult<crate::analysis::ComprehensiveSafetyReport> {
2531        // Initialize integrated components
2532        let safety_analyzer = crate::analysis::SafetyAnalyzer::default();
2533        let passport_tracker = crate::analysis::get_global_passport_tracker();
2534
2535        // Integrate with components
2536        self.integrate_with_safety_analyzer(&safety_analyzer)?;
2537        self.integrate_with_passport_tracker(&passport_tracker)?;
2538
2539        // Detect leaks at shutdown
2540        let leak_detection = passport_tracker.detect_leaks_at_shutdown();
2541
2542        // Get reports and statistics
2543        let unsafe_reports = safety_analyzer.get_unsafe_reports();
2544        let memory_passports = passport_tracker.get_all_passports();
2545        let safety_stats = safety_analyzer.get_stats();
2546        let passport_stats = passport_tracker.get_stats();
2547
2548        let report = crate::analysis::ComprehensiveSafetyReport {
2549            unsafe_reports,
2550            memory_passports,
2551            leak_detection,
2552            safety_stats,
2553            passport_stats,
2554            analysis_timestamp: std::time::SystemTime::now()
2555                .duration_since(std::time::UNIX_EPOCH)
2556                .unwrap_or_default()
2557                .as_secs(),
2558        };
2559
2560        tracing::info!("📊 Generated comprehensive safety analysis report");
2561        Ok(report)
2562    }
2563}
2564
2565/// Comprehensive safety analysis report
2566#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
2567pub struct ComprehensiveSafetyReport {
2568    /// All unsafe operation reports
2569    pub unsafe_reports: std::collections::HashMap<String, crate::analysis::UnsafeReport>,
2570    /// All memory passports
2571    pub memory_passports: std::collections::HashMap<usize, crate::analysis::MemoryPassport>,
2572    /// Leak detection results
2573    pub leak_detection: crate::analysis::LeakDetectionResult,
2574    /// Safety analysis statistics
2575    pub safety_stats: crate::analysis::SafetyAnalysisStats,
2576    /// Passport tracker statistics
2577    pub passport_stats: crate::analysis::PassportTrackerStats,
2578    /// Analysis timestamp
2579    pub analysis_timestamp: u64,
2580}
2581
2582/// Global unsafe/FFI tracker instance
2583static GLOBAL_UNSAFE_TRACKER: OnceLock<Arc<UnsafeFFITracker>> = OnceLock::new();
2584
2585/// Get the global unsafe/FFI tracker instance
2586pub fn get_global_unsafe_tracker() -> Option<Arc<UnsafeFFITracker>> {
2587    GLOBAL_UNSAFE_TRACKER.get().cloned()
2588}
2589
2590/// Initialize the global unsafe/FFI tracker
2591pub fn init_global_unsafe_tracker() -> Arc<UnsafeFFITracker> {
2592    GLOBAL_UNSAFE_TRACKER
2593        .get_or_init(|| Arc::new(UnsafeFFITracker::new()))
2594        .clone()
2595}
2596
2597#[cfg(test)]
2598mod tests {
2599    use super::*;
2600    use std::sync::Arc;
2601
2602    /// Helper function to create a test tracker
2603    fn create_test_tracker() -> UnsafeFFITracker {
2604        UnsafeFFITracker::new()
2605    }
2606
2607    #[test]
2608    fn test_unsafe_ffi_tracker_creation() {
2609        let tracker = create_test_tracker();
2610
2611        // Verify initial state
2612        assert!(tracker
2613            .get_enhanced_allocations()
2614            .expect("Should get enhanced allocations")
2615            .is_empty());
2616        assert!(tracker
2617            .get_safety_violations()
2618            .expect("Should get safety violations")
2619            .is_empty());
2620        assert!(tracker
2621            .get_c_library_stats()
2622            .expect("Should get C library stats")
2623            .is_empty());
2624    }
2625
2626    #[test]
2627    fn test_unsafe_ffi_tracker_default() {
2628        let tracker = UnsafeFFITracker::default();
2629
2630        // Verify default state
2631        assert!(tracker
2632            .get_enhanced_allocations()
2633            .expect("Should get enhanced allocations after reset")
2634            .is_empty());
2635        assert!(tracker
2636            .get_safety_violations()
2637            .expect("Should get safety violations after reset")
2638            .is_empty());
2639    }
2640
2641    #[test]
2642    fn test_track_unsafe_allocation() {
2643        let tracker = create_test_tracker();
2644        let ptr = 0x1000;
2645        let size = 1024;
2646        let location = "test_file.rs:42:10".to_string();
2647
2648        let result = tracker.track_unsafe_allocation(ptr, size, location.clone());
2649        assert!(result.is_ok());
2650
2651        // Verify allocation was tracked
2652        let allocations = tracker.get_enhanced_allocations().unwrap();
2653        assert_eq!(allocations.len(), 1);
2654
2655        let allocation = &allocations[0];
2656        assert_eq!(allocation.base.ptr, ptr);
2657        assert_eq!(allocation.base.size, size);
2658
2659        // Verify it's marked as unsafe
2660        match &allocation.source {
2661            AllocationSource::UnsafeRust {
2662                unsafe_block_location,
2663                ..
2664            } => {
2665                assert_eq!(unsafe_block_location, &location);
2666            }
2667            _ => panic!("Expected UnsafeRust allocation source"),
2668        }
2669    }
2670
2671    #[test]
2672    fn test_track_ffi_allocation() {
2673        let tracker = create_test_tracker();
2674        let ptr = 0x2000;
2675        let size = 512;
2676        let library_name = "libc".to_string();
2677        let function_name = "malloc".to_string();
2678
2679        let result =
2680            tracker.track_ffi_allocation(ptr, size, library_name.clone(), function_name.clone());
2681        assert!(result.is_ok());
2682
2683        // Verify allocation was tracked
2684        let allocations = tracker.get_enhanced_allocations().unwrap();
2685        assert_eq!(allocations.len(), 1);
2686
2687        let allocation = &allocations[0];
2688        assert_eq!(allocation.base.ptr, ptr);
2689        assert_eq!(allocation.base.size, size);
2690        assert!(allocation.ffi_tracked);
2691
2692        // Verify it's marked as FFI
2693        match &allocation.source {
2694            AllocationSource::FfiC {
2695                resolved_function, ..
2696            } => {
2697                assert_eq!(resolved_function.library_name, library_name);
2698                assert_eq!(resolved_function.function_name, function_name);
2699            }
2700            _ => panic!("Expected FfiC allocation source"),
2701        }
2702    }
2703
2704    #[test]
2705    fn test_track_enhanced_deallocation_valid() {
2706        let tracker = create_test_tracker();
2707        let ptr = 0x3000;
2708        let size = 256;
2709
2710        // First track an allocation
2711        tracker
2712            .track_unsafe_allocation(ptr, size, "test_location".to_string())
2713            .unwrap();
2714
2715        // Then deallocate it
2716        let result = tracker.track_enhanced_deallocation(ptr);
2717        assert!(result.is_ok());
2718
2719        // Verify allocation was removed
2720        let allocations = tracker.get_enhanced_allocations().unwrap();
2721        assert!(allocations.is_empty());
2722    }
2723
2724    #[test]
2725    fn test_track_enhanced_deallocation_invalid_free() {
2726        let tracker = create_test_tracker();
2727        let ptr = 0x4000;
2728
2729        // Try to free a pointer that was never allocated
2730        let result = tracker.track_enhanced_deallocation(ptr);
2731        assert!(result.is_err());
2732
2733        // Verify violation was recorded
2734        let violations = tracker.get_safety_violations().unwrap();
2735        assert_eq!(violations.len(), 1);
2736
2737        match &violations[0] {
2738            SafetyViolation::InvalidFree {
2739                attempted_pointer, ..
2740            } => {
2741                assert_eq!(*attempted_pointer, ptr);
2742            }
2743            _ => panic!("Expected InvalidFree violation"),
2744        }
2745    }
2746
2747    #[test]
2748    fn test_track_enhanced_deallocation_double_free() {
2749        let tracker = create_test_tracker();
2750        let ptr = 0x5000;
2751        let size = 128;
2752
2753        // Track allocation
2754        tracker
2755            .track_unsafe_allocation(ptr, size, "test_location".to_string())
2756            .unwrap();
2757
2758        // First deallocation (should succeed)
2759        let result1 = tracker.track_enhanced_deallocation(ptr);
2760        assert!(result1.is_ok());
2761
2762        // Second deallocation (should fail with double free)
2763        let result2 = tracker.track_enhanced_deallocation(ptr);
2764        assert!(result2.is_err());
2765
2766        // Verify double free violation was recorded
2767        let violations = tracker.get_safety_violations().unwrap();
2768        assert_eq!(violations.len(), 1);
2769
2770        match &violations[0] {
2771            SafetyViolation::DoubleFree { .. } => {
2772                // Expected
2773            }
2774            _ => panic!("Expected DoubleFree violation"),
2775        }
2776    }
2777
2778    #[test]
2779    fn test_record_boundary_event() {
2780        let tracker = create_test_tracker();
2781        let ptr = 0x6000;
2782        let size = 1024;
2783
2784        // Track allocation first
2785        tracker
2786            .track_unsafe_allocation(ptr, size, "test_location".to_string())
2787            .unwrap();
2788
2789        // Record boundary event
2790        let result = tracker.record_boundary_event(
2791            ptr,
2792            BoundaryEventType::RustToFfi,
2793            "rust_context".to_string(),
2794            "ffi_context".to_string(),
2795        );
2796        assert!(result.is_ok());
2797
2798        // Verify event was recorded
2799        let allocations = tracker.get_enhanced_allocations().unwrap();
2800        assert_eq!(allocations.len(), 1);
2801
2802        let allocation = &allocations[0];
2803        assert_eq!(allocation.cross_boundary_events.len(), 1);
2804
2805        let event = &allocation.cross_boundary_events[0];
2806        assert!(matches!(event.event_type, BoundaryEventType::RustToFfi));
2807        assert_eq!(event.from_context, "rust_context");
2808        assert_eq!(event.to_context, "ffi_context");
2809    }
2810
2811    #[test]
2812    fn test_register_c_library() {
2813        let tracker = create_test_tracker();
2814        let library_name = "test_lib".to_string();
2815        let library_path = Some("/usr/lib/libtest.so".to_string());
2816        let library_version = Some("1.0.0".to_string());
2817
2818        let result = tracker.register_c_library(
2819            library_name.clone(),
2820            library_path.clone(),
2821            library_version.clone(),
2822        );
2823        assert!(result.is_ok());
2824
2825        // Verify library was registered
2826        let libraries = tracker.get_c_library_stats().unwrap();
2827        assert_eq!(libraries.len(), 1);
2828
2829        let library = libraries.get(&library_name).unwrap();
2830        assert_eq!(library.library_name, library_name);
2831        assert_eq!(library.library_path, library_path);
2832        assert_eq!(library.library_version, library_version);
2833        assert_eq!(library.total_allocations, 0);
2834        assert_eq!(library.total_bytes_allocated, 0);
2835    }
2836
2837    #[test]
2838    fn test_track_c_function_call() {
2839        let tracker = create_test_tracker();
2840        let library_name = "libc";
2841        let function_name = "malloc";
2842        let allocation_size = 1024;
2843        let execution_time_ns = 500;
2844
2845        let result = tracker.track_c_function_call(
2846            library_name,
2847            function_name,
2848            allocation_size,
2849            execution_time_ns,
2850        );
2851        assert!(result.is_ok());
2852
2853        // Verify function call was tracked
2854        let libraries = tracker.get_c_library_stats().unwrap();
2855        assert_eq!(libraries.len(), 1);
2856
2857        let library = libraries.get(library_name).unwrap();
2858        assert_eq!(library.total_allocations, 1);
2859        assert_eq!(library.total_bytes_allocated, allocation_size);
2860
2861        let function = library.functions_called.get(function_name).unwrap();
2862        assert_eq!(function.call_count, 1);
2863        assert_eq!(function.bytes_allocated, allocation_size);
2864        assert_eq!(function.average_allocation_size, allocation_size as f64);
2865        assert_eq!(
2866            function.performance_metrics.avg_execution_time_ns,
2867            execution_time_ns
2868        );
2869    }
2870
2871    #[test]
2872    fn test_install_enhanced_libc_hook() {
2873        let tracker = create_test_tracker();
2874        let function_name = "malloc".to_string();
2875        let hook_method = HookInstallationMethod::Preload;
2876
2877        let result = tracker.install_enhanced_libc_hook(function_name.clone(), hook_method);
2878        assert!(result.is_ok());
2879
2880        // Verify hook was installed
2881        let hooks = tracker.get_libc_hook_info().unwrap();
2882        assert_eq!(hooks.len(), 1);
2883
2884        let hook = hooks.get(&function_name).unwrap();
2885        assert_eq!(hook.base_info.original_function, function_name);
2886        assert!(matches!(
2887            hook.installation_details.installation_method,
2888            HookInstallationMethod::Preload
2889        ));
2890        assert!(hook.installation_details.installation_success);
2891    }
2892
2893    #[test]
2894    fn test_create_and_register_passport() {
2895        let tracker = create_test_tracker();
2896        let ptr = 0x7000;
2897        let origin_context = "rust_main";
2898        let security_clearance = SecurityClearance::Public;
2899
2900        let result = tracker.create_and_register_passport(ptr, origin_context, security_clearance);
2901        assert!(result.is_ok());
2902
2903        let passport_id = result.unwrap();
2904        assert!(!passport_id.is_empty());
2905
2906        // Verify passport was created
2907        let passports = tracker.get_memory_passports().unwrap();
2908        assert_eq!(passports.len(), 1);
2909
2910        let passport = passports.get(&ptr).unwrap();
2911        assert_eq!(passport.passport_id, passport_id);
2912        assert_eq!(passport.origin.context, origin_context);
2913        assert!(matches!(
2914            passport.security_clearance,
2915            SecurityClearance::Public
2916        ));
2917        assert!(matches!(passport.validity_status, ValidityStatus::Valid));
2918    }
2919
2920    #[test]
2921    fn test_stamp_passport() {
2922        let tracker = create_test_tracker();
2923        let ptr = 0x8000;
2924
2925        // Create passport first
2926        tracker
2927            .create_and_register_passport(ptr, "rust_main", SecurityClearance::Public)
2928            .unwrap();
2929
2930        // Stamp the passport
2931        let result =
2932            tracker.stamp_passport(ptr, "memory_access", "ffi_boundary", "UnsafeFFITracker");
2933        assert!(result.is_ok());
2934
2935        // Verify stamp was added
2936        let passports = tracker.get_memory_passports().unwrap();
2937        let passport = passports.get(&ptr).unwrap();
2938        assert_eq!(passport.journey.len(), 1);
2939
2940        let stamp = &passport.journey[0];
2941        assert_eq!(stamp.operation, "memory_access");
2942        assert_eq!(stamp.location, "ffi_boundary");
2943        assert_eq!(stamp.authority, "UnsafeFFITracker");
2944    }
2945
2946    #[test]
2947    fn test_transfer_passport_ownership() {
2948        let tracker = create_test_tracker();
2949        let ptr = 0x9000;
2950
2951        // Create passport first
2952        tracker
2953            .create_and_register_passport(ptr, "rust_main", SecurityClearance::Public)
2954            .unwrap();
2955
2956        // Transfer ownership
2957        let result = tracker.transfer_passport_ownership(ptr, "ffi_context", "malloc");
2958        assert!(result.is_ok());
2959
2960        // Verify ownership was transferred
2961        let passports = tracker.get_memory_passports().unwrap();
2962        let passport = passports.get(&ptr).unwrap();
2963        assert_eq!(passport.current_owner.owner_context, "ffi_context");
2964        assert_eq!(passport.current_owner.owner_function, "malloc");
2965
2966        // Verify transfer was recorded in journey
2967        assert_eq!(passport.journey.len(), 1);
2968        assert_eq!(passport.journey[0].operation, "ownership_transfer");
2969    }
2970
2971    #[test]
2972    fn test_revoke_passport() {
2973        let tracker = create_test_tracker();
2974        let ptr = 0xa000;
2975
2976        // Create passport first
2977        tracker
2978            .create_and_register_passport(ptr, "rust_main", SecurityClearance::Public)
2979            .unwrap();
2980
2981        // Revoke passport
2982        let result = tracker.revoke_passport(ptr, "memory_freed");
2983        assert!(result.is_ok());
2984
2985        // Verify passport was revoked
2986        let passports = tracker.get_memory_passports().unwrap();
2987        let passport = passports.get(&ptr).unwrap();
2988        assert!(matches!(passport.validity_status, ValidityStatus::Revoked));
2989
2990        // Verify revocation was recorded in journey
2991        assert_eq!(passport.journey.len(), 1);
2992        assert!(passport.journey[0].operation.contains("revoked"));
2993    }
2994
2995    #[test]
2996    fn test_validate_passport() {
2997        let tracker = create_test_tracker();
2998        let ptr = 0xb000;
2999
3000        // Track allocation first to make validation work properly
3001        tracker
3002            .track_unsafe_allocation(ptr, 1024, "test_location".to_string())
3003            .unwrap();
3004
3005        // Create passport for the allocation
3006        tracker
3007            .create_or_update_passport(ptr, "create", "rust_main")
3008            .unwrap();
3009
3010        // Validate passport
3011        let result = tracker.validate_passport(ptr);
3012        assert!(result.is_ok());
3013        let is_valid = result.unwrap();
3014        assert!(is_valid);
3015
3016        // Verify passport was created and is valid in enhanced_allocations
3017        let allocations = tracker.get_enhanced_allocations().unwrap();
3018        assert_eq!(allocations.len(), 1);
3019        let allocation = &allocations[0];
3020        assert!(allocation.memory_passport.is_some());
3021        let passport = allocation.memory_passport.as_ref().unwrap();
3022        assert!(matches!(passport.validity_status, ValidityStatus::Valid));
3023
3024        // Test validation with non-existent pointer
3025        let result = tracker.validate_passport(0xdead);
3026        assert!(result.is_ok());
3027        assert!(!result.unwrap()); // Should return false for non-existent allocation
3028
3029        // Test passport functionality with memory_passports registry
3030        let ptr2 = 0xc000;
3031        tracker
3032            .create_and_register_passport(ptr2, "rust_main", SecurityClearance::Public)
3033            .unwrap();
3034
3035        // Verify passport was created in memory_passports
3036        let passports = tracker.get_memory_passports().unwrap();
3037        assert_eq!(passports.len(), 1);
3038        let passport = passports.get(&ptr2).unwrap();
3039        assert!(matches!(passport.validity_status, ValidityStatus::Valid));
3040
3041        // Revoke passport in memory_passports
3042        tracker.revoke_passport(ptr2, "test_revocation").unwrap();
3043        let passports = tracker.get_memory_passports().unwrap();
3044        let passport = passports.get(&ptr2).unwrap();
3045        assert!(matches!(passport.validity_status, ValidityStatus::Revoked));
3046    }
3047
3048    #[test]
3049    fn test_detect_leaks() {
3050        let tracker = create_test_tracker();
3051        let ptr = 0xc000;
3052        let size = 1024;
3053
3054        // Track allocation
3055        tracker
3056            .track_unsafe_allocation(ptr, size, "test_location".to_string())
3057            .unwrap();
3058
3059        // Wait a bit to ensure allocation age exceeds threshold
3060        std::thread::sleep(std::time::Duration::from_millis(10));
3061
3062        // Detect leaks with very low threshold (should detect the allocation)
3063        let result = tracker.detect_leaks(1); // 1ms threshold
3064        assert!(result.is_ok());
3065
3066        let leaks = result.unwrap();
3067        // The leak detection might not always detect leaks immediately due to timing
3068        // So we check if we have leaks or if the allocation is still active
3069        if !leaks.is_empty() {
3070            match &leaks[0] {
3071                SafetyViolation::PotentialLeak { .. } => {
3072                    // Expected
3073                }
3074                _ => panic!("Expected PotentialLeak violation"),
3075            }
3076        } else {
3077            // If no leaks detected, verify allocation is still active
3078            let allocations = tracker.get_enhanced_allocations().unwrap();
3079            assert_eq!(allocations.len(), 1);
3080            assert!(allocations[0].base.is_active());
3081        }
3082    }
3083
3084    #[test]
3085    fn test_analyze_cross_boundary_risks() {
3086        let tracker = create_test_tracker();
3087        let ptr = 0xd000;
3088
3089        // Create passport with many boundary crossings
3090        tracker
3091            .create_and_register_passport(ptr, "rust_main", SecurityClearance::Public)
3092            .unwrap();
3093
3094        // Add many stamps to simulate frequent boundary crossings
3095        for i in 0..15 {
3096            tracker
3097                .stamp_passport(ptr, &format!("operation_{i}"), "boundary", "test")
3098                .unwrap();
3099        }
3100
3101        // Analyze risks
3102        let result = tracker.analyze_cross_boundary_risks();
3103        assert!(result.is_ok());
3104
3105        let risks = result.unwrap();
3106        assert!(!risks.is_empty());
3107
3108        // Should detect frequent boundary crossings
3109        let has_boundary_risk = risks
3110            .iter()
3111            .any(|risk| matches!(risk, SafetyViolation::CrossBoundaryRisk { .. }));
3112        assert!(has_boundary_risk);
3113    }
3114
3115    #[test]
3116    fn test_get_stats() {
3117        let tracker = create_test_tracker();
3118
3119        // Track some operations
3120        tracker
3121            .track_unsafe_allocation(0x1000, 1024, "unsafe_block".to_string())
3122            .unwrap();
3123        tracker
3124            .track_ffi_allocation(0x2000, 512, "libc".to_string(), "malloc".to_string())
3125            .unwrap();
3126
3127        // Get stats
3128        let stats = tracker.get_stats();
3129
3130        assert_eq!(stats.total_operations, 2);
3131        assert_eq!(stats.unsafe_blocks, 1);
3132        assert_eq!(stats.ffi_calls, 1);
3133        assert_eq!(stats.memory_violations, 0);
3134        assert!(stats.risk_score > 0.0);
3135        assert_eq!(stats.operations.len(), 2);
3136    }
3137
3138    #[test]
3139    fn test_boundary_event_statistics() {
3140        let tracker = create_test_tracker();
3141        let ptr = 0xe000;
3142
3143        // Track allocation and boundary events
3144        tracker
3145            .track_unsafe_allocation(ptr, 1024, "test_location".to_string())
3146            .unwrap();
3147        tracker
3148            .record_boundary_event(
3149                ptr,
3150                BoundaryEventType::RustToFfi,
3151                "rust".to_string(),
3152                "ffi".to_string(),
3153            )
3154            .unwrap();
3155        tracker
3156            .record_boundary_event(
3157                ptr,
3158                BoundaryEventType::FfiToRust,
3159                "ffi".to_string(),
3160                "rust".to_string(),
3161            )
3162            .unwrap();
3163
3164        // Get statistics
3165        let result = tracker.get_boundary_event_statistics();
3166        assert!(result.is_ok());
3167
3168        let stats = result.unwrap();
3169        assert_eq!(stats.total_events, 2);
3170        assert!(stats.events_by_type.contains_key("RustToFfi"));
3171        assert!(stats.events_by_type.contains_key("FfiToRust"));
3172        assert!(stats.average_transfer_size > 0.0);
3173        assert!(stats.total_transfer_volume > 0);
3174    }
3175
3176    #[test]
3177    fn test_risk_level_serialization() {
3178        let risk_levels = vec![
3179            RiskLevel::Low,
3180            RiskLevel::Medium,
3181            RiskLevel::High,
3182            RiskLevel::Critical,
3183        ];
3184
3185        for risk_level in risk_levels {
3186            let serialized = serde_json::to_string(&risk_level).expect("Failed to serialize");
3187            let _deserialized: RiskLevel =
3188                serde_json::from_str(&serialized).expect("Failed to deserialize");
3189        }
3190    }
3191
3192    #[test]
3193    fn test_boundary_event_type_serialization() {
3194        let event_types = vec![
3195            BoundaryEventType::RustToFfi,
3196            BoundaryEventType::FfiToRust,
3197            BoundaryEventType::OwnershipTransfer,
3198            BoundaryEventType::SharedAccess,
3199        ];
3200
3201        for event_type in event_types {
3202            let serialized = serde_json::to_string(&event_type).expect("Failed to serialize");
3203            let _deserialized: BoundaryEventType =
3204                serde_json::from_str(&serialized).expect("Failed to deserialize");
3205        }
3206    }
3207
3208    #[test]
3209    fn test_security_clearance_serialization() {
3210        let clearances = vec![
3211            SecurityClearance::Public,
3212            SecurityClearance::Restricted,
3213            SecurityClearance::Confidential,
3214            SecurityClearance::Secret,
3215        ];
3216
3217        for clearance in clearances {
3218            let serialized = serde_json::to_string(&clearance).expect("Failed to serialize");
3219            let _deserialized: SecurityClearance =
3220                serde_json::from_str(&serialized).expect("Failed to deserialize");
3221        }
3222    }
3223
3224    #[test]
3225    fn test_global_tracker_initialization() {
3226        let tracker1 = init_global_unsafe_tracker();
3227        let tracker2 = init_global_unsafe_tracker();
3228
3229        // Should return the same instance
3230        assert!(Arc::ptr_eq(&tracker1, &tracker2));
3231    }
3232
3233    #[test]
3234    fn test_memory_protection_flags() {
3235        let flags = MemoryProtectionFlags {
3236            readable: true,
3237            writable: true,
3238            executable: false,
3239            shared: false,
3240        };
3241
3242        assert!(flags.readable);
3243        assert!(flags.writable);
3244        assert!(!flags.executable);
3245        assert!(!flags.shared);
3246    }
3247
3248    #[test]
3249    fn test_allocation_metadata() {
3250        let metadata = AllocationMetadata {
3251            requested_size: 1024,
3252            actual_size: 1024,
3253            alignment: 8,
3254            allocator_info: "test_allocator".to_string(),
3255            protection_flags: Some(MemoryProtectionFlags {
3256                readable: true,
3257                writable: true,
3258                executable: false,
3259                shared: false,
3260            }),
3261        };
3262
3263        assert_eq!(metadata.requested_size, 1024);
3264        assert_eq!(metadata.actual_size, 1024);
3265        assert_eq!(metadata.alignment, 8);
3266        assert!(metadata.protection_flags.is_some());
3267    }
3268
3269    #[test]
3270    fn test_comprehensive_workflow() {
3271        let tracker = create_test_tracker();
3272
3273        // Register a C library
3274        tracker
3275            .register_c_library(
3276                "test_lib".to_string(),
3277                Some("/lib/libtest.so".to_string()),
3278                Some("1.0".to_string()),
3279            )
3280            .unwrap();
3281
3282        // Track various allocations
3283        let ptr1 = 0x10000;
3284        let ptr2 = 0x20000;
3285
3286        tracker
3287            .track_unsafe_allocation(ptr1, 1024, "unsafe_block".to_string())
3288            .unwrap();
3289        tracker
3290            .track_ffi_allocation(ptr2, 512, "test_lib".to_string(), "test_malloc".to_string())
3291            .unwrap();
3292
3293        // Create passports
3294        tracker
3295            .create_and_register_passport(ptr1, "rust_main", SecurityClearance::Public)
3296            .unwrap();
3297        tracker
3298            .create_and_register_passport(ptr2, "ffi_lib", SecurityClearance::Restricted)
3299            .unwrap();
3300
3301        // Record boundary events
3302        tracker
3303            .record_boundary_event(
3304                ptr1,
3305                BoundaryEventType::RustToFfi,
3306                "rust".to_string(),
3307                "ffi".to_string(),
3308            )
3309            .unwrap();
3310
3311        // Track function calls
3312        tracker
3313            .track_c_function_call("test_lib", "test_malloc", 512, 1000)
3314            .unwrap();
3315
3316        // Install hooks
3317        tracker
3318            .install_enhanced_libc_hook("malloc".to_string(), HookInstallationMethod::Preload)
3319            .unwrap();
3320
3321        // Verify comprehensive state
3322        let allocations = tracker.get_enhanced_allocations().unwrap();
3323        assert_eq!(allocations.len(), 2);
3324
3325        let libraries = tracker.get_c_library_stats().unwrap();
3326        assert_eq!(libraries.len(), 1);
3327
3328        let passports = tracker.get_memory_passports().unwrap();
3329        assert_eq!(passports.len(), 2);
3330
3331        let hooks = tracker.get_libc_hook_info().unwrap();
3332        assert_eq!(hooks.len(), 1);
3333
3334        let stats = tracker.get_stats();
3335        assert_eq!(stats.total_operations, 2);
3336        assert_eq!(stats.unsafe_blocks, 1);
3337        assert_eq!(stats.ffi_calls, 1);
3338
3339        // Clean up
3340        tracker.track_enhanced_deallocation(ptr1).unwrap();
3341        tracker.track_enhanced_deallocation(ptr2).unwrap();
3342
3343        let final_allocations = tracker.get_enhanced_allocations().unwrap();
3344        assert!(final_allocations.is_empty());
3345    }
3346}