Git Product home page Git Product logo

uvisor's Introduction

The Arm Mbed uVisor

Build Status

Warning: uVisor is superseded by the Secure Partition Manager (SPM) defined in the ARM Platform Security Architecture (PSA). uVisor is deprecated as of Mbed OS 5.10, and being replaced by a native PSA-compliant implementation of SPM.

The uVisor is a self-contained software hypervisor that creates independent secure domains on Arm Cortex®-M3 and Cortex®-M4 microcontrollers. It increases resilience against malware and protects secrets from leaking even among different modules of the same application. You can find a high-level overview here (Download PDF).

To start using uVisor, you need to include it as a library in your design. We release the uVisor library periodically into the Mbed OS repository, ARMmbed/mbed-os.

You can find most of the uVisor documentation in the docs folder. Please look at the getting started guide for an introduction to uVisor application development. If you are interested in uVisor internals, please refer to the OS-level introduction and the uVisor API docs.

Contributions to this repository in the form of issue reporting and pull requests are welcome! Please read our contribution guidelines first.

Getting started examples

  • The basic uVisor example shows how secure interrupts and C++ objects are instantiated in the context of secure boxes.
  • The uVisor threaded example demonstrates the configuration of multiple boxes containing secure threads.
  • The secure number store example demonstrates secure communication between boxes and implementation of secure APIs. The example shows how a called box can infer the caller's identity and ownership of secure objects across boots and firmware updates.

Word of caution

This version of the uVisor is an early technology preview with an incomplete implementation of the security features of the final product. Future versions of uVisor will add these functions.

You can find some of the open uVisor issues here:

Further reading

Supported platforms

The uVisor core supports the following platforms:

To use uVisor on a specific OS, you must complete the porting process for that OS. This requires an additional porting step, which the uVisor porting guide for Mbed OS documents.

Currently, uVisor only supports Mbed OS.

The Launchpad GNU Arm Embedded Toolchain builds the uVisor prelinked binary images. Currently, uVisor only supports applications built with this toolchain. The minimum required version is 5.4-2016q3.

The uVisor design philosophy

The need for security features applies across a wide range of today’s IoT products. Many IoT security problems can be solved with standardized building blocks. The uVisor is one of these basic building blocks – complementary to other important blocks such as robust communication stacks, safe firmware updates and secure crypto libraries.

uVisor provides hardware-enforced compartments (sandboxes) for individual code blocks by limiting access to memories and peripherals using the existing hardware security features of the Cortex®-M microcontrollers.

Breaking the established flat security model of microcontrollers into compartmentalized building blocks results in high security levels because the reach of flaws and external attacks can be limited to less sensitive function blocks.

The uVisor example applications demonstrate features to prevent unauthorized access to flash memory from faulty or compromised code and interrupts. This prevents malware from getting resident on the device and enables protection of device secrets such as cryptographic keys.

Services built on top of the security layer can safely depend on an unclonable trusted identity, secure access to internet services and benefit from encryption key protection.

Technical overview

The uVisor:

  • Is initialized right after device startup.
  • Runs in privileged mode.
  • Sets up a protected environment using a Memory Protection Unit (MPU), such as the Arm Cortex®-M MPU or a vendor-specific alternative. In particular:
    • Its own memories and the security-critical peripherals are protected from the unprivileged code.
    • Access Control Lists (ACLs) limit unprivileged access to selected hardware peripherals and memories.
  • Allows interaction from the unprivileged code by exposing SVCall-based APIs.
  • Forwards and deprivileges interrupts to the unprivileged handler that has been registered for them.
  • Prevents registers leakage when switching execution between privileged and unprivileged code and between mutually untrusted unprivileged modules.
  • Forces access to some security-critical peripherals (such as DMA) through SVCall-based APIs.

The unprivileged code

All the code that is not explicitly part of the uVisor is generally referred to as unprivileged code. The unprivileged code:

  • Runs in unprivileged mode.
  • Has direct memory access to unrestricted unprivileged peripherals.
  • Can require exclusive access to memories and peripherals.
  • Can register for unprivileged interrupts.
  • Cannot access privileged memories and peripherals.

The unprivileged code can be made of mutually untrusted isolated modules (or boxes). This way, even if all are running with unprivileged permissions, different modules can protect their own secrets and execute critical code securely.

