Understanding MPU Usage inMicrocontroller-based Systems in theWild
Wei Zhou, Zhouqi Jiang, Le Guan

Agendal Introduction to Memory Protection Unit (MPU)l MPU adoption in the wildl Common pitfalls and limitations in using MPU
l Mitigation suggestionsl Summary and disclosure

MMU on PC à MPU on MCU
MMUPeri.

MemoryCacheTLB

CPUSystem bus
l The Memory Management Unit (MMU), a standard feature on traditional
computing platforms, enforces page-based permission control (R/W/X).
l MMU is absent in resource-restricted microcontroller units (MCUs) .
l As a stripped-down version of MMU, the Memory Protection Unit (MPU)
provides basic security functions for MCUs, e.g., Arm Cortex-M series MCUs.

What is Memory Protection Unit (MPU)l How MPU works?

• For a limited number ofconfigurable memory regions,
MPU assigns accesspermissions (R/W/X) based on
the current execution privilegelevel• A fault happens when a memory
access violates the accesspermission• MPU can only be configured byprivileged code

MEMORIES
PeripheralMPU(RAMROM)CPUHow to Program MPUs (PMSAv7)?
l MPU Control Register (MPU_CTRL)• Enable bit: enable the MPU• The PRIVDEFENA bit: enable the default memory map for privileged accessl MPU Region Base Address Register (MPU_RBAR)• Set the base address and the identifier of a memory regionl MPU Region Attribute/Size Register (RASR)• AP and XN bit: Set permissions (RWX) of a memory region in privileged and unprivileged level• TEX, C and B bits: Set the Attributes (e.g., cacheability and shareability) of a memory region• Size : Set the size of a memory regionl Constrains on MPU memory region(1) At least 32 bytes(2) Power of two(3) Must be aligned with 32 bytes(4) Limited region numbers (M0+/3/4 up to 8 and M7 up to 16)

What’s new in MPUS (PMSAv8)?
l More MPU regions (up to 16 regions for both normal and secure world in M23and M33)
l Use Start and Limit (end) address via separated MPU registers to define any
size of memory regions, but still must be 32-byte alignedl PMSAv8 also introduces a new memory attribute indirection register(MPU_MAIR), making it easier for multiple regions to share the same
attribute, while at the same time maintaining their own access permissions.

Agendal Introduction to Memory Protection Unit (MPU)l MPU adoption in the wildl Common pitfalls and limitations in using MPU
l Mitigation suggestionsl Summary and disclosure

MPU-enabled common security functions
l Code Integrity Protection (CIP): Code regions can be set as non-writable toprevent code injection and manipulation.
l Data Execution Prevention (DEP): Data regions like stack or heap can be set
non-executablel Stack Guard (SG): A redzone can be placed at the task stack boundary to detect
stack overflows.
l Kernel Memory Isolation (KMI): User mode (unprivileged) code cannot accessany memory belonging to the kernel space without invoking system callsl User Task Memory Isolation (TMI): User mode (unprivileged) tasks can only
access its own memory except explicitly shared memory regions that belong toother tasks or kernel.
l Peripherals Isolation (PI): Peripheral access is restricted to tasks having theprivilege to access it.

MPU adoption in the wild

We did first comprehensive study
on MPU usage of top 30 IoToperating systems according tomarket rating.

Observation

Wetry to findl Only a few MCU OSs use MPU, especially for theopen-source
OSsout thereasonsin thisbywork.
l Even if MPU is supported, only a few security features
are enableddefault

Research Questionl Why haven't MPUs been widely used in IoT operating systems?
l Why do only a few OSs enable full-blown MPU-enable protection bydefault?
l How do the OSs implement MPU-enable protections in detail?
l Are MPU-enable protections effective?

Case Study : MPU-enabled RIoTl RIoT runs all the code under privileged level, thus it can only
provide some basic protections such as DEP, and stack guard(SG) with MPU
l Data Execution Prevention (DEP): RIoT
enables the MPU region number 0 to cover thewhole RAM region as non-executable

Task Aprivileged

Task BOS kernel

privileged

MEMORY
Peripheral N#0ARM

Cortex-M

l Stack Guard (SG): RIoT sets last 32 bytes (thesmallest MPU region) on the main stack as
read-only via the MPU region number 1.
Similarly, when switching to another task, RIoTconfigures the last 32 bytes of the target task
stack as read-only.

MPU

Stack fortask A#1
Stack fortask B#1
stack forOS kernel&IRQ handler#1(privileged)

code forOS kernel
code forTasks

