From 60cdfbe265fe2a55fb35d695662e2b23fe8cef57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20L=C3=B3pez?= Date: Thu, 23 Nov 2023 00:34:54 +0100 Subject: [PATCH] greq: sanity check struct sizes at compile time MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The size of SnpGuestRequestMsg, SnpGuestRequestMsgType, and AttestationReport can be asserted at compile time. This allows us to remove asserts within several functions and to remove a corresponding redundant test, since the SVSM will not build at all if one of these assertions fails. Signed-off-by: Carlos López --- src/greq/msg.rs | 28 ++++++++-------------------- src/greq/pld_report.rs | 11 +++-------- 2 files changed, 11 insertions(+), 28 deletions(-) diff --git a/src/greq/msg.rs b/src/greq/msg.rs index e165bab7c..b2ae4c7f6 100644 --- a/src/greq/msg.rs +++ b/src/greq/msg.rs @@ -102,15 +102,11 @@ pub struct SnpGuestRequestMsgHdr { rsvd3: [u8; 35], } +const _: () = assert!(size_of::() <= u16::MAX as usize); + impl SnpGuestRequestMsgHdr { /// Allocate a new [`SnpGuestRequestMsgHdr`] and initialize it - /// - /// # Panic - /// - /// * [`SnpGuestRequestMsgHdr`] size does not fit in a u16. pub fn new(msg_sz: u16, msg_type: SnpGuestRequestMsgType, msg_seqno: u64) -> Self { - assert!(u16::try_from(MSG_HDR_SIZE).is_ok()); - Self { msg_seqno, algo: SnpGuestRequestAead::Aes256Gcm as u8, @@ -139,10 +135,8 @@ impl SnpGuestRequestMsgHdr { msg_type: SnpGuestRequestMsgType, msg_seqno: u64, ) -> Result<(), SvsmReqError> { - let header_size = - u16::try_from(MSG_HDR_SIZE).map_err(|_| SvsmReqError::invalid_format())?; if self.hdr_version != HDR_VERSION - || self.hdr_sz != header_size + || self.hdr_sz != MSG_HDR_SIZE as u16 || self.algo != SnpGuestRequestAead::Aes256Gcm as u8 || self.msg_type != msg_type as u8 || self.msg_vmpck != 0 @@ -209,20 +203,19 @@ pub struct SnpGuestRequestMsg { pld: [u8; MSG_PAYLOAD_SIZE], } +// The GHCB spec says it has to fit in one page and be page aligned +const _: () = assert!(size_of::() <= PAGE_SIZE); + impl SnpGuestRequestMsg { /// Allocate the object in the heap without going through stack as /// this is a large object /// - /// # Panic + /// # Panics /// - /// * Memory allocated is not page aligned or Self does not - /// fit into a page + /// Panics if the new allocation is not page aligned. pub fn boxed_new() -> Result, SvsmReqError> { let layout = Layout::new::(); - // The GHCB spec says it has to fit in one page and be page aligned - assert!(layout.size() <= PAGE_SIZE); - unsafe { let addr = alloc_zeroed(layout); if addr.is_null() { @@ -590,11 +583,6 @@ mod tests { assert!(data.data.iter().all(|c| *c == 0)); } - #[test] - fn u16_from_guest_msg_hdr_size() { - assert!(u16::try_from(MSG_HDR_SIZE).is_ok()); - } - #[test] fn aad_size() { let hdr = SnpGuestRequestMsgHdr::default(); diff --git a/src/greq/pld_report.rs b/src/greq/pld_report.rs index ac7699a11..1d7d7b59a 100644 --- a/src/greq/pld_report.rs +++ b/src/greq/pld_report.rs @@ -102,19 +102,12 @@ impl SnpReportResponse { } /// Validate the [SnpReportResponse] fields - /// - /// # Panic - /// - /// * The size of the struct [`AttestationReport`] must fit in a u32 pub fn validate(&self) -> Result<(), SvsmReqError> { if self.status != SnpReportResponseStatus::Success as u32 { return Err(SvsmReqError::invalid_request()); } - const REPORT_SIZE: usize = size_of::(); - assert!(u32::try_from(REPORT_SIZE).is_ok()); - - if self.report_size != REPORT_SIZE as u32 { + if self.report_size != size_of::() as u32 { return Err(SvsmReqError::invalid_format()); } @@ -199,6 +192,8 @@ pub struct AttestationReport { signature: Signature, } +const _: () = assert!(size_of::() <= u32::MAX as usize); + #[cfg(test)] mod tests { use super::*;