Join our Newsletter — 33% off our NHI Course
Home› Guides› RTOS Security Guide: Hardening Zephyr and FreeRTOS Microcontroller…
Guide OT & IoT Security

RTOS Security Guide: Hardening Zephyr and FreeRTOS Microcontroller Firmware

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 27 October 2026 14 min read
On this page

Most microcontroller firmware still runs every task, driver and network parser with full privilege in one flat address space, so a single memory bug in a packet parser can own the whole device. Real-time operating systems such as Zephyr and FreeRTOS now ship the building blocks to change that: unprivileged threads, MPU-enforced memory regions, Arm TrustZone for Armv8-M, secure boot through MCUboot and PSA-based secure services through Trusted Firmware-M. Few products turn them on, because they cost RAM, flash, cycles and engineering time. This guide is for firmware engineers, product security teams and buyers who need to know which of these controls matter, how they are configured, how to roll them out without breaking real-time behaviour and how to prove they are working. It goes deeper on the RTOS layer than the general Embedded Device Security Guide, which it does not repeat.

Key takeaways

  • Privilege separation is opt-in. Zephyr user mode and FreeRTOS MPU ports exist, but the defaults run everything privileged: configENABLE_MPU defaults to 0 in FreeRTOS and Zephyr user mode needs explicit thread and memory domain configuration.
  • Put untrusted parsers in unprivileged threads first. Network stacks, protocol parsers, file systems and interpreters are where remote memory bugs land; sandboxing them gives the largest risk reduction per kilobyte of RAM.
  • TrustZone-M splits the chip, not the tasks. On Cortex-M23, M33, M35P and M55 class parts, keys, crypto and attestation belong in the secure processing environment (typically Trusted Firmware-M), with the RTOS in the non-secure world.
  • Secure boot without rollback protection is half a control. MCUboot verifies signatures, but only a security counter stops an attacker reinstalling an older, signed, vulnerable image.
  • Hardening is measurable. Zephyr's hardenconfig target, release CVE lists, MPU fault counts and stack high-water marks turn "we hardened it" into evidence a buyer or a Cyber Resilience Act assessor can check.

What makes RTOS security different

An RTOS is not a small Linux. The differences shape every control in this guide.

  • Single image, static configuration: Zephyr compiles the kernel and application into one static binary with no dynamic loading, and each feature is a Kconfig option that must be explicitly enabled. FreeRTOS is configured through FreeRTOSConfig.h macros. Security posture is therefore decided at build time, and the build configuration is the primary artefact to review.
  • MPU, not MMU: most microcontrollers have a memory protection unit with a small fixed number of regions rather than paged virtual memory. Regions often have size and alignment constraints (on some MPUs, Zephyr notes partitions must be a power of two in size and aligned to their own size), which forces memory layout decisions early.
  • Trust in the kernel and supervisor code is total: Zephyr's user mode threat model states that the kernel, any threads in supervisor mode, the toolchain and the build are all assumed trusted. Anything you leave in supervisor mode is inside the trusted computing base.
  • Availability is a safety property: Zephyr explicitly does not protect against denial of service by CPU starvation: a user thread at a given priority can starve all lower-priority threads. Watchdogs and priority design are security controls on an RTOS.
  • Long field life: devices run for a decade or more, so the update path, signing keys and vulnerability handling matter as much as the initial hardening. See the IoT Secure Firmware Update Guide.

Memory protection and privilege separation

Zephyr user mode

Zephyr treats user mode threads as untrusted. A flawed or malicious user thread should not be able to read or modify another thread's or the kernel's private data, use kernel objects or drivers it was not granted, or re-enter supervisor mode except through defined system calls. The mechanisms are:

  • Memory domains and partitions: a user thread can access its own stack, program text, read-only data and the partitions of the memory domain it belongs to. Partitions in a domain may not overlap. Child threads inherit the parent's domain.
  • Kernel object permissions: access to semaphores, queues and device driver instances is granted per object, and system call handlers validate object type, initialisation state and buffer access before acting.
  • Stack isolation: on MPU systems a user thread can only access its own stack buffer. CONFIG_HW_STACK_PROTECTION catches whole-stack overflow in supervisor mode, CONFIG_STACK_CANARIES adds compiler canaries for individual frames, and CONFIG_STACK_SENTINEL provides a software check on hardware without MPU stack protection.

