flaneur2020 / pua-lang

a dialect of The Monkey Programming Language
MIT License
3.28k stars 125 forks source link

dealloc Function Causes Undefined Behavior Due to Improper Use of Vec::from_raw_parts #76

Closed lwz23 closed 2 days ago

lwz23 commented 4 days ago

Description The dealloc function contains an unsound implementation that can lead to undefined behavior. Specifically, the issue arises from the improper use of Vec::from_raw_parts to deallocate memory. https://github.com/flaneur2020/pua-lang/blob/cbaf8e2ca1abc3797c332afcc9103c567ee16002/src/wasm/main.rs#L61

pub fn dealloc(ptr: *mut c_void, size: usize) {
    unsafe {
        let _buf = Vec::from_raw_parts(ptr, 0, size);
    }
}

Problem: Vec::from_raw_parts assumes the pointer is valid: The function assumes the provided pointer is a valid, non-null pointer previously allocated by a Rust allocator. If ptr was not allocated using the Rust allocator (e.g., allocated via a foreign allocator or system calls), calling Vec::from_raw_parts is undefined behavior.

Steps to Reproduce: Provide a foreign-allocated pointer (e.g., using malloc or other allocators) to dealloc, as shown below:

use std::ffi::c_void;

extern "C" {
    fn malloc(size: usize) -> *mut c_void;
    fn free(ptr: *mut c_void);
}

pub fn dealloc(ptr: *mut c_void, size: usize) {
    unsafe {
        let _buf = Vec::from_raw_parts(ptr, 0, size);
    }
}

fn main() {
    unsafe {
        let ptr = malloc(10);
        dealloc(ptr, 10); // Undefined Behavior!
        free(ptr); // Double free or invalid free if `dealloc` already caused UB.
    }
}

Result

PS E:\Github\lwz> cargo run
   Compiling lwz v0.1.0 (E:\Github\lwz)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.57s
     Running `target\debug\lwz.exe`
error: process didn't exit successfully: `target\debug\lwz.exe` (exit code: 0xc0000374, STATUS_HEAP_CORRUPTION)
PS E:\Github\lwz>

Additional Context: Improper use of unsafe functions like Vec::from_raw_parts can lead to serious issues in safety-critical applications. Ensuring correctness when dealing with raw pointers and unsafe code is crucial in Rust to maintain memory safety guarantees.

flaneur2020 commented 3 days ago

thank you for the feedback!

would you mind raising a PR for this? sorry i'm not very familiar with wasm.. would appreciate some help on it

lwz23 commented 3 days ago

Okay, I'll try to fix it :)