浏览代码

Fix unaligned accesses of packed fields

Isaac Woods 3 年之前
父节点
当前提交
d58e64b39e
共有 3 个文件被更改,包括 14 次插入4 次删除
  1. 11 1
      acpi/src/lib.rs
  2. 2 2
      acpi/src/madt.rs
  3. 1 1
      acpi/src/platform/mod.rs

+ 11 - 1
acpi/src/lib.rs

@@ -37,6 +37,16 @@
 //!    - [`PciConfigRegions`](crate::mcfg::PciConfigRegions) parses the MCFG and tells you how PCIe configuration
 //!      space is mapped into physical memory.
 
+/*
+ * Contributing notes (you may find these useful if you're new to contributing to the library):
+ *    - Accessing packed fields without UB: Lots of the structures defined by ACPI are defined with `repr(packed)`
+ *      to prevent padding being introduced, which would make the structure's layout incorrect. In Rust, this
+ *      creates a problem as references to these fields could be unaligned, which is undefined behaviour. For the
+ *      majority of these fields, this problem can be easily avoided by telling the compiler to make a copy of the
+ *      field's contents: this is the perhaps unfamiliar pattern of e.g. `!{ entry.flags }.get_bit(0)` we use
+ *      around the codebase.
+ */
+
 #![no_std]
 #![feature(const_generics)]
 #![deny(unsafe_op_in_unsafe_fn)]
@@ -201,7 +211,7 @@ where
 
     fn process_sdt(&mut self, physical_address: usize) -> Result<(), AcpiError> {
         let header = sdt::peek_at_sdt_header(&self.handler, physical_address);
-        trace!("Found ACPI table with signature {:?} and length {:?}", header.signature, header.length);
+        trace!("Found ACPI table with signature {:?} and length {:?}", header.signature, { header.length });
 
         match header.signature {
             Signature::FADT => {

+ 2 - 2
acpi/src/madt.rs

@@ -129,7 +129,7 @@ impl Madt {
                      * the BSP yet, this must be it.
                      */
                     let is_ap = boot_processor.is_some();
-                    let is_disabled = !entry.flags.get_bit(0);
+                    let is_disabled = !{ entry.flags }.get_bit(0);
 
                     let state = match (is_ap, is_disabled) {
                         (_, true) => ProcessorState::Disabled,
@@ -229,7 +229,7 @@ impl Madt {
     }
 
     pub fn supports_8259(&self) -> bool {
-        self.flags.get_bit(0)
+        { self.flags }.get_bit(0)
     }
 }
 

+ 1 - 1
acpi/src/platform/mod.rs

@@ -63,7 +63,7 @@ pub struct PmTimer {
 impl PmTimer {
     pub fn new(fadt: &Fadt) -> Result<Option<PmTimer>, AcpiError> {
         match fadt.pm_timer_block()? {
-            Some(base) => Ok(Some(PmTimer { base, supports_32bit: fadt.flags.pm_timer_is_32_bit() })),
+            Some(base) => Ok(Some(PmTimer { base, supports_32bit: { fadt.flags }.pm_timer_is_32_bit() })),
             None => Ok(None),
         }
     }