Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add secured page allocator for uVisor #2052

Merged
merged 3 commits into from
Jun 29, 2016
Merged
Show file tree
Hide file tree
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
8 changes: 4 additions & 4 deletions features/FEATURE_UVISOR/AUTHORS.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
513 Milosch Meriac
424 Alessandro Angelino
18 Jaeden Amero
18 Niklas Hauser
511 Milosch Meriac
433 Alessandro Angelino
28 Niklas Hauser
22 Jaeden Amero
3 Hugo Vincent
3 JaredCJR
3 Jim Huang
Expand Down
2 changes: 1 addition & 1 deletion features/FEATURE_UVISOR/VERSION.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v0.9.17-alpha
v0.9.20-alpha
1 change: 1 addition & 0 deletions features/FEATURE_UVISOR/importer/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ rsync:
rm -rf $(TARGET_LIB_SRC)
mkdir -p $(TARGET_LIB_SRC)
cp $(UVISOR_DIR)/core/system/src/page_allocator.c $(TARGET_LIB_SRC)/page_allocator.c_inc
cp $(UVISOR_DIR)/core/system/inc/page_allocator_config.h $(TARGET_LIB_SRC)/page_allocator_config.h
rsync -a --delete $(UVISOR_API)/rtx/src/ $(TARGET_LIB_SRC)/rtx
#
# Copying licenses
Expand Down
10 changes: 4 additions & 6 deletions features/FEATURE_UVISOR/includes/uvisor/api/inc/box_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ UVISOR_EXTERN const uint32_t __uvisor_mode;
0, \
0, \
0, \
0, \
NULL, \
acl_list, \
acl_list_count \
Expand Down Expand Up @@ -78,8 +77,7 @@ UVISOR_EXTERN const uint32_t __uvisor_mode;
sizeof(RtxBoxIndex), \
context_size, \
__uvisor_box_heapsize, \
__uvisor_box_main_function, \
__uvisor_box_main_priority, \
__uvisor_box_lib_config, \
__uvisor_box_namespace, \
acl_list, \
acl_list_count \
Expand Down Expand Up @@ -123,9 +121,9 @@ UVISOR_EXTERN const uint32_t __uvisor_mode;
/* Use this macro before UVISOR_BOX_CONFIG to define the function the main
* thread of your box will use for its body. If you don't want a main thread,
* too bad: you have to have one. */
#define UVISOR_BOX_MAIN(function, priority) \
static void (*const __uvisor_box_main_function)(void const *) = (function); \
static const int32_t __uvisor_box_main_priority = (priority);
#define UVISOR_BOX_MAIN(function, priority, stack_size) \
static osThreadDef(function, priority, stack_size); \
static const void * const __uvisor_box_lib_config = osThread(function);

#define UVISOR_BOX_HEAPSIZE(heap_size) \
static const uint32_t __uvisor_box_heapsize = heap_size;
Expand Down
9 changes: 6 additions & 3 deletions features/FEATURE_UVISOR/includes/uvisor/api/inc/svc_exports.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,12 @@
#define UVISOR_SVC_ID_PAGE_FREE UVISOR_SVC_CUSTOM_TABLE(23)

/* SVC immediate values for hardcoded table (call from unprivileged) */
#define UVISOR_SVC_ID_UNVIC_OUT UVISOR_SVC_FIXED_TABLE(0, 0)
#define UVISOR_SVC_ID_REGISTER_GATEWAY UVISOR_SVC_FIXED_TABLE(3, 0)
#define UVISOR_SVC_ID_BOX_MAIN_NEXT UVISOR_SVC_FIXED_TABLE(5, 0)
#define UVISOR_SVC_ID_UNVIC_OUT UVISOR_SVC_FIXED_TABLE(0, 0)
/* Deprecated: UVISOR_SVC_ID_CX_IN(nargs) UVISOR_SVC_FIXED_TABLE(1, nargs) */
/* Deprecated: UVISOR_SVC_ID_CX_OUT UVISOR_SVC_FIXED_TABLE(2, 0) */
#define UVISOR_SVC_ID_REGISTER_GATEWAY UVISOR_SVC_FIXED_TABLE(3, 0)
#define UVISOR_SVC_ID_BOX_INIT_FIRST UVISOR_SVC_FIXED_TABLE(4, 0)
#define UVISOR_SVC_ID_BOX_INIT_NEXT UVISOR_SVC_FIXED_TABLE(5, 0)

