From 10d6cc0ae9a5dec8792bfb10afd19746376b3549 Mon Sep 17 00:00:00 2001 From: Gerwin Klein Date: Fri, 13 Aug 2021 18:25:16 +1000 Subject: [PATCH] arm: flush cache to RAM on retype reset This fixes a correctness and security issue where uncached user mappings might see old data from before the clearMemory operation. See also the discussion on GitHub issue #481 Signed-off-by: Gerwin Klein --- include/arch/arm/arch/machine.h | 7 ++++--- src/arch/arm/32/kernel/vspace.c | 2 +- src/arch/arm/64/kernel/vspace.c | 6 +++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/include/arch/arm/arch/machine.h b/include/arch/arm/arch/machine.h index 9448eba90..a01bfd0df 100644 --- a/include/arch/arm/arch/machine.h +++ b/include/arch/arm/arch/machine.h @@ -50,14 +50,15 @@ void cleanInvalidateL1Caches(void); static inline void clearMemory(word_t *ptr, word_t bits) { memzero(ptr, BIT(bits)); - cleanCacheRange_PoU((word_t)ptr, (word_t)ptr + BIT(bits) - 1, + cleanCacheRange_RAM((word_t)ptr, (word_t)ptr + BIT(bits) - 1, addrFromPPtr(ptr)); } -static inline void clearMemoryRAM(word_t *ptr, word_t bits) +/* Cleaning memory before page table walker access */ +static inline void clearMemory_PT(word_t *ptr, word_t bits) { memzero(ptr, BIT(bits)); - cleanCacheRange_RAM((word_t)ptr, (word_t)ptr + BIT(bits) - 1, + cleanCacheRange_PoU((word_t)ptr, (word_t)ptr + BIT(bits) - 1, addrFromPPtr(ptr)); } diff --git a/src/arch/arm/32/kernel/vspace.c b/src/arch/arm/32/kernel/vspace.c index 97426acf5..41668a587 100644 --- a/src/arch/arm/32/kernel/vspace.c +++ b/src/arch/arm/32/kernel/vspace.c @@ -1886,7 +1886,7 @@ static exception_t performPageTableInvocationUnmap(cap_t cap, cte_t *ctSlot) cap_page_table_cap_get_capPTMappedASID(cap), cap_page_table_cap_get_capPTMappedAddress(cap), pt); - clearMemory((void *)pt, cap_get_capSizeBits(cap)); + clearMemory_PT((void *)pt, cap_get_capSizeBits(cap)); } cap_page_table_cap_ptr_set_capPTIsMapped(&(ctSlot->cap), 0); diff --git a/src/arch/arm/64/kernel/vspace.c b/src/arch/arm/64/kernel/vspace.c index 249f9b34a..26968af93 100644 --- a/src/arch/arm/64/kernel/vspace.c +++ b/src/arch/arm/64/kernel/vspace.c @@ -1508,7 +1508,7 @@ static exception_t performUpperPageDirectoryInvocationUnmap(cap_t cap, cte_t *ct pude_t *pud = PUD_PTR(cap_page_upper_directory_cap_get_capPUDBasePtr(cap)); unmapPageUpperDirectory(cap_page_upper_directory_cap_get_capPUDMappedASID(cap), cap_page_upper_directory_cap_get_capPUDMappedAddress(cap), pud); - clearMemory((void *)pud, cap_get_capSizeBits(cap)); + clearMemory_PT((void *)pud, cap_get_capSizeBits(cap)); } cap_page_upper_directory_cap_ptr_set_capPUDIsMapped(&(ctSlot->cap), 0); @@ -1531,7 +1531,7 @@ static exception_t performPageDirectoryInvocationUnmap(cap_t cap, cte_t *ctSlot) pde_t *pd = PD_PTR(cap_page_directory_cap_get_capPDBasePtr(cap)); unmapPageDirectory(cap_page_directory_cap_get_capPDMappedASID(cap), cap_page_directory_cap_get_capPDMappedAddress(cap), pd); - clearMemory((void *)pd, cap_get_capSizeBits(cap)); + clearMemory_PT((void *)pd, cap_get_capSizeBits(cap)); } cap_page_directory_cap_ptr_set_capPDIsMapped(&(ctSlot->cap), 0); @@ -1553,7 +1553,7 @@ static exception_t performPageTableInvocationUnmap(cap_t cap, cte_t *ctSlot) pte_t *pt = PT_PTR(cap_page_table_cap_get_capPTBasePtr(cap)); unmapPageTable(cap_page_table_cap_get_capPTMappedASID(cap), cap_page_table_cap_get_capPTMappedAddress(cap), pt); - clearMemory((void *)pt, cap_get_capSizeBits(cap)); + clearMemory_PT((void *)pt, cap_get_capSizeBits(cap)); } cap_page_table_cap_ptr_set_capPTIsMapped(&(ctSlot->cap), 0);