oreboot
oreboot copied to clipboard
Serialize and deserialize structs safely
There are a few places where we unnecessarily use unsafe blocks to serialize and deserialize structs:
In particular see https://github.com/oreboot/oreboot/blob/main/src/lib/uefi/src/lib.rs. For example:
let fveh: efi::EFI_FIRMWARE_VOLUME_EXT_HEADER =
unsafe { core::ptr::read(fveh_bytes.as_ptr() as *const _) };
Instead, we should be using some Rust macros to achieve this safely. There are a number of crates built for this task:
- https://serde.rs/ is obviously the most popular. Some of its flexibility gets in the way. We just need to be able to serialize/deserialize a struct in the same format as a packed C struct.
- https://github.com/xoac/endian_codec
- https://crates.io/crates/packed_struct
- ... (I have no strong opinions for a particular crate at the moment)
I saw a blog post recently about this: https://adventures.michaelfbryan.com/posts/deserializing-binary-data-files/
About the crates that can be used:
ssmarshal is surprisingly good for that (I'd give it 10 of 10 points)--but technically one would be using the crate for something it was not designed for (it's designed as a message format for a microkernel). It does work very well for general C struct serialization--and it's very easy to think about serialization that way (it's just using serde and serde derive).
zerocopy is the right way to do it; but boy is it annoying. I'm using zerocopy quite a lot nowadays regardless.
But really, if you don't care about endianness and the architectures are the same anyway, then just using repr(C) and no crates is fine.
packed_struct is also OK.
With the core library alone, is there a non-unsafe way to convert a &[u8] to a repr(C) struct?
The safe way I know how to do it is parse field-by-field like nom (supports no_std). You can also structure it to parse lazily with accessors (a la capnproto) if you want to avoid having original and deserialized versions in memory. These are not nearly as easy as transmutation.
TIL that there's a safe transmute working group.