Understanding Memory-Safe Languages in Critical Infrastructure
How Rust, Go, and similar languages are reshaping security posture in SCADA systems, medical devices, and transportation networks — and where the adoption bottlenecks actually are.
The White House published its report on memory safety in February 2024, and the discourse has been predictable. Advocates say Rust will save us. Skeptics say you can’t rewrite 50 years of C. Both miss the point.
The question isn’t whether memory-safe languages are better. They are. The question is whether the systems that most need memory safety — SCADA controllers, infusion pumps, avionics — can actually adopt them. The answer is complicated.
The Scale of the Problem
CVE data tells a clear story. Microsoft has repeatedly stated that ~70% of their security vulnerabilities are memory safety issues. Google’s Chrome team reports similar numbers. The pattern holds across operating systems, browsers, and network services.
But critical infrastructure isn’t Chrome. A SCADA controller running in a water treatment plant has constraints that a browser doesn’t:
- Certification cycles measured in years. Medical devices go through FDA 510(k) clearance. Avionics require DO-178C certification. Changing the compiler toolchain means re-certifying.
- Real-time guarantees. Garbage-collected languages are out. Rust works, but the borrow checker introduces a learning curve that embedded teams haven’t budgeted for.
- Hardware constraints. Many PLCs run on microcontrollers with 256KB of flash. Rust’s standard library won’t fit.
no_stdRust is viable but requires expertise that’s scarce.
What’s Actually Happening
The adoption pattern follows a predictable gradient:
Cloud services ████████████████████ (fast adoption)
Desktop apps ██████████████ (moderate)
Mobile ████████████ (moderate)
Network equipment ██████ (slow)
Embedded/SCADA ███ (very slow)
Medical devices █ (almost none)
In cloud infrastructure, the transition is well underway. AWS has been writing new services in Rust since 2017. Cloudflare’s pingora replaced their Nginx-based proxy. Google’s Android team reports that memory safety bugs dropped from 76% to 24% of vulnerabilities as new code shifted to Rust.
The embedded world is different. I spoke with three firmware engineers at ICS companies (off the record) and the consistent theme was: “We know Rust is better. We can’t justify the re-certification cost.”
A Realistic Threat Model
Consider a Modbus TCP gateway — the kind of device that bridges legacy serial PLCs to modern IP networks. These are everywhere in power generation, water treatment, and manufacturing.
A typical vulnerability looks like this:
void handle_modbus_request(uint8_t *buf, size_t len) {
uint16_t transaction_id = (buf[0] << 8) | buf[1];
uint16_t protocol_id = (buf[2] << 8) | buf[3];
uint16_t length = (buf[4] << 8) | buf[5];
uint8_t unit_id = buf[6];
// length is attacker-controlled, no bounds check
uint8_t payload[256];
memcpy(payload, buf + 7, length); // classic overflow
}
The equivalent in Rust physically cannot compile without bounds checking:
fn handle_modbus_request(buf: &[u8]) -> Result<ModbusFrame, ParseError> {
if buf.len() < 7 {
return Err(ParseError::TooShort);
}
let length = u16::from_be_bytes([buf[4], buf[5]]) as usize;
let payload = buf.get(7..7 + length)
.ok_or(ParseError::InvalidLength)?;
Ok(ModbusFrame {
transaction_id: u16::from_be_bytes([buf[0], buf[1]]),
protocol_id: u16::from_be_bytes([buf[2], buf[3]]),
unit_id: buf[6],
payload: payload.to_vec(),
})
}
This isn’t hypothetical. Modbus implementations have had exactly this class of bug repeatedly — CVE-2022-2003 in AutomationDirect, CVE-2023-1548 in Schneider Electric.
What Defenders Should Do Now
You can’t wait for the industry to rewrite everything in Rust. Here’s what’s actionable today:
- Audit your firmware supply chain. Know which devices run C/C++ and which have been updated recently. Old firmware with known CVEs is the real risk, not the language choice.
- Network segmentation. If your Modbus gateways can’t be memory-safe, they shouldn’t be on a network where an attacker can reach them from a compromised workstation.
- Monitor for exploitation patterns. Memory corruption in ICS devices often manifests as unexpected restarts, malformed responses, or timing anomalies. Instrument your network monitoring for these signals.
- Push your vendors. Ask whether new product lines are being developed in memory-safe languages. Make it a procurement criterion.
The Long View
The transition to memory-safe languages in critical infrastructure will take 15-20 years, not 5. The technology is ready. The certification frameworks, workforce training, and economic incentives are not.
In the meantime, the most impactful thing you can do is treat the C/C++ code that exists today with the scrutiny it deserves: static analysis, fuzzing, runtime instrumentation, and network isolation. Memory safety is the destination. Defense in depth is the journey.