For more details about how to setup a secure box and protect memories and peripherals, please read the getting started guide.

Memory layout

Different memory layouts can be used on different platforms, depending on the implemented memory protection scheme and the MPU architecture. The following figure shows the memory layout of a system where the uVisor shares the SRAM module with the operating system (ARMv7-M MPU).

uVisor memory layout

The uVisor secures two main memory blocks, in flash and SRAM respectively. In both cases, it protects its own data and the data of the secure boxes it manages for the unprivileged code. For a more detailed view, please refer to the interactive linker section visualization.

All the unprivileged code that is not protected in a secure domain is referred to as the public box.

This table details the main memory sections that the uVisor protects:

Memory section Description
uVisor code Unprivileged code can read and execute the uVisor code, so code sharing is facilitated, and privileged-unprivileged transitions are easier.
uVisor data / BSS / stack The uVisor places all its constants, initialized and uninitialized data and the stack in secured areas of memory, separated from the unprivileged code.
Secure boxes data / BSS / stack Through a configuration process, unprivileged code can set up a secure box for which data and stack can be secured by the uVisor and placed in isolated and protected memory areas.
Vector table Interrupt vectors are relocated to the SRAM but protected by the uVisor. Access to them is made through specific APIs.

To use the uVisor APIs to set up a secure box, please refer to the getting started guide and the full uVisor API documentation.

The boot process

The uVisor is initialized right after device startup and takes ownership of its most critical assets, such as privileged peripherals, the vector table and memory management. The boot process involves the following steps, in this order:

  1. Several sanity checks verify integrity of the memory structure as expected by the uVisor.
  2. The uVisor bss section is zeroed, the uVisor data section initialized.
  3. The uVisor takes ownership of the vector table.
  4. The virtual Memory Protection Unit (vMPU) is initialized:
    • Secure boxes are loaded. For each of them:
      • The bss section is zeroed.
      • Access Control Lists (ACLs) are registered.
      • Stacks are initialized.
      • A private box context is initialized, if required.
    • The MPU (Arm or third-party) is configured.
  5. Privileged and unprivileged stack pointers are initialized.
  6. Execution is deprivileged and handed over to the unprivileged code.

From this moment on, the operating system/application runs in unprivileged mode and in the default context, which is that of the public box.

Context switching

The uVisor can set up a secure execution environment for itself and for each configured secure box. Whenever an event or an explicit call must run in a specific environment, a context switch is triggered.

During a context switch, the uVisor stores the state of the previous context and then:

  • Reconfigures the stack pointer and the box context pointer.
  • Reconfigures the MPU and the peripherals protection.
  • Hands the execution to the target context.

A context switch is triggered automatically every time the target of a function call or exception handling routine (interrupts) belongs to a different secure domain. This applies to user interrupt service routines, threads and direct function calls.

uvisor's People

Contributors

alessandroa avatar alzix avatar asmellby avatar c1728p9 avatar ccli8 avatar danny4478 avatar fvincenzo avatar hugovincent avatar iriark01 avatar janjongboom avatar jserv avatar mbartling avatar meriac avatar nafe avatar niklarm avatar patater avatar romkuz01 avatar salkinium avatar theamirocohen avatar tibachang avatar tony0620emma avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

uvisor's Issues

Contribution notice needed

Since uvisor is part of ARM mbed project, Contributor Agreement should be accepted before a developers starts to contribute.

Google's open source projects hosted at GitHub explain how to contribute changes. Take re2 as an example. There is a dedicated wiki page Contribute. uvisor should provide one as well.

Add symbol support to uvisor_read & uvisor_write APIs

  • currently uvisor_read & *_write do not accept structures member addresses
  • affects user experience as addresses need to be calculated on the fly

Example:

uvisor_read(&UART0->BAUD_RATE)

needs currently to be written as:

uvisor_read(UART0_ADDRESS + UART_BAUD_RATE_OFFSET)

Support distributed target/module-specific background ACLs

To allow distributed definition of target/module-specific background ACLs:

  • define named section for background region ACLs
  • yotta modules or the C-HAL can place background ACLs via the named section
  • the existing box 0 ACLs are put into this section, too
  • ensure byte alignment in the section
  • add start/end symbols and add them to the uVisor-lib shared structure
    @AlessandroA

Remove UVISOR_DISABLED-specific fallback code

