Next Article in Journal
Advancing Secret Sharing in 3D Models Through Vertex Index Sharing
Previous Article in Journal
SACG-YOLO: A Method of Transmission Line Insulator Defect Detection by Fusing Scene-Aware Information and Detailed-Content-Guided Information
Previous Article in Special Issue
A Gamified Method for Teaching Version Control Concepts in Programming Courses Using the Git Education Game
 
 
Font Type:
Arial Georgia Verdana
Font Size:
Aa Aa Aa
Line Spacing:
Column Width:
Background:
Article

TeeDFuzzer: Fuzzing Trusted Execution Environment

1
School of Computer Science, Guangdong University of Science and Technology, Dongguan 523668, China
2
Institute of Cyberspace Technology, Hong Kong College of Technology, Hong Kong, China
*
Author to whom correspondence should be addressed.
Electronics 2025, 14(8), 1674; https://doi.org/10.3390/electronics14081674
Submission received: 6 March 2025 / Revised: 30 March 2025 / Accepted: 1 April 2025 / Published: 21 April 2025
(This article belongs to the Special Issue Advances in Software Engineering and Programming Languages)

Abstract

:
The Trusted Execution Environment (TEE) is crucial for safeguarding the ecosystem of embedded systems. It uses isolation to minimize the TCB (Trusted Computing Base) and protect sensitive software. It is vital because devices handle vast, potentially sensitive data. Leveraging ARM TrustZone, widely used in mobile and IoT for TEEs, it ensures hardware protection via security extensions, though needing firmware and software stack support. Despite the reputation of TEEs for high security, TrustZone-aided ones have vulnerabilities. Fuzzing, as a practical bug-finding technique, has seen limited research in the context of TEE. The unique software architecture of TrustZone-assisted TEE complicates the direct application of traditional fuzzing methods. Moreover, simplistic approaches, such as feeding random input values into TEE through the API functions of the rich operating system, fail to uncover deeper, latent bugs within the TEE code. In this paper, we present a fuzzing strategy for TrustZone-assisted TEE that utilizes inferred dependencies between Trusted Kernel system calls to uncover deep-seated TEE bugs. We implemented our approach on OP-TEE, where it successfully identified 17 crashes, including one previously undetected kernel bug.

1. Introduction

In a smart society, the communication and collaboration of numerous devices, based on foundational IoT (Internet of Things) technologies, enhance our quality of life [1]. However, IoT devices also generate, process, and exchange large amounts of sensitive data, which poses the crucial problem of providing intelligent services without sacrificing security and privacy. The development of secure IoT devices is challenging due to complexity and connectivity vulnerabilities, as the integration of various third-party components into microcontroller-based devices without proper separation mechanisms increases the risks [2,3,4]. Meanwhile, the growing IoT ecosystem demands reliable security architectures, yet microcontroller limitations impede developers. In secure computing, separation via microkernels, hypervisors, and TEEs (Trusted Execution Environments) like TrustZone-assisted ones is a principle. However, despite its presumed security, TrustZone-assisted TEEs (i.e., Qualcomm, Trustonic, Huawei, Nvidia, and Linaro) still have issues, including architectural flaws and implementation bugs [5]. Resolving these issues is vital for the security and privacy of the IoT infrastructure and the success of intelligent services in a smart society, where user trust and data protection are essential.
Researchers categorize TEE architectures into two types based on the capability of a Trusted Kernel to implement a basic set of OS functions in the secure world and manage multiple TEE instances. Each instance hosts a specific application, known as a Trusted Application (TA). These architectures are termed TEE kernel and TEE service [6]. Compared to TEE services, TEE kernels typically depend on larger Trusted Computing Bases (TCBs), which can be a disadvantage. Although some Trusted Kernels are significantly smaller than the rich OS (operating systems), they are not immune to vulnerabilities [7,8,9].
Recent advances have underscored the prevalence of vulnerabilities in TEEs, highlighting the need for robust security measures [10]. In systems utilizing a TEE kernel, a privileged Trusted Kernel in the secure world supports the lifecycle management of Trusted Applications. This Trusted Kernel is tasked with providing not only trusted storage for data and keys but also cryptographic operations and additional functions essential for TAs. Furthermore, it is responsible for safeguarding access to sensitive data, even when the normal world is compromised by threats such as user attempts to root their smartphones [11,12].
Despite the crucial role of the Trusted Kernel in maintaining security, significant research has uncovered numerous vulnerabilities within it. Currently, there are no effective methods available to assist developers in identifying and addressing these vulnerabilities. Furthermore, the GlobalPlatform organization has established standard APIs (Application Programming Interfaces) that outline the necessary functionalities of the Trusted Kernel for supporting TAs and facilitating communication between the rich OS and TAs [13]. However, Trusted Kernels vary as they are developed by different manufacturers. Particularly in energy-constrained environments like IoT, Trusted Kernels may be customized to meet specific application needs, potentially introducing new vulnerabilities.
Fuzzing has been remarkably successful in uncovering vulnerabilities within operating systems by repeatedly invoking arbitrary sequences of kernel API functions [14,15,16,17,18,19]. We anticipate similar success in identifying vulnerabilities in Trusted Kernels, thereby enhancing the security of TEEs. The advocacy for an open TEE design [20] further facilitates fuzzing efforts on Trusted Kernels. In an open architecture, parts of the software stack can be modified to bypass authentication processes and extract necessary information. However, applying fuzzing to Trusted Kernel testing presents significant challenges, which can be categorized into three aspects.
First, unlike fuzzing a Rich OS, the Trusted Kernel primarily offers functionalities like cryptographic operations and trusted storage. The basic and OS-like features it provides are often insufficient to support conventional fuzzer operations independently, making it difficult to thoroughly assess its security. Second, similar to a Rich OS, the behavior of each Trusted Kernel system call heavily relies on the shared kernel state established by preceding calls. System calls made without the appropriate kernel state might only trigger superficial error handling, failing to reach the core logic. To achieve a deeper inspection, the kernel state must be precisely configured as expected by the system call, necessitating the identification and sequential execution of dependent system calls. Finally, the main challenge with existing fuzzers lies in the reproducibility of discovered bugs. Since Trusted Kernel operations often depend on VMs (Virtual Machines), QEMU (Quick Emulator), and Rich OS instances, reloading a fresh instance for each test, as required in traditional fuzzing practices, takes too long. Instead, reusing previous instances leads to dirty Trusted Kernel states, resulting in unstable executions and irreproducible bugs.
In this work, we tackle the identified challenges in fuzzing the Trusted Kernel with TeeDFuzzer, our proposed solution. TeeDFuzzer resolves the first challenge through a customized set of CAs (Client Applications) and TAs. The CA, operating on the Rich OS, serves as the fuzzer’s target. It processes the binary code of system call sequences, delivers these to the TA, and controls the invocation of system calls via commands. Furthermore, we introduce a lightweight method to analyze the data flow from kernel system calls executed during regular program operations to construct a system call dependencies model. This model incorporates a novel taint tracking mechanism that enhances the dependency graph with taint data throughout the fuzzing process. We utilize this model in TeeDFuzzer to generate improved seeds for the fuzzer and to expand the range of test cases produced during fuzzing sessions. Lastly, we document the system call sequences executed prior to each crash to develop an effective algorithm that identifies the sequences responsible for crashes.
We conducted tests on OP-TEE [21] running on QEMU, a widely recognized open Trusted Kernel developed by Linaro. While our current implementation is tailored to OP-TEE, the underlying technique is broadly applicable and can be adapted to other Trusted Kernels within TEE frameworks across various CPU architectures. The experiments show that our TeeDFuzzer can effectively discover edge coverage of OP-TEE. It also identified 17 crashes in OP-TEE with one bug confirmed by the developer.
The key contributions of our paper can be summarized as follows.
  • We identify three challenges of testing TEE, which are insufficient native features for testing, the requirement of system call dependency, and difficulties in reproducing bugs.
  • We develop innovative methods to test TEE by solving the challenges. We use customized CAs and TAs to conduct fuzzing, analyze data flow of system calls, and record system call sequences for reproducing.
  • We test OP-TEE with our TeeDFuzzer, and it exposes 17 crashes with one bug confirmed by the developer.