Zephyr is explicit about the limits: it cannot protect against a supervisor-mode thread that configures a memory domain to expose private kernel data, so kernel object RAM must always be supervisor-only.

FreeRTOS MPU ports

FreeRTOS provides MPU-enabled ports in which tasks are created as privileged or unprivileged with xTaskCreateRestricted() or xTaskCreateRestrictedStatic(). The task definition carries the stack buffer and a set of memory regions with access attributes (read-write, read-only, privileged-only); setting portPRIVILEGE_BIT in the priority creates a privileged task. On Armv8-M ports (CM23, CM33, CM52, CM55, CM85 and others) configENABLE_MPU turns MPU support on. Current kernels default to the newer MPU wrappers (configUSE_MPU_WRAPPERS_V1 defaults to 0), and configENABLE_ACCESS_CONTROL_LIST (default 0) restricts which kernel objects an unprivileged task can use. Tasks created with plain xTaskCreate() on a non-MPU port all run privileged.

ControlZephyrFreeRTOSWhat it stops
Unprivileged executionUser mode threads (K_USER), CONFIG_USERSPACEMPU port, xTaskCreateRestricted() without portPRIVILEGE_BITParser bug writing kernel or other task memory
Memory regionsMemory domains and partitionsTask xRegions with access attributesCross-task data leakage
Kernel object accessPer-object permissions, syscall validationconfigENABLE_ACCESS_CONTROL_LISTUnauthorised use of queues, drivers, semaphores
Stack overflow detectionCONFIG_HW_STACK_PROTECTION, CONFIG_STACK_CANARIES, CONFIG_STACK_SENTINELconfigCHECK_FOR_STACK_OVERFLOW (methods 1 and 2), MPU stack regionsSilent corruption, control-flow hijack
Secure/non-secure splitTrusted Firmware-M module, PSA APIsconfigENABLE_TRUSTZONE, configRUN_FREERTOS_SECURE_ONLYKey extraction from a compromised application
Secure bootMCUboot, TF-M BL2 (CONFIG_TFM_BL2)MCUboot or vendor ROM bootloaderPersistent malicious firmware

TrustZone-M and Trusted Firmware-M

Arm TrustZone for Armv8-M partitions the microcontroller into a secure and a non-secure state; memory, peripherals, interrupts and debug can each be assigned to the secure world. Arm positions it as the starting point for a device root of trust. The non-secure application (the RTOS and its tasks) calls into the secure side only through defined entry points. See the Hardware Root of Trust Guide.

Trusted Firmware-M (TF-M) is the reference implementation of the Platform Security Architecture for this split. Zephyr integrates it as a module and has been PSA Certified since Zephyr 2.0.0 with TF-M 1.0. TF-M provides isolation of secure resources, crypto, device secret management, firmware verification, protected storage, attestation and audit logging, organised as a hierarchy:

  • PSA Immutable Root of Trust: the secure bootloader (BL2, based on MCUboot), which verifies the secure and non-secure images with public keys built into it.
  • PSA Updateable Root of Trust: the Secure Partition Manager and shared services such as PSA Crypto and Internal Trusted Storage.
  • Application Root of Trust: reduced-privilege secure services such as Protected Storage and your own secure partitions.
TF-M isolation levelBoundary enforcedWhen to choose it
Level 1Secure vs non-secure only; PRoT and ARoT share privilegeSmallest image; acceptable when all secure services come from one trusted supplier
Level 2Adds PRoT vs ARoT separation; ARoT reaches PRoT only through public APIsDefault choice when you add custom secure services
Level 3Adds isolation between individual ARoT servicesMultiple secure services from different parties, or high assurance targets; highest overhead

Check the level actually built through CONFIG_TFM_ISOLATION_LEVEL. Remember that the secure image starts first and configures the device, so peripherals may not be in their reset state when the RTOS boots.

Secure boot, updates and rollback