Case Study : FreeRTOS-MPU
MEMORY
Peripheral N
Peripheral C
Peripheral B#3

Peripheral A

l Background region in grey is enabled for privileged access only

Stack fortask A#4

Stack fortask B#4

data forOS kernel#2

code forOS kernel#1

code forsystem calls
code forTasks#0Case Study : FreeRTOS-MPU
MPUl Code Integrity Protection (CIP): Allcode regions including tasks, system
calls and kernel cannot be written.

MEMORY
Peripheral N#3

Peripheral C
Peripheral B
Peripheral A

ARM

#4

Stack fortask A

Task A#4

Stack fortask B

Task B#2

data forOS kernel#1

code forOS kernel

Cortex-M

l Data Execution Prevention (DEP):
All data regions including tasks, kernel,
and peripheral regions are nonexecutable

unprivileged

unprivileged

OS kernel(privileged)#0

code forsystem calls
code forTasks

Case Study : FreeRTOS-MPU
l User Task Memory Isolation (TMI):
Unprivileged tasks can only access their own
stack and up to three user definable memory
regions (three per task)

MPU

MEMORY
Peripheral N#3

Peripheral C
Peripheral B
Peripheral A

ARMl Kernel Memory Isolation (KMI): The
Cortex-M
FreeRTOS kernel API and data are locatedTask A
in a region of Flash that can only be
unprivileged
accessed while the microcontroller is in
Task B
unprivileged
privileged mode (calling a system call
OS kernel(privileged)causes a temporary switch to privilegedmode)#4

Stack fortask A
Stack fortask B#2

data forOS kernel#1

code forOS kernel#0

code forsystem calls
code forTasks

Case Study : Zephyrl Peripheral Isolation (PI): By default, a peripheral driver instance isconsidered as a kernel object. Therefore, its range is pre-conﬁgured tobe inaccessible by user tasks. To access peripherals, a user task
must invoke system calls.
k_oops()NAPI Call

UsermodeY

Marshal args,
Trigger SW IRQ

ValidCall ID

Lookupmarshaller indispatch tableYN
Return toCaller

Implementation

Marshal Return,Value,exit IRQ

ImplementationPVerifyFZephyr System Call Procedure

return error
codeCase Study: Keil RTX CMSIS-Zonel However, Keil RTX does not offer isolation
between normal user tasks and the kernel(i.e., KMI is unsupported), so code and dataof the kernel cannot be entirely hidden touser tasks.

Task A
Code A, Data A,Peripheral A

Shared Codel TMI: Based to user configuration, CMSISZone assigns the access permission (RWX)
to a bundle of memory regions andperipherals as an isolated execution zone.

Task B(Code B, Data B,Peripheral B)

Task C(Code C, Data C,Peripheral C)

Each box is a protected execution zone

Agendal Introduction to Memory Protection Unit (MPU)l MPU adoption in the wildl Common pitfalls and limitations in using MPU
l Mitigation suggestionsl Summary and disclosure

Common pitfalls in using MPU
l Weak protection• Case study: Bypassing MPU protection in RIoT-MPU• Case study: Privileged escalation in FreeRTOS-MPU
l Incomplete protectionl Prohibitive overheadl Conflict with existing system designsl Fragmented programming Interface

Bypassing MPU in MPU-enabled RIoT
l Bug: MPU can be disabled by control flowhijacking attack (e.g., ROP)MPU

l Cause:MPU control registers (e.g.,MPU_CTRL) are located in the systemperipheral region, which can be accessedby any privileged code. RIoT also provides ARM
an easy-to-use driver APIs for MPU Cortex-M
configurations (e.g., mpu_enable andTask A
privileged
mpu_disable driver APIs).
Task BOS kernel

privileged

MEMORY
Peripheral N#0

Stack fortask A#1
Stack fortask B#1
stack forOS kernel&IRQ handler#1(privileged)

code forOS kernel
code forTasks

System call in FreeRTOS-MPU
l For compatibility, FreeRTOS MPU does not provide newkernel APIs for system calls, but wraps the original
kernel APIs with the xPortRaisePrivilege andvPortResetPrivilege to raise/drop privileges

MPU

Peripheral N

#3

ARM

Cortex-M#4

Stack fortask A#2

data forOS kernel#1

code forOS kernel

OS kernel(privileged)

Peripheral B

Stack fortask B

unprivileged
Privileged

unprivileged

Peripheral C

Peripheral A

Task A

Task BMEMORY#0code forsystem calls
code forTasks