The paper is organized as follows. Section 2 discusses the background and related work. Section 3 describes the overview of our method. Section 4 presents the design details of our paper. Section 5 evaluates our method. Finally, Section 6 concludes this paper.

2. Background and Related Work

In this section, we include background information on TrustZone-assisted TEEs and related work on testing TEEs and fuzzing system kernels. Also, we illustrate the key importance when fuzzing the Trusted Kernel.

2.1. TrustZone-Assisted TEE

ARM introduced TrustZone technology starting with the ARMv6 architecture, which features hardware that divides the ARM core’s runtime state into secure and non-secure states. This division is managed through the Secure Monitor Call (SMC), which facilitates switching between these states. In the ARMv7 architecture, transitions between the secure and non-secure states are constrained to occur only in Monitor mode, dictated by the privilege level (PL) at runtime. With the advent of the ARMv8 architecture, a more structured hierarchy of protection domains was established, defined by Execution Levels (EL) from EL0 to EL3. Within this framework, the secure and non-secure states span from EL0 to EL2, designated as S-EL0 to S-EL2 and N-EL0 to N-EL2, respectively. This structure underpins the general software architecture of TrustZone, as illustrated in Figure 1.
In addition to the well-known applications running on N-EL0 and the Rich OS on N-EL1, a typical TrustZone-enabled system also includes several key components across different execution levels. CAs operate on N-EL0 and N-EL1, interfacing with the TEE through a user-space library that utilizes the TEE Client API to access facilities provided by TAs within the TEE. CAs typically communicate with the secure world via shared memory located in non-secure memory. The TrustZone Driver, located in the kernel space of the Rich OS, is responsible for managing the memory for message queues and registering these with the TEE. This driver initiates contact with the Secure State, usually through an SMC. The call is routed through the EL3 Secure Monitor to the Trusted Kernel in the TEE. Operating in the Secure State, the Trusted Kernel hosts and invokes TAs, which then read requests from the queue.

2.2. Trusted Kernel

As shown in Figure 1, in systems equipped with TEEs, applications operate within two distinct execution environments, each supported differently at runtime. The Trusted Kernel, active on TrustZone-enabled platforms, provides runtime support for TAs, managing their lifecycle through the Trusted Application Interface. Additionally, the Trusted Kernel implements TEE Internal Core APIs, which TAs utilize to execute secure tasks. These APIs are categorized into six main types: (1) trusted core framework API; (2) trusted storage API for data and keys; (3) cryptographic operations API; (4) time API; (5) TEE arithmetical API; and (6) peripheral and event APIs.
TA interactions with the Trusted Kernel are illustrated in Figure 2. To enhance the portability of the Trusted Kernel and TA across different platforms, the GlobalPlatform organization has defined most TEE Internal Core APIs within their TEE standardization efforts, as specified in the TEE Internal Core API specification [13]. These API components are typically compiled into a library file at compile time. TAs then perform operations by calling the relevant interfaces within this library. The core functions of the TEE Internal Core APIs are primarily executed through system calls in the kernel space, which these APIs invoke to perform their respective functions. According to GlobalPlatform specifications, TEE Internal Core API functions generally return a TEE_Result code to signal errors to the caller. Consequently, system calls within the Trusted Kernel also commonly use TEE_Result as their return value, instead of a more informative parameter. Additionally, certain limitations of API parameters cannot be represented in C when developing the Trusted Kernel. The GlobalPlatform specification employs a set of patterns for function parameters to specify the permissions and usage of pointer parameters. These annotations not only help construct system call parameters for test cases but also determine the read and write permissions for these parameters. This approach is also used as a reference in data flow analysis. Such annotations include [in], [out], [inout], [outopt], [inbuf], [inoutbuf], [outbuf], [outbufopt], [instring], [instringopt], [outstring], [outstringopt], and [ctx].

2.3. Trusted Execution Environment Testing

Cybersecurity is increasingly important as people more and more rely on the digital world [22,23]. The GlobalPlatform compliance test includes a compliance adaptive layer specification and a configuration set that outlines how functions should be called, the parameters involved, and the expected test outcomes. However, it does not supply any actual code for completing tests, requiring developers to implement the specifications themselves [24,25,26].
Xtest, provided by Linaro, is a testing framework that conducts API testing on the functionalities exposed by the Client API and the Internal Core API. It includes numerous test cases. To conduct Trusted Kernel-related tests, including those for cryptography, storage, secure storage implementation, and benchmarking, Xtest utilizes standard user-space applications running on Linux along with various TAs. Importantly, Xtest does not modify the drivers or the Trusted Kernel. Researchers at Riscure have proposed a method for fuzzing embedded trusted operating systems [27]. They developed an OP-TEE fuzzer that, unlike TeeDFuzzer, generates random system calls based on predefined grammar rules without considering the dependencies between calls. PARTEMU [28] supports the emulation of various Trusted Kernels, including QSEE [29], Kinibi [30], TEEGRIS [31], and OP-TEE, facilitating dynamic analysis on the Trusted Kernel and TAs during fuzzing. However, testing Trusted Kernels through emulation does not fully replicate real-world operations. Both PARTEMU and FuzzZone [32] for QSEE focus solely on testing the Trusted Kernel image through SMC, which significantly limits the effectiveness of such tests.

2.4. Kernel Fuzzing

Fuzzing is a practical bug detection technique that has already discovered numerous bugs [33,34]. Many research works in fuzzing focus on optimizing fuzzing schedule on mutations based on different motivations. For example, some fuzzers focus on analyzing bugs and use the features of bugs to guide fuzzing [35]. The fuzzing targets that are related to TEE are the fuzzing on embedded systems [36]. The fuzzing of rich OS kernels is highly relevant to our work, which has acknowledged the importance of dependencies between system calls [14,15,37]. Unlike fuzzing rich OS kernels, fuzzing the Trusted Kernel in a TEE not only requires it to provide lightweight OS functionalities but also necessitates support for communication with the Rich OS, focusing particularly on security functions such as trusted storage and cryptographic operations. Additionally, when fuzzing the Trusted Kernel, the fuzzer often does not operate directly on the Trusted Kernel itself and faces several constraints related to permission issues.

2.5. LLM Based Testing

