code-423n4 / 2024-08-superposition-validation

0 stars 0 forks source link

Vulnerability in storage_load_bytes32 Function Due to Unsafe Pointer Handling #200

Closed c4-bot-6 closed 1 month ago

c4-bot-6 commented 1 month ago

Lines of code

https://github.com/code-423n4/2024-08-superposition/blob/4528c9d2dbe1550d2660dac903a8246076044905/pkg/leo/src/host.rs#L40

Vulnerability details

Summary

The storage_load_bytes32 function in the provided Rust code contains a vulnerability due to unsafe handling of raw pointers. This function reads a value from storage based on a provided key and writes the result to an output pointer. The lack of validation for pointer validity and alignment introduces the risk of undefined behavior, including memory corruption and potential crashes.

Vulnerability Detail

The storage_load_bytes32 function assumes that the raw pointers key and out are valid and correctly sized, and that they point to appropriately allocated and aligned memory. The function's reliance on these assumptions without any validation exposes it to several risks:

  1. Invalid Pointer Access: If key points to an invalid or incorrectly sized memory location, reading from this pointer using slice::from_raw_parts can result in undefined behavior.
  2. Incorrect Memory Alignment: The function writes 32 bytes of data to the location pointed to by out. If out is not properly aligned, this may cause runtime errors or inefficient memory access.
  3. Potential Memory Corruption: If out points to a memory region that is not writable, the write operation can corrupt memory or cause application crashes.

Code Snippet

The vulnerable code is as follows:

#[no_mangle]
pub unsafe extern "C" fn storage_load_bytes32(key: *const u8, out: *mut u8) {
    let key = unsafe { read_word(slice::from_raw_parts(key, WORD_BYTES)) };

    let value = STORAGE.with(|storage| {
        storage
            .borrow()
            .get(&key)
            .map(Word::to_owned)
            .unwrap_or_default()
    });

    unsafe { write_word(out, value) };
}

Key Points:

Impact

The impact of this vulnerability can be severe:

Recommendations

  1. Pointer Validity Checks: Implement checks to ensure that the pointers key and out are valid and properly allocated. Although this is challenging with raw pointers, consider validating input parameters before usage.

  2. Use Safe Abstractions: Where possible, replace raw pointer operations with safe Rust abstractions. For example, use slices and vectors instead of raw pointers, and consider using safer APIs or crates that abstract away unsafe operations.

  3. Document Assumptions: Clearly document the assumptions regarding pointer validity and alignment for users of the API. This will help in maintaining the correct usage and avoid misuse.

  4. Test Thoroughly: Ensure extensive testing of the function, especially with edge cases that might expose pointer-related issues. Implement additional unit tests to cover various scenarios.

  5. Review and Refactor: Regularly review and refactor code that uses unsafe operations. Consider adopting safer coding practices and modern Rust features to mitigate risks associated with unsafe code.

By addressing these recommendations, you can improve the safety and robustness of the storage_load_bytes32 function and reduce the risk of undefined behavior in the application.

Assessed type

DoS