From d8745ad07f140f785705c9bf44f4ed19ea9b9931 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 and size was not padded. 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 | 234 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 198 insertions(+), 36 deletions(-) diff --git a/src/fs/fuse.rs b/src/fs/fuse.rs index 6c6df6c72f..2e7fe8d110 100644 --- a/src/fs/fuse.rs +++ b/src/fs/fuse.rs @@ -331,9 +331,17 @@ 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::(), + ), + ) + .unwrap() + .pad_to_align(); let cmd = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(layout); 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 +354,20 @@ fn create_init() -> (Box>, Box>) { Box::from_raw(raw) }; + assert_eq!(layout, 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::(), + ), + ) + .unwrap() + .pad_to_align(); let rsp = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(layout); 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 +376,7 @@ fn create_init() -> (Box>, Box>) { Box::from_raw(raw) }; + assert_eq!(layout, Layout::for_value(&*rsp)); (cmd, rsp) } @@ -369,9 +387,17 @@ 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::(), + ), + ) + .unwrap() + .pad_to_align(); let cmd = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(layout); 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 +407,20 @@ 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::(), + ), + ) + .unwrap() + .pad_to_align(); let rsp = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(layout); 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 +429,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::(), + ), + ) + .unwrap() + .pad_to_align(); let cmd = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(layout); 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 +529,22 @@ fn create_read( Box::from_raw(raw) }; + assert_eq!(layout, 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::(), + ), + ) + .unwrap() + .pad_to_align(); let rsp = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(layout); let raw = core::ptr::slice_from_raw_parts_mut(data, size.try_into().unwrap()) as *mut Rsp; (*raw).header = fuse_out_header { @@ -501,6 +554,7 @@ fn create_read( Box::from_raw(raw) }; + assert_eq!(layout, Layout::for_value(&*rsp)); (cmd, rsp) } @@ -529,9 +583,17 @@ 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::(), + ), + ) + .unwrap() + .pad_to_align(); let cmd = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(layout); 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 +611,20 @@ fn create_lseek( Box::from_raw(raw) }; + assert_eq!(layout, 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::(), + ), + ) + .unwrap() + .pad_to_align(); let rsp = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(layout); 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 +633,7 @@ fn create_lseek( Box::from_raw(raw) }; + assert_eq!(layout, Layout::for_value(&*rsp)); (cmd, rsp) } @@ -596,9 +668,17 @@ 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::(), + ), + ) + .unwrap() + .pad_to_align(); let cmd = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(layout); 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 +697,20 @@ fn create_write( Box::from_raw(raw) }; + assert_eq!(layout, 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::(), + ), + ) + .unwrap() + .pad_to_align(); let rsp = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(layout); 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 +719,7 @@ fn create_write( Box::from_raw(raw) }; + assert_eq!(layout, Layout::for_value(&*rsp)); (cmd, rsp) } @@ -655,9 +745,17 @@ 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::(), + ), + ) + .unwrap() + .pad_to_align(); let cmd = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(layout); 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 +765,20 @@ 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::(), + ), + ) + .unwrap() + .pad_to_align(); let rsp = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(layout); 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 +787,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::(), + ), + ) + .unwrap() + .pad_to_align(); let cmd = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(layout); 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 +830,20 @@ 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::(), + ), + ) + .unwrap() + .pad_to_align(); let rsp = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(layout); 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 +852,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::(), + ), + ) + .unwrap() + .pad_to_align(); let cmd = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(layout); 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 +933,20 @@ 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::(), + ), + ) + .unwrap() + .pad_to_align(); let rsp = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(layout); 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 +955,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::(), + ), + ) + .unwrap() + .pad_to_align(); let cmd = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(layout); 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 +1014,20 @@ fn create_create( Box::from_raw(raw) }; + assert_eq!(layout, 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::(), + ), + ) + .unwrap() + .pad_to_align(); let rsp = unsafe { - let data = alloc(layout.unwrap()); + let data = alloc(layout); 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 +1036,7 @@ fn create_create( Box::from_raw(raw) }; + assert_eq!(layout, Layout::for_value(&*rsp)); (cmd, rsp) }