#repr #memory #validation #no-alloc

no-std isrepr

从任意内存生成 repr(C) 类型的验证

1 个不稳定版本

0.1.0 2023年5月7日

Rust 模式 中排名第 2840

MIT 许可证

40KB
758 行(不包括注释)

一个将任意内存安全转换为 Rust 类型的 crate。

简介

想象你有一个枚举类型,如下所示

#[repr(C)]
enum Foo {
    FOO(u16, u32),
    BAR,
    BAZ(usize, *const ()),
}

假设你有一个指向该枚举的指针,它来自不受信任的上下文,如糟糕的 C API 或从用户空间进程到你的内核

let foo: *const Foo = todo!()

虽然指针对齐很容易验证,但“不受信任的上下文”意味着指针后面的内存可以是任意的。我们不能简单地将这样的指针转换为内存引用,因为这可能导致未定义的行为。

幸运的是,正确定义的 #[repr(C)] 类型的布局是 明确定义的。不幸的是,处理这种布局需要编写大量的样板代码,特别是对于枚举。

此 crate 为你处理了这些样板代码,如下所示

use isrepr::{IsRepr, Repr, ReprError};
use core::convert::TryInto;
use core::mem::transmute;

#[derive(IsRepr, Clone, Copy, Debug, PartialEq, Eq)]
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
~36K SLoC