CVE-2026-56111 Overview
CVE-2026-56111 is an out-of-bounds write vulnerability in Marlin Firmware through 2.1.2.7, affecting builds with MESH_BED_LEVELING enabled. The flaw resides in the M421 G-code handler, which fails to validate X and Y grid indices before writing to the z_values array. Attackers can send a single crafted G-code command through USB serial, a network interface, or a malicious gcode file to write an attacker-controlled 32-bit float past the array bounds. This corrupts adjacent firmware variables, causing denial of service or firmware state corruption on affected 3D printer controllers. The issue is fixed in commit 1f255d1.
Critical Impact
A single crafted M421 command writes an arbitrary 32-bit float to out-of-bounds memory, corrupting firmware state and enabling denial of service on affected 3D printers.
Affected Products
- Marlin Firmware versions through 2.1.2.7
- Marlin Firmware builds compiled with MESH_BED_LEVELING enabled
- 3D printer controllers running vulnerable Marlin builds exposed via USB serial, network interfaces, or accepting external gcode files
Discovery Timeline
- 2026-06-24 - CVE-2026-56111 published to NVD
- 2026-06-25 - Last updated in NVD database
Technical Details for CVE-2026-56111
Vulnerability Analysis
The vulnerability is an improper input validation issue classified under [CWE-129] (Improper Validation of Array Index). Marlin's M421 G-code command sets a Z height at a specified mesh grid coordinate during bed leveling. The handler in Marlin/src/gcode/bedlevel/mbl/M421.cpp checks only that the supplied indices are non-negative. It does not enforce the upper bounds defined by GRID_MAX_POINTS_X and GRID_MAX_POINTS_Y.
When an attacker supplies an I or J value exceeding the configured grid dimensions, the firmware writes the parsed float into memory past the end of the z_values two-dimensional array. The write is attacker-controlled in both offset and value, allowing targeted corruption of adjacent firmware globals.
Root Cause
The pre-patch code validated only the lower bound of the grid indices:
else if (ix < 0 || iy < 0)
SERIAL_ERROR_MSG(STR_ERR_MESH_XY);
No upper-bound check is performed before the call to bedlevel.set_z(ix, iy, ...), which uses the indices directly to compute a write offset into the fixed-size z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y] array.
Attack Vector
Marlin accepts G-code from any configured input channel including USB serial, optional network interfaces such as OctoPrint bridges or WebSocket modules, and SD card or filesystem-loaded gcode files. An attacker who can submit a single line of G-code to the printer can trigger the write. No authentication is required on typical Marlin deployments.
if (int(hasI && hasJ) + int(hasX && hasY) != 1 || !(hasZ || hasQ))
SERIAL_ERROR_MSG(STR_ERR_M421_PARAMETERS);
- else if (ix < 0 || iy < 0)
+ else if (!WITHIN(ix, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(iy, 0, GRID_MAX_POINTS_Y - 1))
SERIAL_ERROR_MSG(STR_ERR_MESH_XY);
else
bedlevel.set_z(ix, iy, parser.value_linear_units() + (hasQ ? bedlevel.z_values[ix][iy] : 0));
Source: Marlin Firmware commit 1f255d1
The patch replaces the lower-bound-only check with WITHIN macros that enforce both lower and upper grid bounds before any write occurs.
Detection Methods for CVE-2026-56111
Indicators of Compromise
- M421 G-code commands containing I or J parameter values greater than or equal to the printer's configured GRID_MAX_POINTS_X or GRID_MAX_POINTS_Y
- Unexpected printer reboots, watchdog resets, or firmware state anomalies following receipt of mesh-bed-leveling commands
- Unsolicited gcode files containing M421 I<n> J<n> Z<f> lines with large index values arriving from untrusted sources
Detection Strategies
- Inspect inbound gcode streams and uploaded files for M421 commands and validate I/J parameters against the device's grid configuration before forwarding to the printer
- Log all G-code parser errors emitting STR_ERR_MESH_XY and treat repeated occurrences as a probable probing attempt
- Where network-attached print servers are deployed, capture and review G-code traffic for malformed M421 patterns
Monitoring Recommendations
- Monitor print server logs and serial console output for unexpected firmware resets correlated with M421 command receipt
- Alert on unauthenticated network access to print services that relay G-code to Marlin controllers
- Track firmware version inventory across deployed 3D printers to identify unpatched Marlin builds with MESH_BED_LEVELING enabled
How to Mitigate CVE-2026-56111
Immediate Actions Required
- Update Marlin Firmware to a build containing commit 1f255d1 or later and reflash affected 3D printer controllers
- Restrict access to USB serial and network G-code interfaces so only authorized hosts can submit commands
- Review and sanitize gcode files received from external or shared sources before sending them to printers
Patch Information
The fix is committed upstream as 1f255d16ec2d456454fd444494cfb338d62b0fa1 and tracked in Marlin issue #28467 and pull request #28468. Additional analysis is available in the VulnCheck advisory. The patch adds WITHIN(ix, 0, GRID_MAX_POINTS_X - 1) and WITHIN(iy, 0, GRID_MAX_POINTS_Y - 1) bounds checks in M421.cpp before any write to z_values.
Workarounds
- Disable MESH_BED_LEVELING in Configuration.h and rebuild the firmware if mesh bed leveling is not required
- Place affected printers behind a trusted print server that filters or rejects M421 commands with out-of-range I/J indices
- Isolate printer control networks from general user networks and disable remote G-code submission where feasible
# Build-time mitigation: disable MESH_BED_LEVELING in Marlin Configuration.h
# //#define MESH_BED_LEVELING
# Pre-flight gcode sanitization example
grep -nE '^M421[^\r\n]*[IJ][[:space:]]*[0-9]{2,}' input.gcode \
&& { echo 'Rejected: out-of-range M421 indices detected'; exit 1; }
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