Recent advancements have enabled the use of large language models (LLMs) in fuzz testing, offering a promising means to automate and enhance software security testing [8,23]. These approaches generally follow a three-phase workflow—pre-processing, prompt generation, and post-processing—wherein relevant contextual information is first extracted from the target application to formulate effective prompts. The prompts are then used by LLMs, either in a zero-shot or fine-tuned setting, to generate fuzz drivers and test inputs [38,39]. Specifically, LLMs have been applied to produce code that creates fuzz drivers for API invocation across various programming environments, as well as to generate structured textual inputs for GUI-based applications, thereby broadening the diversity of test cases and improving code coverage [39]. Despite their potential to increase bug detection rates and reduce manual intervention, these methods face challenges related to generation speed, integration with existing fuzzing frameworks, and ensuring the syntactic and semantic accuracy of the generated outputs. Due to the complexity of TEE fuzzing, we have not seen related works that use LLMs to improve the performance of TEE fuzzing.

3. Overview of TeeDFuzzer

As shown in Figure 3, TeeDFuzzer consists of two components, the Analysis Host and the Target Host. The Analysis Host is responsible for inferring dependencies of system calls and managing the restart of testing. The Target Host is responsible for generating system call sequences, testing the target Trusted Kernel, and collecting data during testing.

Architecture of  TeeDFuzzer

The primary objective of TeeDFuzzer is to effectively fuzz the Trusted Kernel within the TEE environment. As highlighted in Section 2.2, the Trusted Kernel is tasked with providing OS functionalities such as integration, scheduling, communication, memory management, and retrieving system information, which are facilitated through the TEE internal core API.
These APIs, implemented at S-EL0, include numerous checks that are not characteristic of the system calls performed at S-EL1. A compromised or malicious TA might bypass these checks by not utilizing the wrapper APIs, leading to the potential rejection of test cases during API checks and missing critical vulnerabilities due to untriggered bugs in the system call handlers. To address this, TeeDFuzzer is designed to directly invoke system calls to fuzz the Trusted Kernel. However, the OS functionalities provided by the Trusted Kernel are primarily security-related and often do not support the operational needs of a fuzzer. This limitation makes it impractical to use a customized TA to directly fuzz on the Trusted Kernel. Implementing such a fuzzer would require extensive engineering work, especially when adapting to different Trusted Kernel implementations. This issue is circumvented by operating the fuzzer on a Rich OS like Linux. Nonetheless, even though the interface for S-EL0 provided by the Trusted Kernel is accessible from N-EL0, test cases must still be generated in the normal world and transferred to the secure world for execution. Additionally, kernel panics triggered during fuzzing can lead to system instability, requiring a reboot or causing data loss.
To mitigate these challenges, we have developed a dual-host architecture for TeeDFuzzer, consisting of a target host and an analysis host, as depicted in Figure 3. By continuously refining the dynamic graph during the fuzzing process, analysis tasks can be offloaded to a separate host, ensuring that the execution speed of fuzzing remains unaffected. This decoupled approach not only prevents manual intervention but also minimizes the risk of data loss during fuzzing operations. Furthermore, this architecture enhances scalability and resource allocation, enabling simultaneous analysis and fuzzing without compromising system performance. As a result, the overall workflow becomes more robust and automated, supporting higher testing standards and more thorough security assessments. This setup prevents the need for manual intervention and minimizes data loss during fuzzing operations. The operation of TeeDFuzzer is structured into two main phases: (1) During regular system operation, TeeDFuzzer gathers system call data to complete its initialization, which includes generating an initial seed corpus and establishing a system call dependency digraph. (2) The second phase is the fuzzing stage, during which the system call dependency digraph is dynamically refined.
Given the instability of the Target Host during fuzzing, there is a high risk of data loss in the event of a crash. To mitigate this, the Analysis Host plays a dual role. It not only provides configuration settings for the Target Host and manages its restarts upon system hangs, but it also analyzes logs from the Target Host to infer dependencies between system calls. This analysis aids in generating a dependency graph that enhances the fuzzer’s test cases. Moreover, the Analysis Host documents the sequence of system calls executed on the Trusted Kernel, ensuring that inputs are recorded for reproducibility and detailed post-crash analysis. While the initial stages of TeeDFuzzer are conducted on the Analysis Host, the actual execution of the system calls occurs in the secure world of the Target Host. TeeDFuzzer continuously produces system call sequences via the fuzzer operating in the normal world of the Target Host. These sequences are then communicated to the secure world through interactions between the CA and the TA, enabling the detection of vulnerabilities within the Trusted Kernel.
  • Data Collection. The data collection module of TeeDFuzzer gathers information using two distinct approaches. The first involves instrumenting the core code of the Trusted Kernel. This method captures parameter information at the entry and exit points of system calls by instrumenting their source code, as well as code block coverage by modifying the kernel code itself. The second approach employs a Pseudo TA, which runs in the secure world and is compiled alongside the system kernel core code. This Pseudo TA encodes and collects sequences of system calls invoked during normal system operation, enabling the construction of test cases that closely mimic real-world scenarios.
  • Dependency Inferrer. During the normal operation of the Target Host, we employ a lightweight data flow-based method to infer dependencies between system calls within the Trusted Kernel. This inference leverages characteristics of the Trusted Kernel system call parameters and the parameter data collected at system call entry and exit points by the data collection module. Using this approach, the dependency inferrer initializes the system call dependency digraph. During the fuzzing process, the data collection module continuously captures system call logs to track taint information. This tainted data is then used to dynamically enhance the system call dependency digraph.
  • Initial Seed Corpus Generation. We will utilize the system call sequences collected during normal system operations, along with the inferred system call dependency digraph, to guide the initialization of the seed corpus.
  • Fuzzer. During the fuzzing of the Trusted Kernel in the TEE, the fuzzer utilizes the initial seed corpus, system call dependency digraph, and fuzzing configuration as inputs. The outputs, which are test cases containing system call information, can be transmitted to the secure world’s invoker via the CA. The fuzzer retains the following types of test cases: (1) those that traverse each distinctive execution path for coverage-guided fuzzing, (2) unique test cases that induce a fatal signal in the tested program, and (3) unique test cases that cause the program to time out. The latter two types are identified as potential bugs.
  • Invoker. The invoker, running as a TA in S-EL0, receives test cases shared by the fuzzer via the CA. It then parses these test cases and executes the system call sequences derived from them.
  • Manager. Sometimes, a bug in the Trusted Kernel causes the Target Host to become trapped in the secure world, preventing it from returning to the normal world and causing it to hang. During fuzzing, the manager on the Analysis Host monitors the Trusted Kernel for any bugs that might crash or hang the Target Host. This monitoring involves checking the heartbeat signal between the Analysis Host and the Target Host to determine if a restart is necessary. Upon restarting, the manager records the input sequence that triggered the system crash, along with error information, for further analysis and reproduction.

4. Design of TeeDFuzzer

In this section, we detail the design of TeeDFuzzer. Our TeeDFuzzer includes system call encoding, data collection, Dependency Inferrer, Dependency Graph Refinement, Fuzzer, Invoker, and Manager. The key of TeeDFuzzer is to infer system call dependency, based on which it will generate new system call sequences. The dependency graph is dynamically refined during fuzzing.