/* SVC immediate values for hardcoded table (call from privileged) */
#define UVISOR_SVC_ID_UNVIC_IN UVISOR_SVC_FIXED_TABLE(0, 0)
Expand Down
20 changes: 16 additions & 4 deletions features/FEATURE_UVISOR/includes/uvisor/api/inc/vmpu_exports.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,24 @@

#if defined(UVISOR_PRESENT) && UVISOR_PRESENT == 1

/** Round an address down to the closest 32-byte boundary.
* @param address[in] The address to round.
*/
#define UVISOR_ROUND32_DOWN(address) ((address) & ~0x1FUL)

/** Round an address up to the closest 32-byte boundary.
* @param address[in] The address to round.
*/
#define UVISOR_ROUND32_UP(address) UVISOR_ROUND32_DOWN((address) + 31UL)


#if defined(ARCH_MPU_ARMv7M)
#define UVISOR_REGION_ROUND_DOWN(x) ((x) & ~((1UL << UVISOR_REGION_BITS(x)) - 1))
#define UVISOR_REGION_ROUND_UP(x) (1UL << UVISOR_REGION_BITS(x))
#define UVISOR_STACK_SIZE_ROUND(x) UVISOR_REGION_ROUND_UP(x)
#elif defined(ARCH_MPU_KINETIS)
#define UVISOR_REGION_ROUND_DOWN(x) ((x) & ~0x1FUL)
#define UVISOR_REGION_ROUND_UP(x) UVISOR_REGION_ROUND_DOWN((x) + 31UL)
#define UVISOR_REGION_ROUND_DOWN(x) UVISOR_ROUND32_DOWN(x)
#define UVISOR_REGION_ROUND_UP(x) UVISOR_ROUND32_UP(x)
#define UVISOR_STACK_SIZE_ROUND(x) UVISOR_REGION_ROUND_UP((x) + (UVISOR_STACK_BAND_SIZE * 2))
#else
#error "Unknown MPU architecture. uvisor: Check your Makefile. uvisor-lib: Check if uVisor is supported"
Expand Down Expand Up @@ -158,8 +169,9 @@ typedef struct {
/* Contains user provided size of box heap without guards of buffers. */
uint32_t heap_size;

void (*main_function)(void const *argument);
int32_t main_priority;
/* Opaque-to-uVisor data that potentially contains uvisor-lib-specific or
* OS-specific per-box configuration */
const void * const lib_config;

const char * box_namespace;
const UvisorBoxAclItem * const acl_list;
Expand Down
55 changes: 25 additions & 30 deletions features/FEATURE_UVISOR/source/page_allocator.c_inc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include <uvisor.h>
#include "page_allocator.h"
#include "page_allocator_faults.h"
#include "mpu/vmpu_unpriv_access.h"
#include "mpu/vmpu.h"
#include "halt.h"
Expand All @@ -38,40 +39,31 @@

#endif /* defined(UVISOR_PRESENT) && (UVISOR_PRESENT == 1) */

/* We can only protect a small number of pages efficiently, so there should be
* a relatively low limit to the number of pages.
* By default a maximum of 16 pages are allowed. This can only be overridden
* by the porting engineer for the current platform. */
#ifndef UVISOR_PAGE_TABLE_MAX_COUNT
#define UVISOR_PAGE_TABLE_MAX_COUNT ((uint32_t) 16)
#endif
/* The number of pages is decided by the page size. A small page size leads to
* a lot of pages, however, number of pages is capped for efficiency.
* Furthermore, when allocating large continous memory, a too small page size
* will lead to allocation failures. This can only be overridden
* by the porting engineer for the current platform. */
#ifndef UVISOR_PAGE_SIZE_MINIMUM
#define UVISOR_PAGE_SIZE_MINIMUM ((uint32_t) 1024)
#endif
#include "page_allocator_config.h"

/* The page box_id is the box id which is 8-bit large. */
typedef uint8_t page_owner_t;
/* Maps the page to the owning box handle. */
static page_owner_t g_page_owner_table[UVISOR_PAGE_TABLE_MAX_COUNT];
/* Define a unused value for the page table. */
#define UVISOR_PAGE_UNUSED ((page_owner_t) (-1))

page_owner_t g_page_owner_table[UVISOR_PAGE_TABLE_MAX_COUNT];
/* Contains the configured page size. */
static uint32_t g_page_size;
uint32_t g_page_size;
/* Points to the beginning of the page heap. */
static const void * g_page_heap_start;
const void * g_page_heap_start;
/* Points to the end of the page heap. */
static const void * g_page_heap_end;
const void * g_page_heap_end;
/* Contains the number of free pages. */
static uint8_t g_page_count_free;
uint8_t g_page_count_free;
/* Contains the total number of available pages. */
static uint8_t g_page_count_total;
uint8_t g_page_count_total;

/* Helper function maps pointer to page id, or UVISOR_PAGE_UNUSED. */
uint8_t page_allocator_get_page_from_address(uint32_t address)
{
/* Range check the returned pointer. */
if (address < (uint32_t) g_page_heap_start || address >= (uint32_t) g_page_heap_end) {
return UVISOR_PAGE_UNUSED;
}
/* Compute the index for the pointer. */
return (address - (uint32_t) g_page_heap_start) / g_page_size;
}

void page_allocator_init(void * const heap_start, void * const heap_end, const uint32_t * const page_size)
{
Expand Down Expand Up @@ -142,8 +134,9 @@ void page_allocator_init(void * const heap_start, void * const heap_end, const u
(unsigned int) (g_page_size / 1024));

uint32_t page = 0;
for (; page < g_page_count_total; page++) {
for (; page < UVISOR_PAGE_TABLE_MAX_COUNT; page++) {
g_page_owner_table[page] = UVISOR_PAGE_UNUSED;
page_allocator_reset_faults(page);
}
}

Expand Down Expand Up @@ -187,6 +180,8 @@ int page_allocator_malloc(UvisorPageTable * const table)
if (g_page_owner_table[page] == UVISOR_PAGE_UNUSED) {
/* Marry this page to the box id. */
g_page_owner_table[page] = box_id;
/* Reset the fault count for this page. */
page_allocator_reset_faults(page);
/* Get the pointer to the page. */
void * ptr = (void *) g_page_heap_start + page * g_page_size;
/* Zero the entire page before handing it out. */
Expand Down Expand Up @@ -239,14 +234,14 @@ int page_allocator_free(const UvisorPageTable * const table)
int table_size = page_count;
for (; table_size > 0; page_table++, table_size--) {
void * page = (void *) page_table_read((uint32_t) page_table);
/* Compute the index for the pointer. */
uint8_t page_index = page_allocator_get_page_from_address((uint32_t) page);
/* Range check the returned pointer. */
if (page < g_page_heap_start || page >= g_page_heap_end) {
if (page_index == UVISOR_PAGE_UNUSED) {
DPRINTF("uvisor_page_free: FAIL: Pointer 0x%08x does not belong to any page!\n\n", (unsigned int) page);
UVISOR_PAGE_ALLOCATOR_MUTEX_RELEASE;
return UVISOR_ERROR_PAGE_INVALID_PAGE_ORIGIN;
}
/* Compute the index for the pointer. */
uint32_t page_index = (page - g_page_heap_start) / g_page_size;
/* Check if the page belongs to the caller. */
if (g_page_owner_table[page_index] == box_id) {
g_page_owner_table[page_index] = UVISOR_PAGE_UNUSED;
Expand Down
45 changes: 45 additions & 0 deletions features/FEATURE_UVISOR/source/page_allocator_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2016, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef __PAGE_ALLOCATOR_CONFIG_H__
#define __PAGE_ALLOCATOR_CONFIG_H__
/* This file can be compiled externally to provide the page allocator algorithm
* for devices NOT supported by uVisor. For this purpose this file is copied as
* is into the target build folder and compiled by the target build system. */

/* We can only protect a small number of pages efficiently, so there should be
* a relatively low limit to the number of pages.
* By default a maximum of 16 pages are allowed. This can only be overwritten
* by the porting engineer for the current platform. */
#ifndef UVISOR_PAGE_TABLE_MAX_COUNT
#define UVISOR_PAGE_TABLE_MAX_COUNT ((uint32_t) 16)
#endif
/* The number of pages is decided by the page size. A small page size leads to
* a lot of pages, however, number of pages is capped for efficiency.
* Furthermore, when allocating large continous memory, a too small page size
* will lead to allocation failures. This can only be overwritten
* by the porting engineer for the current platform. */
#ifndef UVISOR_PAGE_SIZE_MINIMUM
#define UVISOR_PAGE_SIZE_MINIMUM ((uint32_t) 1024)
#endif

/* The page box_id is the box id which is 8-bit large. */
typedef uint8_t page_owner_t;
/* Define a unused value for the page table. */
#define UVISOR_PAGE_UNUSED ((page_owner_t) (-1))

#endif /* __PAGE_ALLOCATOR_CONFIG_H__ */
56 changes: 56 additions & 0 deletions features/FEATURE_UVISOR/source/rtx/box_init.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2016, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "uvisor-lib/uvisor-lib.h"
#include "mbed_interface.h"
#include "cmsis_os.h"
#include <stdint.h>
#include <string.h>

/* This function is called by uVisor in unprivileged mode. On this OS, we
* create box main threads for the box. */
void __uvisor_lib_box_init(void * lib_config)
{
osThreadId thread_id;
osThreadDef_t * flash_thread_def = lib_config;
osThreadDef_t thread_def;

/* Copy thread definition from flash to RAM. The thread definition is most
* likely in flash, so we need to copy it to box-local RAM before we can
* modify it. */
memcpy(&thread_def, flash_thread_def, sizeof(thread_def));

/* Note that the box main thread stack is separate from the box stack. This
* is because the thread must be created to use a different stack than the
* stack osCreateThread() is called from, as context information is saved
* to the thread stack by the call to osCreateThread(). */
/* Allocate memory for the main thread from the process heap (which is
* private to the process). This memory is never freed, even if the box's
* main thread exits. */
thread_def.stack_pointer = malloc_p(thread_def.stacksize);

if (thread_def.stack_pointer == NULL) {
/* No process heap memory available */
mbed_die();
}

thread_id = osThreadCreate(&thread_def, NULL);

if (thread_id == NULL) {
/* Failed to create thread */
mbed_die();
}
}
43 changes: 0 additions & 43 deletions features/FEATURE_UVISOR/source/rtx/box_main.c

This file was deleted.

3 changes: 2 additions & 1 deletion features/FEATURE_UVISOR/source/rtx/rtx_malloc_wrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ static void * memory(void * ptr, size_t size, int heap, int operation)
return NULL;
}
/* Check if we need to aquire the mutex. */
int mutexed = (is_kernel_initialized() && (heap == HEAP_PROCESS));
int mutexed = is_kernel_initialized() &&
((heap == HEAP_PROCESS) || __uvisor_ps->index.box_heap == __uvisor_ps->index.active_heap);
void * allocator = (heap == HEAP_PROCESS) ?
(__uvisor_ps->index.box_heap) :
(__uvisor_ps->index.active_heap);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#define HALT_ERROR(id, ...) {}
#define UVISOR_PAGE_ALLOCATOR_MUTEX_AQUIRE page_allocator_mutex_aquire()
#define UVISOR_PAGE_ALLOCATOR_MUTEX_RELEASE osMutexRelease(g_page_allocator_mutex_id)
#define page_allocator_reset_faults(...) {}

/* Forward declaration of the page allocator API. */
int page_allocator_malloc(UvisorPageTable * const table);
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
5 changes: 5 additions & 0 deletions rtos/rtx/TARGET_CORTEX_M/RTX_CM_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,12 @@ osThreadDef_t os_thread_def_main = {(os_pthread)pre_main, osPriorityNormal, 1U,
#define INITIAL_SP (0x20003000UL)

#elif defined(TARGET_K64F)
#if defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED)
extern uint32_t __StackTop[];
#define INITIAL_SP (__StackTop)
#else
#define INITIAL_SP (0x20030000UL)
#endif

#elif defined(TARGET_K22F)
#define INITIAL_SP (0x20010000UL)
Expand Down