From 0ff5752e9a8fddb862392ce66587bc8ebe8e1402 Mon Sep 17 00:00:00 2001 From: joannejchen Date: Sat, 15 Apr 2023 14:50:46 -0500 Subject: [PATCH] Change alignment of virtiofs structs to maximum alignment of all fields. Alignment of the virtiofs struct was previously based on the alignment of only the first field. Changed to explicitly use the maximum alignment of all of the fields and added assertions to ensure this manually-allocated layout matches the compiler-generated layout. Fixes #691 Signed-off-by: joannejchen --- src/fs/fuse.rs | 198 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 162 insertions(+), 36 deletions(-) diff --git a/src/fs/fuse.rs b/src/fs/fuse.rs index 6c6df6c72f..c1a0b83002 100644 --- a/src/fs/fuse.rs +++ b/src/fs/fuse.rs @@ -331,9 +331,15 @@ where fn create_init() -> (Box>, Box>) { let len = core::mem::size_of::() + core::mem::size_of::(); - let layout = Layout::from_size_align(len, core::mem::align_of::()); + let layout = Layout::from_size_align( + len, + core::cmp::max( + core::mem::align_of::(), + core::mem::align_of::(), + ), + ); let cmd = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(*layout.as_ref().unwrap()); let raw = core::ptr::slice_from_raw_parts_mut(data, 0) as *mut Cmd; (*raw).header = create_in_header::(FUSE_ROOT_ID, Opcode::FUSE_INIT); (*raw).header.len = len.try_into().unwrap(); @@ -346,11 +352,18 @@ fn create_init() -> (Box>, Box>) { Box::from_raw(raw) }; + assert_eq!(layout.unwrap(), Layout::for_value(&*cmd)); let len = core::mem::size_of::() + core::mem::size_of::(); - let layout = Layout::from_size_align(len, core::mem::align_of::()); + let layout = Layout::from_size_align( + len, + core::cmp::max( + core::mem::align_of::(), + core::mem::align_of::(), + ), + ); let rsp = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(*layout.as_ref().unwrap()); let raw = core::ptr::slice_from_raw_parts_mut(data, 0) as *mut Rsp; (*raw).header = fuse_out_header { len: len.try_into().unwrap(), @@ -359,6 +372,7 @@ fn create_init() -> (Box>, Box>) { Box::from_raw(raw) }; + assert_eq!(layout.unwrap(), Layout::for_value(&*rsp)); (cmd, rsp) } @@ -369,9 +383,15 @@ fn create_lookup(name: &str) -> (Box>, Box() + slice.len() + 1; - let layout = Layout::from_size_align(len, core::mem::align_of::()); + let layout = Layout::from_size_align( + len, + core::cmp::max( + core::mem::align_of::(), + core::mem::align_of::(), + ), + ); let cmd = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(*layout.as_ref().unwrap()); let raw = core::ptr::slice_from_raw_parts_mut(data, slice.len() + 1) as *mut Cmd; (*raw).header = create_in_header::(FUSE_ROOT_ID, Opcode::FUSE_LOOKUP); @@ -381,11 +401,18 @@ fn create_lookup(name: &str) -> (Box>, Box() + core::mem::size_of::(); - let layout = Layout::from_size_align(len, core::mem::align_of::()); + let layout = Layout::from_size_align( + len, + core::cmp::max( + core::mem::align_of::(), + core::mem::align_of::(), + ), + ); let rsp = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(*layout.as_ref().unwrap()); let raw = core::ptr::slice_from_raw_parts_mut(data, 0) as *mut Rsp; (*raw).header = fuse_out_header { len: len.try_into().unwrap(), @@ -394,6 +421,7 @@ fn create_lookup(name: &str) -> (Box>, Box (Box>, Box>) { let len = core::mem::size_of::() + core::mem::size_of::(); - let layout = Layout::from_size_align(len, core::mem::align_of::()); + let layout = Layout::from_size_align( + len, + core::cmp::max( + core::mem::align_of::(), + core::mem::align_of::(), + ), + ); let cmd = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(*layout.as_ref().unwrap()); let raw = core::ptr::slice_from_raw_parts_mut(data, 0) as *mut Cmd; (*raw).header = create_in_header::(nid, Opcode::FUSE_READ); (*raw).cmd = fuse_read_in { @@ -485,13 +519,20 @@ fn create_read( Box::from_raw(raw) }; + assert_eq!(layout.unwrap(), Layout::for_value(&*cmd)); let len = core::mem::size_of::() + core::mem::size_of::() + usize::try_from(size).unwrap(); - let layout = Layout::from_size_align(len, core::mem::align_of::()); + let layout = Layout::from_size_align( + len, + core::cmp::max( + core::mem::align_of::(), + core::mem::align_of::(), + ), + ); let rsp = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(*layout.as_ref().unwrap()); let raw = core::ptr::slice_from_raw_parts_mut(data, size.try_into().unwrap()) as *mut Rsp; (*raw).header = fuse_out_header { @@ -501,6 +542,7 @@ fn create_read( Box::from_raw(raw) }; + assert_eq!(layout.unwrap(), Layout::for_value(&*rsp)); (cmd, rsp) } @@ -529,9 +571,15 @@ fn create_lseek( whence: SeekWhence, ) -> (Box>, Box>) { let len = core::mem::size_of::() + core::mem::size_of::(); - let layout = Layout::from_size_align(len, core::mem::align_of::()); + let layout = Layout::from_size_align( + len, + core::cmp::max( + core::mem::align_of::(), + core::mem::align_of::(), + ), + ); let cmd = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(*layout.as_ref().unwrap()); let raw = core::ptr::slice_from_raw_parts_mut(data, 0) as *mut Cmd; (*raw).header = fuse_in_header { len: len.try_into().unwrap(), @@ -549,11 +597,18 @@ fn create_lseek( Box::from_raw(raw) }; + assert_eq!(layout.unwrap(), Layout::for_value(&*cmd)); let len = core::mem::size_of::() + core::mem::size_of::(); - let layout = Layout::from_size_align(len, core::mem::align_of::()); + let layout = Layout::from_size_align( + len, + core::cmp::max( + core::mem::align_of::(), + core::mem::align_of::(), + ), + ); let rsp = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(*layout.as_ref().unwrap()); let raw = core::ptr::slice_from_raw_parts_mut(data, 0) as *mut Rsp; (*raw).header = fuse_out_header { len: len.try_into().unwrap(), @@ -562,6 +617,7 @@ fn create_lseek( Box::from_raw(raw) }; + assert_eq!(layout.unwrap(), Layout::for_value(&*rsp)); (cmd, rsp) } @@ -596,9 +652,15 @@ fn create_write( ) -> (Box>, Box>) { let len = core::mem::size_of::() + core::mem::size_of::() + buf.len(); - let layout = Layout::from_size_align(len, core::mem::align_of::()); + let layout = Layout::from_size_align( + len, + core::cmp::max( + core::mem::align_of::(), + core::mem::align_of::(), + ), + ); let cmd = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(*layout.as_ref().unwrap()); let raw = core::ptr::slice_from_raw_parts_mut(data, buf.len()) as *mut Cmd; (*raw).header = fuse_in_header { len: len.try_into().unwrap(), @@ -617,11 +679,18 @@ fn create_write( Box::from_raw(raw) }; + // assert_eq!(layout.unwrap(), Layout::for_value(&*cmd)); let len = core::mem::size_of::() + core::mem::size_of::(); - let layout = Layout::from_size_align(len, core::mem::align_of::()); + let layout = Layout::from_size_align( + len, + core::cmp::max( + core::mem::align_of::(), + core::mem::align_of::(), + ), + ); let rsp = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(*layout.as_ref().unwrap()); let raw = core::ptr::slice_from_raw_parts_mut(data, 0) as *mut Rsp; (*raw).header = fuse_out_header { len: len.try_into().unwrap(), @@ -630,6 +699,7 @@ fn create_write( Box::from_raw(raw) }; + assert_eq!(layout.unwrap(), Layout::for_value(&*rsp)); (cmd, rsp) } @@ -655,9 +725,15 @@ unsafe impl FuseOut for fuse_open_out {} fn create_open(nid: u64, flags: u32) -> (Box>, Box>) { let len = core::mem::size_of::() + core::mem::size_of::(); - let layout = Layout::from_size_align(len, core::mem::align_of::()); + let layout = Layout::from_size_align( + len, + core::cmp::max( + core::mem::align_of::(), + core::mem::align_of::(), + ), + ); let cmd = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(*layout.as_ref().unwrap()); let raw = core::ptr::slice_from_raw_parts_mut(data, 0) as *mut Cmd; (*raw).header = create_in_header::(nid, Opcode::FUSE_OPEN); (*raw).cmd = fuse_open_in { @@ -667,11 +743,18 @@ fn create_open(nid: u64, flags: u32) -> (Box>, Box() + core::mem::size_of::(); - let layout = Layout::from_size_align(len, core::mem::align_of::()); + let layout = Layout::from_size_align( + len, + core::cmp::max( + core::mem::align_of::(), + core::mem::align_of::(), + ), + ); let rsp = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(*layout.as_ref().unwrap()); let raw = core::ptr::slice_from_raw_parts_mut(data, 0) as *mut Rsp; (*raw).header = fuse_out_header { len: len.try_into().unwrap(), @@ -680,6 +763,7 @@ fn create_open(nid: u64, flags: u32) -> (Box>, Box (Box>, Box>) { let len = core::mem::size_of::() + core::mem::size_of::(); - let layout = Layout::from_size_align(len, core::mem::align_of::()); + let layout = Layout::from_size_align( + len, + core::cmp::max( + core::mem::align_of::(), + core::mem::align_of::(), + ), + ); let cmd = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(*layout.as_ref().unwrap()); let raw = core::ptr::slice_from_raw_parts_mut(data, 0) as *mut Cmd; (*raw).header = create_in_header::(nid, Opcode::FUSE_RELEASE); (*raw).cmd = fuse_release_in { @@ -714,11 +804,18 @@ fn create_release(nid: u64, fh: u64) -> (Box>, Box() + core::mem::size_of::(); - let layout = Layout::from_size_align(len, core::mem::align_of::()); + let layout = Layout::from_size_align( + len, + core::cmp::max( + core::mem::align_of::(), + core::mem::align_of::(), + ), + ); let rsp = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(*layout.as_ref().unwrap()); let raw = core::ptr::slice_from_raw_parts_mut(data, 0) as *mut Rsp; (*raw).header = fuse_out_header { len: len.try_into().unwrap(), @@ -727,6 +824,7 @@ fn create_release(nid: u64, fh: u64) -> (Box>, Box (Box>, Box() + slice.len() + 1; - let layout = Layout::from_size_align(len, core::mem::align_of::()); + let layout = Layout::from_size_align( + len, + core::cmp::max( + core::mem::align_of::(), + core::mem::align_of::(), + ), + ); let cmd = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(*layout.as_ref().unwrap()); let raw = core::ptr::slice_from_raw_parts_mut(data, slice.len() + 1) as *mut Cmd; (*raw).header = create_in_header::(FUSE_ROOT_ID, Opcode::FUSE_UNLINK); @@ -799,11 +903,18 @@ fn create_unlink(name: &str) -> (Box>, Box() + core::mem::size_of::(); - let layout = Layout::from_size_align(len, core::mem::align_of::()); + let layout = Layout::from_size_align( + len, + core::cmp::max( + core::mem::align_of::(), + core::mem::align_of::(), + ), + ); let rsp = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(*layout.as_ref().unwrap()); let raw = core::ptr::slice_from_raw_parts_mut(data, 0) as *mut Rsp; (*raw).header = fuse_out_header { len: len.try_into().unwrap(), @@ -812,6 +923,7 @@ fn create_unlink(name: &str) -> (Box>, Box() + slice.len() + 1; - let layout = Layout::from_size_align(len, core::mem::align_of::()); + let layout = Layout::from_size_align( + len, + core::cmp::max( + core::mem::align_of::(), + core::mem::align_of::(), + ), + ); let cmd = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(*layout.as_ref().unwrap()); let raw = core::ptr::slice_from_raw_parts_mut(data, slice.len() + 1) as *mut Cmd; (*raw).header = create_in_header::(FUSE_ROOT_ID, Opcode::FUSE_CREATE); @@ -862,11 +980,18 @@ fn create_create( Box::from_raw(raw) }; + assert_eq!(layout.unwrap(), Layout::for_value(&*cmd)); let len = core::mem::size_of::() + core::mem::size_of::(); - let layout = Layout::from_size_align(len, core::mem::align_of::()); + let layout = Layout::from_size_align( + len, + core::cmp::max( + core::mem::align_of::(), + core::mem::align_of::(), + ), + ); let rsp = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(*layout.as_ref().unwrap()); let raw = core::ptr::slice_from_raw_parts_mut(data, 0) as *mut Rsp; (*raw).header = fuse_out_header { len: len.try_into().unwrap(), @@ -875,6 +1000,7 @@ fn create_create( Box::from_raw(raw) }; + assert_eq!(layout.unwrap(), Layout::for_value(&*rsp)); (cmd, rsp) }