Papers
Topics
Authors
Recent
Search
2000 character limit reached

StackPatch: Lightweight Embedded Hot Patching

Updated 10 July 2026
  • StackPatch is a lightweight hot patching framework that reconstructs and edits stack frames at runtime to remediate vulnerabilities in embedded systems.
  • It employs exception-driven patching with hardware and software breakpoints to accurately detect update points with minimal overhead.
  • Evaluations on ARM, RISC-V, and Xtensa architectures show it patches vulnerabilities within 260 clock cycles while maintaining continuous system operation.

Searching arXiv for the cited StackPatch paper and closely related patching literature to ground the article. StackPatch is a hot patching framework for embedded systems that performs runtime vulnerability remediation by reconstructing and editing stack frames at precisely chosen update points, then resuming execution without rebooting. It is designed for resource-constrained, uninterrupted-service settings such as medical devices, soft programmable logic controllers, and network services running on real-time operating systems or bare-metal firmware, and is evaluated on ARM, RISC-V, and Xtensa microcontroller architectures. Its central claim is that exception-driven stack frame reconstruction provides a lightweight, cross-architecture mechanism for transforming a vulnerable execution state into a benign one while keeping time and memory overhead very small (Zhou et al., 12 Sep 2025).

1. Problem setting and design objectives

StackPatch is motivated by a combination of embedded-systems constraints that make conventional hot patching poorly matched to deployed firmware. The target systems are characterized by limited RAM and flash, limited computational power, strict real-time deadlines, little or no spare memory, heterogeneous processor architectures, frequent use of statically linked firmware, and the absence of facilities common in general-purpose operating systems, including dynamic linking, signals, and user-level context switching. The framework is explicitly aimed at mission-critical embedded systems that require uninterrupted service, including medical equipment and industrial controllers (Zhou et al., 12 Sep 2025).

The paper argues that several prior families of update mechanisms are unsuitable in this setting. Dynamic-linking-based approaches depend on OS support that many RTOS or bare-metal systems do not provide. A/B image schemes require duplicate storage and often a reboot. Instrumentation-heavy approaches impose ongoing runtime overhead and may force expensive Flash-sector rewrites. Hardware-specific designs such as HERA depend on ARM Cortex-M debug features, while VM-based systems such as RapidPatch introduce runtime and storage overhead and require conversion of patches into eBPF bytecode. By contrast, StackPatch seeks a mechanism that can patch both code in Flash and code in RAM, operate across multiple MCU architectures, and preserve service continuity (Zhou et al., 12 Sep 2025).

The paper formalizes the hot-patching objective as a state transition problem. For a vulnerable program state

s=(md,gr,pc),s = (md, gr, pc),

where mdmd is processor mode, grgr denotes general registers, and pcpc is the program counter, the goal is to construct a transition mechanism FF such that

s=F(s),s' = F(s),

with ss' the benign execution state corresponding to patched behavior. StackPatch realizes FF by capturing live execution into a reconstructed stack frame, editing that frame, and restoring control so that execution continues in a patched state (Zhou et al., 12 Sep 2025).

2. System architecture and runtime workflow

StackPatch is organized as an offline host-side preparation pipeline plus an on-device runtime patching path. On the patch host, the workflow begins by retrieving vulnerability descriptions and official patch code. Vulnerability localization is then performed manually by comparing vulnerable and patched source, disassembling both versions for the target MCU architecture, using BinDiff to identify binary differences, and using Ghidra P-Code and variable tracking to reason about semantics in optimized code. The framework then performs update-point detection, choosing the entry of the vulnerable code at the first point of semantic divergence between vulnerable and patched behavior (Zhou et al., 12 Sep 2025).