Privilege escalation in FreeRTOS-MPU
l Bug1 (v10.4.5 and before): An unprivileged task can raise its
privilege by calling the internal function
xPortRaisePrivilegel Cause: Privilege escalation function (xPortRaisePrivilege)
is a kernel function which can be called directlyl Patch (v10.4.6): Change it to macro
implementation

Is problem
solved?

MPU

MEMORY
Peripheral N#3

Peripheral C
Peripheral B
Peripheral A

ARM

Cortex-M#4

Stack fortask B

Task A

Privileged
unprivileged

Task B

unprivileged

OS kernel(privileged)

Stack fortask A#2data forOS kernel#1

code forOS kernel#0

code forsystem calls
code forTasks

Privilege escalation in FreeRTOS-MPU
l Bug2 (v10.4.6 and before): Privilege escalation by branchingdirectly inside system calls (MPU wrapper APIs) with amanually crafted stack framel Causes: Privilege escalation operation (SVC interrupt)
is separated with kernel API and uses stack to store
ARM
the original privilege level
Cortex-M

MPU

Peripheral N#3
Stack fortask B#4

unprivileged
Privileged

①④⑥③

②⑤

task
OS kernel
B(privileged)Peripheral C
Peripheral B
Peripheral A
Stack fortask A
Stack fortask Btask
A
unprivileged

MEMORY#2

data forOS kernel#1

code forOS kernel#0

code forsystem calls
code forTasks

Exploitation Steps
0x2000XXX+N

0x2000XXX+N

BufferOverflow…

Stackgrowth0x2000XXX…

LR(Return Address)

Address to SVC 2vars

Padding

Buffer!unprivileged"

Stack Frame（A function in
unprivileged task)

0x2000XXX

Buffer!unprivileged"

Privilege Level
Manipulation
0x2000XXX+N…
①④⑥

Stack Frame（A function in
unprivileged task)③SP②⑤Privileged Level
Address to SVC 2Padding

0x2000XXX

Stack Frame(MPU wrapperfunction)

Buffer!unprivileged"

Stack Frame（A function inunprivileged task)

Patchl Decide the original privilege level at the beginning using control registerl Introduced the portMEMORY_BARRIER macro to prevent instruction reordering when GCC link time optimization is usedCommon pitfalls in using MPU
l Weak protection• Case study: Bypassing MPU protection in RIoT-MPU• Case study: Privileged escalation in FreeRTOS-MPU
l Incomplete protectionl Prohibitive overheadl Conflict with existing system designsl Fragmented Programming Interface

Incomplete protectionl Unsafe interrupt handlers• Exception vector reads from the Vector Address Table always use

the default system address map and are not subject to an MPU check• Interrupt handlers (handle mode) run in the privileged mode, which
can access any resourcesl Incomplete protection for peripherals• Any load, store or instruction fetch transactions to the PPB, within therange 0xE0000000-0xE00FFFFF (system peripherals), are notsubject to an MPU check.

• Due to the programming constrains (e.g., 32B granules andalignment requirement), MPU is not suitable for protecting peripherals
with small regions

Incomplete protectionl Incomplete permissions assignment• No execute-only (XO) permission• Privileged permission ≥ Unprivileged permissions
l Arm MPU does not restrict peripherals as master, allowing themto access all memory (e.g., via DMA)

Prohibitive overheadl To leverage MPU to realize kernel/task isolation, invocation tokernel APIs has to go through context switch twice• Our experiment shows that one thousand privilege switches in a

FreeRTOS-MPU system takes 3.5ms on average on the MPS2+FPGA prototyping system broad (Cortex-M4 AN386) with 25MHZ
CPU clock frequency.

l MPU regions need to be re-configured for different tasks andapplications.

• FreeRTOS has to reset MPU regions #5-7 during an applicationswitch• Tizen has to reset MPU regions #3-7 during an app (includingmultiple tasks) switch and #6 and #7 during a task switch

Conflict with exiting system designl Limited MPU regions for real world applications• Very few available user-defined regions for peripheral isolation• No OS provides peripheral isolation by default.

• Very few available regions shared between two tasks• No OS provides shared memory protection by default.

• It is impossible to enable too many security features at same times• E.g., activating all MPU features in Tizen exhausts all MPU regionsl Porting software leveraging MPU may cause compatibility issues• Only 30% manufacturers implement MCU hardware security features incurrent designs