MCUboot is the common bootloader for both Zephyr and TF-M designs. Its image format carries type-length-value records for the image hash (SHA-256, SHA-384 or SHA-512), the signature (ECDSA, Ed25519 or RSA-PSS 2048/3072), optional encryption key material and a security counter.

  • Signing keys: public keys are compiled into the bootloader, and secure and non-secure images can be signed with different keys (in Zephyr with TF-M, CONFIG_TFM_KEY_FILE_S and CONFIG_TFM_KEY_FILE_NS). Never ship the default development keys: they are public. Keep production signing keys in an HSM. See the Code Signing Security Guide.
  • Rollback protection: the optional security counter stops a validly signed but older image from being installed. Enable it and store the counter in hardware-protected storage or OTP.
  • Encryption: optional image encryption (AES-CTR with the key wrapped by RSA-OAEP, AES-KW or ECIES) protects intellectual property and secrets in transit, but hashing and signing cover the unencrypted image, so it is not a substitute for signing.
  • Slot strategy: swap modes keep a recoverable copy of the previous image; overwrite-only and direct-XIP modes behave differently on power loss. Test the revert path, not just the happy path.

Treat device identity and update credentials as non-human identities with a lifecycle: provisioning, rotation and revocation. See the IoT Device Identity with TPM and DICE Guide.

Build hardening and attack surface reduction

Zephyr ships a hardening tool that compares a build's Kconfig against a database curated by the Zephyr Security Working Group. Run it with west build -t hardenconfig. The default strict profile adds removal of logging, shell, assertions and tracing to the base profile, which enables available memory protection and exploit mitigations. It also flags any enabled option marked experimental, deprecated or not secure (CONFIG_EXPERIMENTAL, CONFIG_DEPRECATED, CONFIG_NOT_SECURE), and recommends CONFIG_BUILD_OUTPUT_STRIPPED so shipped ELF files carry no symbols.

AreaProduction settingWhy
Debug and shellDisable shell, assertions and verbose logging, or gate them behind authenticated accessShells and logs expose internal state and commands
Debug portLock SWD/JTAG using the silicon vendor's readout and debug protection; use authenticated debug where supportedAn open debug port defeats every software control
Unused featuresTurn off unused network protocols, Bluetooth profiles, file systems and driversEvery enabled parser is reachable attack surface
CryptoUse PSA Crypto APIs (Mbed TLS or TF-M) and hardware RNG; no hand-rolled cryptoConsistent, reviewed primitives and key handling
CompilerStack canaries, warnings as errors, static analysis on every releaseZephyr requires static analysis findings to be fixed or waived before release
LanguageConsider memory-safe languages for new parsers where toolchains allowRemoves classes of bugs MPU isolation only contains

See the Memory-Safe Languages Guide and the Fuzzing Guide for the testing side.

Choosing an approach

  • Armv7-M or older parts with an MPU only: use unprivileged threads and memory domains (Zephyr) or restricted tasks (FreeRTOS MPU port). Isolate network and protocol code first. Budget for alignment padding.
  • Armv8-M with TrustZone: put keys, crypto, attestation and storage in TF-M, run the RTOS non-secure, and still use MPU isolation inside the non-secure side. TrustZone alone does not stop one non-secure task corrupting another.
  • Parts without an MPU: rely on stack sentinels, canaries, watchdogs, strict input validation and a minimal feature set, and record the residual risk. If the device is network-facing and long-lived, push for a part with protection hardware at the next revision.
  • Small teams: start from a vendor or upstream sample that already enables TF-M and MCUboot, run hardenconfig and fix the findings. Do not build custom secure partitions until the basics are in place.
  • Large product lines: define a reference security configuration per silicon family, enforce it in CI, and track deviations as waivers with an owner.

Rolling it out

  1. Inventory: list RTOS version, enabled Kconfig or FreeRTOSConfig.h options, third-party stacks and bootloader for every product. Generate an SBOM per build. See the SBOM Guide.
  2. Threat model: follow the Zephyr approach: define assets, draw data flows, classify threats with STRIDE and score with CVSS. Mark every external input and the task that parses it. The MITRE EMB3D Embedded Device Threat Model Guide provides a device-specific catalogue.
  3. Baseline hardening: run hardenconfig (base profile first), disable unused features and enable stack protection. Measure flash, RAM and timing before and after.
  4. Secure boot: enable MCUboot with production keys in an HSM and the security counter on, then test update, revert after a failed boot and refusal of an older image.
  5. Isolate parsers: move the network stack consumers and protocol parsers into user threads or restricted tasks. Run under load and fault injection to confirm deadlines are still met.
  6. Secure world: on Armv8-M, move keys and crypto into TF-M at isolation level 2, and replace direct key access with PSA Crypto calls.
  7. Lock down: enable debug protection on production units only, after confirming a recovery and failure analysis path exists.
  8. Roll back safely: keep every hardening change as a separate configuration fragment so a change that breaks timing can be reverted in one build, and ship through staged field rings so a bad image is caught before the whole fleet updates.

