Skip to content

Commit

Permalink
greq: sanity check struct sizes at compile time
Browse files Browse the repository at this point in the history
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 <carlos.lopez@suse.com>
  • Loading branch information
00xc committed Nov 23, 2023
1 parent 8a393cd commit 60cdfbe
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 28 deletions.
28 changes: 8 additions & 20 deletions src/greq/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,15 +102,11 @@ pub struct SnpGuestRequestMsgHdr {
rsvd3: [u8; 35],
}

const _: () = assert!(size_of::<SnpGuestRequestMsgHdr>() <= 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,
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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::<SnpGuestRequestMsg>() <= 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<Box<Self>, SvsmReqError> {
let layout = Layout::new::<Self>();

// 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() {
Expand Down Expand Up @@ -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();
Expand Down
11 changes: 3 additions & 8 deletions src/greq/pld_report.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<AttestationReport>();
assert!(u32::try_from(REPORT_SIZE).is_ok());

if self.report_size != REPORT_SIZE as u32 {
if self.report_size != size_of::<AttestationReport>() as u32 {
return Err(SvsmReqError::invalid_format());
}

Expand Down Expand Up @@ -199,6 +192,8 @@ pub struct AttestationReport {
signature: Signature,
}

const _: () = assert!(size_of::<AttestationReport>() <= u32::MAX as usize);

#[cfg(test)]
mod tests {
use super::*;
Expand Down

0 comments on commit 60cdfbe

Please sign in to comment.