Fragmented Programming Interface
l Chip vendors may design customized MPUs, which provide better
security guarantees, but impose a steep learning curve for developers
l This may discourage them from adopting MPUs or even lead toprogramming errors
l Case study: NXP‘s Kinetis series MCUs discard ARM MPU and integrate
NXP’s proprietary system MPU (i.e., sysMPU)
l It can restrict the permission of peripherals as mastersl When enabled, by default, peripherals cannot access RAM
l To use it, developers have to properly configure sysMPU. Otherwise,
many official demos cannot execute

Agendal Introduction to Memory Protection Unit (MPU)l MPU adoption in the wildl Common pitfalls and limitations in using MPU
l Mitigation suggestionsl Summary and disclosureMinimizing pitfalls
l Be careful about permission overlap• Observation: all open-source OSs but the latest FreeRTOSv10.5
use lower-number MPU regions for kernel protections ().

• Risk: Developer could configure those higher numbered user-defined
MPU regions to override kernel protections.

• Recommendation: System and general protection (e.g., KMI,DEP,CIP) should use higher-number MPU regions.

Minimizing pitfalls
l Be careful about privilege switch during system calls• Observation: OSs wrap the kernel APIs by temperately raising anddropping privilege (e.g., FreeRTOSv10.5.0 before).

• Risk: Privilege escalation with control flow hijacking or a manipulablestack.

• Recommendation: MCU OSs should provide a system call interface

with software interrupts, similar to traditional OSs. Alternatively, they canenforce additional caller checks before system call invocations, and thekernel should make sure that the privilege is dropped after system calls.

Minimizing pitfallsl Avoid over-privileged execution• Observation: OSs which only provide protections like Stack Guard, DEP and CIP,
always run the whole system at the privileged level like RIoT.

• Risk: Disabling the desired protections by reconfiguring MPUs withcontrol flow hijacking attack.

• Recommendation: System drop privilege whenever possible.

Region usage optimizationl Leverage the default MPU region on ARMv7-M• Default memory access permissions/attributes of memory regions is enforced by
ARM without MPU• E.g., non-executable for standard and system peripheral regionsl Leverage sub-regions• Save memory usage. Without Sub-region
MEMORY(ARMv7-m)
Running Task B
8KB MPU region

Task B Stack
5KB

12KB memory used
Running Task A
4KB MPU region

Task A Stack
3KB

With Sub-region
MEMORY(ARMv7-m)

8KB memory usedwith one region

Task B Stack
5KB

Running Task B
SRD = 11111000

Task A Stack
3KB

Running Task A
SRD = 00000111

Region Usage Optimizationl Leverage sub-regions• Save memory usage• Save MPU regions

Without Sub-region
MEMORY
Peripheral H
Peripheral G

At least three separated
MPU Region needed

Peripheral F
Peripheral E
Peripheral DUnprivileged
Peripheral
C

Peripheral C

Privileged

Peripheral B

Privileged(backgroundregion)

Peripheral A

With Sub-region
MEMORYSRD

1
Peripheral G
0
Peripheral F
1
Peripheral E
0
Peripheral D
1
Peripheral A
Peripheral C
1
Peripheral B
1
Peripheral A
0
Peripheral H

Only oneMPU Region

Region Usage Optimizationl Automatically find optimized region allocation strategies• MINION (NDSS 2018)• ACES (USENIX Security 2018)

New Hardware Security Featuresl ARMv8-M architecture extends the TrustZone technology toCortex-M series. The secure regions can be used as additionalregions and be assigned with higher privileged level beyond
privileged level in normal world.
l Trustlite proposed execution-aware MPU which the not only
validates data accesses (read/write/execute) but additionallyconsiders the currently active instruction pointer as the subject
performing the access.

Agendal Introduction to Memory Protection Unit (MPU)l MPU adoption in the wildl Common pitfalls and limitations in using MPU
l Mitigation suggestionsl Summary and disclosureSummaryl To our surprise, we found that MPU as a ready-to-use
security feature for protecting microcontroller is rarely usedin real-world productsl We studied the source code of multiple MCU OSs to findexplanations for this situation and eventually identified somecommon pitfalls.
l Some of the flaws are fundamental and not remedial in ashort terml We give recommendations for better use of MPU

Disclosurel All bugs we demonstrated has been patched in latest
FreeRTOS kernel• Security update Reference:https://www.freertos.org/security/security_updates.html

l RIoT developer team has acknowledged our finding, but thebenefit of disabling access to the MPU or the `mpu_disable()`function without a userspace / kernelspace split is quite limited,
only mildly increases the attack surface in the context of theattack model RIOT assumes.

Q&A