Git Product home page Git Product logo

buffer's People

Contributors

elrnv avatar

Watchers

 avatar  avatar

buffer's Issues

Unsoundness in `DataBuffer::push`

The source of unsoundness

pub fn push<T: Any>(&mut self, element: T) -> Option<&mut Self> {
        self.check_ref::<T>()?;
        let element_ref = &element;
        let element_byte_ptr = element_ref as *const T as *const u8;
        let element_byte_slice = unsafe { slice::from_raw_parts(element_byte_ptr, size_of::<T>()) };
        unsafe { self.push_bytes(element_byte_slice) }
    }

https://docs.rs/data-buffer/0.8.0/src/data_buffer/lib.rs.html#248-254
There are two unsoundness in the from_slice method. First of all, allocator and deallocator got different alignment on vector, which will lead to undefined behavior. Secondly, the code will call from_raw_parts to create a slice starting from raw pointer to u8. Based on the doc of slice::from_raw_parts:

data must be valid for reads for len * mem::size_of::() many bytes, and it must be properly aligned.

If caller of push passes a byte containing padding bytes as T, it can lead to uninitialized memory exposure because the slice is returned to caller.

To reproduce the bug

use data_buffer::DataBuffer;
use std::mem::align_of;

#[derive(Copy, Clone, Debug)]
pub struct A {
    a: i8,
    b: i32,
    c: i8,
}


fn main() {
    let sa = A { a: 10, b: 11, c: 12 };
    println!("align: {}", align_of::<A>());
    let struct_arr: [A; 10] = [sa; 10];
    let mut buf = DataBuffer::from_slice(&struct_arr);
    println!("{:?}", buf.push(sa));
}

Run with Miri,

error: Undefined Behavior: incorrect layout on deallocation: alloc2486 has size 80 and alignment 4, but gave size 80 and alignment 1

I also summarized backtrace information to help debug here (start from top to bottom here)

data_buffer::DataBuffer::push::<A>
data_buffer::DataBuffer::push_bytes
std::vec::Vec::<u8>::extend_from_slice
<std::vec::Vec<u8> as std::vec::spec_extend::SpecExtend<&u8, std::slice::Iter<'_, u8>>>::spec_extend
std::vec::Vec::<u8>::append_elements
std::vec::Vec::<u8>::reserve
alloc::raw_vec::RawVec::<u8>::reserve
alloc::raw_vec::RawVec::<T, A>::reserve::do_reserve_and_handle::<u8, std::alloc::Global>
alloc::raw_vec::RawVec::<u8>::grow_amortized
alloc::raw_vec::finish_grow::<std::alloc::Global>
<std::alloc::Global as std::alloc::Allocator>::grow
std::alloc::Global::grow_impl
std::alloc::realloc

Add typed data buffer

Currently the data buffer effectively erases the type of the data it contains. The only way to retrieve it is to check if a given type matches. This works for applications that use data buffer transiently, but it can be cumbersome to check each potential type when retrieving the data.

The proposal here is to provide some functionality to allow users to dictate what data is expected to be stored in the data buffer, and provide a simply lookup table for translating between their enum and concrete types.

This will hopefully transform type oblivious code from probing the data buffer for typed data to simply passing an enum and getting the type you need. I think the mechanism to do this may be tricky. So far this type of code was left up to the user, but the idea here is to move it into data buffer itself since there are so many different typed accessors (iter, as_slice, ...) that can be consolidated inside this crate.

TODO:

  • generate concrete use cases to demonstrate the problem
  • propose/implement (a) potential soution(s)
    • Include alternatives like manual use case specific solutions
    • Include dynamic a vanilla dispatch solution
  • compare pros and cons of solutions in terms of usability
  • compare performance (benchmarks)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.