4.1. System Call Encoding in TEE

TeeDFuzzer accomplishes the following objectives through the encoding of system calls: (1) It facilitates the sharing of system call information between the secure world and the normal world. (2) It uses encoding to allow the TA to invoke different system call sequences based on the encoded information, eliminating the need to compile and generate different TAs. (3) It enables quick and flexible changes to the sequence of executed system calls through encoding, which also supports dynamic dependency inference. On the one hand, if the parameters passed into a system call do not align with the annotations specified in the TEE Internal Core API Specification, they are likely to be rejected. For example, the [inbuf] annotation refers to a pair of parameters where the first (pointer) parameter cannot be NULL unless the second (size_t) parameter is set to 0. This pair of parameters represents an input data buffer, which must be entirely readable by the TA and is not restricted by ownership; it can be located in either shared or private memory. On the other hand, system call arguments often depend on previous system calls, such as returned handles. In encoding design, the challenges include managing different parameter types and preserving dependencies between parameters.
TeeDFuzzer categorizes parameters in system calls into various types such as value, reference, dereference, buffer, and buffer with data to design the encoding scheme for each system call. The encoding includes the following details: (1) the system call number, (2) the type of each parameter, (3) specific information about each parameter, and (4) the data contained within any buffers. During the fuzzing process, the invoker of TeeDFuzzer decodes this information and invokes the system call according to the specified encoding. For example, the system call cryp_obj_alloc(0xa0000010, 0x80, &obj_handle) is encoded into 1b00 0000 4406 0000 1000 00a0 8000 0000 0080 0000. In this format, every byte is assigned a specific role in encoding the system call. The first four bytes serve as the system call identifier, uniquely determining which system call is being invoked. Given that the number of system calls is relatively limited, these four bytes provide ample capacity for complete encoding. Following this, the next four bytes are designated to indicate the types of arguments associated with the system call, ensuring that each parameter is correctly identified and processed. The remaining bytes contain the actual data to be passed, delivering the precise input required for the system call’s execution. This structured encoding not only facilitates clear and efficient communication within the system but also ensures that each component of the call is accurately interpreted. By segregating the identifier, argument types, and data, the design promotes robustness and simplifies debugging, making the entire process more reliable and easier to maintain.

4.2. Data Collection for Graph Construction

If a client needs to utilize services provided by a TA running in the TEE, they must first create a session with that TA. This session establishes a connection to an instance of the TA that operates within its own dedicated physical memory space. The session facilitates interactions between the CA and the TA, as well as between different TAs. During the existence of the connection, the target TA supports operations by responding to commands. Each session can invoke multiple commands within the target TA, with each session maintaining its distinct state. This state typically encompasses the session’s context and the context of tasks executed during the session. TeeDFuzzer enhances session management by extending the session’s context to include bitmap information and details of each system call invoked. This information is stored within the session’s context, allowing the Trusted Kernel’s instrumentation to access and manipulate it effectively.
Data Collection Strategies in TeeDFuzzer. TeeDFuzzer employs two complementary data collection strategies to enhance the efficacy of the fuzzing process: kernel instrumentation for coverage collection and Pseudo Trusted Applications (Pseudo TAs) for capturing real-world system call sequences. Although both strategies serve to enrich the fuzzing feedback loop, they operate in distinct manners and contribute different types of information.
Kernel Instrumentation for Coverage Collection. Kernel instrumentation is integrated into the Trusted Kernel to capture fine-grained execution coverage. This method involves the following steps:
  • Coverage Bitmap Initialization: Prior to each test case, a dedicated system call in the secure world initializes a coverage bitmap within the session context. This bitmap is designed to record executed code paths and branches within the Trusted Kernel.
  • Instrumentation and Logging: As system calls are executed, the instrumented kernel logs detailed entry and exit events, including parameter information, to secure world logs. These logs provide a comprehensive trace of the kernel’s execution flow.
  • Data Analysis: The logged data are transmitted to an Analysis Host where they are processed to generate a system call dependency digraph. This digraph elucidates the relationships and dependencies between system calls, serving as a metric for the code coverage achieved during fuzzing.
This strategy ensures that the fuzzing process is informed by precise coverage metrics, thereby facilitating the identification and exploration of previously untested code paths.
Pseudo Trusted Applications for Real-World System Call Sequence Collection. In parallel, TeeDFuzzer leverages Pseudo Trusted Applications, which are compiled directly into the Trusted Kernel, to capture authentic sequences of system calls. The key aspects of this approach include the following:
  • Direct Integration with the Trusted Kernel: Unlike conventional Trusted Applications that operate in user space and rely on the GlobalPlatform API, Pseudo TAs are embedded within the kernel. This integration allows them to execute with the same privileges as the kernel core, eliminating the overhead associated with address space isolation.
  • Trace Buffer Management: At the commencement of a secure session, the session identifier is passed to the Pseudo TA, which initializes a dedicated system call trace buffer. Throughout the session, this buffer is populated with the sequence of executed system calls.
  • Data Retrieval: Upon the termination of the session, the contents of the trace buffer are retrieved and stored via a command issued from the normal world. This recorded sequence represents the real-world operational behavior of the system.
The Pseudo TA strategy thus captures the sequential ordering of system calls, providing critical insights into the practical application scenarios and behavioral patterns of the Trusted Kernel.

4.3. Dependency Inferrer

As shown in Figure 4, TeeDFuzzer infers dependency based on parameters and environment variables. We analyze dataflow of parameters of system calls and taint tracking to trace the data.

4.3.1. System Call Dependencies

As discussed in Section 2.2, the GlobalPlatform specification imposes restrictions on the return values and parameters of TEE Internal Core API functions, which are typically implemented as system calls in the Trusted Kernel. To elucidate the dependency inference process, we first note that these system calls are constrained by two primary rules: (1) The return value is limited to conveying the status information of the call, and (2) the determination of read and write permissions for specific parameters is governed by the implementation details of the system call itself. Consequently, traditional dependency inference strategies used in fuzzing the Linux kernel—where system calls such as sys_read and sys_write are directly dependent on the return value from sys_open—are not readily applicable in this context. Instead, in the Trusted Kernel we adopt a two-pronged approach that categorizes dependencies into parameter dependencies and environment dependencies. As shown in Figure 4, in a step-by-step manner, parameter dependencies are identified by first monitoring when a system call s y s c a l l a writes a value to one of its parameters; this value is then tracked and, if a subsequent system call s y s c a l l b reads or utilizes that same parameter value, a dependency is inferred, establishing that s y s c a l l b is reliant on s y s c a l l a for that parameter. In parallel, environment dependencies are determined by observing when a system call s y s c a l l a writes to a variable outside of its designated parameters; if another system call s y s c a l l b later uses this variable, the dependency inferrer records that s y s c a l l b is environmentally dependent on s y s c a l l a . This systematic, step-by-step approach allows for a precise mapping of how data flows through the system calls, ultimately facilitating the construction of a detailed dependency graph that reflects both parameter and environmental influences within the Trusted Kernel.

4.3.2. System Call Dependency Digraph

