Article illustration 1

For decades, C and C++ have dominated Windows driver development—a realm where memory safety flaws can cascade into catastrophic security breaches. Now, Microsoft is steering toward a safer future. In a significant move detailed in their latest blog post, the Windows team is enabling Rust for kernel-mode and user-mode drivers (KMDF/UMDF), responding to developer demand for robust, maintainable systems code.

The Rust Imperative in Kernel Space

Drivers sit at the heart of system security, yet memory corruption vulnerabilities plague traditional C-based code. Rust’s ownership model and borrow checker eliminate entire classes of bugs—use-after-free, buffer overflows—at compile time. Microsoft acknowledges this as non-negotiable in today’s threat landscape. As stated in the blog:

"We believe that memory-safe languages such as Rust represent the future of secure software engineering... device drivers play a role at every layer in the stack."

This isn’t theoretical. Internal teams, including Surface, have pioneered Rust prototypes, proving its viability for performance-critical paths like lookaside list management (more on that later).

Building the Foundation: windows-drivers-rs

Central to this effort is the windows-drivers-rs GitHub repo, offering crates that bridge Rust with the Windows Driver Kit (WDK):
- wdk-sys: Low-level FFI bindings to WDK APIs.
- wdk: Idiomatic Rust wrappers for safer interactions.
- wdk-alloc: Global allocator for kernel memory.
- cargo-wdk: A CLI tool simplifying project setup and builds.

Developers can now write drivers like this KMDF entry point, where Rust’s type system enforces correctness even amid unsafe blocks:

#[link_section = "INIT"]
#[export_name = "DriverEntry"]
extern "system" fn driver_entry(
    driver: &mut DRIVER_OBJECT,
    registry_path: PCUNICODE_STRING,
) -> NTSTATUS {
    let mut driver_config = WDF_DRIVER_CONFIG {
        EvtDriverDeviceAdd: Some(echo_evt_device_add),
        ..WDF_DRIVER_CONFIG::default()
    };
    // ...
    let nt_status = unsafe { 
        call_unsafe_wdf_function_binding!(
            WdfDriverCreate, 
            driver as PDRIVER_OBJECT,
            registry_path,
            WDF_NO_OBJECT_ATTRIBUTES,
            &raw mut driver_config,
            driver_handle_output,
        )
    };
    // Error handling with Rust's expressiveness
    if !nt_success(nt_status) {
        println!("Error: WdfDriverCreate failed {nt_status:#010X}");
        return nt_status;
    }
    nt_status
}
Article illustration 3

Demonstration of cargo-wdk automating driver builds and validation.

The Road to Safe Abstractions

Today’s approach still requires unsafe for kernel interactions—a temporary compromise. Microsoft is actively designing safe Rust abstractions for WDF and core kernel APIs. For example, an experimental wrapper for lookaside lists showcases the intended direction:

impl<T> LookasideList<T> {
    pub fn new(pool_type: POOL_TYPE, tag: u32) -> Result<Arc<Self>> {
        // Initialization with compile-time checks
        if size_of::<T>() == 0 {
            return Err(STATUS_NOT_SUPPORTED);
        }
        // ...
    }

    fn allocate(&self) -> Result<*mut T> {
        // Safe interaction with kernel internals
        let ptr = unsafe { ExAllocateFromLookasideListEx(self.inner.get()) };
        // ...
    }
}

Such wrappers aim to minimize unsafe footprints, but Microsoft cautions that finalizing sound, idiomatic APIs for complex kernel systems demands rigorous iteration.

Why This Matters for Developers

For the industry, this signals a pivotal shift:
1. Security Gains: Reducing memory-safety bugs in drivers could thwart supply-chain attacks targeting critical infrastructure.
2. Tooling Maturity: cargo-wdk will evolve to match Visual Studio’s capabilities, including ARM64 support and deployment automation.
3. Ecosystem Growth: Crates will eventually publish to crates.io, inviting broader community contributions.

Microsoft’s commitment mirrors a wider trend—Linux, Android, and cloud stacks are adopting Rust for similar reasons. Yet, Windows’ scale and legacy add unique complexity. As the team refines safe abstractions, developers gain a path to modernize without sacrificing performance. The journey from C to Rust in the kernel isn’t just possible; it’s becoming inevitable for those prioritizing resilience in an era of relentless cyber threats.