We need to generalize the concept of a disabled uVisor, so that disabled.c can be removed.

In that scenario, uVisor core would still be used in UVISOR_DISABLED mode, with less restrictions and with the MPU/Kinetis peripheral protections disabled.

Currently the file disabled.c file implements several fallback implementations of uVisor core, that with time become difficult to maintain. One example is captured by this commit.

public module registry

when commands yotta target frdm-k64f-gcc and yotta install are executed, dependency files are downloading from public module registry:

yotta target frdm-k64f-gcc
info: get versions for frdm-k64f-gcc
info: download [email protected] from the public module registry
info: get versions for kinetis-k64-gcc
info: download [email protected] from the public module registry
info: get versions for mbed-gcc
info: download [email protected] from the public module registry

yotta install
info: get versions for mbed-drivers
info: download [email protected] from the public module registry
info: get versions for cmsis-core
info: download [email protected] from the public module registry
info: get versions for cmsis-core-freescale
info: download [email protected] from the public module registry
info: get versions for cmsis-core-k64f
info: download [email protected] from the public module registry
info: get versions for mbed-hal
info: download [email protected] from the public module registry
info: get versions for ualloc
info: download [email protected] from the public module registry
info: get versions for minar
info: download [email protected] from the public module registry
info: get versions for core-util
info: download [email protected] from the public module registry
info: get versions for compiler-polyfill
info: download [email protected] from the public module registry
info: get versions for mbed-hal-freescale
info: download [email protected] from the public module registry
info: get versions for mbed-hal-ksdk-mcu
info: download [email protected] from the public module registry
info: get versions for mbed-hal-k64f
info: download [email protected] from the public module registry
info: get versions for mbed-hal-frdm-k64f
info: download [email protected] from the public module registry
info: get versions for dlmalloc
info: download [email protected] from the public module registry
info: get versions for minar-platform
info: download [email protected] from the public module registry
info: get versions for minar-platform-mbed
info: download [email protected] from the public module registry
error: mbed-drivers does not meet specification ~0.11.1 required by core-util

The question is how to have all these required modules locally installed instead of downloading from public module registry?
and also it throws error:
error: mbed-drivers does not meet specification ~0.11.1 required by core-util

Map bitband ACLs back to original peripheral adresses to detect overlap

  • currently the ACL collision detection in uVisor does not take into account that a bitband-ACL might overlap with a peripheral-ACL for the same peripheral.
  • ensure to mark peripherals corresponding to bitband-ACL as used
  • still allow the same box to have both bitband ACL and peripheral ACL for the same peripherals

Add bus fault recover-ability to STM32F4

Some of the fallback implementations of register-level gateway are currently using managed bus faults to perform read/write operations to restricted registers. Add support for this feature to STM32F4 (altready there for K64F).

All unprivileged memory accesses in uVisor should be centralized

Every time uVisor reads or writes a memory location belonging to a secure box, it should do so using unprivileged instructions, ldrt, strt.

We will change every occurrence of these memory accesses to use a static inline function, which in turn uses the CMSIS intrinsics for unprivileged access.

A single function helps with security verification and allows a consistent security model. In addition, if assumptions about a piece of code change, the security of the memory accesses is not compromised.

[K64F] A secure box with an empty ACL list does not get the background ACLs

In vmpu_load_boxes() we have a for loop that scans ACLs and calls the function vmpu_acl_add() for each of them.

In K64F this function further calls vmpu_aips_add(), which

  • adds the relevant AIPS slot and
  • also adds ACLs from box 0 to the ACL list of the currently parsed box

This last point creates the bug: If the ACL list for a secure box is empty, then the vmpu_acl_add() will never be called and hence (for the K64F) the box 0 ACLs for AIPS slots are never applied to other boxes.

For reference:


Possible solution:

  • Create a new function that gets called after ACLs parsing: vmpu_add_common_acls()
    • Implemented differently for ARM and Freescale MPUs
    • All shared box 0 ACLs can be accounted for after private ACLs have been parsed
    • sharing box 0 ACLs is decoupled from having own ACLs

@meriac
@Patater

Temporary Enabling of Debug Features in uVisor

Please note that currently the latest version of uVisor (the HEAD of the uvisor repository) does not support the following features:

  • LED blinking patterns
  • Memory mapped debugging

