Skip to content

Commit

Permalink
Fix WASI fd_readdir on big-endian (#3016)
Browse files Browse the repository at this point in the history
This code assumes that the Dirent structure has the same memory
layout on the host (Rust code) as in wasm code.  This is not true
if the host is big-endian, as wasm is always little-endian.

Fixed by always byte-swapping Dirent fields to little-endian
before passing them on to wasm code.
  • Loading branch information
uweigand authored Jun 22, 2021
1 parent acdb388 commit 1a865fb
Showing 1 changed file with 12 additions and 1 deletion.
13 changes: 12 additions & 1 deletion crates/wasi-common/src/snapshots/preview_1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1548,13 +1548,24 @@ fn dirent_bytes(dirent: types::Dirent) -> Vec<u8> {
std::mem::size_of::<types::Dirent>() as _,
"Dirent guest repr and host repr should match"
);
assert_eq!(
1,
std::mem::size_of_val(&dirent.d_type),
"Dirent member d_type should be endian-invariant"
);
let size = types::Dirent::guest_size()
.try_into()
.expect("Dirent is smaller than 2^32");
let mut bytes = Vec::with_capacity(size);
bytes.resize(size, 0);
let ptr = bytes.as_mut_ptr() as *mut types::Dirent;
unsafe { ptr.write_unaligned(dirent) };
let guest_dirent = types::Dirent {
d_ino: dirent.d_ino.to_le(),
d_namlen: dirent.d_namlen.to_le(),
d_type: dirent.d_type, // endian-invariant
d_next: dirent.d_next.to_le(),
};
unsafe { ptr.write_unaligned(guest_dirent) };
bytes
}

Expand Down

0 comments on commit 1a865fb

Please sign in to comment.