Feb 1, 2026·6 min read·17 visits
A critical RCE vulnerability exists in the Garrett iC Module used in PD 6500i and MZ 6100 metal detectors. The device listens on UDP port 6877 and blindly copies up to 512 bytes of data into a 256-byte stack buffer. This allows unauthenticated remote attackers to smash the stack, control the program counter, and potentially disable security features or pivot into the management network. CVSS 9.8.
Garrett Metal Detectors, the ubiquitous guardians of airports and stadiums, embedded a critical stack-based buffer overflow in their iC Module network interface. By sending a malformed UDP packet to port 6877, an attacker can bypass the physical security layer entirely and execute arbitrary code on the device itself.
You’ve walked through them a thousand times. The gray arches at the airport, the stadium, the courthouse. Garrett Metal Detectors (specifically the PD 6500i and MZ 6100) are the gold standard for physical access control. But in the age of IoT, nothing stays offline forever. To make management easier, Garrett introduced the iC Module CMA, a network interface that allows security teams to monitor alarms, change sensitivity settings, and aggregate data remotely.
Here lies the irony: In an effort to secure physical spaces, the vendor introduced a massive hole in the digital one. The iC Module exposes a discovery service on UDP port 6877. It requires no authentication and listens to the entire network. Ideally, this service should just chirp back, "Here I am!" when queried.
Instead, it serves as a direct entry point for remote code execution. It’s the digital equivalent of locking the armored front door of a bank but leaving the vault window open with a neon sign pointing to it. This isn't just a glitch; it's a fundamental failure in memory management that turns a security device into a hacker's playground.
The root cause of CVE-2021-21901 is a classic, textbook case of "Big Bucket into Small Bucket." It stems from a disconnect between how data is received and how it is processed. The application architecture involves a receiving thread and a validation function.
The receiving thread (udp_thread) is generous. It allocates a 512-byte buffer (msgbuf) to catch incoming UDP packets via recvmsg. It assumes that any data coming in is friendly. Once the data is received, the code performs a cursory check for a carriage return/line feed (\r\n) to null-terminate the string, but if those characters aren't there, it happily keeps the full payload.
The fatal error happens when this 512-byte payload is passed to the validation function, check_udp_crc. The developer of this function evidently didn't talk to the developer of the receiving thread. Inside check_udp_crc, a local stack buffer is allocated with a size of only 256 bytes. The code then calculates the length of the incoming data (which can be up to 512 bytes) and blindly memcpys it into the 256-byte local buffer. No size checks. No bounds enforcement. Just a direct copy that obliterates the stack frame if the packet is too large.
Let’s look at the assembly, courtesy of the Talos reverse engineering effort. This is where the magic (or tragedy) happens. The vulnerable function check_udp_crc sets up its stack frame:
.text:0001D13C SUB SP, SP, #0x128 ; Allocates ~296 bytes on stack
.text:0001D150 MOV R2, #0x100 ; Set size to 256 bytes for memset
.text:0001D154 BL memset ; Zero out the local bufferSo far, so good. We have a clean buffer. But then, the code retrieves the pointer to the incoming data (passed in R0) and calculates its length:
.text:0001D158 LDR R0, [R11,#msg] ; Load pointer to input data
.text:0001D15C BL strlen ; Calculate length (up to 512!)
.text:0001D160 MOV R3, R0 ; Move length to R3And here is the kill shot:
.text:0001D170 MOV R2, R3 ; R2 = length (could be 500+)
.text:0001D174 BL memcpy ; memcpy(dest, src, length)The memcpy writes past the 256-byte boundary of the local variable. It continues writing up the stack, overwriting the saved frame pointer (R11 in ARM) and, crucially, the Link Register (LR / Return Address). When check_udp_crc attempts to return, it pops the corrupted address into the Program Counter (PC), redirecting execution flow to wherever the attacker chooses.
Exploiting this is trivially easy for anyone with network access. The attack vector does not require a complex handshake or authentication. It is a "fire and forget" UDP packet.
To construct the exploit, an attacker needs to format a payload that exceeds 256 bytes. The structure generally looks like this:
The Talos crash dump confirms the control of the instruction pointer:
Thread 2 "cma" received signal SIGSEGV
$pc : 0x4d4d4d4c ("LMMM")The value 0x4d4d4d4c suggests the attacker successfully overwrote the PC with their own data. From here, an attacker could execute code to bridge the gap between the physical security network and the corporate IT network, or simply disable the metal detector silently, allowing weapons to pass through undetected.
The implications here go beyond standard IT security. We are talking about critical infrastructure protection. If an attacker gains RCE on the iC Module, they have total control over the metal detector's network interface.
Scenario A: The Silent Bypass An attacker could modify the sensitivity settings of the detector on the fly. They could lower the detection threshold to zero just as a confederate walks through with a weapon, then raise it back up immediately after. The logs would be scrubbed, and the guards would be none the wiser.
Scenario B: The Pivot Often, these devices are placed on management VLANs that have trusts with other sensitive systems. A compromised iC Module becomes a perfect pivot point—a persistent foothold inside a high-security zone that nobody thinks to scan with an EDR agent.
This vulnerability scores a CVSS 9.8 for a reason. It is unauthenticated, remote, and results in total compromise of confidentiality, integrity, and availability.
Garrett Metal Detectors released a patch (Version 5.1) in late 2021 to address this. The fix likely involves properly checking the length of the input data before performing the memcpy, or ensuring the destination buffer size matches the maximum receive size.
Immediate Remediation Steps:
This vulnerability serves as a grim reminder: Just because a device is designed for security, doesn't mean the device itself is secure.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
iC Module CMA Garrett Metal Detectors | = 5.0 | 5.1 |
| Attribute | Detail |
|---|---|
| CWE | CWE-120 (Buffer Copy without Checking Size of Input) |
| Attack Vector | Network (UDP 6877) |
| CVSS v3.1 | 9.8 (Critical) |
| Impact | Remote Code Execution (RCE) |
| Root Cause | Stack-based Buffer Overflow |
| EPSS Score | 0.19% |
The program copies an input buffer to an output buffer without verifying that the size of the input buffer is less than the size of the output buffer, leading to a buffer overflow.
An uncontrolled resource consumption vulnerability exists in the Scala-based http4s-blaze-server package of the http4s/blaze library. The vulnerability allows remote, unauthenticated attackers to cause an Out of Memory Error (OOM) and JVM crash by streaming a continuous sequence of small or empty WebSocket continuation frames with the FIN bit set to 0. This bypasses typical payload size checks because of the JVM's per-object allocation overhead, leading to rapid heap exhaustion with minimal network bandwidth.
A critical path traversal vulnerability has been identified in the OpenList Go-based backend package. The vulnerability exists within the batch rename handler because the application does not validate the source filename parameter before constructing filesystems paths. This omission allows authenticated users to escape their designated directory and rename files in sibling paths.
OpenList version 4.2.3 and prior is vulnerable to an authorization bypass and metadata leakage. When configured with the Bleve search engine backend, OpenList fails to perform separator-aware path matching when validating tenant containment. This allows authenticated users to access sibling directories sharing similar name prefixes. Furthermore, the search backend returns unfiltered global result counts, leaking existence verification data of unauthorized files via side-channel analysis.
An authorization bypass vulnerability in OpenList version 4.2.3 and below allows authenticated users to read arbitrary files outside of their designated base directories due to an insecure path prefix check using Go's standard strings.HasPrefix function.
A security policy bypass vulnerability exists in the AWS API MCP Server (awslabs-aws-api-mcp-server) from version 0.2.13 through 1.3.46. When the server fails to load the read-only operations index during startup (due to transient network failures, file permission issues, or other exceptions), it logs a warning but continues running in an insecure, degraded state. Under this condition, the security policy engine fails open, silently skipping all subsequent security checks and consent prompts for the lifetime of the process. This permits unauthorized mutating AWS CLI commands to execute via indirect prompt injection attacks.
An incomplete escaping vulnerability in the npm package 'shescape' allows unauthenticated users to trigger dynamic shell expansions, absolute path disclosure, and command block break-outs on Unix and Windows systems.