This means that the support for hardware-specific debugging is temporarily unavailable. If you want to revert back to a version of uVisor that still supports those features, please checkout the uvisor_with_memory_map_debug branch:

git clone --recursive -b uvisor_with_memory_map_debug [email protected]:ARMmbed/uvisor.git

This command will clone both uvisor and uvisor-lib. You can then build uVisor as usual, as reported in the branch README.md.

Failed to build uvisor

Failed to build uvisor on the latest commit(master branch).
At uvisor/platform/stm32
Commands:$make clean release

Did I forget to update something?

rm -f stm32.map stm32.elf stm32.bin stm32.asm\
      stm32.linker gdb.script source.c.tags JLink.log\
        ../../release/source/stm32/version.txt
find . ../../core -iname '*.o' -exec rm -f \{\} \;
arm-none-eabi-gcc -mcpu=cortex-m4 -march=armv7e-m -mthumb -Os -DNDEBUG -g3 -Wall -Werror -DARCH_MPU_ARMv7M -DCONFIGURATION_ -DPROGRAM_VERSION=\"0.9.10-55-gcef5-dirty\" -I. -Iinc -I../../core -I../../core/cmsis/inc -I../../core/system/inc -I../../core/system/inc/mpu -I../../core/debug/inc -I../../core/lib/printf -ffunction-sections -fdata-sections -fno-exceptions  -c -o ../../core/system/src/benchmark.o ../../core/system/src/benchmark.c
In file included from inc/config.h:25:0,
                 from ../../core/uvisor.h:25,
                 from ../../core/system/src/benchmark.c:17:
inc/configurations.h:65:2: error: #error "Unrecognized uVisor configuration. Check your Makefile."
 #error "Unrecognized uVisor configuration. Check your Makefile."
  ^
In file included from ../../core/uvisor.h:25:0,
                 from ../../core/system/src/benchmark.c:17:
inc/config.h:31:2: error: #error "Currently only STM32 devices with a CCM are supported."
 #error "Currently only STM32 devices with a CCM are supported."
  ^
In file included from ../../core/uvisor.h:31:0,
                 from ../../core/system/src/benchmark.c:17:
../../core/cmsis/inc/core_generic.h:71:2: error: #error "Unsupported ARM core. Make sure CORE_* is defined in your workspace."
 #error "Unsupported ARM core. Make sure CORE_* is defined in your workspace."
  ^
In file included from ../../core/system/inc/svc_cx.h:22:0,
                 from ../../core/system/inc/svc.h:22,
                 from ../../core/system/inc/unvic.h:21,
                 from ../../core/system/inc/system.h:21,
                 from ../../core/uvisor.h:74,
                 from ../../core/system/src/benchmark.c:17:
../../core/system/inc/mpu/vmpu.h: In function 'vmpu_sram_addr':
../../core/system/inc/mpu/vmpu.h:37:33: error: 'SRAM_ORIGIN' undeclared (first use in this function)
     return (((uint32_t) addr >= SRAM_ORIGIN) &&
                                 ^
../../core/system/inc/mpu/vmpu.h:37:33: note: each undeclared identifier is reported only once for each function it appears in
../../core/system/src/benchmark.c: In function 'benchmark_configure':
../../core/system/src/benchmark.c:30:9: error: 'CoreDebug' undeclared (first use in this function)
         CoreDebug->DEMCR |= (1 >> 24);
         ^
../../core/system/src/benchmark.c:33:9: error: 'DWT' undeclared (first use in this function)
         DWT->CYCCNT = 0;
         ^
../../core/system/src/benchmark.c: In function 'benchmark_start':
../../core/system/src/benchmark.c:45:5: error: 'DWT' undeclared (first use in this function)
     DWT->CYCCNT = 0;
     ^
../../core/system/src/benchmark.c: In function 'benchmark_stop':
../../core/system/src/benchmark.c:50:12: error: 'DWT' undeclared (first use in this function)
     return DWT->CYCCNT - g_benchmark_overhead;
            ^
../../core/system/src/benchmark.c:51:1: error: control reaches end of non-void function [-Werror=return-type]
 }
 ^
cc1: all warnings being treated as errors
<builtin>: recipe for target '../../core/system/src/benchmark.o' failed
make: *** [../../core/system/src/benchmark.o] Error 1

And the tutorial to build uvisor seems to be old.
The k64f directory no longer exists.