We have developed a system call dependency digraph to illustrate the relationships between system calls. As shown in Figure 5, this digraph consists of nodes, which contain information about individual system calls, and edges, which denote the dependencies between them. Each node represents a system call and includes the following information: (1) system call number, (2) parameter number, and (3) parameter type. If we consider nodes x and y linked by an edge ( x , y ) , node x is referred to as the tail and node y as the head, representing the direction of dependency. The edge ( x , y ) carries one or more pieces of parameter information—specifically, the number and type of parameters involved in the two system calls. This setup indicates that the system call represented by node x depends on the system call at node y, with the nature of this dependency defined by the parameters outlined on the edge. TeeDFuzzer initializes the dependency digraph using data flow analysis during normal system operations and refines it with taint information throughout the fuzzing process. Once the system call dependency digraph is established, it serves as a critical resource for refining our test cases.

4.3.3. Program Slicing for Dependency Graph

As previously discussed, the return values of Trusted Kernel system calls are restricted. If a system call needs to assign a value to a variable, this must be done via an input parameter, annotated as [outopt], [inoutbuf], [outbuf], [outbufopt], [outstring], or [outstringopt], as detailed in Section 2.2. Parameters with these annotations allow system call write access, making system calls that use these parameter types potential head nodes in our system call dependency digraph. During normal system operations, the dependency inferrer analyzes the entry and exit parameter information of each system call in sequence. For all potential head node system calls, checking the consistency between their exit and entry parameters is crucial to determining if a parameter was already written. If a parameter has been written, its information and the system call number are stored in the queue of potential head nodes. For each system call, we compare its entry parameter information with all existing data in the potential head node queue, including parameter names, types, and values. If there is a match, it indicates that the system call depends on another system call in the queue via the parameter, establishing a dependency between them. Following this, we assess whether to add a dependency edge to the system call dependency digraph. If the edge does not already exist, it is added and the parameter information is recorded on the edge. If the edge already exists, we check for the presence of the parameter information on the edge and add it if it is absent. Through this process, we can slice the code we need to construct the dependency graph.

4.3.4. Taint Tracking

Figure 4 illustrates three system calls—syscall_a, syscall_b, and syscall_c—and an ENV node representing the broader environment that can influence or be influenced by these calls.
  • Log Collection and Initial Analysis: During fuzzing, the Trusted Kernel transmits logs of executed system calls to the Analysis Host. These logs include both entry and exit parameter information for each call. The dependency inferrer on the Analysis Host parses these logs, identifying which parameters are written (e.g., b in syscall_a) and which parameters or environmental variables are subsequently read.
  • Identifying the Taint Source: In the deterministic phase of fuzzing, two nearly identical test cases are executed. They differ in exactly one parameter for a single system call (e.g., syscall_a with a1 modified), which is marked as the taint source. In Figure 4, syscall_a produces the output b, which may propagate to other calls.
  • Monitoring Subsequent Calls for Changes: After syscall_a completes, every subsequent call (such as syscall_b and syscall_c) is monitored for exit parameter changes that might be attributed to the taint source. If the exit parameter (e.g., b1 in syscall_b) differs between the two test cases, that parameter is flagged as tainted and added to the taint queue.
  • Comparing Parameters with the Taint Queue: For each subsequent system call, the dependency inferrer compares its parameters (name, type, and value) against the entries in the taint queue. If a parameter matches a taint entry, it indicates that the system call depends on the earlier tainted call. In the figure, if b or an environment variable updated by syscall_a is later consumed by syscall_b or syscall_c, a taint match is recorded.
  • Establishing the Dependency in the Digraph: Once a taint match is identified, the dependency inferrer adds or updates an edge in the system call dependency digraph. For example, if syscall_b reads a parameter tainted by syscall_a, an edge is drawn from syscall_a to syscall_b, annotated with the specific parameter (b) or environment variable that triggered the dependency. This annotation ensures that future analysis can distinguish between parameter-based and environment-based dependencies.
  • Integrating Environment Variables: The ENV node in Figure 4 represents global or shared state that can be read or modified by system calls. If syscall_a writes to ENV and syscall_b subsequently relies on this updated state, the inferrer notes an environment dependency. Such dependencies are captured in the digraph by edges leading to or from the ENV node, reflecting how changes to global state can affect the behavior of subsequent calls.
By following these steps, taint tracking enables TeeDFuzzer to dynamically uncover dependencies that extend beyond direct parameter passing, accounting for broader environmental effects and ensuring that the fuzzing process systematically explores how data flows through the Trusted Kernel.

4.4. Dynamic Refinement of Dependency Graph

During fuzzing, when new system call sequences are found, TeeDFuzzer will dynamically update the dependency graph. As shown in Figure 6, because system calls are encoded into bytes, we do not need to re-compile the system call sequences. The system call sequences are transmitter into the TA as data, as mentioned before. If a generated system call sequence, via mutating bytes in the seed system call sequence, discovers a new system call sequence, TeeDFuzzer will retain the system call sequence and update the dependency graph. A new system call sequence is found when the system call sequence is valid and discovers new code coverage in TEE. The updated dependency graph is then used to generate new system call sequences.

4.5. Fuzzer

With the encoded system calls and the dependency graph, the fuzzer can generate system call sequences that conforms to the requirements of Trusted Kernel. As shown in Figure 7, the fuzzer will generate system call sequences. Based on the existing system call sequences, the fuzzer will mutate bytes in the encoded system calls, which will change the values of parameters. The fuzzer will also change the order of bytes, which can change the order of system call sequence. For example, as shown in Figure 7, the encoded bytes for the system call cryp_obj_alloc(0xa0000010, 0x80, &obj_handle) are 1b00 0000 4406 0000 1000 00a0 8000 0000 0080 0000, and the ones for cry_state_alloc(0x10000110, 0, obj_handle, 0, &cryp_handle) are 0f00 0000 4447 0600 1001 0010 0000 0000 0040 0000 0000 0000 0180 0000. We can mutate the corresponding bytes for the value 0x80 of the system call cryp_obj_alloc(), which tests the second parameter of the system call. We can also change the order of two system calls cryp_obj_alloc() and cry_state_alloc() to test different system call sequences.

4.6. Invoker

The Invoker is in the secure world of TEE, running as a TA. It receives inputs from CA, and the inputs are generated by the fuzzer. As aforementioned, the Invoker works as a PTA. After receiving the inputs from fuzzer, the Invoker then translates the encoded system call sequences into original system call sequences, which can be executed in TEE.

4.7. Manager

The responsibility of the Manager is to manage the running of the fuzzing. During fuzzing, crashes or exceptions will stop the fuzzing process. To continue the fuzzing, we have to restart the fuzzing process. The Manager is responsible for restarting the fuzzing process when fuzzing stops. Additionally, the Manager will also log execution states so that it can restore the previous execution when restarting fuzzing process.

5. Evaluation

We implemented our TeeDFuzzer based on optee_fuzzer [27]. We added our components to the OpTEEFuzzer and tested our tool on OP-TEE Trusted Kernel. The experiment is conducted on testing OPTEE 3.3.0 over QEMU V8. The results show that our tool can effectively discover new edges and bugs. We ran TeeDFuzzer and optee_fuzzer for 24 h and repeated this 10 times. The experiment results are shown in Figure 8.

5.1. Coverage and Bug Discovery

