diff options
author | Olivier Deprez <olivier.deprez@arm.com> | 2021-04-22 14:39:54 +0200 |
---|---|---|
committer | Olivier Deprez <olivier.deprez@arm.com> | 2022-03-01 18:51:43 +0100 |
commit | 20b9b1784f209811a05db71f8503980c97f4634a (patch) | |
tree | 8c5da473df4f3cab66eeb9c12ed7c45f62a7d635 /spm | |
parent | 572ee4fde07faf8c208ebfd1bcaf745a93db003d (diff) |
test(cactus): prevent realm region access from swd
This change adds TFTF and cactus tests to check a realm region cannot
be accessed from secure world.
A non-secure buffer is delegated to realm PAS and shared to a secure
partition through FF-A memory sharing operations.
The SP retrieves the region from the SPM, maps it and attempts a write
access. The PE is expected to trigger a GPF data abort caught by a
custom exception handler.
Exception is trapped at S-EL1 within the secure partition because
Hafnium configures HCR_EL2.GPF=0 (and SCR_EL3.GPF=0).
Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
Change-Id: I8f855f394d0490b3584e60ceba4f3d2a20197495
Diffstat (limited to 'spm')
-rw-r--r-- | spm/cactus/aarch64/cactus_exceptions.S | 27 | ||||
-rw-r--r-- | spm/cactus/cactus.mk | 1 | ||||
-rw-r--r-- | spm/cactus/cactus_main.c | 7 | ||||
-rw-r--r-- | spm/cactus/cactus_tests/cactus_test_memory_sharing.c | 32 |
4 files changed, 48 insertions, 19 deletions
diff --git a/spm/cactus/aarch64/cactus_exceptions.S b/spm/cactus/aarch64/cactus_exceptions.S index 6aec16d..9b024f8 100644 --- a/spm/cactus/aarch64/cactus_exceptions.S +++ b/spm/cactus/aarch64/cactus_exceptions.S @@ -31,14 +31,16 @@ unhandled_exception serr_sp0 /* * Current EL with SPx : 0x200 - 0x400. */ -unhandled_exception sync_spx +vector_entry sync_spx + b sync_exception_vector_entry +end_vector_entry sync_spx vector_entry irq_spx - b irq_vector_entry + b interrupt_vector_entry end_vector_entry irq_spx vector_entry fiq_spx - b fiq_vector_entry + b interrupt_vector_entry end_vector_entry fiq_spx unhandled_exception serr_spx @@ -98,23 +100,30 @@ unhandled_exception serr_a32 ldp x0, x1, [sp, #0x0] .endm -func irq_vector_entry +func sync_exception_vector_entry sub sp, sp, #0x100 save_gp_regs - bl cactus_interrupt_handler - restore_gp_regs + mov x19, sp + bl tftf_sync_exception_handler + cbnz x0, 0f + mov x0, x19 + /* Save original stack pointer value on the stack */ + add x1, x0, #0x100 + str x1, [x0, #0xf8] + b print_exception +0: restore_gp_regs add sp, sp, #0x100 eret -endfunc irq_vector_entry +endfunc sync_exception_vector_entry -func fiq_vector_entry +func interrupt_vector_entry sub sp, sp, #0x100 save_gp_regs bl cactus_interrupt_handler restore_gp_regs add sp, sp, #0x100 eret -endfunc fiq_vector_entry +endfunc interrupt_vector_entry func crash_dump /* Save general-purpose registers on the stack. */ diff --git a/spm/cactus/cactus.mk b/spm/cactus/cactus.mk index 4109579..8970b29 100644 --- a/spm/cactus/cactus.mk +++ b/spm/cactus/cactus.mk @@ -68,6 +68,7 @@ CACTUS_SOURCES += drivers/arm/pl011/${ARCH}/pl011_console.S \ lib/smc/${ARCH}/asm_smc.S \ lib/smc/${ARCH}/smc.c \ lib/smc/${ARCH}/hvc.c \ + lib/exceptions/${ARCH}/sync.c \ lib/locks/${ARCH}/spinlock.S \ lib/utils/mp_printf.c \ ${XLAT_TABLES_LIB_SRCS} diff --git a/spm/cactus/cactus_main.c b/spm/cactus/cactus_main.c index c80abd9..58186d1 100644 --- a/spm/cactus/cactus_main.c +++ b/spm/cactus/cactus_main.c @@ -181,13 +181,6 @@ static void register_secondary_entrypoint(void) tftf_smc(&args); } -int tftf_irq_handler_dispatcher(void) -{ - ERROR("%s\n", __func__); - - return 0; -} - void __dead2 cactus_main(bool primary_cold_boot) { assert(IS_IN_EL1() != 0); diff --git a/spm/cactus/cactus_tests/cactus_test_memory_sharing.c b/spm/cactus/cactus_tests/cactus_test_memory_sharing.c index 69d62dd..051208e 100644 --- a/spm/cactus/cactus_tests/cactus_test_memory_sharing.c +++ b/spm/cactus/cactus_tests/cactus_test_memory_sharing.c @@ -14,6 +14,27 @@ #include <sp_helpers.h> #include <xlat_tables_defs.h> #include <lib/xlat_tables/xlat_tables_v2.h> +#include <sync.h> + +static volatile uint32_t data_abort_gpf_triggered; + +static bool data_abort_gpf_handler(void) +{ + uint64_t esr_el1 = read_esr_el1(); + + VERBOSE("%s count %u esr_el1 %llx elr_el1 %llx\n", + __func__, data_abort_gpf_triggered, esr_el1, + read_elr_el1()); + + /* Expect a data abort because of a GPF. */ + if ((EC_BITS(esr_el1) == EC_DABORT_CUR_EL) && + ((ISS_BITS(esr_el1) & ISS_DFSC_MASK) == DFSC_GPF_DABORT)) { + data_abort_gpf_triggered++; + return true; + } + + return false; +} /** * Each Cactus SP has a memory region dedicated to memory sharing tests @@ -51,7 +72,7 @@ CACTUS_CMD_HANDLER(mem_send_cmd, CACTUS_MEM_SEND_CMD) cactus_mem_send_get_retrv_flags(*args); uint32_t words_to_write = cactus_mem_send_words_to_write(*args); - expect(memory_retrieve(mb, &m, handle, source, vm_id, mem_func, + expect(memory_retrieve(mb, &m, handle, source, vm_id, retrv_flags), true); composite = ffa_memory_region_get_composite(m, 0); @@ -104,12 +125,17 @@ CACTUS_CMD_HANDLER(mem_send_cmd, CACTUS_MEM_SEND_CMD) } } + data_abort_gpf_triggered = 0; + register_custom_sync_exception_handler(data_abort_gpf_handler); + /* Write mem_func to retrieved memory region for validation purposes. */ VERBOSE("Writing: %x\n", mem_func); for (unsigned int i = 0U; i < words_to_write; i++) { ptr[i] = mem_func; } + unregister_custom_sync_exception_handler(); + /* * A FFA_MEM_DONATE changes the ownership of the page, as such no * relinquish is needed. @@ -120,7 +146,7 @@ CACTUS_CMD_HANDLER(mem_send_cmd, CACTUS_MEM_SEND_CMD) composite->constituents[0].page_count * PAGE_SIZE); if (ret != 0) { - ERROR("Failed first mmap_add_dynamic_region!\n"); + ERROR("Failed to unmap received memory region(%d)!\n", ret); return cactus_error_resp(vm_id, source, CACTUS_ERROR_TEST); } @@ -139,7 +165,7 @@ CACTUS_CMD_HANDLER(mem_send_cmd, CACTUS_MEM_SEND_CMD) } return cactus_success_resp(vm_id, - source, 0); + source, data_abort_gpf_triggered); } CACTUS_CMD_HANDLER(req_mem_send_cmd, CACTUS_REQ_MEM_SEND_CMD) |