# assuming you are developing in ~/code, select the correct platform in the code tree
cd ~/code/k64f/uvisor

I have seen the Warning: Enabling Debug Features on uVisor,and it says that the current uvisor does not have Debug Features.

Move uVisor debug functionality to debug box

  • uVisor is supposed to have as little as possible special knowledge about the target and it peripherals
  • uVisor must still support complex debugging like over meshed wireless networks, IPv6 Ethernet with SSL or USB CDC serial.

Solution:

  • Debug communication and debug LED handling will be moved into a uVisor box: a "debug driver" that doesn't even need to be uVisor aware. Such a debug driver will map debug requirements like ("blink LED 3 times repeating" or "print log-text over whatever interface you support") to the underlying hardware. The OS above uses that driver in a hardware-independent way.
  • uVisor or OS create a machine readable stack trace of crash in network endianness format, the debug box can choose to forward it to turn it into a local "bluescreen" (USB serial etc.)
  • The debug box can choose to maintain the hardware-dependent memory map with human readable peripheral names to enrich a "blue screen" output- whenever the remote system wants to communicate to uVisor, the debug box will call into uVisor to deliver just the payload.
  • whenever uVisor will print messages, it will issue a de-privileged call to the dedicated box that handles the output.
  • as a result uVisor does not need to know about complex protocols, but is still able to interact with remote systems in a debug session.
  • the debug box might be able to debug other boxes if these boxes allow to do so (similar to Android where an app needs to explicitly allow debugging in its manifest)
  • we stop uVisors attack surface from growing by reducing privileged code
  • uVisors security properties are very comparable across a multitude of system: security verifications become transferable across systems
  • consider using CBOR format for a verbose debug dump, as the format requires not just standard outputs like stack traces etc, but various status register and context/security related info that might be platform dependent

See also #64

Add register clearing between context switches

  • for security reasons CPU core registers need to be cleared whenever execution shifts to a new box to avoid leakage of information
  • a box can opt-out from register clearing for performance reasons in case privacy is not required

Not possible to release multiple configurations for a platform

With the current Makefile.rules, it seems that it isn't possible to release multiple configurations. If I have a Makefile like this for my platform:

CONFIGURATIONS:= \
    MY_CONFIG_1 \
    MY_CONFIG_2 \
    MY_CONFIG_3

my_platform_r:
    $(foreach CONFIGURATION, \
              $(CONFIGURATIONS), \
              CONFIGURATION=$(CONFIGURATION) make -f ../../core/Makefile.rules clean release && ) true

Then only the last configuration will be preserved in release/source/<platform>/, since the release make target performs rm -rf $(RELEASE_SRC_HW).

If I understand the comments on the refactoring pull request + comments in source code correctly, it should be possible to call make release multiple times to output multiple binaries/configurations for the same platform.

Check if all hardware interrupts are disabled when entering uVisor boot

  • always verify if any of the hardware interrupts are enabled when uvisor is initialised
  • on debug build fail with a verbose security message explaining that the port is broken and interrupts need to be initialised using uVisor APIs.
  • on release build just die & drop over in an endless loop

Add debug-time/run-time fixes for broken porting / Interrupts

  • verify if interrupts are enabled before they are set
  • each attempt to change the enable-state of an interrupt while it's not assigned to the calling box must fail with a security exception. This allows detecting race conditions in application code.

Note: changes above prevent bugs like #87

Dedicated type for box id

The box id is currently of type uint8_t, but there should be dedicated box_id_t which abstracts this for future compatibility.

ARMCC support

  • currently ARMCC breaks as there is now way for enforcing unoptimized assembler inlines
  • as a result function gateways and register gateways do not function when compiled with ARMCC

Memory access macros do not work when optimization is turned on

Bug description
On the NXP FRDM-K64F it has been observed that turning on compiler
optimizations interferes with the content of the r0 register in memory access
macros.

Although r0 is in the register list of the inline asm used for the
uvisor_write32() API, it contains garbage at the moment of use. The bug is
observed in the form of a hard fault due to an invalid address (r0) in a str
instruction.

To reproduce
Create a yotta application that uses the frdm-k64f-gcc target. Use the
following source code:

#include "mbed-drivers/mbed.h"

PwmOut led(D5);

void app_start(int, char **) {
    led = 0.5f;
}

