Skip to content

Commit d54fe53

Browse files
committed
Remove some unsafe code; fix a soundness hole
Replace a number of lines of unsafe code with safe equivalents, some using `zerocopy`. In one instance, fix a soundness hole (#720). Closes #720
1 parent b65ab93 commit d54fe53

File tree

6 files changed

+61
-15
lines changed

6 files changed

+61
-15
lines changed

Cargo.lock

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ exclude = [
2828
[dependencies]
2929
cfg-if = "1.0"
3030
rustc-demangle = "0.1.24"
31+
zerocopy = "0.8.26"
3132

3233
# Optionally enable the ability to serialize a `Backtrace`, controlled through
3334
# the `serialize-serde` feature below.

crates/as-if-std/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ bench = false
1515
cfg-if = "1.0"
1616
rustc-demangle = "0.1.21"
1717
libc = { version = "0.2.156", default-features = false }
18+
zerocopy = "0.8.26"
1819

1920
[target.'cfg(not(all(windows, target_env = "msvc", not(target_vendor = "uwp"))))'.dependencies]
2021
miniz_oxide = { version = "0.8", optional = true, default-features = false }

src/print/fuchsia.rs

Lines changed: 7 additions & 10 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 zerocopy::FromBytes;
55

66
unsafe extern "C" {
77
// dl_iterate_phdr takes a callback that will receive a dl_phdr_info pointer
@@ -181,15 +181,12 @@ fn take_bytes_align4<'a>(num: usize, bytes: &mut &'a [u8]) -> Option<&'a [u8]> {
181181
// architectures correctness). The values in the Elf_Nhdr fields might
182182
// be nonsense but this function ensures no such thing.
183183
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>()..];
192-
Some(out)
184+
let (hdr, suffix) = <[u32; 3]>::ref_from_prefix(*bytes).ok()?;
185+
*bytes = suffix;
186+
187+
let hdr: *const [u32; 3] = hdr;
188+
// SAFETY: `[u32; 3]` and `Elf_Nhdr` have the same layout.
189+
Some(unsafe { &*hdr.cast::<Elf_Nhdr>() })
193190
}
194191

195192
impl<'a> Iterator for NoteIter<'a> {

src/symbolize/dbghelp.rs

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,9 +222,35 @@ unsafe fn do_resolve(
222222
get_line_from_addr: impl FnOnce(&mut IMAGEHLP_LINEW64) -> BOOL,
223223
cb: &mut dyn FnMut(&super::Symbol),
224224
) {
225-
const SIZE: usize = 2 * MAX_SYM_NAME as usize + mem::size_of::<SYMBOL_INFOW>();
226-
let mut data = Aligned8([0u8; SIZE]);
227-
let info = unsafe { &mut *data.0.as_mut_ptr().cast::<SYMBOL_INFOW>() };
225+
const TRAILER_SIZE: usize = 2 * MAX_SYM_NAME as usize;
226+
227+
#[repr(C)]
228+
struct Data {
229+
symbol_infow: SYMBOL_INFOW,
230+
__max_sym_name: [u8; TRAILER_SIZE],
231+
}
232+
233+
let mut data = Aligned8(Data {
234+
symbol_infow: SYMBOL_INFOW {
235+
SizeOfStruct: 0,
236+
TypeIndex: 0,
237+
Reserved: [0, 0],
238+
Index: 0,
239+
Size: 0,
240+
ModBase: 0,
241+
Flags: 0,
242+
Value: 0,
243+
Address: 0,
244+
Register: 0,
245+
Scope: 0,
246+
Tag: 0,
247+
NameLen: 0,
248+
MaxNameLen: 0,
249+
Name: [0],
250+
},
251+
__max_sym_name: [0u8; TRAILER_SIZE],
252+
});
253+
let info = &mut data.0.symbol_infow;
228254
info.MaxNameLen = MAX_SYM_NAME as u32;
229255
// the struct size in C. the value is different to
230256
// `size_of::<SYMBOL_INFOW>() - MAX_SYM_NAME + 1` (== 81)

src/symbolize/gimli/libs_illumos.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use super::{Library, LibrarySegment};
44
use alloc::borrow::ToOwned;
55
use alloc::vec::Vec;
66
use core::ffi::CStr;
7-
use core::mem;
87
use object::NativeEndian;
98

109
#[cfg(target_pointer_width = "64")]
@@ -38,8 +37,8 @@ pub(super) fn native_libraries() -> Vec<Library> {
3837
let mut libs = Vec::new();
3938

4039
// Request the current link map from the runtime linker:
40+
let mut map: *const LinkMap = core::ptr::null();
4141
let map = unsafe {
42-
let mut map: *const LinkMap = mem::zeroed();
4342
if dlinfo(
4443
RTLD_SELF,
4544
RTLD_DI_LINKMAP,

0 commit comments

Comments
 (0)