As shown in Figure 8, TeeDFuzzer discovers 1082 edges in 24 h. For the first hour, TeeDFuzzer does not discover more edges than optee_fuzzer. In about 2 h, TeeDFuzzer discovers about 600 edges while optee_fuzzer only finds 323 edges. Then, in about 8 h, TeeDFuzzer discovers about 860 edges while optee_fuzzer only finds 550 edges. Then, in about 20 h, TeeDFuzzer discovers the highest number of edges, which is 1105 edges. However, the highest number of edges found by optee_fuzzer is 806 edges. This lasts to the end of the experiment. This experiment shows that our TeeDFuzzer can efficiently and effectively discover coverage in the TEE kernel.
As shown in Table 1, TTC means time to first crash, which indicates the efficiency of crash discovery. TTB means time to first bug, which indicates the efficiency of bug discovery. TeeDFuzzer discovers 17 crashes in 24 h while optee_fuzzer only discovers two. In the first hour, TeeDFuzzer discovers no crashes, and the first crash appears in 1.5 h. Then, the number of crashes discovered by TeeDFuzzer quickly increases to three crashes. Then, no new crashes are discovered in about one hour. In 2.5 h, TeeDFuzzer discovers 17 crashes and the number lasts to the end of the experiment. However, as for optee_fuzzer, the first crash appears in 5 h. optee_fuzzer discovers only five crashes in 24 h. This experiment shows that our TeeDFuzzer can effectively expose crashes in the TEE kernel.

5.2. Case Study

We analyze the crashes and one bug is confirmed by the developer. Figure 9 shows the crash stack of the discovered bug. This crash occurs when executing the system call cryp_random_number_generate[33](4003a4a0, c0a). By debugging the bug, the crash code line can be located at line core/lib/libtomcrypt/src/modes/ecb/ ecb_encrypt.c:74. The code line is a if condition that is if ((err = cipher_descriptor[ecb->cipher]->ecb_encrypt (pt, ct, &ecb->key)) != CRYPT_OK).
When reproducing the bug, we can obtain the results as shown in Figure 10. In the Figure 10a, the bug trace Core data-abort at address 0x4003b000 (translation fault) reveals that user space TAs can cause the OP-TEE core to panic, an outcome that is undesirable for TEEs. This issue warrants further investigation to determine if it persists in recent OP-TEE releases. In Figure 10b, the trace assertion ’BH((char *) b - b->bh.bsize)->prevfree == 0’ failed at lib/libutils/isoc/bget.c:891 in brel() identifies heap corruption within the TA, possibly linked to the TEE_Malloc()/malloc() functions. This suggests that fuzzing system call arguments might lead to corruption of the TA’s heap. In the Figure 10c, the trace assertion ’g_buf[p_arg->buffer.nr] != NULL’ failed at svc.c:158 in invoke_syscall() displays an invalid argument in a system call made by a TA. Fuzzing system call API arguments can induce such errors, and in these cases, the OP-TEE core is expected to panic the TA.

5.3. Limitations and Future Directions

While the taint tracking method is powerful for uncovering dependencies, it does have notable limitations. It may fail to capture indirect taint propagation or complex interactions that go beyond straightforward parameter comparisons, potentially leading to incomplete coverage. The approach can also generate false positives or negatives due to noise in log data and simultaneous modifications to multiple variables, and it incurs additional computational overhead from the continuous monitoring and updating of taint information. Moreover, the granularity of the method is limited, as it focuses primarily on parameters and select environment variables, which might result in overlooking more subtle dependencies related to internal state changes or external interactions. For example, our method confines the return value of system calls to the status information, but the return values may be handles or other data formats.
Future directions may focus more on how to build an accurate dependency graph, as it is the core of this method. We may research improving the data dependency analysis and taint analysis. We may also research the other techniques that can help build dependency graph, such as symbolic execution. Another promising direction is to design the framework with a portable, modular architecture that automatically supports diverse TEEs and broadens its use in cloud-based and multi-platform environments.

6. Conclusions

In this paper, we present TeeDFuzzer, a novel tool designed to test TrustZone-assisted Trusted Execution Environment (TEE) kernels. Our TeeDFuzzer effectively infers data dependencies between system calls, enabling it to fuzz and identify deep-seated TEE bugs. The core mechanism of TeeDFuzzer involves encoding system calls into byte sequences and passing these sequences as data into the TEE. Within the TEE, a TA receives the encoded data and translates them back into executable system call sequences. These system calls are then executed within the TEE environment, facilitating comprehensive testing. Our experimental results demonstrate that TeeDFuzzer significantly enhances coverage and efficiency in discovering vulnerabilities. Notably, TeeDFuzzer exposed 17 crashes, with one of the bugs being confirmed by the developer, underscoring its effectiveness in identifying critical issues within TEE kernels.

Author Contributions

Conceptualization, S.W., L.X., L.T., S.L. and Y.D.; methodology, S.W., L.X., L.T., S.L. and Y.D.; validation, S.W., L.X., L.T., S.L. and Y.D.; formal analysis, S.W. and L.X.; investigation, S.W. and L.X.; resources, S.W., L.X., L.T., S.L. and Y.D.; data curation, S.W. and L.X.; writing—original draft preparation, S.W. and L.X.; writing—review and editing, L.T., S.L. and Y.D.; visualization, S.W. and L.X.; supervision, L.T. and Y.D.; project administration, L.T. and S.L. All authors have read and agreed to the published version of the manuscript.

Funding

This research received no external funding.

Data Availability Statement

Data are contained within the article.

Conflicts of Interest

The authors declare no conflicts of interest.

Abbreviations

The following abbreviations are used in this manuscript:
TEEThe Trusted Execution Environment
TCBTrusted Computing Base
IoTInternet of Things
TATrusted Application
OSOperating System
CAClient Application
SMCSecure Monitor Call
PLPrivilege Level
ELExecution Levels

