Skip to content

Commit 5d3bcc8

Browse files
committed
Fix missing alignment check for ELF note header in fuchsia support
The transmute required that the alignment of bytes was correct, but nothing checked this. Use `object::pod::from_bytes` which does the transmute and includes this check.
1 parent b65ab93 commit 5d3bcc8

File tree

1 file changed

+12
-22
lines changed

1 file changed

+12
-22
lines changed

src/print/fuchsia.rs

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use core::fmt::{self, Write};
2-
use core::mem::{size_of, transmute};
32
use core::slice::from_raw_parts;
43
use libc::c_char;
4+
use object::NativeEndian as NE;
55

66
unsafe extern "C" {
77
// dl_iterate_phdr takes a callback that will receive a dl_phdr_info pointer
@@ -118,12 +118,7 @@ const NT_GNU_BUILD_ID: u32 = 3;
118118

119119
// Elf_Nhdr represents an ELF note header in the endianness of the target.
120120
#[allow(non_camel_case_types)]
121-
#[repr(C)]
122-
struct Elf_Nhdr {
123-
n_namesz: u32,
124-
n_descsz: u32,
125-
n_type: u32,
126-
}
121+
type Elf_Nhdr = object::elf::NoteHeader32<NE>;
127122

128123
// Note represents an ELF note (header + contents). The name is left as a u8
129124
// slice because it is not always null terminated and rust makes it easy enough
@@ -176,19 +171,14 @@ fn take_bytes_align4<'a>(num: usize, bytes: &mut &'a [u8]) -> Option<&'a [u8]> {
176171
Some(out)
177172
}
178173

179-
// This function has no real invariants the caller must uphold other than
180-
// perhaps that 'bytes' should be aligned for performance (and on some
181-
// architectures correctness). The values in the Elf_Nhdr fields might
182-
// be nonsense but this function ensures no such thing.
174+
// This function has no invariants the caller must uphold, but it will return `None`
175+
// if 'bytes' is not correctly aligned. The values in the Elf_Nhdr fields might be
176+
// nonsense but this function ensures no such thing.
183177
fn take_nhdr<'a>(bytes: &mut &'a [u8]) -> Option<&'a Elf_Nhdr> {
184-
if size_of::<Elf_Nhdr>() > bytes.len() {
185-
return None;
186-
}
187-
// This is safe as long as there is enough space and we just confirmed that
188-
// in the if statement above so this should not be unsafe.
189-
let out = unsafe { transmute::<*const u8, &'a Elf_Nhdr>(bytes.as_ptr()) };
190-
// Note that sice_of::<Elf_Nhdr>() is always 4-byte aligned.
191-
*bytes = &bytes[size_of::<Elf_Nhdr>()..];
178+
let (out, rest) = object::pod::from_bytes::<Elf_Nhdr>(bytes).ok()?;
179+
// Note that size_of::<Elf_Nhdr>() is always a multiple of 4-bytes, so the
180+
// 4-byte alignment is maintained.
181+
*bytes = rest;
192182
Some(out)
193183
}
194184

@@ -204,12 +194,12 @@ impl<'a> Iterator for NoteIter<'a> {
204194
// decisions based on the type. So even if we get out complete garbage
205195
// we should still be safe.
206196
let nhdr = take_nhdr(&mut self.base)?;
207-
let name = take_bytes_align4(nhdr.n_namesz as usize, &mut self.base)?;
208-
let desc = take_bytes_align4(nhdr.n_descsz as usize, &mut self.base)?;
197+
let name = take_bytes_align4(nhdr.n_namesz.get(NE) as usize, &mut self.base)?;
198+
let desc = take_bytes_align4(nhdr.n_descsz.get(NE) as usize, &mut self.base)?;
209199
Some(Note {
210200
name: name,
211201
desc: desc,
212-
tipe: nhdr.n_type,
202+
tipe: nhdr.n_type.get(NE),
213203
})
214204
}
215205
}

0 commit comments

Comments
 (0)