and compile in release mode with yotta build -r. Run the program and observe the hard fault.
The fault comes from the pwmout_write function, in which a series of optimizations leads
to the following str instruction:

str r1, [r0]
dsb
nop
nop
nop

where r0 = 0x0. The instructions above implement the uvisor_write32() API.

Inconsistent coding style

Comparing to other ARM mbed projects such as mbed-drivers and mbed-client, I found that the existing coding style in uvisor is a bit inconsistent. For example, the keyword if in C program statement usually lacks of corresponding space in uvisor, but both mbed-drivers and mbed-client have the explicit space: if (...).

I just wonder if there is the documentation about coding style globally applied to all mbed projects.

Add mutli-box support to vmpu_load_box

Hi,

  • We want to create a secure box for debugging, it seems that CrashCatcher is a good choice. By using CrashCather we can capture the register and RAM state at a time of a crash, and through CrashDebug we can do post-mortem debugging.
  • Currently vmpu can only load one secure box, and if we want to capture its state when crashed, there is no available box for integrating CrashCather.
void vmpu_load_box(uint8_t box_id)
{
        if(box_id == 0)
             vmpu_switch(0, 0);
        else
             HALT_ERROR(NOT_IMPLEMENTED, "currently only box 0 can be loaded"); 
}

THX !

STM32F4 ISR default handler is not UVISOR_NAKED and UVISOR_NORETURN

Without UVISOR_NAKED the compiler (especially in debug mode) introduces push/pop operations; the pop operation is cut off by the bx lr instruction in unvic_isr_mux() and the r4-r11 registers might be broken as a consequence.

00001c24 <isr_default_handler>:
    1c24:       b480            push    {r7}
    1c26:       af00            add     r7, sp, #0
    1c28:       df10            svc     16
    1c2a:       df10            svc     16
    1c2c:       4770            bx      lr                 <---- returns before popping
    1c2e:       46bd            mov     sp, r7
    1c30:       f85d 7b04       ldr.w   r7, [sp], #4
    1c34:       4770            bx      lr
    1c36:       bf00            nop

Init-/Runtime-Only ACLs

  • add a UVISOR_TACL_INIT_ONLY for init-time-only ACLs
  • add a UVISOR_TACL_RUNTIME_ONLY for runtime-only ACLs
  • add a uvisor API call to switch from init to runtime mode, but not back

Usage:

  • simplified hardware initialization and runtime optimization as some regions will only be used once during init

uvisor_read() gets wrong value

uvisor_read gets wrong value in this example.
I printed it out,and got 00000000000000000000000000000000(32-bits)
However,with ST-LINK(debugger),I got different value.
And I think the ST-LINK is right.
This value is used to calculate how many FPB comparators does STM32F429i support.

#define FPB_CTRL 0xE0002000
uvisor_read(debug_box,FPB_CTRL);
(gdb) p/t *0xE0002000
$1 = 1001100001

Allow secure callbacks to box 0

Currently secure gateways to box 0 are not allowed.

We should implement a secure callback that allows switching context to box 0. This callback would look like any other secure gateway but will allow runtime-determined function pointers to be given as a destination for the callback.

Add documentation for ACL types

The different types of ACLs must be documented, specifying the access rights they imply and how to use them in real world examples. @akselsm

Context switch bug

  • Fix the interrupt bug related to tailchained IRQ that happen during a context switch.
  • Affects EFM32GG

Acceptance criteria:

  • create test to reproduce the behaviour
  • verify the bug if fixed in the context of the test

Release mode binaries aren't actually built in release mode

Trying to run make all, I noticed that the binaries that get output to the "release" folder are the exact same size as the ones in the "debug" folder. Also, the "release" binaries seem to still have the semihosting code intact, which requires a debugger to be connected for programs to run.

It looks like clean is not run between building debug and release, causing make/gcc to skip recompiling the binaries, therefore linking the old "debug" versions instead. This means that -DNDEBUG is not applied to the compile step in release mode.

This is also a problem when building multiple configurations. Since the source files aren't recompiled, any defines set in configurations.h won't actually be applied to the given configuration, you'll just end up with multiple copies of whatever configuration was built first.

The following build string successfully builds a single release mode binary without semihosting code: make BUILD_MODE=release PLATFORM=<my_platform> clean <MY_CONFIG>

