3个版本 (破坏性更新)
0.3.0 | 2023年11月15日 |
---|---|
0.2.0 | 2021年11月1日 |
0.1.0 | 2021年8月5日 |
180 在 Unix API 中排名
每月下载量19,553
用于dbs-boot
58KB
937 行
vm-fdt
vm-fdt包提供将Flattened Devicetree blob写入到Devicetree规范中定义的功能。
在Crosvm和Firecracker等项目中,设备树用于在启动操作系统时指定虚拟机拓扑(内存、vcpu、缓存、中断等)。
设计
在vm-fdt中,我们定义并使用以下原语:
- FDT写入器(
FdtWriter
), - 节点(
FdtWriterNode
)和 - 属性(定义为键值对)。
FDT有一个或多个节点,每个节点可以可选地包含属性和子节点,从而形成一个树状结构。
FdtWriter
结构提供了一个适合在运行时动态生成Devicetree blob的接口。支持的运算包括:
- 创建节点。这是通过在
FdtWriter
上调用begin_node
来完成的。该调用返回一个类型为FdtWriterNode
的对象,我们可以设置属性(使用以下定义的property_*
函数),或添加子节点(通过嵌套调用begin_node
)。节点的属性只能添加在创建子节点之前(如规范中定义)。每个节点都必须通过调用end_node
函数来结束。 - 创建属性。属性是键值对,其中键是一个字符串,值是一个原始字节数组。为了使用方便,使得调用FDT接口的用户不需要创建原始字节数组,我们定义了以下常见属性类型的包装器:
property_null
(一个空属性)property_string
属性字符串列表
属性_u32
属性_u64
属性数组_u32
属性数组_u64
属性
(原始字节数组)
威胁模型
输入:调用 vm-fdt 公共接口的调用者是可信的。
输出:FDT blob 的内容位于内存中,且是可信的。此 crate 分配的内存与用户定义的节点和属性数量(通过 property*
和 begin_node
函数)成正比。
#NR | 威胁 | 缓解措施 |
---|---|---|
1 | 由于编程错误,FDT 代码导致大内存分配。 | vm-fdt 接口的操作者是可信的,内存分配与对公共 FDT 接口的调用次数成正比。在 vm-fdt 级别,blob 允许的最大大小为 4.3 GB。这是通过检查数据 blob 的长度是否适合 u32,以及 u32 的最大值为 4294967295(约 4.3 GB)来强制执行的。调用 vm-fdt 接口的调用者可以在调用 finish 函数时检查 FDT blob 的大小。 |
2 | 在初始化 FdtWriter 时传递大型内存预留数组会导致未定义行为。 | 检查内存预留的长度。所有基于输入的后续操作都检查溢出。 |
3 | 在初始化 FdtWriter 时传递重叠的内存预留会导致在客人内存中加载 blob 时出现未定义行为 | FDT 规范明确定义,内存预留条目不得重叠。这是由 FdtWriter 强制执行的,并在单元测试中检查。 |
用法
以下代码创建了一个具有根节点的 FDT blob,该根节点有 3 个属性(“compatible”、“#address-cells” 和 “#size-cells”),并包含 2 个子节点
- "chosen",它有 2 个属性(“linux,pci-probe-only” 和 “bootargs”)。
- "memory",它有一个属性(“device_type”)
以下是 FDT 的图形表示。
use vm_fdt::{FdtWriter, Error};
fn create_fdt() -> Result<Vec<u8>, Error> {
let mut fdt = FdtWriter::new()?;
let root_node = fdt.begin_node("root")?;
fdt.property_string("compatible", "linux,dummy-virt")?;
fdt.property_u32("#address-cells", 0x2)?;
fdt.property_u32("#size-cells", 0x2)?;
let chosen_node = fdt.begin_node("chosen")?;
fdt.property_u32("linux,pci-probe-only", 1)?;
fdt.property_string("bootargs", "panic=-1 console=hvc0")?;
fdt.end_node(chosen_node)?;
let memory_node = fdt.begin_node("memory")?;
fdt.property_string("device_type", "memory")?;
fdt.end_node(memory_node)?;
fdt.end_node(root_node)?;
fdt.finish()
}
特性
此 crate 定义了一个开发特性:long_running_test
。此特性不应在生产中使用,因为它可能会启用仅在开发用例中安全的函数。
许可证
本项目许可采用以下之一
- Apache 许可证,版本 2.0
- BSD-3-Clause 许可证
依赖项
~0–435KB