Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Paul Meyer <katexochen0@gmail.com>
Date: Tue, 17 Feb 2026 10:47:28 +0100
Subject: [PATCH] drivers/acpi: add BadAML sandbox

Signed-off-by: Paul Meyer <katexochen0@gmail.com>
---
drivers/acpi/acpica/exregion.c | 6 ++
drivers/acpi/acpica/sandbox.h | 139 +++++++++++++++++++++++++++++++++
2 files changed, 145 insertions(+)
create mode 100644 drivers/acpi/acpica/sandbox.h

diff --git a/drivers/acpi/acpica/exregion.c b/drivers/acpi/acpica/exregion.c
index a390a1c2b0abb01a7c8490b207ec377818120207..638323389e970500c004b7ccdd52a9e7455eaf67 100644
--- a/drivers/acpi/acpica/exregion.c
+++ b/drivers/acpi/acpica/exregion.c
@@ -14,6 +14,8 @@
#define _COMPONENT ACPI_EXECUTER
ACPI_MODULE_NAME("exregion")

+#include "sandbox.h"
+
/*******************************************************************************
*
* FUNCTION: acpi_ex_system_memory_space_handler
@@ -38,6 +40,7 @@ acpi_ex_system_memory_space_handler(u32 function,
u64 *value,
void *handler_context, void *region_context)
{
+ SANDBOX_SECT_START;
acpi_status status = AE_OK;
void *logical_addr_ptr = NULL;
struct acpi_mem_space_context *mem_info = region_context;
@@ -192,6 +195,7 @@ acpi_ex_system_memory_space_handler(u32 function,
case ACPI_READ:

*value = 0;
+ SANDBOX_READ_HOOK((u64)logical_addr_ptr, (u64)address);
switch (bit_width) {
case 8:

@@ -223,6 +227,7 @@ acpi_ex_system_memory_space_handler(u32 function,

case ACPI_WRITE:

+ SANDBOX_WRITE_HOOK((u64)logical_addr_ptr, (u64)address);
switch (bit_width) {
case 8:

@@ -258,6 +263,7 @@ acpi_ex_system_memory_space_handler(u32 function,
break;
}

+ SANDBOX_SECT_END;
return_ACPI_STATUS(status);
}

diff --git a/drivers/acpi/acpica/sandbox.h b/drivers/acpi/acpica/sandbox.h
new file mode 100644
index 0000000000000000000000000000000000000000..1d9d95a87698dde14429f2f33a0c375ad51774fe
--- /dev/null
+++ b/drivers/acpi/acpica/sandbox.h
@@ -0,0 +1,139 @@
+/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
+/* SPDX-FileCopyrightText: Satoru Takekoshi, Manami Mori, Takaaki Fukai,
+ * Takahiro Shinagawa */
+/* SPDX-FileCopyrightText: Edgeless Systems GmbH */
+#include <asm/coco.h>
+#include <linux/cc_platform.h>
+#include <linux/efi.h>
+#include <linux/mm.h>
+#include <linux/once.h>
+#include <linux/sched.h>
+
+#define SANDBOX_READ_HOOK(virt_addr, phys_addr) { if (!__sandbox_validate_memory_access(virt_addr, phys_addr, true)) break; }
+#define SANDBOX_WRITE_HOOK(virt_addr, phys_addr) { if (!__sandbox_validate_memory_access(virt_addr, phys_addr, false)) break; }
+#define SANDBOX_SECT_START { __sandbox_section_start(); }
+#define SANDBOX_SECT_END { __sandbox_section_end(); }
+
+static struct __sandbox_access_log {
+ bool is_read;
+ unsigned long phys_addr;
+ unsigned long virt_addr;
+ bool access_allowed;
+} __sandbox_access_log;
+
+static void __sandbox_log_enabled(void)
+{
+ DO_ONCE(pr_info, "SANDBOX: Enabled\n");
+}
+
+static unsigned long __sandbox_get_page_table_entry(unsigned long addr)
+{
+ pgd_t *pgd;
+ p4d_t *p4d;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+
+ pgd = pgd_offset_k(addr);
+ if (pgd_none(*pgd)) {
+ return 0;
+ }
+
+ p4d = p4d_offset(pgd, addr);
+ if (p4d_none(*p4d)) {
+ return 0;
+ }
+
+ pud = pud_offset(p4d, addr);
+ if (pud_none(*pud)) {
+ return 0;
+ }
+
+ /* Check for 1GB huge page */
+ if (pud_leaf(*pud)) {
+ return pud_val(*pud);
+ }
+
+ pmd = pmd_offset(pud, addr);
+ if (pmd_none(*pmd)) {
+ return 0;
+ }
+
+ /* Check for 2MB huge page */
+ if (pmd_leaf(*pmd)) {
+ return pmd_val(*pmd);
+ }
+
+ pte = pte_offset_kernel(pmd, addr);
+ if (pte_none(*pte)) {
+ return 0;
+ }
+
+ return pte_val(*pte);
+}
+
+static bool __sandbox_is_encrypted_generic(unsigned long virt_addr)
+{
+ unsigned long val;
+
+ val = __sandbox_get_page_table_entry((unsigned long)(virt_addr));
+ if (val) {
+ return val == cc_mkenc(val);
+ } else {
+ ACPI_ERROR((AE_INFO, "SANDBOX: Page table walk failed"));
+ }
+
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "SANDBOX: Falling back to 'encrypted' state\n"));
+ return true;
+}
+
+static bool __sandbox_validate_memory_access(unsigned long virt_addr, unsigned long phys_addr, bool is_read)
+{
+ __sandbox_log_enabled();
+ __sandbox_access_log.is_read = is_read;
+ __sandbox_access_log.phys_addr = phys_addr;
+ __sandbox_access_log.virt_addr = virt_addr;
+ phys_addr &= PAGE_MASK;
+ virt_addr &= PAGE_MASK;
+
+ cond_resched();
+
+ bool encrypted = true;
+ if (cc_platform_has(CC_ATTR_MEM_ENCRYPT)) {
+ encrypted = __sandbox_is_encrypted_generic(virt_addr);
+ } else {
+ ACPI_ERROR((AE_INFO, "SANDBOX: Unknown platform"));
+ }
+
+ cond_resched();
+
+ if (!encrypted) {
+ return true;
+ }
+
+ __sandbox_access_log.access_allowed = false;
+ return false;
+}
+
+static void __sandbox_section_start(void)
+{
+ __sandbox_access_log.is_read = true;
+ __sandbox_access_log.phys_addr = 0xdeadbeefcafebabeuL;
+ __sandbox_access_log.virt_addr = 0xdeadbeefcafebabeuL;
+ __sandbox_access_log.access_allowed = true;
+}
+
+static void __sandbox_section_end(void)
+{
+ cond_resched();
+
+ ACPI_INFO((
+ "SANDBOX: ACCESS %s virt=%lx phys=%lx %s",
+ __sandbox_access_log.is_read ? "r" : "w",
+ (unsigned long)__sandbox_access_log.virt_addr,
+ (unsigned long)__sandbox_access_log.phys_addr,
+ __sandbox_access_log.access_allowed ? "allowed" : "denied"
+ ));
+
+ cond_resched();
+}
--
2.49.0