From 4d9d21391a3e1d662c7eaf84d0cef092c9fe667f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Ma=C4=87kowski?= Date: Thu, 22 Oct 2026 11:33:03 +0000 Subject: [PATCH] fix(fdt_mut): use correct slice length on FdtMut=>Fdt conversion `Fdt` assumes that `data.len() == totalsize`. If the slice capacity is bigger than the FDT blob itself, this breaks the assumption. This commit ensures the slice passed to `Fdt` is exactly `totalsize` bytes long. This mainly affects `Fdt::data()` which could return garbage data after the end of the FDT blob. --- src/fdt_mut.rs | 4 +--- src/fdt_mut/buffer.rs | 17 ++++++++++++----- tests/fdt_mut.rs | 11 +++++++++++ 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/fdt_mut.rs b/src/fdt_mut.rs index 4bebb9e..2205fa6 100644 --- a/src/fdt_mut.rs +++ b/src/fdt_mut.rs @@ -551,9 +551,7 @@ impl Display for FdtMut { impl<'a> From>> for Fdt<'a> { fn from(fdt: FdtMut>) -> Self { - Self { - data: fdt.data.slice, - } + Self::new_unchecked(fdt.data.into_slice()) } } diff --git a/src/fdt_mut/buffer.rs b/src/fdt_mut/buffer.rs index 750e0ef..cf1aaf7 100644 --- a/src/fdt_mut/buffer.rs +++ b/src/fdt_mut/buffer.rs @@ -51,7 +51,7 @@ impl FdtBuffer for &mut B { /// buffer. #[derive(Debug, PartialEq, Eq)] pub struct SliceBuffer<'a> { - pub(crate) slice: &'a mut [u8], + slice: &'a mut [u8], } impl<'a> SliceBuffer<'a> { @@ -88,6 +88,14 @@ impl<'a> SliceBuffer<'a> { Self { slice } } + pub(super) fn into_slice(self) -> &'a [u8] { + &self.slice[..self.len()] + } + + fn len(&self) -> usize { + self.header().totalsize() as usize + } + fn header(&self) -> &FdtHeader { let (header, _) = FdtHeader::ref_from_prefix(self.slice) .expect("FDT header should be valid after SliceBuffer construction"); @@ -103,14 +111,13 @@ impl<'a> SliceBuffer<'a> { impl AsRef<[u8]> for SliceBuffer<'_> { fn as_ref(&self) -> &[u8] { - let len = self.header().totalsize() as usize; - &self.slice[..len] + &self.slice[..self.len()] } } impl AsMut<[u8]> for SliceBuffer<'_> { fn as_mut(&mut self) -> &mut [u8] { - let len = self.header().totalsize() as usize; + let len = self.len(); &mut self.slice[..len] } } @@ -131,7 +138,7 @@ impl FdtBuffer for SliceBuffer<'_> { capacity: self.slice.len(), }); } - let current_len = self.as_ref().len(); + let current_len = self.len(); if new_len > current_len { self.slice[current_len..new_len].fill(0); } diff --git a/tests/fdt_mut.rs b/tests/fdt_mut.rs index 93f0b9f..2656e69 100644 --- a/tests/fdt_mut.rs +++ b/tests/fdt_mut.rs @@ -656,3 +656,14 @@ fn from_raw_bounded_mut_rejects_invalid_headers() { let err = unsafe { FdtMut::from_raw_bounded(huge_size.as_mut_ptr(), dtb.len()) }.unwrap_err(); assert_eq!(err.kind, FdtErrorKind::InvalidLength); } + +#[test] +fn from_slice_buffer_into_fdt_uses_totalsize() { + let dtb = include_bytes!("dtb/test.dtb"); + let mut buf = [0u8; 256]; + buf[..dtb.len()].copy_from_slice(dtb); + + let fdt_mut = FdtMut::from_slice(&mut buf).unwrap(); + let fdt = Fdt::from(fdt_mut); + assert_eq!(fdt.data().len(), dtb.len()); +}