After the update point is identified, the patch generation component constructs a stack-frame-based patch. The generated patch is compiled into a binary payload, accompanied by metadata describing the update point address, patch memory location, patch code, and patch size. Patches are stored as a patch list and transferred to the device over Bluetooth, WiFi, JTAG, or UART. On the device, an update service installs the patch into available RAM and arms the chosen trigger mechanism. Because the patches reside in RAM, they are lost on power loss; this is an explicit property of the design rather than an accidental detail (Zhou et al., 12 Sep 2025).

At runtime, when execution reaches an update point, StackPatch triggers an exception, enters a modified exception handler through the interrupt vector table, reconstructs the relevant stack frame, dispatches to the appropriate patch, edits the saved execution context, and restores state. The patched continuation is realized either by passing over the trapped instruction or by redirecting control to a different resumption address. This arrangement makes the patch act on the in-flight invocation of vulnerable code rather than replacing entire modules or requiring a process restart (Zhou et al., 12 Sep 2025).

The framework also distinguishes three memory roles: the original program in .text, globals in .data, and patch payloads and metadata in .patch. This separation suggests a compact deployment model in which the original firmware remains largely untouched while the patch logic is injected as an auxiliary runtime structure, though the exact memory-management policy remains device-specific (Zhou et al., 12 Sep 2025).

3. Stack frame reconstruction, triggering, and control-flow transfer

The technical core of StackPatch is stack frame reconstruction. When the update point is reached, StackPatch forces an exception and constructs a frame

f(gr,ra),f(gr, ra),

where rara is the return address. Patch execution transforms this into

mdmd0

and restoring from the modified frame yields the patched execution state. The framework derives a variable-to-stack mapping in three stages:

mdmd1

mdmd2

mdmd3

Here mdmd4 determines which register holds a live source variable at the update point, mdmd5 determines where each saved register resides in the exception frame, and mdmd6 composes them into a direct source-variable-to-stack-offset mapping. StackPatch then rewrites the official patch so that references to local variables, return values, and return addresses become stack-pointer-relative accesses into the reconstructed frame (Zhou et al., 12 Sep 2025).

This mechanism is coupled to three trigger strategies: hardware breakpoints, software breakpoints, and hooks.

Trigger Typical use Main trade-off
Hardware breakpoints Few vulnerabilities Very efficient, but limited by available breakpoint registers
Software breakpoints Code in RAM; many patch sites Portable and effectively unbounded, but requires instruction replacement
Hooks Code in Flash or RAM; many sites Flexible and unbounded, but adds ongoing control-transfer overhead

Hardware breakpoints are preferred when only a few vulnerabilities must be patched. Software breakpoints replace the original instruction with an architecture-specific trap such as bkpt, ebreak, or break. Hooks insert a trampoline-style redirection at designated function or block points. The framework’s policy is to prefer hardware breakpoints for a small number of vulnerabilities and to use instrumentation in Flash plus software breakpoints in SRAM when many sites must be patched (Zhou et al., 12 Sep 2025).

Exception handling is architecture-specific but conceptually uniform. ARM Cortex-class MCUs may use dual stacks, MSP and PSP, and benefit from hardware or lazy stacking on exception entry. RISC-V and Xtensa require more manual save and restore logic in assembly. The modified exception-handler algorithm allocates stack space, saves mdmd7, saves general registers, updates processor status, dispatches the patch, restores registers, restores mdmd8, frees stack space, and returns. The paper states that mdmd9 is always pushed first and that restoration of the program counter is deferred until all other general registers have been recovered, which is a practical integrity condition for safe control transfer (Zhou et al., 12 Sep 2025).

Control resumption follows one of two strategies. In Pass, StackPatch sets grgr0 to the instruction immediately after the update point, advancing by the trapped instruction length. In Redirect, StackPatch sets grgr1 either to the vulnerable function’s return path or to the first instruction after the vulnerable region. The paper describes the second case as computing the vulnerable-code length by binary comparison between vulnerable and patched code and then setting the resumption address accordingly (Zhou et al., 12 Sep 2025).

