[PATCH v2] Strict thread-stack isolation
Utkarsh Rai
utkarsh.rai60 at gmail.com
Thu Jul 16 11:29:31 UTC 2020
Kindly ignore this patch. It breaks the build.
On Thu, Jul 16, 2020 at 4:54 PM Utkarsh Rai <utkarsh.rai60 at 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
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/devel/attachments/20200716/dee54333/attachment-0001.html>
More information about the devel
mailing list