Assessment reports>Pinocchio and p-token>High findings>Missing ,Copy, bound on ,copy_val, function
Category: Coding Mistakes

Missing Copy bound on copy_val function

High Impact
High Severity
High Likelihood

Description

The copy_val function takes two parameters of generic type T and copies bytes from src to dst.

#[inline]
pub fn copy_val<T: ?Sized>(dst: &mut T, src: &T) {
    #[cfg(target_os = "solana")]
    // SAFETY: dst and src are of same type therefore the size is the same
    unsafe {
        syscalls::sol_memcpy_(
            dst as *mut T as *mut u8,
            src as *const T as *const u8,
            core::mem::size_of_val(dst) as u64,
        );
    }

    #[cfg(not(target_os = "solana"))]
    core::hint::black_box((dst, src));
}

At first glance, this operation seems harmless, but it has the potential to break important invariants. For example, imagine a type that internally stores a unique identifier and intentionally does not implement Clone nor Copy. This function would allow creating two instances of that type with the same unique identifier, breaking the invariant.

In Rust, the Copy trait is used to indicate that a byte-by-byte copy of a type is a legal and safe operation. Therefore, for copy_val to be safe, it should require the Copy trait as a bound on T. This also has the additional effect of requiring that the type does not have a custom Drop implementation, meaning that it is not required to drop the instance in place before writing over dst.

Impact

This can be used to break invariants that are typically enforced on types without the Copy trait.

Recommendations

Require that T implements Copy.

Remediation

Zellic © 2025Back to top ↑