4. Patch generation, safety conditions, and heterogeneous support

Patch generation is semi-automated rather than fully automatic. The paper is explicit that vulnerability localization and update-point selection remain manual, largely because automatic fault localization is considered too inaccurate for the intended deployment context. Once these two decisions are made, however, StackPatch automates variable mapping, source-to-stack rewriting of the official patch logic, compilation of the generated C patch, and generation of metadata for the patch list (Zhou et al., 12 Sep 2025).

The framework supports patches involving local variables, global variables, and macro variables, and it claims support for changes to global-variable values, removals of globals, additions of globals, and size increases of global variables. This is presented as a distinction from prior hot-patching approaches that cannot accommodate some data-layout changes. The generated patch code is written in C rather than assembly, eBPF, or LLVM IR, with architecture-specific adaptation concentrated in exception handling, save/restore sequences, breakpoint instructions, and ABI-aware register-to-stack mapping (Zhou et al., 12 Sep 2025).

Safety checking is an explicit component of the design. The paper defines

grgr2

and compares this with a system-specific threshold

grgr3

where grgr4 is watchdog timeout and grgr5 is the worst-case execution time of the critical task. Patches are rejected if their delay exceeds grgr6 or if they contain unbounded loops, C function calls, or dangerous instructions. Update points are also constrained: they must be after initialization of all variables needed by the patch, must not fall on stack-manipulating instructions such as PUSH or POP, and must not be placed in illegal or unwritable regions for the selected trigger mechanism (Zhou et al., 12 Sep 2025).

Portability across architectures is achieved by separating architecture-independent logic from architecture-specific mechanisms. The vulnerability-localization workflow, update-point concept, mapping logic, dispatcher, verification policy, and update service are presented as architecture-independent. Exception handler modification, stack-frame layout, dual-stack handling, trap instructions, save/restore ordering, and register-to-stack mapping are architecture-specific. The framework is evaluated on ARM Cortex-M4, RISC-V32, and Xtensa LX7, and the paper reports that it remains accurate under compiler optimization levels -O0, -O1, -O2, and -O3, finding the same update points and semantically equivalent patches for the tested vulnerabilities (Zhou et al., 12 Sep 2025).

The scope is broad but not universal. StackPatch is not presented as robust for multiple complex multi-line macros, complex macro expressions in a single update, patches that require dozens or hundreds of update points, build or configuration changes such as CMakeLists, or multi-core systems. The paper identifies five CVEs it could not repair for these reasons (Zhou et al., 12 Sep 2025).

5. Evaluation, overheads, and case studies

The evaluation spans four boards across three architectures: nRF52840 and STM32F401RE on ARM Cortex-M4, GD32VF103 on RISC-V32, and ESP32S3 on Xtensa LX7. The software corpus includes FreeRTOS, Zephyr OS, and libraries such as PicoTCP, WolfSSL, mbedTLS, uIP, Contiki, and AMNESIA33-related components. The paper reports a study of 107 vulnerabilities across 30 software versions, with StackPatch successfully patching 102 of them, corresponding to a success rate of approximately grgr7 (Zhou et al., 12 Sep 2025).

The principal timing result is that remediation completes in fewer than 260 MCU clock cycles. The reported mean ranges are: nRF52840 and STM32F401RE with grgr8 cycles, grgr9, and pcpc0; GD32VF103 with pcpc1, pcpc2, and pcpc3; and ESP32S3 with pcpc4, pcpc5, and pcpc6. For a representative set of 12 CVEs, average patch latency is 15 cycles on STM32F401RE, 16 cycles on GD32VF103, and 30 cycles on ESP32S3. Mean patch payload size on the representative set is 39 bytes on ARM, 34 bytes on RISC-V, and 46 bytes on Xtensa (Zhou et al., 12 Sep 2025).

