1个不稳定版本
0.1.0 | 2023年5月7日 |
---|
#38 在 #repr
用于 isrepr
40KB
1K SLoC
一个将任意内存安全转换为Rust类型的crate。
简介
想象你有一个枚举类型,如下所示
#[repr(u8)]
enum Foo {
FOO(u16, u32),
BAR,
BAZ(usize, *const ()),
}
比如说,你有一个指向该枚举的指针,它来自一个不可信的上下文,比如一个古怪的C API或者来自用户空间进程到你的内核
let foo: *const Foo = todo!()
虽然指针对齐很容易验证,但“不可信的上下文”意味着指针后面的内存可以是任意的。我们不能简单地将这样的内存转换为引用,因为 这样会导致未定义行为。
幸运的是,正确定义的 #[repr)]
类型的布局是 明确定义的。不幸的是,处理这种布局需要编写大量的模板代码,尤其是对于枚举。
这个crate为你处理模板代码,如下所示
use isrepr::{IsRepr, Repr, ReprError};
use core::convert::TryInto;
use core::mem::transmute;
#[derive(IsRepr, Clone, Copy, Debug, PartialEq, Eq)]
#[repr(u8)]
enum Foo {
FOO(u16, u32),
BAR,
BAZ(usize, *const ()),
}
// Repr<Foo> can have any memory contents.
fn bar(f_repr: Repr<Foo>) -> Result<Foo, ReprError> {
f_repr.repr_try_into()
}
fn main() {
// Pretend that we're some untrusted context.
let foo = bar(unsafe { transmute(Foo::BAR) }).unwrap();
assert_eq!(foo, Foo::BAR);
// Send an invalid value!
bar(unsafe { transmute(17u8) }).unwrap_err();
}
链接
依赖项
~1.5MB
~35K SLoC