Make Base-ACLs module-friendly

  • create a dedicated linker section for base-ACLs
  • each module declares its own base-ACLs
  • the init function of each module fake-refers to its base-ACLs
  • by referring to the base-ACLs, the ACLs get linked in and not garbage collected
  • due to the linker section they end up in one big chunk
  • all secure boxes can override the base-ACL (taking ownership of an ACL)
  • the base-ACLs are processed last, the remaning ACLs get assigned to the main box

Hardware floating point support

  • add hardware floating point support for the main box as a first step
  • extend floating point support to other secure boxes later

Distinguish between read/write faults

When creating a RO region, write access will create an access fault as expected - but it needs to avoid configuring the corresponding MPU region again: instead faulting with an security exception.

Workaround:

  • avoid writing to RO-regions

uVisor should not contain its own copy of CMSIS headers

Currently, uVisor contains copies of CMSIS headers for each platform it supports. These same headers are available from yotta modules, manufacturer zip files, KEIL packs, and/or other git repos. It'd be nice if uVisor could get the headers from someplace else instead of making yet another unmaintainable copy.

As a positive side effect, this will reduce the cognitive overhead of porting uVisor to a new platform, as one no longer need worry about how to make a maintainable copy of CMSIS definitions that, to quote the porting guide, "keep the header files to a minimum, providing only basic symbols and macros for the platform."

[debug] Allow unprivileged code to provide memory maps and custom fault handlers

With the changes introduced in #142 uVisor becomes even more hardware-agnostic.

This means that no memory map, IRQ map, LED blinking patterns are available for debugging. We should then provide APIs/mechanisms for unprivileged code to provide such information.

This may fit in the larger picture of a debug box, but for the moment I am creating this issue as an enhancement to keep track of the removed functionality.

Add register level security for RCC/EXTI/SYSCFG

Currently access is granted to RCC, EXTI and SYSCFG - for all of these registers access can't be directly granted, but filtered per register / bit. Especially SYSCFG is security critical as it allows re-mapping of the RAM/FLASH memory.

As a result we added the new concept called "Register Level Access Security" as seen in https://github.com/ARMmbed/uvisor-lib/blob/master/uvisor-lib/register_gateway.h#L90 .

Our solution creates a similar mechanism as the call gateway, but for registers - the register level gateway can grant access to a set of bits of a single register - avoiding the creation of large ACLs covering the whole region.
As the access is specified in flash an attacker can't get access to other bits or using a different box context - as long as write access is blocked to flash.

The implementation is currently undergoing and needs to be released to fix this problem.

Add verbosity level for debug output

  • allow the developer to place debug messages at various verbosity levels
    • critical
    • medium
    • verbose
  • for the debug mode the verbosity is set to low, so only critical messages are displayed by default
    • medium and verbose messages are suppressed
    • the verbosity level can be overridden during compilation to get more verbose debug messages

Allow configuration of 3 parameters to assemble $CPU

Hardware-specific code for uVisor lives in dedicated folders. Currently these are simply named after the 2 platforms that we support at the moment.

To make porting easier, we should change the Makefile and Makefile.rules formats so that the symbol $CPU is assembled from at least 3 parameters:

CPU := $(ARCH)$(FAMILY)$(CHIP)

Targets that leave one or more of those fields empty get less granularity, but everything still works.


In general we can expect a porting to look like this:

  • a new folder named lowercase($(ARCH)) contains hw-specific code;
  • the hw-specific code contains #ifdefs depending on $(FAMILY) and $(CPU); we expect those to be very few, since uVisor only relies on few hw-specific parameters (memories boundaries, usually);
  • the release rule is available for more complex release scripts; for example, in a given hw-specific $(ARCH) folder a release-all rule could iterate over all $(ARCH)s and over all $(CPU)s to create release binaries for all possible targets in the family.

Method to detect whether current code is being executed as a result of an IRQ

For some library functions, it is important, for fault detection, to know whether the API has been called as part of the call tree of an IRQ.

Examples:

  • Memory allocators
  • Some scheduler functions, e.g. postCallbackAgain()

It may be adequate to document that these should not be done, but runtime checks are more direct.

Issue with porting guide

upon execution of command git clone --recursive [email protected]:ARMMbed/uvisor.git throws following error:
Cloning into 'uvisor'...
Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.