Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add KMDF Sample Driver with pool leak to demonstrate Driver Verifier #27

Merged
merged 11 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
[workspace]
members = ["general/echo/kmdf/driver/*", "general/echo/kmdf/exe"]
members = [
"general/echo/kmdf/driver/*",
"general/echo/kmdf/exe",
"tools/dv/samples/kmdf/pool_leak",
]
resolver = "2"

[workspace.package]
Expand Down
26 changes: 26 additions & 0 deletions tools/dv/samples/kmdf/pool_leak/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[package]
name = "pool_leak"
version = "0.1.0"
edition.workspace = true
publish.workspace = true
repository.workspace = true
license.workspace = true

[package.metadata.wdk]

[lib]
crate-type = ["cdylib"]

[dependencies]
wdk.workspace = true
wdk-alloc.workspace = true
wdk-panic.workspace = true
wdk-sys.workspace = true
paste = ">=1.0.14, <2.0.0"

[build-dependencies]
wdk-build.workspace = true

[features]
default = []
nightly = ["wdk/nightly", "wdk-sys/nightly"]
90 changes: 90 additions & 0 deletions tools/dv/samples/kmdf/pool_leak/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Driver Verifier Pool Leak Sample

This KMDF sample contains an intentional error that demonstrates the capabilities and features of Driver Verifier and the Device Fundamental tests.
wmmc88 marked this conversation as resolved.
Show resolved Hide resolved

The driver uses WDM's ExAllocatePool2 API to allocate memory in its Device Context buffer when a device is added by the PnP manager. However, this buffer is not freed anywhere in the driver, including the driver unload function.

By enabling the Driver Verifier on this driver, the pool leak violation can be caught when the driver is unloaded and with an active KDNET session, the bug can be analyzed further.
wmmc88 marked this conversation as resolved.
Show resolved Hide resolved

## Steps to Reproduce the issue

1. Clone the repository and navigate to the project directory.

2. Build the driver project using the following command in a WDK environment (or EWDK prompt) -
```
cargo make
```
3. Prepare a target system (a Hyper-V VM can be used) for testing

Follow the below steps to setup the test system -
1. Disable Secure boot and start the system
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)
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.
4. Connect to the test VM and run the following commands -
```
bcdedit /set testsigning on
bcdedit /debug on
bcdedit /dbgsettings net hostip:<PASTE.HOST.IP.HERE> port:<50000-50030>

### Copy the key string output by the above command
```
5. Paste the key in host's WinDbg prompt and connect to the kernel
6. Restart the target/test system
```
shutdown -r -t 0
```

4. Copy the driver package, available under ".\target\debug\pool_leak_package" to the target system.

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.

6. Install the driver package and create the device in the target system using the below commands -
```
cd "pool_leak_package"
devgen.exe /add /bus ROOT /hardwareid "pool_leak"

## Copy the Device ID. This will be used later to run the tests

pnputil.exe /add-driver .\pool_leak.inf /install
```
7. Enable Driver Verifier for 'pool_leak.sys' driver package
1. Open run command promt (Start + R) or cmd as administator and run "verifier"
wmmc88 marked this conversation as resolved.
Show resolved Hide resolved
2. In the verifier manager,
- Create Standard Settings
- Select driver names from list
- Select 'pool_leak.sys'
- Finish
- Restart the system

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

9. Run the following test after TAEF and WDTF are installed -
```
cd "C:\Program Files (x86)\Windows Kits\10\Testing\Tests\Additional Tests\x64\DevFund"
TE.exe .\Devfund_PnPDTest_WLK_Certification.dll /P:"DQ=DeviceID='ROOT\DEVGEN\{PASTE-DEVICE-GUID-HERE}'" --rebootResumeOption:Manual
```

10. The test will lead to a Bugcheck and a BlueScreen on the target system with the following error -
```
DRIVER_VERIFIER_DETECTED_VIOLATION (c4)
```
The logs will be available in WinDbg
run ```!analyze -v``` for detailed bugcheck report
run ```!verifier 3 pool_leak.sys``` for info on the allocations that were leaked that caused the bugcheck.

11. (Alternatively), the bugcheck can be observed when all the devices managed by this driver are removed.
You may use pnputil/devcon to enumerate and remove the devices -
```
# To enumerate the devices
pnputil /enum-devices
# To remove a device
pnputil /remove-device "DEVICE/ID"
```

References

- https://learn.microsoft.com/en-us/windows-hardware/drivers/devtest/driver-verifier
- https://learn.microsoft.com/en-us/windows-hardware/drivers/devtest/device-fundamentals-tests
- https://learn.microsoft.com/en-us/windows-hardware/drivers/taef/getting-started
- https://learn.microsoft.com/en-us/windows-hardware/drivers/wdtf/wdtf-runtime-library
- https://learn.microsoft.com/en-us/windows-hardware/drivers/develop/how-to-test-a-driver-at-runtime-from-a-command-prompt
7 changes: 7 additions & 0 deletions tools/dv/samples/kmdf/pool_leak/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Copyright (c) Microsoft Corporation
// License: MIT OR Apache-2.0

fn main() -> Result<(), wdk_build::ConfigError> {
wdk_build::Config::from_env_auto()?.configure_binary_build();
Ok(())
}
56 changes: 56 additions & 0 deletions tools/dv/samples/kmdf/pool_leak/pool_leak.inx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
;===================================================================
; Copyright (c)2023, Microsoft Corporation
;
;Module Name:
; pool_leak.INF
;===================================================================

[Version]
Signature = "$WINDOWS NT$"
Class = SoftwareComponent
ClassGuid = {5c4c3332-344d-483c-8739-259e934c9cc8}
Provider = %ProviderString%
PnpLockDown = 1

[DestinationDirs]
DefaultDestDir = 13

[SourceDisksNames]
1 = %DiskId1%,,,""

[SourceDisksFiles]
pool_leak.sys = 1,,

; ================= Install section =================

[Manufacturer]
%StdMfg%=Standard,NT$ARCH$.10.0...16299

[Standard.NT$ARCH$.10.0...16299]
%POOL_LEAK.DeviceDesc%=POOL_LEAK_Device, pool_leak

[POOL_LEAK_Device.NT$ARCH$]
CopyFiles=Drivers_Dir

[Drivers_Dir]
pool_leak.sys

; ================= Service installation =================
[POOL_LEAK_Device.NT$ARCH$.Services]
AddService = pool_leak, %SPSVCINST_ASSOCSERVICE%, pool_leak_svc_ins

[pool_leak_svc_ins]
DisplayName = %POOL_LEAK.SVCDESC%
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
StartType = 3 ; SERVICE_DEMAND_START
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
ServiceBinary = %13%\pool_leak.sys

; ================= Strings =================
[Strings]
SPSVCINST_ASSOCSERVICE = 0x00000002
ProviderString = "Rust-DVFail-Sample"
StdMfg = "(Standard system devices)"
DiskId1 = "WDF DVFail Sample POOL_LEAK Installation Disk #1"
POOL_LEAK.DeviceDesc = "DVFail Sample WDF POOL_LEAK Driver"
POOL_LEAK.SVCDESC = "DVFail Sample WDF POOL_LEAK Service"
Loading
Loading