Detection and measurement

  • Fault telemetry: report MPU faults, stack overflow events, hard faults and watchdog resets with the faulting task identifier to the device management back end. A spike after a release, or on a single network segment, can indicate exploitation attempts.
  • Boot evidence: record image version, security counter and boot result; with TF-M, use initial attestation tokens so the back end can verify what firmware is running.
  • Vulnerability intake: watch the upstream advisories. Zephyr tracks vulnerabilities through GitHub security advisories, acknowledges reports within one week, uses an embargo of at most 90 days and lists fixed CVEs in each release. FreeRTOS reports go to AWS security. See the Bug Bounty and Vulnerability Disclosure Guide.

Useful metrics:

  1. Percentage of products whose release build passes hardenconfig base (or an equivalent FreeRTOS configuration review) with no unwaived failures.
  2. Percentage of externally reachable parsers running unprivileged.
  3. Percentage of fleet with secure boot and rollback counter enabled and debug locked.
  4. Median days from upstream RTOS CVE publication to fixed firmware available, and to 90 per cent fleet adoption.
  5. MPU fault and watchdog reset rate per thousand devices per month.

Common failure patterns

  • Shipping development signing keys: sample keys in bootloader projects are public, so anyone can sign firmware the device will accept.
  • Isolation on paper only: user mode is enabled, but the network stack, its buffers and the drivers it needs are granted to every thread, or everything still runs in supervisor mode because of a single legacy driver.
  • Secure boot without anti-rollback: attackers reinstall an old signed image with a known bug, and the device accepts it.
  • Debug left open: production units ship with SWD enabled, allowing flash readout of keys and firmware.
  • Stale RTOS forks: a vendor SDK pins an old RTOS release with a modified TCP/IP stack, so upstream CVE fixes never reach the product.
  • Keys in non-secure flash: TrustZone is present, but device keys and cloud credentials live in the application image where any memory disclosure bug can read them.

Framework mapping

RTOS controlNIST SP 800-53 Rev. 5NIST CSF 2.0
MPU regions, stack protectionSI-16 Memory ProtectionPR.PS-01
User mode, restricted tasks, TF-M isolationSC-39 Process IsolationPR.PS-01
Secure boot and signed updatesSI-7 Software, Firmware, and Information Integrity; SI-7(15) Code AuthenticationPR.PS-02
Disable unused features, hardenconfigCM-7 Least FunctionalityPR.PS-01
Key storage and PSA CryptoSC-12, SC-13PR.DS-01
Threat modelling, static analysis, fuzzingSA-8, SA-11, SA-15PR.PS-06
Upstream CVE trackingRA-5ID.RA-01

For products placed on the EU market, these controls also support the essential requirements of the Cyber Resilience Act. See the EU Cyber Resilience Act Guide and the PSA Certified and SESIP Guide.

Practitioner checklist

  • Record RTOS version, configuration and third-party stacks per product, with an SBOM per build.
  • Run west build -t hardenconfig (Zephyr) or an equivalent configuration review (FreeRTOS) in CI and fail the release on unwaived findings.
  • Enable MPU support and run every externally reachable parser unprivileged with the minimum memory partitions.
  • Enable hardware stack protection, canaries and the stack overflow hook.
  • On Armv8-M parts, keep keys and crypto in the secure world through TF-M and PSA Crypto APIs.
  • Enable MCUboot with production keys held in an HSM and the security counter on; test revert and rollback refusal.
  • Lock debug ports on production units and document the authorised recovery path.
  • Collect MPU fault, watchdog and boot telemetry from the fleet and alert on spikes.
  • Subscribe to Zephyr and FreeRTOS security advisories and track time to fix in the field.

Standards and references

Related NHI Mgmt Group resources: Embedded Device Security Guide · Firmware and Boot Security Guide · IoT Secure Firmware Update Guide · Device and IoT Identity Guide

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 27 October 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org