Skip to content

Many possible unsound public functions #36

@charlesxsh

Description

@charlesxsh

src/utils/vk_convert.rs

...
pub fn new_vk_array<R : VkRawType<W>, W>(length: u32, ptr: *const R) -> Vec<W> {
    unsafe {
        let len = length as usize;
        let mut vector : Vec<W> = Vec::with_capacity(len);

        for i in 0..len {
            vector.push(R::vk_to_wrapped(&*ptr.add(i)));
        }

        vector
    }
}
...
pub fn new_array<T : Copy>(length: u32, ptr: *const T) -> Vec<T> {
    unsafe {
        let len = length as usize;
        let mut vector : Vec<T> = Vec::with_capacity(len);

        for i in 0..len {
            vector.push(*ptr.add(i));
        }

        vector
    }
}
...
pub fn new_string_vec(length: u32, ptr: *const *const c_char) -> Vec<String> {
    let len = length as usize;
    let mut result : Vec<String> = Vec::with_capacity(len);

    for i in 0..len {
        result.push(new_string(unsafe { *ptr.add(i) }));
    }

    result
}
...
pub fn new_string_ref_vec<'a>(length: u32, ptr: *const *const c_char) -> Vec<&'a str> {
    let len = length as usize;
    let mut result : Vec<&'a str> = Vec::with_capacity(len);

    for i in 0..len {
        result.push(new_string_ref(unsafe { *ptr.add(i) }));
    }

    result
}
...
pub fn new_string_ref<'a>(ptr: *const c_char) -> &'a str {
    unsafe {
        if ptr.is_null() {
                ""
        } else {
            let len = std::ffi::CStr::from_ptr(ptr).to_bytes().len();
            let slice = std::slice::from_raw_parts(ptr as *const u8, len);

            std::str::from_utf8_unchecked(slice)
        }
    }
}

In vk_convert.rs:

  • function new_vk_array, new_array, new_string_vec, new_string_ref_vec are taking a pointer parameter and use in pointer calculation and dereference without sufficient checks.
  • function new_string_ref are transferring a pointer to utf8 without validating.

src/utils/vk_ptr.rs

...
pub fn free_vk_ptr_array<T : VkFree>(size: usize, ptr: *mut T) {
    unsafe {
        if !ptr.is_null() {
            for i in 0..size {
                (&*ptr.add(i)).vk_free();
            }

            free_ptr(ptr);
        }
    }
}
...
pub fn free_vk_ptr_array_array<T : VkFree>(size: usize, ptr: *mut *mut T) {
    unsafe {
        if !ptr.is_null() {
            for i in 0..size {
                let addr = *ptr.add(i);
                (&*addr).vk_free();
            }

            free_ptr(ptr);
        }
    }
}

similiar things happened in function free_vk_ptr_array and free_vk_ptr_array_array.

In Rust, we should not cause memory issues or UB by merely using safe functions.

Suggestions:

  1. add sufficient check
  2. mark them with unsafe functions

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions