Kindly ignore this patch. It breaks the build. On Thu, Jul 16, 2020 at 4:54 PM Utkarsh Rai <utkarsh.ra...@gmail.com> wrote:
> - This is the complete set of changes for strict isolation of thread > stacks. > - There needs to be a confiuration operation,(#if > defined(USE_THREAD_STACK_PROTECTION) for simple configuration can be used) > - The stack attributes are allocated through malloc, this needs to be done > through score unlimited objects. > > Mechanism for thread-stack isolation > - Whenever a stack is allocated we assign READ_WRITE memory attributes to > the memory region, the stack attribute structure is appended to a chain for > tracking > - On each context switch, the executing stack is marked as 'not-current' > and we unset its memory attributes. The heir stack is marked as 'current' > - On context restore we set the memory attributes of the heir stack and > iterate thorugh the chain to check for any other 'current' stack and unset > its memory > attribute (This requires some refinement, so that we don't have to > iterate over the chain). > --- > .../include/bsp/arm-cp15-set-ttb-entries.h | 0 > bsps/arm/xilinx-zynq/mmu/bsp-set-mmu-attr.c | 79 ++++++++ > bsps/shared/start/stackalloc.c | 16 ++ > c/src/lib/libbsp/arm/xilinx-zynq/Makefile.am | 5 +- > cpukit/Makefile.am | 1 + > cpukit/headers.am | 2 + > cpukit/include/rtems/score/memorymanagement.h | 89 +++++++++ > cpukit/include/rtems/score/stackprotection.h | 149 ++++++++++++++ > cpukit/score/cpu/arm/cpu.c | 4 + > cpukit/score/cpu/arm/cpu_asm.S | 45 ++++- > .../score/cpu/arm/include/rtems/score/cpu.h | 18 ++ > cpukit/score/src/stackprotection.c | 188 ++++++++++++++++++ > 12 files changed, 593 insertions(+), 3 deletions(-) > create mode 100644 bsps/arm/include/bsp/arm-cp15-set-ttb-entries.h > create mode 100644 bsps/arm/xilinx-zynq/mmu/bsp-set-mmu-attr.c > create mode 100644 cpukit/include/rtems/score/memorymanagement.h > create mode 100644 cpukit/include/rtems/score/stackprotection.h > create mode 100644 cpukit/score/src/stackprotection.c > > diff --git a/bsps/arm/include/bsp/arm-cp15-set-ttb-entries.h > b/bsps/arm/include/bsp/arm-cp15-set-ttb-entries.h > new file mode 100644 > index 0000000000..e69de29bb2 > diff --git a/bsps/arm/xilinx-zynq/mmu/bsp-set-mmu-attr.c > b/bsps/arm/xilinx-zynq/mmu/bsp-set-mmu-attr.c > new file mode 100644 > index 0000000000..0c82f113a9 > --- /dev/null > +++ b/bsps/arm/xilinx-zynq/mmu/bsp-set-mmu-attr.c > @@ -0,0 +1,79 @@ > +#include <bsp/arm-cp15-start.h> > +#include <rtems/score/memorymanagement.h> > +#include <libcpu/arm-cp15.h> > +#include <rtems.h> > + > +#ifdef USE_THREAD_STACK_PROTECTION > + #define ARM_MMU_USE_SMALL_PAGES > +#endif > + > +void Memorymanagement_Set_entries(uintptr_t begin, size_t size, > Memorymanagement_flags flags) > +{ > + > + uintptr_t end; > + rtems_interrupt_level irq_level; > + uint32_t access_flags; > + > + end = begin + size; > + access_flags = Memorymanagement_Translate_flags(flags); > + > + /** > + * The ARM reference manual instructs to disable all the interrupts > before > + * setting up page table entries. > + */ > + rtems_interrupt_disable(irq_level); > + arm_cp15_set_translation_table_entries(begin, end, access_flags); > + rtems_interrupt_enable(irq_level); > +} > + > +void Memorymanagement_Unset_entries(uintptr_t begin, size_t size) > +{ > + uint32_t access_flags; > + uintptr_t end; > + rtems_interrupt_level irq_level; > + > + end = begin + size; > + access_flags = Memorymanagement_Translate_flags(NO_ACCESS); > + > + /** > + * The ARM reference manual instructs to disable all the interrupts > before > + * setting up page table entries. > + */ > + rtems_interrupt_disable(irq_level); > + arm_cp15_set_translation_table_entries(begin, end, access_flags); > + rtems_interrupt_enable(irq_level); > +} > + > + > +uint32_t Memorymanagement_Translate_flags(Memorymanagement_flags > attr_flags) > +{ > + uint32_t flags; > + switch (attr_flags) > + { > + case READ_WRITE: > + flags = ARMV7_MMU_READ_WRITE; > + break; > + > + case READ_WRITE_CACHED: > + flags = ARMV7_MMU_DATA_READ_WRITE_CACHED; > + break; > + > + case READ_ONLY: > + flags = ARMV7_MMU_READ_ONLY; > + break; > + > + case READ_ONLY_CACHED: > + flags = ARMV7_MMU_READ_ONLY_CACHED; > + break; > + > + case NO_ACCESS: > + flags = 0; > + break; > + > + default: > + return 0; > + break; > + } > + > + return flags; > +} > \ No newline at end of file > diff --git a/bsps/shared/start/stackalloc.c > b/bsps/shared/start/stackalloc.c > index f7cf7be0f1..ea8028c8db 100644 > --- a/bsps/shared/start/stackalloc.c > +++ b/bsps/shared/start/stackalloc.c > @@ -25,6 +25,7 @@ > #include <rtems.h> > #include <rtems/score/heapimpl.h> > #include <rtems/score/wkspace.h> > +#include <rtems/score/stackprotection.h> > > #include <bsp/linker-symbols.h> > > @@ -43,6 +44,7 @@ void bsp_stack_allocate_init(size_t stack_space_size) > void *bsp_stack_allocate(size_t size) > { > void *stack = NULL; > + uintptr_t page_table_base; > > if (bsp_stack_heap.area_begin != 0) { > stack = _Heap_Allocate(&bsp_stack_heap, size); > @@ -52,6 +54,20 @@ void *bsp_stack_allocate(size_t size) > stack = _Workspace_Allocate(size); > } > > +#ifdef USE_THREAD_STACK_PROTECTION > + /** > + * Although we are not performing page table switching, still we > assign a value > + * to avoid compiler warniing. > + */ > + page_table_base = (uintptr_t)0x1000; > + > + /** > + * The current way to get protected stack is to assign memory attributes > + * to the allocated memory. > + */ > + _Stackprotection_Allocate_attr( (uintptr_t)stack, size, page_table_base > ); > + > +#endif > return stack; > } > > diff --git a/c/src/lib/libbsp/arm/xilinx-zynq/Makefile.am > b/c/src/lib/libbsp/arm/xilinx-zynq/Makefile.am > index cfd59475c2..490f99792e 100644 > --- a/c/src/lib/libbsp/arm/xilinx-zynq/Makefile.am > +++ b/c/src/lib/libbsp/arm/xilinx-zynq/Makefile.am > @@ -74,6 +74,9 @@ librtemsbsp_a_SOURCES += > ../../../../../../bsps/arm/xilinx-zynq/i2c/cadence-i2c. > # Cache > librtemsbsp_a_SOURCES += > ../../../../../../bsps/arm/shared/cache/cache-l2c-310.c > > +#MMU > +librtemsbsp_a_SOURCES += > ../../../../../../bsps/arm/xilinx-zynq/mmu/bsp-set-mmu-attr.c > + > # Start hooks > librtemsbsp_a_SOURCES += > ../../../../../../bsps/arm/xilinx-zynq/start/bspstarthooks.c > librtemsbsp_a_SOURCES += > ../../../../../../bsps/arm/xilinx-zynq/start/bspstartmmu.c > @@ -85,4 +88,4 @@ librtemsbsp_a_SOURCES += > ../../../../../../bsps/arm/xilinx-zynq/start/bspstartmm > > include $(srcdir)/../../../../../../bsps/shared/irq-sources.am > include $(srcdir)/../../../../../../bsps/shared/shared-sources.am > -include $(srcdir)/../../../../../../bsps/arm/xilinx-zynq/headers.am > +include $(srcdir)/../../../../../../bsps/arm/xilinx-zynq/headers.am > \ No newline at end of file > diff --git a/cpukit/Makefile.am b/cpukit/Makefile.am > index 51f38c84c7..83f9bfb3ef 100644 > --- a/cpukit/Makefile.am > +++ b/cpukit/Makefile.am > @@ -929,6 +929,7 @@ librtemscpu_a_SOURCES += > score/src/schedulercbsgetserverid.c > librtemscpu_a_SOURCES += score/src/schedulercbssetparameters.c > librtemscpu_a_SOURCES += score/src/schedulercbsreleasejob.c > librtemscpu_a_SOURCES += score/src/schedulercbsunblock.c > +librtemscpu_a_SOURCES += score/src/stackprotection.c > librtemscpu_a_SOURCES += score/src/stackallocator.c > librtemscpu_a_SOURCES += score/src/pheapallocate.c > librtemscpu_a_SOURCES += score/src/pheapextend.c > diff --git a/cpukit/headers.am b/cpukit/headers.am > index fcf679f09d..2f16c71d9c 100644 > --- a/cpukit/headers.am > +++ b/cpukit/headers.am > @@ -352,6 +352,7 @@ include_rtems_score_HEADERS += > include/rtems/score/isr.h > include_rtems_score_HEADERS += include/rtems/score/isrlevel.h > include_rtems_score_HEADERS += include/rtems/score/isrlock.h > include_rtems_score_HEADERS += include/rtems/score/memory.h > +include_rtems_score_HEADERS += include/rtems/score/memorymanagement.h > include_rtems_score_HEADERS += include/rtems/score/mpci.h > include_rtems_score_HEADERS += include/rtems/score/mpciimpl.h > include_rtems_score_HEADERS += include/rtems/score/mppkt.h > @@ -405,6 +406,7 @@ include_rtems_score_HEADERS += > include/rtems/score/smplockstats.h > include_rtems_score_HEADERS += include/rtems/score/smplockticket.h > include_rtems_score_HEADERS += include/rtems/score/stack.h > include_rtems_score_HEADERS += include/rtems/score/stackimpl.h > +include_rtems_score_HEADERS += include/rtems/score/stackprotection.h > include_rtems_score_HEADERS += include/rtems/score/states.h > include_rtems_score_HEADERS += include/rtems/score/statesimpl.h > include_rtems_score_HEADERS += include/rtems/score/status.h > diff --git a/cpukit/include/rtems/score/memorymanagement.h > b/cpukit/include/rtems/score/memorymanagement.h > new file mode 100644 > index 0000000000..2a5490c680 > --- /dev/null > +++ b/cpukit/include/rtems/score/memorymanagement.h > @@ -0,0 +1,89 @@ > +/* SPDX-License-Identifier: BSD-2-Clause */ > + > +/** > + * @file > + * > + * @ingroup RTEMSScoreMemorymanagement > + * > + * @brief This file provodes APIs for high-level memory management > + * > + */ > + > +/* > + * Copyright (C) 2020 Utkarsh Rai > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#ifndef _RTEMS_SCORE_MEMORYMANAGEMENT_H > +#define _RTEMS_SCORE_MEMORYMANAGEMENT_H > + > +#include <rtems/score/basedefs.h> > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +/** This defines the various high-level memory access flags.*/ > +typedef enum > +{ > + READ_WRITE, > + READ_WRITE_CACHED, > + READ_ONLY, > + READ_ONLY_CACHED, > + NO_ACCESS > +} Memorymanagement_flags; > + > +/** > + * @brief Define the memory access permission for the specified memory > region > + * > + * @param begin_addr Begining of the memory region > + * @param size Size of the memory region > + * @param flag Memory access flag > + * > + */ > +void Memorymanagement_Set_entries(uintptr_t begin_addr, size_t size, > Memorymanagement_flags flag); > + > +/** > + * @brief Unset the memory access permission for the specified memory > region > + * This operation implcitly sets the specified memory region with > 'NO_ACCESS' > + * flag. > + * > + * @param begin_addr Begining of the memory region > + * @param size Size of the memory region > + */ > +void Memorymanagement_Unset_entries(uintptr_t begin_addr, size_t size); > + > +/** > + * @brief Translate the high-level flags to BSP-specifc MMU flags. > + * > + * @param attr_flags High-level memory access flags. > + * > + * @retval flag BSP-specifc MMU flag > + */ > +uint32_t Memorymanagement_Translate_flags(Memorymanagement_flags > attr_flags); > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif > \ No newline at end of file > diff --git a/cpukit/include/rtems/score/stackprotection.h > b/cpukit/include/rtems/score/stackprotection.h > new file mode 100644 > index 0000000000..91e3f6daba > --- /dev/null > +++ b/cpukit/include/rtems/score/stackprotection.h > @@ -0,0 +1,149 @@ > +/** > + * @file > + * > + * @ingroup RTEMSScoreStackprotection > + * > + * @brief Stackprotection API > + * > + * This include file provides the API for the management of protected > thread- > + * stacks > + */ > + > +/* > + * COPYRIGHT (c) 2020 Utkarsh Rai. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER > IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR > OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > + * > + */ > + > +#ifndef _RTEMS_SCORE_STACKPROTECTION_H > +#define _RTEMS_SCORE_STACKPROTECTION_H > + > +#if defined ( ASM ) > +#include <rtems/asm.h> > +#else > + #include <rtems/score/basedefs.h> > + #include <rtems/score/memorymanagement.h> > + #include <rtems/score/chainimpl.h> > +#endif > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +#if !defined ( ASM ) > + > +/** > + * The following defines the attributes of a protected stack > + */ > +typedef struct > +{ > + /** This is the node to the chain for tracking each allocated/shared > stack */ > + Chain_Node node; > + /** This is the stack address */ > + uintptr_t stack_address; > + /** This is the stack size */ > + size_t size; > + /** This is the pointer to the page table base */ > + uintptr_t page_table_base; > + /**Memory flag for the alllocated/shared stack */ > + Memorymanagement_flags access_flags; > +} Stackprotection_Attr; > + > +/** > + * The following defines the control block of a shared stack > + */ > +typedef struct > +{ > + /** This is the attribute of a shared stack*/ > + Stackprotection_Attr Base; > +} Stackprotection_Shared_stack; > + > +/** > + * The following defines the control block of an allocated stack > + */ > +typedef struct > +{ > + /** This is the attribute of an allocated stack*/ > + Stackprotection_Attr Base; > + /** This is the pointer to the attributes of a stack shared with the > stack > + * in question > + */ > + Stackprotection_Shared_stack *shared_stacks; > + /**This marks if the stack in question belongs to an executing thread*/ > + bool current_stack; > +} Stackprotection_The_stack; > + > +/** > + * @brief Allocate the attributes of the stack in question. > + * > + * @param freechain The stack address. > + * @param size Size of the stack. > + * @param page_table_base Pointer to the start of a page table > + */ > +void _Stackprotection_Allocate_attr(uintptr_t stack_address, size_t size, > uintptr_t page_table_base); > + > +/** > + * @brief Share a stack with another stack. > + * > + * @param shared_stack The stack to be shared > + * @param target_stack The stack with which to share > + */ > +void _Stackprotection_Share_stack(Stackprotection_The_stack > *shared_stack, Stackprotection_The_stack* target_stack); > + > +/** > + * @brief Initialize the context of a thread with the control block of a > + * protected stack > + * > + * @retval the_stack The protected stack > + */ > +Stackprotection_The_stack *_Stackprotection_Context_initialize(void); > + > +/** > + * @brief Swap out the executing protected stack from the page table > during > + * context switch > + * > + * The current method of switching the protected stack is to mark the > switched > + * out stack as 'NO ACCESS' > + * > + * @param excuting_stack Control block of the executing stack > + */ > +void _Stackprotection_Context_switch(Stackprotection_The_stack > *executing_stack, Stackprotection_The_stack *heir_stack); > + > +/** > + * @brief Swap the restored protected stack in the page table during > context > + * restoration > + * > + * We set the entries of the restored stack and mark all the remainig > stacks as > + * 'NO-ACCESS'. > + * > + * @param Control block of the restored stack > + */ > +void _Stackprotection_Context_restore(Stackprotection_The_stack > *restored_stack); > + > +#endif /* !defined ( ASM ) */ > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif > diff --git a/cpukit/score/cpu/arm/cpu.c b/cpukit/score/cpu/arm/cpu.c > index 07b9588afd..cbb62d45e5 100644 > --- a/cpukit/score/cpu/arm/cpu.c > +++ b/cpukit/score/cpu/arm/cpu.c > @@ -28,6 +28,7 @@ > > #include <rtems/score/assert.h> > #include <rtems/score/cpu.h> > +#include <rtems/score/stackprotection.h> > #include <rtems/score/thread.h> > #include <rtems/score/tls.h> > > @@ -97,6 +98,9 @@ void _CPU_Context_Initialize( > { > (void) new_level; > > + #if defined (USE_THREAD_STACK_PROTECTION) > + the_context->the_stack = _Stackprotection_Context_initialize(); > + #endif > the_context->register_sp = (uint32_t) stack_area_begin + > stack_area_size; > the_context->register_lr = (uint32_t) entry_point; > the_context->isr_dispatch_disable = 0; > diff --git a/cpukit/score/cpu/arm/cpu_asm.S > b/cpukit/score/cpu/arm/cpu_asm.S > index 66f8ba6032..7473303f02 100644 > --- a/cpukit/score/cpu/arm/cpu_asm.S > +++ b/cpukit/score/cpu/arm/cpu_asm.S > @@ -36,7 +36,7 @@ > #ifdef ARM_MULTILIB_ARCH_V4 > > .text > - > + > /* > * void _CPU_Context_switch( run_context, heir_context ) > * void _CPU_Context_restore( run_context, heir_context ) > @@ -66,6 +66,27 @@ DEFINE_FUNCTION_ARM(_CPU_Context_switch) > > str r3, [r0, #ARM_CONTEXT_CONTROL_ISR_DISPATCH_DISABLE] > > +#if defined ( USE_THREAD_STACK_PROTECTION ) > + /* > + * Save the registers modifed during function call > + */ > + mov r8, r0 > + mov r9, r1 > + mov r10, r2 > + /* > + * Load the parameters to be passed > + */ > + ldr r0, [r0, #ARM_CONTEXT_CONTROL_STACK_ATTR_OFFSET] > + ldr r1, [r1, #ARM_CONTEXT_CONTROL_STACK_ATTR_OFFSET] > + bl _Stackprotection_Context_switch > + /* > + * Restore the saved registers > + */ > + mov r0, r8 > + mov r1, r9 > + mov r2, r10 > +#endif > + > #ifdef RTEMS_SMP > /* > * The executing thread no longer executes on this processor. > Switch > @@ -132,7 +153,27 @@ DEFINE_FUNCTION_ARM(_CPU_Context_switch) > * > */ > DEFINE_FUNCTION_ARM(_CPU_Context_restore) > - mov r1, r0 > + > + mov r1, r0 > +#if defined( USE_THREAD_STACK_PROTECTION ) > + /* > + * Save the registers modifed during function call > + */ > + mov r8, r0 > + mov r9, r1 > + mov r10, r2 > + /* > + * Load the parameters to be passed > + */ > + ldr r0, [r0, #ARM_CONTEXT_CONTROL_STACK_ATTR_OFFSET] > + bl _Stackprotection_Context_switch > + /* > + * Restore the saved registers > + */ > + mov r0, r8 > + mov r1, r9 > + mov r2, r10 > +#endif > GET_SELF_CPU_CONTROL r2 > b .L_restore > > diff --git a/cpukit/score/cpu/arm/include/rtems/score/cpu.h > b/cpukit/score/cpu/arm/include/rtems/score/cpu.h > index b7b48a3ac3..df13fed258 100644 > --- a/cpukit/score/cpu/arm/include/rtems/score/cpu.h > +++ b/cpukit/score/cpu/arm/include/rtems/score/cpu.h > @@ -34,6 +34,7 @@ > #include <rtems/score/paravirt.h> > #endif > #include <rtems/score/arm.h> > +#include <rtems/score/stackprotection.h> > > /** > * @addtogroup RTEMSScoreCPUARM > @@ -157,6 +158,21 @@ > > #ifdef ARM_MULTILIB_HAS_THREAD_ID_REGISTER > #define ARM_CONTEXT_CONTROL_THREAD_ID_OFFSET 44 > + #ifdef ARM_MULITLIB_VFP > + #define ARM_STACK_PROT_ATTR_OFFSET 112 > + #else > + #define ARM_STACK_PROT_ATTR_OFFSET 48 > + #endif > +#endif > + > +#ifdef USE_THREAD_STACK_PROTECTION > + #if defined ARM_MULITLIB_VFP > + #define ARM_CONTEXT_CONTROL_STACK_ATTR_OFFSET 112 > + #elif ARM_MULTILIB_HAS_THREAD_ID_REGISTER > + #define ARM_CONTEXT_CONTROL_STACK_ATTR_OFFSET 48 > + #else > + #define ARM_CONTEXT_CONTROL_STACK_ATTR_OFFSET 44 > + #endif > #endif > > #ifdef ARM_MULTILIB_VFP > @@ -185,6 +201,7 @@ > > #define ARM_VFP_CONTEXT_SIZE 264 > > + > #ifndef ASM > > #ifdef __cplusplus > @@ -235,6 +252,7 @@ typedef struct { > #ifdef RTEMS_SMP > volatile bool is_executing; > #endif > +Stackprotection_The_stack *the_stack; > } Context_Control; > > static inline void _ARM_Data_memory_barrier( void ) > diff --git a/cpukit/score/src/stackprotection.c > b/cpukit/score/src/stackprotection.c > new file mode 100644 > index 0000000000..20c5a17b0e > --- /dev/null > +++ b/cpukit/score/src/stackprotection.c > @@ -0,0 +1,188 @@ > +/* SPDX-License-Identifier: BSD-2-Clause */ > + > +/** > + * @file > + * > + * @ingroup RTEMSScoreStackprotection > + * > + * @brief Short "Table of Contents" Description of File Contents > + * > + * A short description of the purpose of this file. > + */ > + > +/* > + * Copyright (C) 2020 Utkarsh Rai > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > + */ > + > + > +#ifdef HAVE_CONFIG_H > +#include "config.h" > +#endif > + > +#include <rtems/score/stackprotection.h> > + > +Chain_Control _Stackprotection_node_control = > CHAIN_INITIALIZER_EMPTY(_Stackprotection_node_control); > + > +static void _Stackprotection_Remove_prev_entry(void) > +{ > + > + Chain_Node *node; > + Stackprotection_The_stack *prot_stack; > + > + if( _Chain_Is_empty(&_Stackprotection_node_control) == true ) { > + _Chain_Initialize_empty(&_Stackprotection_node_control); > + } > + node = _Chain_First( &_Stackprotection_node_control ); > + > + while(_Chain_Is_tail(&_Stackprotection_node_control, node) == false) > { > + > + prot_stack = RTEMS_CONTAINER_OF(node,Stackprotection_The_stack, > Base.node); > + > + if( prot_stack->current_stack == false ) { > + > Memorymanagement_Unset_entries(prot_stack->Base.stack_address, > prot_stack->Base.size); > + } > + node = _Chain_Immutable_next( node ); > + } > + > +} > + > +/* > +Iterate to the end of the chain and mark all the 'currnet' stack as false > +Append the current stack attribute to the end of the chain > +*/ > +static void _Stackprotection_Append_chain (Chain_Control *control, > Stackprotection_The_stack *stack_append_attr) > +{ > + Chain_Node *node; > + Stackprotection_The_stack *present_stacks_attr; > + > + if(_Chain_Is_empty(&_Stackprotection_node_control) == true ) { > + > + _Chain_Initialize_one(&_Stackprotection_node_control, > &stack_append_attr->Base.node); > + } else { > + _Chain_Append_unprotected(&_Stackprotection_node_control, > &stack_append_attr->Base.node); > + } > +} > + > +void _Stackprotection_Allocate_attr(uintptr_t stack_address, size_t > size, uintptr_t page_table_base) > +{ > + Stackprotection_The_stack *prot_stack; > + > +/*This field will be refactored and score objects will be used for > dynamic allocation*/ > + prot_stack = malloc(sizeof(Stackprotection_The_stack)); > + > + if(prot_stack != NULL) { > + prot_stack->Base.stack_address = stack_address; > + prot_stack->Base.size = size; > + prot_stack->Base.page_table_base = page_table_base; > + prot_stack->Base.access_flags = READ_WRITE_CACHED; > + prot_stack->current_stack = true; > + } > + > + /* > + Add the attribute field to the end of the chain, remove the memory > entries of > + previously allocated stack and set the memory entry of the currnet > stack. > + */ > + _Stackprotection_Append_chain(&_Stackprotection_node_control, > prot_stack ); > + Memorymanagement_Set_entries(stack_address, size, READ_WRITE_CACHED); > + > +} > + > +Stackprotection_The_stack *_Stackprotection_Context_initialize(void) > +{ > + Chain_Node *node; > + Stackprotection_The_stack *prot_stack; > + > + if( _Chain_Is_empty(&_Stackprotection_node_control) == false ) { > + node = _Chain_First( &_Stackprotection_node_control ); > + > + while( _Chain_Is_tail(&_Stackprotection_node_control, node ) == > false) { > + prot_stack = RTEMS_CONTAINER_OF( node, > Stackprotection_The_stack, Base.node); > + > + if(prot_stack->current_stack == true) { > + return prot_stack; > + } else { > + node = _Chain_Immutable_next( node ); > + } > + } > + } > + > + return prot_stack; > +} > + > +void _Stackprotection_Context_switch(Stackprotection_The_stack > *executing_stack, Stackprotection_The_stack *heir_stack) > +{ > + void *stack_address; > + size_t size; > + Chain_Node *node; > + Chain_Control *shared_node_control; > + > + /* > + Remove the stacks shared with the current stack by iterating the > chain > + */ > + if( executing_stack != NULL) { > + > + stack_address = executing_stack->Base.stack_address; > + size = executing_stack->Base.size; > + > + if(executing_stack->current_stack == true) { > + executing_stack->current_stack = false; > + Memorymanagement_Unset_entries(stack_address, size); > + } > + } > + > + _Stackprotection_Context_restore(heir_stack); > + > +} > + > +void _Stackprotection_Context_restore(Stackprotection_The_stack > *heir_stack) > +{ > + void *stack_address; > + size_t size; > + Chain_Node *node; > + Memorymanagement_flags flags; > + Chain_Control *shared_node_control; > + Stackprotection_The_stack *present_stacks_attr; > + > + if(heir_stack != NULL) { > + heir_stack->current_stack = true; > + stack_address = heir_stack->Base.stack_address; > + size = heir_stack->Base.size; > + flags = heir_stack->Base.access_flags; > + Memorymanagement_Set_entries(stack_address, size, flags); > + } > + > + node = _Chain_First(&_Stackprotection_node_control); > + /** Iterate through the chain and unset memory entries of all the > + * previous thread-stacks > + */ > + while(_Chain_Is_tail(&_Stackprotection_node_control,node) == false) { > + > + present_stacks_attr = RTEMS_CONTAINER_OF(node, > Stackprotection_The_stack, Base.node); > + > + if(present_stacks_attr->current_stack == true && > present_stacks_attr != heir_stack) > + present_stacks_attr->current_stack = false; > + > Memorymanagement_Unset_entries(present_stacks_attr->Base.stack_address, > present_stacks_attr->Base.size); > + node = _Chain_Immutable_next( node ); > + } > +} > -- > 2.17.1 > >
_______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel