Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Helper function to safely read structure from stream

Tags:

rust

osdev

Lets say we have an OS of single address space. To maintain stability we need to force memory protection for user applications, e.g. to forbid usage of 'unsafe' keyword unless user has a special capability.

Our users need to have a way to safely read/write arbitrary structures from/to byte streams (e.g. files). Of course we are talking about structures which don't contain references (otherwise we loose memory safety).

Now I tried to implement this kind of generic reader function:

#![feature(core)]

use std::io;
use std::mem;
use std::raw;

fn read<T>(reader: &mut io::Read, dest: &mut T) -> io::Result<usize> {
    let slice = raw::Slice{ data:dest, len:mem::size_of::<T>() };
    let buf: &mut [u8] = unsafe { mem::transmute(slice) };
    reader.read(buf)
}

The implementation above has a serious problem. It allows to read structures which contain references. So how can I fix that?

like image 709
ababo Avatar asked Apr 20 '26 00:04

ababo


1 Answers

You can use a so-called "Marker Trait": a custom unsafe trait with a default impl for all types and a negative trait impl for all references. Since you forbid all uses of unsafe, the user cannot implement the trait on their own, and therefore there cannot be an implementation of the trait for any type that has references.

You should probably also include raw pointers (*mut and *const) in the negative impls... otherwise the user could deserialize a Vec or some other "safe" type that has inner unsafety.

#![feature(optin_builtin_traits)]

unsafe trait NoInnerRefs {}

impl<'a, T> !NoInnerRefs for &'a T {}
unsafe impl NoInnerRefs for .. {}

struct A(&'static str);

struct B(i32);

fn test<T: NoInnerRefs>(_: T) {
}

fn main() {
    test(B(5));
    test(A("hi"));
}

This will fail to compile:

<anon>:17:5: 17:9 error: the trait `NoInnerRefs` is not implemented for the type `&'static str` [E0277]
<anon>:17     test(A("hi"));
              ^~~~
like image 146
oli_obk Avatar answered Apr 23 '26 14:04

oli_obk



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!