References

  1. Wu, B.; He, S. Self-learning and explainable deep learning network toward the security of artificial intelligence of things. J. Supercomput. 2023, 79, 4436–4467. [Google Scholar]
  2. Kurmus, A.; Tartler, R.; Dorneanu, D.; Heinloth, B.; Rothberg, V.; Ruprecht, A.; Schröder-Preikschat, W.; Lohmann, D.; Kapitza, R. Attack Surface Metrics and Automated Compile-Time OS Kernel Tailoring. In Proceedings of the NDSS, San Diego, CA, USA, 24–27 February 2013; The Internet Society: Reston, VA, USA, 2013. [Google Scholar]
  3. Akram, A.; Akella, V.; Peisert, S.; Lowe-Power, J. Sok: Limitations of confidential computing via tees for high-performance compute systems. In Proceedings of the 2022 IEEE International Symposium on Secure and Private Execution Environment Design (SEED), Storrs, CT, USA, 26–27 September 2022; IEEE: Piscataway, NJ, USA, 2022; pp. 121–132. [Google Scholar]
  4. Paju, A.; Javed, M.O.; Nurmi, J.; Savimäki, J.; McGillion, B.; Brumley, B.B. SoK: A Systematic Review of TEE Usage for Developing Trusted Applications. In Proceedings of the 18th International Conference on Availability, Reliability and Security, Benevento, Italy, 29 August–1 September 2023; pp. 1–15. [Google Scholar]
  5. Oliveira, D.; Gomes, T.; Pinto, S. uTango: An Open-Source TEE for IoT Devices. IEEE Access 2022, 10, 23913–23930. [Google Scholar]
  6. Pinto, S.; Santos, N. Demystifying Arm TrustZone: A Comprehensive Survey. ACM Comput. Surv. 2019, 51, 130. [Google Scholar] [CrossRef]
  7. Cerdeira, D.; Santos, N.; Fonseca, P.; Pinto, S. SoK: Understanding the Prevailing Security Vulnerabilities in TrustZone-assisted TEE Systems. In Proceedings of the 2020 IEEE Symposium on Security and Privacy (SP), San Francisco, CA, USA, 18–21 May 2020; pp. 1416–1432. [Google Scholar] [CrossRef]
  8. Zhu, X.; Zhou, W.; Han, Q.L.; Ma, W.; Wen, S.; Xiang, Y. When Software Security Meets Large Language Models: A Survey. IEEE/CAA J. Autom. Sin. 2025, 12, 317–334. [Google Scholar] [CrossRef]
  9. Zhou, W.; Zhu, X.; Han, Q.L.; Li, L.; Chen, X.; Wen, S.; Xiang, Y. The Security of Using Large Language Models—A Survey with Emphasis on ChatGPT. IEEE/CAA J. Autom. Sin. 2025, 12, 1–26. [Google Scholar] [CrossRef]
  10. Shiba, K.; Kuzuno, H.; Yamauchi, T. Prevention Method for Stack Buffer Overflow Attack in TA Command Calls in OP-TEE. In Proceedings of the 2023 Eleventh International Symposium on Computing and Networking Workshops (CANDARW), Matsue, Japan, 27–30 November 2023; IEEE: Piscataway, NJ, USA, 2023; pp. 274–278. [Google Scholar]
  11. Zhang, H.; She, D.; Qian, Z. Android Root and Its Providers: A Double-Edged Sword. In Proceedings of the 22nd ACM SIGSAC Conference on Computer and Communications Security, Denver, CO, USA, 12–16 October 2015; Association for Computing Machinery: New York, NY, USA, 2015; pp. 1093–1104. [Google Scholar] [CrossRef]
  12. Chen, X.; Li, C.; Wang, D.; Wen, S.; Zhang, J.; Nepal, S.; Xiang, Y.; Ren, K. Android HIV: A study of repackaging malware for evading machine-learning detection. IEEE Trans. Inf. Forensics Secur. 2019, 15, 987–1001. [Google Scholar] [CrossRef]
  13. GlobalPlatform. TEE Internal Core API Specification. 2021. Available online: https://globalplatform.org/specs-library/tee-internal-core-api-specification/ (accessed on 23 March 2025).
  14. Han, H.; Cha, S.K. IMF: Inferred Model-Based Fuzzer. In Proceedings of the 2017 ACM SIGSAC Conference on Computer and Communications Security, Dallas, TX, USA, 30 October–3 November 2017; Association for Computing Machinery: New York, NY, USA, 2017; pp. 2345–2358. [Google Scholar] [CrossRef]
  15. Pailoor, S.; Aday, A.; Jana, S. MoonShine: Optimizing OS Fuzzer Seed Selection with Trace Distillation. In Proceedings of the 27th USENIX Security Symposium (USENIX Security 18), Baltimore, MD, USA, 15–17 August 2018; pp. 729–743. [Google Scholar]
  16. Liu, B.; Zhang, C.; Gong, G.; Zeng, Y.; Ruan, H.; Zhuge, J. FANS: Fuzzing Android Native System Services via Automated Interface Analysis. In Proceedings of the 29th USENIX Security Symposium (USENIX Security 20), Boston, MA, USA, 12–14 August 2020; pp. 307–323. [Google Scholar]
  17. Ispoglou, K.; Austin, D.; Mohan, V.; Payer, M. FuzzGen: Automatic Fuzzer Generation. In Proceedings of the 29th USENIX Security Symposium (USENIX Security 20), Boston, MA, USA, 12–14 August 2020; pp. 2271–2287. [Google Scholar]
  18. Corina, J.; Machiry, A.; Salls, C.; Shoshitaishvili, Y.; Hao, S.; Kruegel, C.; Vigna, G. Difuze: Interface aware fuzzing for kernel drivers. In Proceedings of the 2017 ACM SIGSAC Conference on Computer and Communications Security, Dallas, TX, USA, 30 October–3 November 2017; pp. 2123–2138. [Google Scholar]
  19. Babić, D.; Bucur, S.; Chen, Y.; Ivančić, F.; King, T.; Kusano, M.; Lemieux, C.; Szekeres, L.; Wang, W. Fudge: Fuzz driver generation at scale. In Proceedings of the 2019 27th ACM Joint Meeting on European Software Engineering Conference and Symposium on the Foundations of Software Engineering, Tallinn, Estonia, 26–30 August 2019; pp. 975–985. [Google Scholar]
  20. Kohlbrenner, D.; Shinde, S.; Lee, D.; Asanovic, K.; Song, D. Building Open Trusted Execution Environments. IEEE Secur. Priv. 2020, 18, 47–56. [Google Scholar] [CrossRef]
  21. Mill, H. OP-TEE. 2024. Available online: https://www.trustedfirmware.org/projects/op-tee/ (accessed on 1 May 2024).
  22. Sheng, C.; Zhou, W.; Han, Q.L.; Ma, W.; Zhu, X.; Wen, S.; Xiang, Y. Network Traffic Fingerprinting for IIoT Device Identification: A Survey. IEEE Trans. Ind. Inform. 2025, 1–14. [Google Scholar] [CrossRef]
  23. Deng, Z.; Guo, Y.; Han, C.; Ma, W.; Xiong, J.; Wen, S.; Xiang, Y. AI agents under threat: A survey of key security challenges and future pathways. ACM Comput. Surv. 2025, 57, 182. [Google Scholar]
  24. Cai, C.; Xu, L.; Zhou, A.; Wang, C. Toward a secure, rich, and fair query service for light clients on public blockchains. IEEE Trans. Dependable Secur. Comput. 2021, 19, 3640–3655. [Google Scholar] [CrossRef]
  25. Jeon, S.; Kim, H.K. TZMon: Improving mobile game security with ARM trustzone. Comput. Secur. 2021, 109, 102391. [Google Scholar] [CrossRef]
  26. Dai, W.; Wang, Q.; Wang, Z.; Lin, X.; Zou, D.; Jin, H. Trustzone-based secure lightweight wallet for hyperledger fabric. J. Parallel Distrib. Comput. 2021, 149, 66–75. [Google Scholar]
  27. Riscure. OP-TEE Fuzzer. 2019. Available online: https://github.com/Keysight/optee_fuzzer (accessed on 1 May 2024).
  28. Harrison, L.; Vijayakumar, H.; Padhye, R.; Sen, K.; Grace, M. PARTEMU: Enabling Dynamic Analysis of Real-World TrustZone Software Using Emulation. In Proceedings of the 29th USENIX Security Symposium (USENIX Security 20), Boston, MA, USA, 12–14 August 2020; USENIX Association: Berkeley, CA, USA, 2020; pp. 789–806. [Google Scholar]
  29. Khalid, F.; Masood, A. Vulnerability analysis of qualcomm secure execution environment (QSEE). Comput. Secur. 2022, 116, 102628. [Google Scholar] [CrossRef]
  30. Hanel, L. Kinibi-520a: The latest Trustonic Trusted Execution Environment (TEE). 2021. Available online: https://www.trustonic.com/technical-articles/kinibi-520a-the-latest-trusted-execution-environment-tee/ (accessed on 23 March 2025).
  31. Samsung. SAMSUNG TEEGRIS SDK. 2017. Available online: https://developer.samsung.com/teegris/overview.html (accessed on 23 March 2025).
  32. Beniamini. FuzzZone. 2017. Available online: https://github.com/laginimaineb/fuzz_zone/tree/master/FuzzZone (accessed on 23 March 2025).
  33. Zhu, X.; Wen, S.; Camtepe, S.; Xiang, Y. Fuzzing: A survey for roadmap. ACM Comput. Surv. 2022, 54, 230. [Google Scholar] [CrossRef]
  34. Feng, X.; Zhu, X.; Han, Q.L.; Zhou, W.; Wen, S.; Xiang, Y. Detecting vulnerability on IoT device firmware: A survey. IEEE/CAA J. Autom. Sin. 2022, 10, 25–41. [Google Scholar] [CrossRef]
  35. Zhu, X.; Böhme, M. Regression greybox fuzzing. In Proceedings of the 2021 ACM SIGSAC Conference on Computer and Communications Security, Virtual Event, 15–19 November 2021; pp. 2169–2182. [Google Scholar]
  36. Feng, X.; Sun, R.; Zhu, X.; Xue, M.; Wen, S.; Liu, D.; Nepal, S.; Xiang, Y. Snipuzz: Black-box fuzzing of iot firmware via message snippet inference. In Proceedings of the 2021 ACM SIGSAC Conference on Computer and Communications Security, Virtual Event, 15–19 November 2021; pp. 337–350. [Google Scholar]
  37. Kim, K.; Jeong, D.R.; Kim, C.H.; Jang, Y.; Shin, I.; Lee, B. HFL: Hybrid Fuzzing on the Linux Kernel. In Proceedings of the NDSS, San Diego, CA, USA, 23–26 February 2020. [Google Scholar]
  38. Deng, Y.; Xia, C.S.; Peng, H.; Yang, C.; Zhang, L. Large language models are zero-shot fuzzers: Fuzzing deep-learning libraries via large language models. In Proceedings of the 32nd ACM SIGSOFT International Symposium on Software Testing and Analysis, Seattle, WA, USA, 17–21 July 2023; pp. 423–435. [Google Scholar]
  39. Liu, Z.; Chen, C.; Wang, J.; Che, X.; Huang, Y.; Hu, J.; Wang, Q. Fill in the blank: Context-aware automated text input generation for mobile gui testing. In Proceedings of the 2023 IEEE/ACM 45th International Conference on Software Engineering (ICSE), Melbourne, Australia, 14–20 May 2023; IEEE: Piscataway, NJ, USA, 2023; pp. 1355–1367. [Google Scholar]
