From 025a5f6f70aa206efd8cca125738b26205367dc2 Mon Sep 17 00:00:00 2001 From: Raito Bezarius Date: Thu, 25 Jan 2024 23:56:17 +0100 Subject: [PATCH] pe(certificate_table): reinforce checks when writing aligned attribute certificates It's possible that a user may pass an improperly created attribute certificate and the write will cause all sorts of failure. We sprinkle some `debug_assert!` to avoid this. --- src/pe/certificate_table.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/pe/certificate_table.rs b/src/pe/certificate_table.rs index 6f4b8da1..9fe11aab 100644 --- a/src/pe/certificate_table.rs +++ b/src/pe/certificate_table.rs @@ -186,11 +186,23 @@ impl<'a> ctx::TryIntoCtx for &AttributeCertificate<'a> { /// Writes an aligned attribute certificate in the buffer. fn try_into_ctx(self, bytes: &mut [u8], ctx: scroll::Endian) -> Result { let offset = &mut 0; + debug_assert!( + (self.length - ATTRIBUTE_CERTIFICATE_HEADER_SIZEOF as u32) % 8 == 0, + "Attribute certificate's length field is unaligned" + ); + debug_assert!( + bytes.len() >= self.length as usize, + "Insufficient buffer to write an aligned certificate" + ); bytes.gwrite_with(self.length, offset, ctx)?; bytes.gwrite_with(self.revision as u16, offset, ctx)?; bytes.gwrite_with(self.certificate_type as u16, offset, ctx)?; - // Extend by zero the buffer until it is aligned on a quadword (16 bytes). - let maybe_certificate_padding = pad(self.certificate.len(), Some(16usize)); + // Extend by zero the buffer until it is aligned on a quadword (16 bytes), according to + // spec: + // > If the bCertificate content does not end on a quadword boundary, the attribute + // > certificate entry is padded with zeros, from the end of bCertificate to the next + // > quadword boundary. + let maybe_certificate_padding = pad(self.certificate.len(), Some(8usize)); bytes.gwrite(self.certificate, offset)?; if let Some(cert_padding) = maybe_certificate_padding { debug!(