From 32d7f77780ec9f7735e729ca1ead8bcc07597163 Mon Sep 17 00:00:00 2001 From: Martin Hughes Date: Wed, 24 Jun 2026 15:57:50 +0100 Subject: [PATCH] Keep a copy of block stream instead of raw pointer This mitigates the possibility of the pointed-to code stream being dropped, which would result in a use-after-free. Fixes #300. The use of a Vec isn't the most memory or CPU efficient. I tried using borrows but it was leading to a horrible mess of lifetime specifiers and there were still a few areas of code I couldn't figure out how to make compile... --- src/aml/mod.rs | 17 +++++------------ tests/uacpi_examples.rs | 1 - 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/aml/mod.rs b/src/aml/mod.rs index bdd0dfc3..cb3af956 100644 --- a/src/aml/mod.rs +++ b/src/aml/mod.rs @@ -2855,13 +2855,6 @@ where /// A `MethodContext` represents a piece of running AML code - either a real method, or the /// top-level of an AML table. -/// -/// ### Safety -/// `MethodContext` does not keep the lifetime of the underlying AML stream, which for tables is -/// borrowed from the underlying physical mapping. This is because the interpreter needs to -/// preempt method contexts that execute other methods, and these contexts may have disparate -/// lifetimes. This is made safe in the case of methods by the context holding a reference to the -/// method object, but must be handled manually for AML tables. struct MethodContext { current_block: Block, block_stack: Vec, @@ -2874,14 +2867,14 @@ struct MethodContext { } struct Block { - stream: *const [u8], + stream: Vec, pc: usize, kind: BlockKind, } impl Block { fn stream(&self) -> &[u8] { - unsafe { &*self.stream } + &self.stream } } @@ -3009,7 +3002,7 @@ impl OpInFlight { impl MethodContext { unsafe fn new_from_table(stream: &[u8]) -> MethodContext { - let block = Block { stream: stream as *const [u8], pc: 0, kind: BlockKind::Table }; + let block = Block { stream: Vec::from(stream), pc: 0, kind: BlockKind::Table }; MethodContext { current_block: block, block_stack: Vec::new(), @@ -3031,7 +3024,7 @@ impl MethodContext { return Err(AmlError::MethodArgCountIncorrect); } let block = Block { - stream: code as &[u8] as *const [u8], + stream: code.clone(), pc: 0, kind: BlockKind::Method { method_scope: scope.clone() }, }; @@ -3079,7 +3072,7 @@ impl MethodContext { fn start_new_block(&mut self, kind: BlockKind, length: usize) { let block = Block { - stream: &self.current_block.stream()[..(self.current_block.pc + length)] as *const [u8], + stream: self.current_block.stream()[..(self.current_block.pc + length)].into(), pc: self.current_block.pc, kind, }; diff --git a/tests/uacpi_examples.rs b/tests/uacpi_examples.rs index 4c1aa82d..128fe30f 100644 --- a/tests/uacpi_examples.rs +++ b/tests/uacpi_examples.rs @@ -181,7 +181,6 @@ DefinitionBlock("", "DSDT", 1, "RSACPI", "UACPI", 1) { } #[test] -#[ignore] // See issue #300 fn copy_object_to_self() { const ASL: &str = r#" DefinitionBlock("", "DSDT", 1, "RSACPI", "UACPI", 1) {