Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,14 @@ All submissions, including submissions by project members, require review. We
use GitHub pull requests for this purpose. Consult
[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
information on using pull requests.

### Unsafe code policy

* The use of `unsafe` code is generally disallowed. The Device Tree parser
must validate all input data, treating it as untrusted. This includes bounds
checking for all offsets and indices to prevent vulnerabilities.
* Should a compelling justification arise for the inclusion of `unsafe` code
(beyond performance optimization) it must be accompanied by
an `#[expect(unsafe_code)]` attribute, stating the rationale.
* All `unsafe` code must be tested. The CI suite includes Miri to detect any
undefined behavior.
6 changes: 6 additions & 0 deletions src/fdt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,12 @@ impl<'a> Fdt<'a> {
/// let ptr = dtb.as_ptr();
/// let fdt = unsafe { Fdt::from_raw(ptr).unwrap() };
/// ```
#[expect(
unsafe_code,
reason = "Having a methods that reads a Device Tree from a raw pointer is useful for \
embedded applications, where the binary only gets a pointer to DT from the firmware or \
a bootloader. The user must ensure it trusts the data."
)]
pub unsafe fn from_raw(data: *const u8) -> Result<Self, FdtError> {
// SAFETY: The caller guarantees that `data` is a valid pointer to a Flattened
// Device Tree (FDT) blob. We are reading an `FdtHeader` from this
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#![no_std]
#![warn(missing_docs, rustdoc::missing_crate_level_docs)]
#![deny(unsafe_code)]
#![cfg_attr(docsrs, feature(doc_cfg))]

#[cfg(feature = "write")]
Expand Down
15 changes: 13 additions & 2 deletions tests/fdt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
// except according to those terms.

use dtoolkit::fdt::Fdt;
#[cfg(feature = "write")]
use dtoolkit::model::DeviceTree;

#[test]
fn read_child_nodes() {
Expand Down Expand Up @@ -183,11 +185,20 @@ fn pretty_print() {
#[cfg(feature = "write")]
fn round_trip() {
for (dtb, _dts, name) in ALL_DT_FILES {
use dtoolkit::model::DeviceTree;

let fdt = Fdt::new(dtb).unwrap();
let ir = DeviceTree::from_fdt(&fdt).unwrap();
let new_dtb = ir.to_dtb();
assert_eq!(dtb.to_vec(), new_dtb, "Mismatch for {name}");
}
}

#[test]
#[cfg(feature = "write")]
fn round_trip_raw() {
for (dtb, _dts, name) in ALL_DT_FILES {
let fdt = unsafe { Fdt::from_raw(dtb.as_ptr()).unwrap() };
let ir = DeviceTree::from_fdt(&fdt).unwrap();
let new_dtb = ir.to_dtb();
assert_eq!(dtb.to_vec(), new_dtb, "Mismatch for {name}");
}
}