Skip to content

Commit

Permalink
Auto merge of #38352 - bluss:unaligned-metadata, r=eddyb
Browse files Browse the repository at this point in the history
Fix unaligned loads in librustc_metadata

Creating a `&[u32]` from an `&[u8]` is not necessarily valid, and crashes
on certain platforms if the data is not well aligned.
  • Loading branch information
bors committed Dec 16, 2016
2 parents 8f02c42 + 7bc1054 commit 8ae9040
Showing 1 changed file with 12 additions and 4 deletions.
16 changes: 12 additions & 4 deletions src/librustc_metadata/index.rs
Expand Up @@ -70,7 +70,7 @@ impl<'tcx> LazySeq<Index> {
index,
words.len());

let position = u32::from_le(words[index]);
let position = u32::from_le(words[index].get());
if position == u32::MAX {
debug!("Index::lookup: position=u32::MAX");
None
Expand All @@ -84,7 +84,7 @@ impl<'tcx> LazySeq<Index> {
bytes: &'a [u8])
-> impl Iterator<Item = (DefIndex, Lazy<Entry<'tcx>>)> + 'a {
let words = &bytes_to_words(&bytes[self.position..])[..self.len];
words.iter().enumerate().filter_map(|(index, &position)| {
words.iter().map(|word| word.get()).enumerate().filter_map(|(index, position)| {
if position == u32::MAX {
None
} else {
Expand All @@ -95,8 +95,16 @@ impl<'tcx> LazySeq<Index> {
}
}

fn bytes_to_words(b: &[u8]) -> &[u32] {
unsafe { slice::from_raw_parts(b.as_ptr() as *const u32, b.len() / 4) }
#[repr(packed)]
#[derive(Copy, Clone)]
struct Unaligned<T>(T);

impl<T> Unaligned<T> {
fn get(self) -> T { self.0 }
}

fn bytes_to_words(b: &[u8]) -> &[Unaligned<u32>] {
unsafe { slice::from_raw_parts(b.as_ptr() as *const Unaligned<u32>, b.len() / 4) }
}

fn words_to_bytes(w: &[u32]) -> &[u8] {
Expand Down

0 comments on commit 8ae9040

Please sign in to comment.