From 1a865fb0f5b7cf394c3719e499ca804c1e8c43b5 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Tue, 22 Jun 2021 17:39:38 +0200 Subject: [PATCH] Fix WASI fd_readdir on big-endian (#3016) 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. --- crates/wasi-common/src/snapshots/preview_1.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/crates/wasi-common/src/snapshots/preview_1.rs b/crates/wasi-common/src/snapshots/preview_1.rs index 896d7a1e1d..c05727a735 100644 --- a/crates/wasi-common/src/snapshots/preview_1.rs +++ b/crates/wasi-common/src/snapshots/preview_1.rs @@ -1548,13 +1548,24 @@ fn dirent_bytes(dirent: types::Dirent) -> Vec { std::mem::size_of::() 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 }