Memory overhead is correspondingly small. Exception-handler modifications require 82 bytes on ARM, 160 bytes on RISC-V, and 51 bytes on Xtensa. The runtime footprint is reported as 0.5 KB of flash and 0.2 KB of SRAM, for a total of 0.7 KB. The paper also states that the mean patch payload for the 102 vulnerabilities is around 40 bytes on nRF52840 (Zhou et al., 12 Sep 2025).

Three case studies illustrate practical deployment. In a heart-rate monitor, StackPatch dynamically patched CVE-2018-16601, an out-of-bounds read in FreeRTOS IP processing, and restored correct photoplethysmography waveforms without interrupting heart-rate monitoring. In a soft PLC on STM32F401RE, StackPatch patched CVE-2020-10023 during idle cycles without restart in a watchdog-protected cyclic control system with a 0.012 ms scan period. In network-service experiments on ESP32-S3, StackPatch instrumented 1,535 functions, corresponding to 34% of all functions, and patched four vulnerabilities in parallel while handling 5,000 HTTP GET and CoAP GET requests. The reported overheads were modest: for CoAP, average latency increased by 1.2%, P99 latency by 6.7%, and WCET by 6.3%; for HTTP, average latency increased by 2.1%, P99 latency by 10.7%, and WCET by 9.7% (Zhou et al., 12 Sep 2025).

The paper also compares StackPatch with RapidPatch and AutoPatch on nRF52840 for CVE-2018-16601 under 1–5 scheduled patches. RapidPatch requires 4.1–5.38 pcpc7, AutoPatch 3.0–4.37 pcpc8, and StackPatch 2.01–2.06 pcpc9 with hardware breakpoints, 2.52–2.83 FF0 with software breakpoints, and 2.11–2.42 FF1 with instrumentation or hooks. The authors interpret this as StackPatch being over 50% faster than AutoPatch and more than twice as fast as RapidPatch on average (Zhou et al., 12 Sep 2025).

6. Relation to other uses of “patch” in the literature

Within arXiv literature, “patch” denotes several distinct objects, and StackPatch belongs to a specific one. It should be situated in the domain of runtime embedded remediation rather than in production-driven server repair, patch-stack maintenance, patch representation learning, or geometric surface modeling. For example, Itzal performs production-driven patch generation from live failures and validates candidate fixes on shadow traffic without requiring a failing developer-written test case, but it targets Java HTTP applications and does not automatically deploy patches into the live production process (Durieux et al., 2018). PaStA analyzes long-lived downstream patch stacks by grouping similar commits into equivalence classes and studying integrability, maintainability, and engineering effort over repository history, which is a different notion of “stack patching” centered on version-control lineage rather than runtime state transformation (Ramsauer et al., 2016).

A further distinction arises from work on semantic representations of software patches. Patcherizer treats a patch as a multimodal object composed of code context, sequence-level change intention, and structural intention in AST space, for tasks such as description generation and patch correctness prediction (Tang et al., 2023). PatchExplainer frames patch description generation as a machine translation problem over patch-related code, patch scope, and historical descriptions, with auxiliary supervision from description-similarity clusters (Vu et al., 2024). These systems help explain or classify patches; StackPatch instead executes native patch code against reconstructed machine state.

The term should also be distinguished from the S-patch in geometric modeling, a constrained bicubic Hermite rectangular patch whose defining property is that both principal diagonals are cubic rather than degree-6, intended for tessellation-sensitive surface design (Skala et al., 2022). This suggests that “StackPatch” is best understood not as a generic label for any patch-related method, but as the specific embedded hot-patching framework based on stack frame reconstruction introduced in “Dynamic Vulnerability Patching for Heterogeneous Embedded Systems Using Stack Frame Reconstruction” (Zhou et al., 12 Sep 2025).

Topic to Video (Beta)

No one has generated a video about this topic yet.

Whiteboard

No one has generated a whiteboard explanation for this topic yet.

Follow Topic

Get notified by email when new papers are published related to StackPatch.