Figure 1. Architecture of TEE-assisted platform. The Rich OS communicates with TEE kernel via CA and TA.
Figure 1. Architecture of TEE-assisted platform. The Rich OS communicates with TEE kernel via CA and TA.
Electronics 14 01674 g001
Figure 2. TA interactions with the Trusted Kernel. TAs perform operations by calling the relevant interfaces.
Figure 2. TA interactions with the Trusted Kernel. TAs perform operations by calling the relevant interfaces.
Electronics 14 01674 g002
Figure 3. The workflow of TeeDFuzzer. The key is to generate the dependency graph based on feedback from executing system calls.
Figure 3. The workflow of TeeDFuzzer. The key is to generate the dependency graph based on feedback from executing system calls.
Electronics 14 01674 g003
Figure 4. Inference of dependency. The inference includes dataflow analysis and taint tracking of data.
Figure 4. Inference of dependency. The inference includes dataflow analysis and taint tracking of data.
Electronics 14 01674 g004
Figure 5. The generated digraph. The graph will be dynamically updated during fuzzing.
Figure 5. The generated digraph. The graph will be dynamically updated during fuzzing.
Electronics 14 01674 g005
Figure 6. The workflow of refining the dependency graph. This is feasible because the system calls are encoded into bytes, which can be changed easily.
Figure 6. The workflow of refining the dependency graph. This is feasible because the system calls are encoded into bytes, which can be changed easily.
Electronics 14 01674 g006
Figure 7. Fuzzing system call sequences. TeeDFuzzer can mutates bytes to change values of parameters and the order of system calls.
Figure 7. Fuzzing system call sequences. TeeDFuzzer can mutates bytes to change values of parameters and the order of system calls.
Electronics 14 01674 g007
Figure 8. The number of discovered edges over time. TeeDFuzzer can effectively discover more edges.
Figure 8. The number of discovered edges over time. TeeDFuzzer can effectively discover more edges.
Electronics 14 01674 g008
Figure 9. Case study: a bug exposed by our TeeDFuzzer. This is the crash stack of the bug.
Figure 9. Case study: a bug exposed by our TeeDFuzzer. This is the crash stack of the bug.
Electronics 14 01674 g009
Figure 10. Reproducing the bug. We obtain different information when reproducing the bug.
Figure 10. Reproducing the bug. We obtain different information when reproducing the bug.
Electronics 14 01674 g010
Table 1. Bugs discovered by fuzzers. TeeDFuzzer performs better.
Table 1. Bugs discovered by fuzzers. TeeDFuzzer performs better.
Fuzzers#CrashesTTC (h)#BugsTTB
TeeDFuzzer171.511.5
optee_fuzzer2515
Disclaimer/Publisher’s Note: The statements, opinions and data contained in all publications are solely those of the individual author(s) and contributor(s) and not of MDPI and/or the editor(s). MDPI and/or the editor(s) disclaim responsibility for any injury to people or property resulting from any ideas, methods, instructions or products referred to in the content.

Share and Cite

MDPI and ACS Style

Wen, S.; Xu, L.; Tian, L.; Liu, S.; Ding, Y. TeeDFuzzer: Fuzzing Trusted Execution Environment. Electronics 2025, 14, 1674. https://doi.org/10.3390/electronics14081674

AMA Style

Wen S, Xu L, Tian L, Liu S, Ding Y. TeeDFuzzer: Fuzzing Trusted Execution Environment. Electronics. 2025; 14(8):1674. https://doi.org/10.3390/electronics14081674

Chicago/Turabian Style

Wen, Sheng, Liam Xu, Liwei Tian, Suping Liu, and Yong Ding. 2025. "TeeDFuzzer: Fuzzing Trusted Execution Environment" Electronics 14, no. 8: 1674. https://doi.org/10.3390/electronics14081674

APA Style

Wen, S., Xu, L., Tian, L., Liu, S., & Ding, Y. (2025). TeeDFuzzer: Fuzzing Trusted Execution Environment. Electronics, 14(8), 1674. https://doi.org/10.3390/electronics14081674

Note that from the first issue of 2016, this journal uses article numbers instead of page numbers. See further details here.

Article Metrics

Back to TopTop