Skip to content

Commit 8b8847f

Browse files
authored
feat: Add KMDF Sample Driver with pool leak to demonstrate Driver Verifier (microsoft#27)
1 parent 64c426e commit 8b8847f

8 files changed

Lines changed: 448 additions & 1 deletion

File tree

Cargo.lock

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
[workspace]
2-
members = ["general/echo/kmdf/driver/*", "general/echo/kmdf/exe"]
2+
members = [
3+
"general/echo/kmdf/driver/*",
4+
"general/echo/kmdf/exe",
5+
"tools/dv/kmdf/fail_driver_pool_leak",
6+
]
37
resolver = "2"
48

59
[workspace.package]
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
[package]
2+
name = "fail_driver_pool_leak"
3+
version = "0.1.0"
4+
edition.workspace = true
5+
publish.workspace = true
6+
repository.workspace = true
7+
license.workspace = true
8+
9+
[package.metadata.wdk]
10+
11+
[lib]
12+
crate-type = ["cdylib"]
13+
14+
[dependencies]
15+
wdk.workspace = true
16+
wdk-alloc.workspace = true
17+
wdk-panic.workspace = true
18+
wdk-sys.workspace = true
19+
20+
[build-dependencies]
21+
wdk-build.workspace = true
22+
23+
[features]
24+
default = []
25+
nightly = ["wdk/nightly", "wdk-sys/nightly"]
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# Fail_Driver_Pool_Leak Sample
2+
3+
This sample KMDF Fail Driver demonstrates the capabilities and features of **Driver Verifier** and the **Device Fundamentals Tests**.
4+
5+
It allocates a pool of memory to a global buffer when a supported device is added by the PnP Manager and intentionally does not free it before the driver is unloaded. This memory leak fault is a system vulnerability that could lead to security and performance issues and bad user experience.
6+
7+
By enabling Driver Verifier on this driver, this pool leak violation can be caught before the driver is unloaded and with an active KDNET session, the bug can be analyzed further.
8+
9+
NOTE: The driver uses WDM's ExAllocatePool2 API directly to allocate memory for its buffer. Ideally, such allocations should be freed by using ExFreePool API. A cleaner way to manage memory in a WDF Driver is to use [wdfmemory](https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdfmemory/)
10+
11+
12+
## Steps to reproduce the issue
13+
14+
1. Clone the repository and navigate to the project root.
15+
16+
2. Build the driver project using the following command in a WDK environment (or EWDK prompt) -
17+
```
18+
cargo make
19+
```
20+
3. Prepare a target system (a Hyper-V VM can be used) for testing
21+
22+
Follow the below steps to setup the test system -
23+
1. Disable Secure boot and start the system
24+
2. Run "ipconfig" on the host system and note down the IP (if you are using Default Switch for the VM, note down the IP on the Default Switch)
25+
3. Install and open WinDbg, click on "Attach to Kernel". The key for the connection will be generated in the test system in the next steps.
26+
4. Connect to the test VM and run the following commands -
27+
```
28+
bcdedit /set testsigning on
29+
bcdedit /debug on
30+
bcdedit /dbgsettings net hostip:<PASTE.HOST.IP.HERE> port:<50000-50030>
31+
32+
### Copy the key string output by the above command
33+
```
34+
5. Paste the key in host's WinDbg prompt and connect to the kernel
35+
6. Restart the target/test system
36+
```
37+
shutdown -r -t 0
38+
```
39+
40+
4. Copy the driver package, available under ".\target\debug\fail_driver_pool_leak_package" to the target system.
41+
42+
5. Copy "devgen.exe" from host to the target system. Alternatively you may install WDK on the target system and add the directory that contains "devgen.exe" to PATH variable.
43+
44+
6. Install the driver package and create the device in the target system using the below commands -
45+
```
46+
cd "fail_driver_pool_leak_package"
47+
devgen.exe /add /bus ROOT /hardwareid "fail_driver_pool_leak"
48+
49+
## Copy the Device ID. This will be used later to run the tests
50+
51+
pnputil.exe /add-driver .\fail_driver_pool_leak.inf /install
52+
```
53+
7. Enable Driver Verifier for 'fail_driver_pool_leak.sys' driver package
54+
1. Open run command prompt (Start + R) or cmd as administator and run "verifier"
55+
2. In the verifier manager,
56+
- Create Standard Settings
57+
- Select driver names from list
58+
- Select 'fail_driver_pool_leak.sys'
59+
- Finish
60+
- Restart the system
61+
62+
8. Follow the steps in https://learn.microsoft.com/en-us/windows-hardware/drivers/develop/how-to-test-a-driver-at-runtime-from-a-command-prompt to run tests against the device managed by this driver
63+
64+
9. Install TAEF and WDTF on the test computer and run the following test -
65+
```
66+
cd "C:\Program Files (x86)\Windows Kits\10\Testing\Tests\Additional Tests\x64\DevFund"
67+
TE.exe .\Devfund_PnPDTest_WLK_Certification.dll /P:"DQ=DeviceID='ROOT\DEVGEN\{PASTE-DEVICE-ID-HERE}'" --rebootResumeOption:Manual
68+
```
69+
70+
10. The test will lead to a Bugcheck and a BlueScreen on the target system with the following error -
71+
```
72+
DRIVER_VERIFIER_DETECTED_VIOLATION (c4)
73+
```
74+
The logs will be available in WinDbg
75+
run ```!analyze -v``` for detailed bugcheck report
76+
run ```!verifier 3 fail_driver_pool_leak.sys``` for info on the allocations that were leaked that caused the bugcheck.
77+
78+
11. (Alternatively), the bugcheck can be observed when all the devices managed by this driver are removed, i.e, when the driver is unloaded from the system.
79+
You may use pnputil/devcon to enumerate and remove the devices -
80+
```
81+
# To enumerate the devices
82+
pnputil /enum-devices
83+
# To remove a device
84+
pnputil /remove-device "DEVICE-ID"
85+
```
86+
87+
### References
88+
89+
- [Driver Verifier](https://learn.microsoft.com/en-us/windows-hardware/drivers/devtest/driver-verifier)
90+
- [Device Fundamentals Tests](https://learn.microsoft.com/en-us/windows-hardware/drivers/devtest/device-fundamentals-tests)
91+
- [TAEF](https://learn.microsoft.com/en-us/windows-hardware/drivers/taef/getting-started)
92+
- [WDTF](https://learn.microsoft.com/en-us/windows-hardware/drivers/wdtf/wdtf-runtime-library)
93+
- [Testing a driver at runtime](https://learn.microsoft.com/en-us/windows-hardware/drivers/develop/how-to-test-a-driver-at-runtime-from-a-command-prompt)
94+
- [Using WDF to Develop a Driver](https://learn.microsoft.com/en-us/windows-hardware/drivers/wdf/using-the-framework-to-develop-a-driver)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Copyright (c) Microsoft Corporation
2+
// License: MIT OR Apache-2.0
3+
4+
fn main() -> Result<(), wdk_build::ConfigError> {
5+
wdk_build::Config::from_env_auto()?.configure_binary_build();
6+
Ok(())
7+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
;===================================================================
2+
; Copyright (c)2023, Microsoft Corporation
3+
;
4+
;Module Name:
5+
; FAIL_DRIVER_POOL_LEAK.INF
6+
;===================================================================
7+
8+
[Version]
9+
Signature = "$WINDOWS NT$"
10+
Class = SoftwareComponent
11+
ClassGuid = {5c4c3332-344d-483c-8739-259e934c9cc8}
12+
Provider = %ProviderString%
13+
PnpLockDown = 1
14+
15+
[DestinationDirs]
16+
DefaultDestDir = 13
17+
18+
[SourceDisksNames]
19+
1 = %DiskId1%,,,""
20+
21+
[SourceDisksFiles]
22+
fail_driver_pool_leak.sys = 1,,
23+
24+
; ================= Install section =================
25+
26+
[Manufacturer]
27+
%StdMfg%=Standard,NT$ARCH$.10.0...16299
28+
29+
[Standard.NT$ARCH$.10.0...16299]
30+
%FAIL_DRIVER_POOL_LEAK.DeviceDesc%=FAIL_DRIVER_POOL_LEAK_DEVICE, fail_driver_pool_leak
31+
32+
[FAIL_DRIVER_POOL_LEAK_DEVICE.NT$ARCH$]
33+
CopyFiles=Drivers_Dir
34+
35+
[Drivers_Dir]
36+
fail_driver_pool_leak.sys
37+
38+
; ================= Service installation =================
39+
[FAIL_DRIVER_POOL_LEAK_Device.NT$ARCH$.Services]
40+
AddService = fail_driver_pool_leak, %SPSVCINST_ASSOCSERVICE%, fail_driver_pool_leak_svc_ins
41+
42+
[fail_driver_pool_leak_svc_ins]
43+
DisplayName = %FAIL_DRIVER_POOL_LEAK.SVCDESC%
44+
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
45+
StartType = 3 ; SERVICE_DEMAND_START
46+
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
47+
ServiceBinary = %13%\fail_driver_pool_leak.sys
48+
49+
; ================= Strings =================
50+
[Strings]
51+
SPSVCINST_ASSOCSERVICE = 0x00000002
52+
ProviderString = "Rust-DV-Fail-Sample"
53+
StdMfg = "(Standard system devices)"
54+
DiskId1 = "WDF FAIL_DRIVER_POOL_LEAK Installation Disk #1"
55+
FAIL_DRIVER_POOL_LEAK.DeviceDesc = "WDF FAIL_DRIVER_POOL_LEAK Device"
56+
FAIL_DRIVER_POOL_LEAK.SVCDESC = "WDF FAIL_DRIVER_POOL_LEAK Service"

0 commit comments

Comments
 (0)