Kernel stack overflow
TL;DR: A buffer overflow on a kernel-mode stack — same root cause as user mode, but stack canaries (
/GS), small stacks (~24 KiB), CET shadow stacks, and the lack of a libc make the exploit path very different.
What it is
Kernel routines allocate local buffers on the per-thread kernel stack. If a driver copies attacker-controlled data into one of those buffers without bounds-checking, the stack frame, saved RIP, and adjacent frames are corrupted. On modern Windows the chain is gated by /GS cookies, kCFI/kCET, and HVCI — usually the bug yields a controlled crash, not direct RIP control.
Preconditions / where it applies
- Vulnerable driver function with
memcpy/RtlCopyMemory/manual loop into a stack-local of fixed size from a user-controlled source (oftenIOCTL Type3InputBufferorMETHOD_NEITHER). - Source size attacker-controlled or unchecked; or double-fetch races a checked-then-used length.
- Driver compiled without
/GSor with weak canary placement (third-party drivers, legacy kernel modules).
Technique
Find it. Reverse driver IRP dispatch (DriverEntry → MajorFunction[IRP_MJ_DEVICE_CONTROL]); for each IOCTL, trace user-buffer copies into stack locals. BinExport + BinDiff against patched versions narrows fixes quickly.
Trigger.
1
2
3
DeviceIoControl(hDev, IOCTL_VULN,
payload, payload_len,
NULL, 0, &cbRet, NULL);
What the corruption gives you.
- Saved RIP overwrite → without kCET, you can chain into kernel
ret-gadgets (rop-chains style, but insidentoskrnl.exe/HAL). - With
/GSon, the canary precedes RIP; overflow that touches both crashes in__report_gsfailure. Bypasses include: avoid reaching the cookie (overwrite an adjacent pointer used earlier),try/exceptregistration overwrite (older builds), or use a sibling bug to leak the cookie. - With kCET on, even after RIP overwrite the
retmismatches the shadow stack →#CP→ bug check.
Post-RIP path (where it still works):
- Disable SMEP via
cr4toggle gadget, then jump to user-mode shellcode that callscommit_creds-equivalent token swap. SMEP defeats the most naive form (see smep-smap-overview). - Pure kernel ROP into a
nt!HalpSetSystemInformation-style sink that calls into attacker-shaped data.
Modern reality. On HVCI+CET targets, most stack overflows are escalated by not taking RIP. Use the linear write to corrupt an adjacent struct (object pointer or IRP field) and pivot to arbitrary-read-write-primitives.
Detection and defence
- Compile drivers with
/GS,/guard:cf,/CETCOMPAT,/GUARD:EHCONT. - Driver Verifier (
verifier /flags 0x209BB) flags many overflow patterns at test time. - KASLR + HVCI + kCET combination makes RIP-control extremely rare for stack overflows on current targets.
References
- Microsoft: Driver security guidance — IOCTL hardening rules
- Connor McGarr — kernel stack overflow — modern walk-through
- HEVD project — practice driver with stack-overflow lab
See also: arbitrary-read-write-primitives, double-fetch, smep-smap-overview.