1 个不稳定版本
0.1.0 | 2020年3月25日 |
---|
#4 在 #auditing
11KB
75 行
为描述和审计 Rust 代码中 unsafe
代码的使用提供注解。
该包对 Rust 代码的编译或运行时行为没有影响。其目的是允许开发者使用信息来注解 Rust 代码,说明为什么使用不安全代码,并使自动审计使用不安全代码的代码库变得容易。
而不是这个
unsafe {
// Scary interop code:
let ptr: *mut libc::c_void = allocate_foreign_object();
use_foreign_object(ptr, 42);
free_foreign_object(ptr);
}
开发者可以这样做
use unsafety::{unsafe_because, USES_FOREIGN_CODE};
unsafe_because! {
USES_FOREIGN_CODE => {
// Scary interop code:
let ptr: *mut libc::c_void = allocate_foreign_object();
use_foreign_object(ptr, 42);
free_foreign_object(ptr);
}
}
类型安全和并发安全是 Rust 的关键优势。因为这些安全性属性依赖于系统中所有组件正确地尊重这些属性,即使是 unsafe 代码,因此,确保 unsafe 代码仍然是 正确 的代码至关重要。该包旨在帮助实现这一目标,通过允许开发者描述代码为什么这样做,尤其是关于 unsafe 代码的部分,并使审计这些描述变得容易。
标注原因
unsafe_because
宏要求您提供原因,并允许您提供额外的、可选的信息。您可以将以下内容添加到 unsafe_because
的任何调用中。 (所有这些都可以重复使用。)
reason.owner(""foo"")
:识别设计该部分的所有者或专家。reason.bug(""..."")
:bug 跟踪系统中的一个标识符。这通常是 URL 或 bug 编号。reason.link(""http://..."")
:指向任何相关网页的链接,例如设计文档。reason.tag(""key"", ""value"")
:允许您指定任意的键值对。
重用原因
为了避免重复相同的理由,可以将原因定义为常量并重复使用。当原因有注释时,这非常有用,因为每次使用时都需要重复这些注释。示例
use unsafety::{UnsafeReason, IMPLEMENTS_DEVICE_DRIVER, unsafe_because};
const IMPLEMENTS_FANCY_NETWORK_DRIVER: UnsafeReason = IMPLEMENTS_DEVICE_DRIVER
.bug("some_bug_link")
.owner("foo")
.owner("bar")
.link("https://.../some_design_doc.html");
unsafe_because! {
IMPLEMENTS_FANCY_NETWORK_DRIVER => {
// ...
}
}
unsafe_because! {
IMPLEMENTS_FANCY_NETWORK_DRIVER => {
// ... even more code ...
}
}
组合原因
有时候一个单独的 unsafe
块使用 unsafe
代码的理由不止一个。如果可能的话,开发者应该将这些块拆分成单独的块,并为它们提供各自的理由。然而,有时这是不可能的。unsafe_because!
允许你在一个方括号内提供一个理由列表。
示例
use unsafety::{PERFORMANCE, IMPLEMENTS_DEVICE_DRIVER, unsafe_because};
// Some code has more than one reason for requiring unsafe code.
unsafe_because! {
[PERFORMANCE, IMPLEMENTS_DEVICE_DRIVER] =>
println!("Super fast and scary (but correct) code goes here.");
}
待办事项
- 改进标准理由列表。
- 审计工具。
- 需要宏来定义不安全的特性和不安全函数签名,而不仅仅是 unsafe 代码块。
未来方向
可能某个版本的 Rust 可以验证特定的 集合 的 unsafe
使用符合某些要求。例如,可能允许在给定 crate 中出于访问设备驱动程序的原因使用不安全代码,但无其他原因。unsafe_because
允许开发者在开发一个大型、成熟的组件之后重新发现这一知识之前,现在就编码这一知识。