Skip to content

Commit 6d2fd59

Browse files
authored
docs: add unsafe code policy (#10)
1 parent c167ed8 commit 6d2fd59

File tree

4 files changed

+31
-2
lines changed

4 files changed

+31
-2
lines changed

CONTRIBUTING.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,14 @@ All submissions, including submissions by project members, require review. We
3131
use GitHub pull requests for this purpose. Consult
3232
[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
3333
information on using pull requests.
34+
35+
### Unsafe code policy
36+
37+
* The use of `unsafe` code is generally disallowed. The Device Tree parser
38+
must validate all input data, treating it as untrusted. This includes bounds
39+
checking for all offsets and indices to prevent vulnerabilities.
40+
* Should a compelling justification arise for the inclusion of `unsafe` code
41+
(beyond performance optimization) it must be accompanied by
42+
an `#[expect(unsafe_code)]` attribute, stating the rationale.
43+
* All `unsafe` code must be tested. The CI suite includes Miri to detect any
44+
undefined behavior.

src/fdt/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,12 @@ impl<'a> Fdt<'a> {
216216
/// let ptr = dtb.as_ptr();
217217
/// let fdt = unsafe { Fdt::from_raw(ptr).unwrap() };
218218
/// ```
219+
#[expect(
220+
unsafe_code,
221+
reason = "Having a methods that reads a Device Tree from a raw pointer is useful for \
222+
embedded applications, where the binary only gets a pointer to DT from the firmware or \
223+
a bootloader. The user must ensure it trusts the data."
224+
)]
219225
pub unsafe fn from_raw(data: *const u8) -> Result<Self, FdtError> {
220226
// SAFETY: The caller guarantees that `data` is a valid pointer to a Flattened
221227
// Device Tree (FDT) blob. We are reading an `FdtHeader` from this

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
7575
#![no_std]
7676
#![warn(missing_docs, rustdoc::missing_crate_level_docs)]
77+
#![deny(unsafe_code)]
7778
#![cfg_attr(docsrs, feature(doc_cfg))]
7879

7980
#[cfg(feature = "write")]

tests/fdt.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
// except according to those terms.
88

99
use dtoolkit::fdt::Fdt;
10+
#[cfg(feature = "write")]
11+
use dtoolkit::model::DeviceTree;
1012

1113
#[test]
1214
fn read_child_nodes() {
@@ -183,11 +185,20 @@ fn pretty_print() {
183185
#[cfg(feature = "write")]
184186
fn round_trip() {
185187
for (dtb, _dts, name) in ALL_DT_FILES {
186-
use dtoolkit::model::DeviceTree;
187-
188188
let fdt = Fdt::new(dtb).unwrap();
189189
let ir = DeviceTree::from_fdt(&fdt).unwrap();
190190
let new_dtb = ir.to_dtb();
191191
assert_eq!(dtb.to_vec(), new_dtb, "Mismatch for {name}");
192192
}
193193
}
194+
195+
#[test]
196+
#[cfg(feature = "write")]
197+
fn round_trip_raw() {
198+
for (dtb, _dts, name) in ALL_DT_FILES {
199+
let fdt = unsafe { Fdt::from_raw(dtb.as_ptr()).unwrap() };
200+
let ir = DeviceTree::from_fdt(&fdt).unwrap();
201+
let new_dtb = ir.to_dtb();
202+
assert_eq!(dtb.to_vec(), new_dtb, "Mismatch for {name}");
203+
}
204+
}

0 commit comments

Comments
 (0)