From 44ce636bbf758ce2c9603aa3af268f8c2b936bf0 Mon Sep 17 00:00:00 2001 From: Shravan Vasista Date: Thu, 26 Sep 2024 04:42:36 -0700 Subject: [PATCH 1/7] initial commit: fail_driver_irql_violation sample --- Cargo.lock | 11 + Cargo.toml | 6 +- .../fail_driver_irql_violation/Cargo.toml | 25 ++ .../kmdf/fail_driver_irql_violation/README.md | 94 ++++++++ .../kmdf/fail_driver_irql_violation/build.rs | 7 + .../fail_driver_irql_violation.inx | 56 +++++ .../fail_driver_irql_violation/src/driver.rs | 218 ++++++++++++++++++ .../fail_driver_irql_violation/src/lib.rs | 86 +++++++ 8 files changed, 502 insertions(+), 1 deletion(-) create mode 100644 tools/dv/kmdf/fail_driver_irql_violation/Cargo.toml create mode 100644 tools/dv/kmdf/fail_driver_irql_violation/README.md create mode 100644 tools/dv/kmdf/fail_driver_irql_violation/build.rs create mode 100644 tools/dv/kmdf/fail_driver_irql_violation/fail_driver_irql_violation.inx create mode 100644 tools/dv/kmdf/fail_driver_irql_violation/src/driver.rs create mode 100644 tools/dv/kmdf/fail_driver_irql_violation/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index da2a50f..eff4d29 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -245,6 +245,17 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "fail_driver_irql_violation" +version = "0.1.0" +dependencies = [ + "wdk", + "wdk-alloc", + "wdk-build", + "wdk-panic", + "wdk-sys", +] + [[package]] name = "glob" version = "0.3.1" diff --git a/Cargo.toml b/Cargo.toml index 411f2d0..847728b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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/kmdf/fail_driver_irql_violation", +] resolver = "2" [workspace.package] diff --git a/tools/dv/kmdf/fail_driver_irql_violation/Cargo.toml b/tools/dv/kmdf/fail_driver_irql_violation/Cargo.toml new file mode 100644 index 0000000..d78f3b4 --- /dev/null +++ b/tools/dv/kmdf/fail_driver_irql_violation/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "fail_driver_irql_violation" +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 + +[build-dependencies] +wdk-build.workspace = true + +[features] +default = [] +nightly = ["wdk/nightly", "wdk-sys/nightly"] diff --git a/tools/dv/kmdf/fail_driver_irql_violation/README.md b/tools/dv/kmdf/fail_driver_irql_violation/README.md new file mode 100644 index 0000000..adfcecf --- /dev/null +++ b/tools/dv/kmdf/fail_driver_irql_violation/README.md @@ -0,0 +1,94 @@ +# Fail_Driver_IRQL_Violdation Sample + +This sample KMDF Fail Driver demonstrates the capabilities and features of **Driver Verifier** and the **Device Fundamentals Tests**. + +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. + +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. + +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/) + + +## Steps to reproduce the issue + +1. Clone the repository and navigate to the project root. + +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: 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\fail_driver_irql_violation_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 "fail_driver_irql_violation_package" + devgen.exe /add /bus ROOT /hardwareid "fail_driver_irql_violation" + + ## Copy the Device ID. This will be used later to run the tests + + pnputil.exe /add-driver .\fail_driver_irql_violation.inf /install + ``` +7. Enable Driver Verifier for 'fail_driver_irql_violation.sys' driver package + 1. Open run command prompt (Start + R) or cmd as administator and run "verifier" + 2. In the verifier manager, + - Create Standard Settings + - Select driver names from list + - Select 'fail_driver_irql_violation.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. Install TAEF and WDTF on the test computer and run the following test - + ``` + 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-ID-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 fail_driver_irql_violation.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, i.e, when the driver is unloaded from the system. + 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 + +- [Driver Verifier](https://learn.microsoft.com/en-us/windows-hardware/drivers/devtest/driver-verifier) +- [Device Fundamentals Tests](https://learn.microsoft.com/en-us/windows-hardware/drivers/devtest/device-fundamentals-tests) +- [TAEF](https://learn.microsoft.com/en-us/windows-hardware/drivers/taef/getting-started) +- [WDTF](https://learn.microsoft.com/en-us/windows-hardware/drivers/wdtf/wdtf-runtime-library) +- [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) +- [Using WDF to Develop a Driver](https://learn.microsoft.com/en-us/windows-hardware/drivers/wdf/using-the-framework-to-develop-a-driver) diff --git a/tools/dv/kmdf/fail_driver_irql_violation/build.rs b/tools/dv/kmdf/fail_driver_irql_violation/build.rs new file mode 100644 index 0000000..ebbc7e2 --- /dev/null +++ b/tools/dv/kmdf/fail_driver_irql_violation/build.rs @@ -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(()) +} diff --git a/tools/dv/kmdf/fail_driver_irql_violation/fail_driver_irql_violation.inx b/tools/dv/kmdf/fail_driver_irql_violation/fail_driver_irql_violation.inx new file mode 100644 index 0000000..b72d79f --- /dev/null +++ b/tools/dv/kmdf/fail_driver_irql_violation/fail_driver_irql_violation.inx @@ -0,0 +1,56 @@ +;=================================================================== +; Copyright (c)2023, Microsoft Corporation +; +;Module Name: +; fail_driver_irql_violation.INF +;=================================================================== + +[Version] +Signature = "$WINDOWS NT$" +Class = SoftwareComponent +ClassGuid = {5c4c3332-344d-483c-8739-259e934c9cc8} +Provider = %ProviderString% +PnpLockDown = 1 + +[DestinationDirs] +DefaultDestDir = 13 + +[SourceDisksNames] +1 = %DiskId1%,,,"" + +[SourceDisksFiles] +fail_driver_irql_violation.sys = 1,, + +; ================= Install section ================= + +[Manufacturer] +%StdMfg%=Standard,NT$ARCH$.10.0...16299 + +[Standard.NT$ARCH$.10.0...16299] +%FAIL_DRIVER_IRQL_VIOLATION.DeviceDesc%=FAIL_DRIVER_IRQL_VIOLATION_DEVICE, fail_driver_irql_violation + +[FAIL_DRIVER_IRQL_VIOLATION_DEVICE.NT$ARCH$] +CopyFiles=Drivers_Dir + +[Drivers_Dir] +fail_driver_irql_violation.sys + +; ================= Service installation ================= +[FAIL_DRIVER_IRQL_VIOLATION_DEVICE.NT$ARCH$.Services] +AddService = fail_driver_irql_violation, %SPSVCINST_ASSOCSERVICE%, fail_driver_irql_violation_svc_ins + +[fail_driver_irql_violation_svc_ins] +DisplayName = %FAIL_DRIVER_IRQL_VIOLATION.SVCDESC% +ServiceType = 1 ; SERVICE_KERNEL_DRIVER +StartType = 3 ; SERVICE_DEMAND_START +ErrorControl = 1 ; SERVICE_ERROR_NORMAL +ServiceBinary = %13%\fail_driver_irql_violation.sys + +; ================= Strings ================= +[Strings] +SPSVCINST_ASSOCSERVICE = 0x00000002 +ProviderString = "Rust-DVFail-Sample" +StdMfg = "(Standard system devices)" +DiskId1 = "WDF DVFail Sample fail_driver_irql_violation Installation Disk #1" +FAIL_DRIVER_IRQL_VIOLATION_DEVICE.DeviceDesc = "DVFail Sample WDF fail_driver_irql_violation Device" +FAIL_DRIVER_IRQL_VIOLATION_DEVICE.SVCDESC = "DVFail Sample WDF fail_driver_irql_violation Service" \ No newline at end of file diff --git a/tools/dv/kmdf/fail_driver_irql_violation/src/driver.rs b/tools/dv/kmdf/fail_driver_irql_violation/src/driver.rs new file mode 100644 index 0000000..27899d4 --- /dev/null +++ b/tools/dv/kmdf/fail_driver_irql_violation/src/driver.rs @@ -0,0 +1,218 @@ +// Copyright (c) Microsoft Corporation. +// License: MIT OR Apache-2.0 + +use wdk::{nt_success, paged_code, println}; +use wdk_sys::{ + macros, + ntddk::{ExAllocatePool2, KeEnterCriticalRegion, KeGetCurrentIrql}, + APC_LEVEL, + DRIVER_OBJECT, + NTSTATUS, + PCUNICODE_STRING, + PDRIVER_OBJECT, + POOL_FLAG_NON_PAGED, + SIZE_T, + ULONG, + WDFDEVICE, + WDFDEVICE_INIT, + WDFDRIVER, + WDF_DRIVER_CONFIG, + WDF_NO_HANDLE, + WDF_NO_OBJECT_ATTRIBUTES, + WDF_OBJECT_ATTRIBUTES, + _WDF_EXECUTION_LEVEL, + _WDF_SYNCHRONIZATION_SCOPE, +}; + +use crate::{initialize_spinlock, GLOBAL_BUFFER, GUID_DEVINTERFACE, SPINLOCK}; + +/// `DriverEntry` initializes the driver and is the first routine called by the +/// system after the driver is loaded. `DriverEntry` specifies the other entry +/// points in the function driver, such as `EvtDevice` and `DriverUnload`. +/// +/// # Arguments +/// +/// * `driver` - represents the instance of the function driver that is loaded +/// into memory. `DriverEntry` must initialize members of `DriverObject` +/// before it returns to the caller. `DriverObject` is allocated by the system +/// before the driver is loaded, and it is released by the system after the +/// system unloads the function driver from memory. +/// * `registry_path` - represents the driver specific path in the Registry. The +/// function driver can use the path to store driver related data between +/// reboots. The path does not store hardware instance specific data. +/// +/// # Return value: +/// +/// * `STATUS_SUCCESS` - if successful, +/// * `STATUS_UNSUCCESSFUL` - otherwise. +#[link_section = "INIT"] +#[export_name = "DriverEntry"] +extern "system" fn driver_entry( + driver: &mut DRIVER_OBJECT, + registry_path: PCUNICODE_STRING, +) -> NTSTATUS { + println!("Enter: driver_entry"); + + let mut driver_config = { + let wdf_driver_config_size: ULONG; + + // clippy::cast_possible_truncation cannot currently check compile-time constants: https://github.com/rust-lang/rust-clippy/issues/9613 + #[allow(clippy::cast_possible_truncation)] + { + const WDF_DRIVER_CONFIG_SIZE: usize = core::mem::size_of::(); + + // Manually assert there is not truncation since clippy doesn't work for + // compile-time constants + const { assert!(WDF_DRIVER_CONFIG_SIZE <= ULONG::MAX as usize) } + + wdf_driver_config_size = WDF_DRIVER_CONFIG_SIZE as ULONG; + } + + WDF_DRIVER_CONFIG { + Size: wdf_driver_config_size, + EvtDriverDeviceAdd: Some(evt_driver_device_add), + EvtDriverUnload: Some(evt_driver_unload), + ..WDF_DRIVER_CONFIG::default() + } + }; + + let driver_handle_output = WDF_NO_HANDLE.cast::(); + + let nt_status = unsafe { + macros::call_unsafe_wdf_function_binding!( + WdfDriverCreate, + driver as PDRIVER_OBJECT, + registry_path, + WDF_NO_OBJECT_ATTRIBUTES, + &mut driver_config, + driver_handle_output, + ) + }; + + if !nt_success(nt_status) { + println!("Error: WdfDriverCreate failed {nt_status:#010X}"); + return nt_status; + } + + // Allocate non-paged memory pool of 64 bytes (arbitrarily chosen) for the + // Global buffer + unsafe { + const LENGTH: usize = 64; + GLOBAL_BUFFER = ExAllocatePool2(POOL_FLAG_NON_PAGED, LENGTH as SIZE_T, 's' as u32); + } + + println!("Exit: driver_entry"); + + nt_status +} + +/// `EvtDeviceAdd` is called by the framework in response to `AddDevice` +/// call from the `PnP` manager. We create and initialize a device object to +/// represent a new instance of the device. +/// +/// # Arguments: +/// +/// * `_driver` - Handle to a framework driver object created in `DriverEntry` +/// * `device_init` - Pointer to a framework-allocated `WDFDEVICE_INIT` +/// structure. +/// +/// # Return value: +/// +/// * `NTSTATUS` +#[link_section = "PAGE"] +extern "C" fn evt_driver_device_add( + _driver: WDFDRIVER, + mut device_init: *mut WDFDEVICE_INIT, +) -> NTSTATUS { + paged_code!(); + + println!("Enter: evt_driver_device_add"); + + #[allow(clippy::cast_possible_truncation)] + let mut attributes = WDF_OBJECT_ATTRIBUTES { + Size: core::mem::size_of::() as ULONG, + ExecutionLevel: _WDF_EXECUTION_LEVEL::WdfExecutionLevelInheritFromParent, + SynchronizationScope: _WDF_SYNCHRONIZATION_SCOPE::WdfSynchronizationScopeInheritFromParent, + ..WDF_OBJECT_ATTRIBUTES::default() + }; + + let mut device = WDF_NO_HANDLE as WDFDEVICE; + let mut nt_status = unsafe { + macros::call_unsafe_wdf_function_binding!( + WdfDeviceCreate, + &mut device_init, + &mut attributes, + &mut device, + ) + }; + + if !nt_success(nt_status) { + println!("Error: WdfDeviceCreate failed {nt_status:#010X}"); + return nt_status; + } + + nt_status = unsafe { + macros::call_unsafe_wdf_function_binding!( + WdfDeviceCreateDeviceInterface, + device, + &GUID_DEVINTERFACE, + core::ptr::null_mut(), + ) + }; + + if !nt_success(nt_status) { + println!("Error: WdfDeviceCreateDeviceInterface failed {nt_status:#010X}"); + return nt_status; + } + + // Initialize spinlock + if let Err(status) = initialize_spinlock() { + println!("Failed to initialize spinlock: {status:#010X}"); + } + + println!("Exit: evt_driver_device_add"); + + nt_status +} + +/// This event callback function is called before the driver is unloaded +/// +/// The EvtDriverUnload callback function must deallocate any +/// non-device-specific system resources that the driver's DriverEntry routine +/// allocated. +/// +/// # Argument: +/// +/// * `driver` - Handle to the framework driver object +/// +/// # Return Value: +/// +/// None +extern "C" fn evt_driver_unload(_driver: WDFDRIVER) { + println!("Enter: evt_driver_unload"); + + unsafe { + if let Some(ref spinlock) = SPINLOCK { + spinlock.acquire(); + if !GLOBAL_BUFFER.is_null() { + // Access and modify the global buffer here + println!("Accessing and modifying global buffer"); + // Example: Write to the global buffer + core::ptr::write_bytes(GLOBAL_BUFFER, 0, 64); + + // Illegal call to KeEnterCriticalRegion will lead to a + // violation of 'IrqlKeApcLte2' rule + KeEnterCriticalRegion(); + } else { + println!("Global buffer is null"); + } + spinlock.release(); + } else { + println!("Spinlock is not initialized"); + } + } + + unsafe { wdk_sys::ntddk::ExFreePool(GLOBAL_BUFFER) }; + + println!("Exit: evt_driver_unload"); +} diff --git a/tools/dv/kmdf/fail_driver_irql_violation/src/lib.rs b/tools/dv/kmdf/fail_driver_irql_violation/src/lib.rs new file mode 100644 index 0000000..f2f1589 --- /dev/null +++ b/tools/dv/kmdf/fail_driver_irql_violation/src/lib.rs @@ -0,0 +1,86 @@ +// Copyright (c) Microsoft Corporation. +// License: MIT OR Apache-2.0 + +//! # Abstract +//! +//! This KMDF sample contains an intentional error that is designed to +//! demonstrate the capabilities and features of Driver Verifier and the Device +//! Fundamental tests. +//! +//! The driver is designed to allocate memory using ExAllocatePool2 to 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 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. + +#![no_std] +#![cfg_attr(feature = "nightly", feature(hint_must_use))] +#![deny(clippy::all)] +#![warn(clippy::pedantic)] +#![warn(clippy::nursery)] +#![warn(clippy::cargo)] +#![allow(clippy::missing_safety_doc)] +#![allow(clippy::doc_markdown)] + +#[cfg(not(test))] +extern crate wdk_panic; + +#[cfg(not(test))] +use wdk_alloc::WDKAllocator; + +#[cfg(not(test))] +#[global_allocator] +static GLOBAL_ALLOCATOR: WDKAllocator = WDKAllocator; + +use wdk::{println, wdf::SpinLock}; +use wdk_sys::{ + GUID, + PVOID, + ULONG, + WDF_OBJECT_ATTRIBUTES, + _WDF_EXECUTION_LEVEL, + _WDF_SYNCHRONIZATION_SCOPE, +}; + +// {B2C3D4E5-F678-9012-3456-7890ABCDEF12} +const GUID_DEVINTERFACE: GUID = GUID { + Data1: 0xB2C3_D4E5u32, + Data2: 0xF678u16, + Data3: 0x9012u16, + Data4: [ + 0x34u8, 0x56u8, 0x78u8, 0x90u8, 0xABu8, 0xCDu8, 0xEFu8, 0x12u8, + ], +}; + +// Global Buffer for the driver +static mut GLOBAL_BUFFER: PVOID = core::ptr::null_mut(); + +// Spinlock to synchronize access to the global buffer +static mut SPINLOCK: Option = None; + +/// `initialize_spinlock` is called by +fn initialize_spinlock() -> Result<(), usize> { + let mut attributes = WDF_OBJECT_ATTRIBUTES { + Size: core::mem::size_of::() as ULONG, + ExecutionLevel: _WDF_EXECUTION_LEVEL::WdfExecutionLevelInheritFromParent, + SynchronizationScope: _WDF_SYNCHRONIZATION_SCOPE::WdfSynchronizationScopeInheritFromParent, + ..WDF_OBJECT_ATTRIBUTES::default() + }; + + match SpinLock::create(&mut attributes) { + Err(status) => { + println!("SpinLock create failed {status:#010X}"); + return Err(status as usize); + } + Ok(spin_lock) => unsafe { + SPINLOCK = Some(spin_lock); + }, + } + + Ok(()) +} + +mod driver; From a70b3ab8a4dc890158dbdea62299e5e261b2eba1 Mon Sep 17 00:00:00 2001 From: Shravan Vasista Date: Thu, 26 Sep 2024 09:10:30 -0700 Subject: [PATCH 2/7] Add IRQL Violation by calling KeEnterCriticalRegion() in EVT_DEVICE_D0_EXIT callback --- .../kmdf/fail_driver_irql_violation/README.md | 2 +- .../fail_driver_irql_violation/src/driver.rs | 67 ++++++++++++++----- .../fail_driver_irql_violation/src/lib.rs | 4 +- 3 files changed, 55 insertions(+), 18 deletions(-) diff --git a/tools/dv/kmdf/fail_driver_irql_violation/README.md b/tools/dv/kmdf/fail_driver_irql_violation/README.md index adfcecf..f5e2c0c 100644 --- a/tools/dv/kmdf/fail_driver_irql_violation/README.md +++ b/tools/dv/kmdf/fail_driver_irql_violation/README.md @@ -75,7 +75,7 @@ NOTE: The driver uses WDM's ExAllocatePool2 API directly to allocate memory for run ```!analyze -v``` for detailed bugcheck report run ```!verifier 3 fail_driver_irql_violation.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, i.e, when the driver is unloaded from the system. +11. (Alternatively), the bugcheck can be observed when a device managed by this driver is removed, i.e, when the EVT_WDF_DEVICE_D0_EXIT callback function is executed. You may use pnputil/devcon to enumerate and remove the devices - ``` # To enumerate the devices diff --git a/tools/dv/kmdf/fail_driver_irql_violation/src/driver.rs b/tools/dv/kmdf/fail_driver_irql_violation/src/driver.rs index 27899d4..c2f31ec 100644 --- a/tools/dv/kmdf/fail_driver_irql_violation/src/driver.rs +++ b/tools/dv/kmdf/fail_driver_irql_violation/src/driver.rs @@ -20,6 +20,7 @@ use wdk_sys::{ WDF_NO_HANDLE, WDF_NO_OBJECT_ATTRIBUTES, WDF_OBJECT_ATTRIBUTES, + WDF_PNPPOWER_EVENT_CALLBACKS, _WDF_EXECUTION_LEVEL, _WDF_SYNCHRONIZATION_SCOPE, }; @@ -94,13 +95,19 @@ extern "system" fn driver_entry( return nt_status; } - // Allocate non-paged memory pool of 64 bytes (arbitrarily chosen) for the + // Allocate non-paged memory pool of 1 byte (arbitrarily chosen) for the // Global buffer unsafe { - const LENGTH: usize = 64; + const LENGTH: usize = 1; GLOBAL_BUFFER = ExAllocatePool2(POOL_FLAG_NON_PAGED, LENGTH as SIZE_T, 's' as u32); } + // Initialize a spinlock that can be used to synchronize access to the buffer + if let Err(status) = initialize_spinlock() { + println!("Failed to initialize spinlock: {status:#010X}"); + return status; + } + println!("Exit: driver_entry"); nt_status @@ -128,6 +135,21 @@ extern "C" fn evt_driver_device_add( println!("Enter: evt_driver_device_add"); + let mut pnp_power_callbacks = WDF_PNPPOWER_EVENT_CALLBACKS { + Size: core::mem::size_of::() as ULONG, + EvtDeviceD0Entry: Some(evt_device_d0_entry), + EvtDeviceD0Exit: Some(evt_device_d0_exit), + ..WDF_PNPPOWER_EVENT_CALLBACKS::default() + }; + + let [()] = [unsafe { + macros::call_unsafe_wdf_function_binding!( + WdfDeviceInitSetPnpPowerEventCallbacks, + device_init, + &mut pnp_power_callbacks + ); + }]; + #[allow(clippy::cast_possible_truncation)] let mut attributes = WDF_OBJECT_ATTRIBUTES { Size: core::mem::size_of::() as ULONG, @@ -165,11 +187,6 @@ extern "C" fn evt_driver_device_add( return nt_status; } - // Initialize spinlock - if let Err(status) = initialize_spinlock() { - println!("Failed to initialize spinlock: {status:#010X}"); - } - println!("Exit: evt_driver_device_add"); nt_status @@ -191,15 +208,37 @@ extern "C" fn evt_driver_device_add( extern "C" fn evt_driver_unload(_driver: WDFDRIVER) { println!("Enter: evt_driver_unload"); + unsafe { wdk_sys::ntddk::ExFreePool(GLOBAL_BUFFER) }; + + println!("Exit: evt_driver_unload"); +} + +extern "C" fn evt_device_d0_entry(_device: WDFDEVICE, _prev_state: i32) -> i32 { + println!("Enter: evt_device_d0_entry"); unsafe { if let Some(ref spinlock) = SPINLOCK { spinlock.acquire(); if !GLOBAL_BUFFER.is_null() { - // Access and modify the global buffer here - println!("Accessing and modifying global buffer"); - // Example: Write to the global buffer - core::ptr::write_bytes(GLOBAL_BUFFER, 0, 64); + core::ptr::write_bytes(GLOBAL_BUFFER, 1, 1); + } else { + println!("Global buffer is null"); + } + spinlock.release(); + } else { + println!("Spinlock is not initialized"); + } + } + println!("Exit: evt_device_d0_entry"); + 0 +} +extern "C" fn evt_device_d0_exit(_device: WDFDEVICE, _prev_state: i32) -> i32 { + println!("Enter: evt_device_d0_exit"); + unsafe { + if let Some(ref spinlock) = SPINLOCK { + spinlock.acquire(); + if !GLOBAL_BUFFER.is_null() { + core::ptr::write_bytes(GLOBAL_BUFFER, 0, 1); // Illegal call to KeEnterCriticalRegion will lead to a // violation of 'IrqlKeApcLte2' rule KeEnterCriticalRegion(); @@ -211,8 +250,6 @@ extern "C" fn evt_driver_unload(_driver: WDFDRIVER) { println!("Spinlock is not initialized"); } } - - unsafe { wdk_sys::ntddk::ExFreePool(GLOBAL_BUFFER) }; - - println!("Exit: evt_driver_unload"); + println!("Exit: evt_device_d0_exit"); + 0 } diff --git a/tools/dv/kmdf/fail_driver_irql_violation/src/lib.rs b/tools/dv/kmdf/fail_driver_irql_violation/src/lib.rs index f2f1589..5cd90f1 100644 --- a/tools/dv/kmdf/fail_driver_irql_violation/src/lib.rs +++ b/tools/dv/kmdf/fail_driver_irql_violation/src/lib.rs @@ -62,7 +62,7 @@ static mut GLOBAL_BUFFER: PVOID = core::ptr::null_mut(); static mut SPINLOCK: Option = None; /// `initialize_spinlock` is called by -fn initialize_spinlock() -> Result<(), usize> { +fn initialize_spinlock() -> Result<(), i32> { let mut attributes = WDF_OBJECT_ATTRIBUTES { Size: core::mem::size_of::() as ULONG, ExecutionLevel: _WDF_EXECUTION_LEVEL::WdfExecutionLevelInheritFromParent, @@ -73,7 +73,7 @@ fn initialize_spinlock() -> Result<(), usize> { match SpinLock::create(&mut attributes) { Err(status) => { println!("SpinLock create failed {status:#010X}"); - return Err(status as usize); + return Err(status); } Ok(spin_lock) => unsafe { SPINLOCK = Some(spin_lock); From 10de07704575f601cb0aa38e600a80f565299eb7 Mon Sep 17 00:00:00 2001 From: Shravan Vasista Date: Thu, 26 Sep 2024 09:37:30 -0700 Subject: [PATCH 3/7] Fix issues in the inx file --- .../fail_driver_irql_violation/fail_driver_irql_violation.inx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/dv/kmdf/fail_driver_irql_violation/fail_driver_irql_violation.inx b/tools/dv/kmdf/fail_driver_irql_violation/fail_driver_irql_violation.inx index b72d79f..2014e99 100644 --- a/tools/dv/kmdf/fail_driver_irql_violation/fail_driver_irql_violation.inx +++ b/tools/dv/kmdf/fail_driver_irql_violation/fail_driver_irql_violation.inx @@ -52,5 +52,5 @@ SPSVCINST_ASSOCSERVICE = 0x00000002 ProviderString = "Rust-DVFail-Sample" StdMfg = "(Standard system devices)" DiskId1 = "WDF DVFail Sample fail_driver_irql_violation Installation Disk #1" -FAIL_DRIVER_IRQL_VIOLATION_DEVICE.DeviceDesc = "DVFail Sample WDF fail_driver_irql_violation Device" -FAIL_DRIVER_IRQL_VIOLATION_DEVICE.SVCDESC = "DVFail Sample WDF fail_driver_irql_violation Service" \ No newline at end of file +FAIL_DRIVER_IRQL_VIOLATION.DeviceDesc = "DVFail Sample WDF fail_driver_irql_violation Device" +FAIL_DRIVER_IRQL_VIOLATION.SVCDESC = "DVFail Sample WDF fail_driver_irql_violation Service" \ No newline at end of file From 95c81afe92207258b0450993efce37730c88bd78 Mon Sep 17 00:00:00 2001 From: Shravan Vasista Date: Fri, 27 Sep 2024 02:28:18 -0700 Subject: [PATCH 4/7] Add comments and docs --- .../fail_driver_irql_violation/src/driver.rs | 38 +++++++++++++++++-- .../fail_driver_irql_violation/src/lib.rs | 25 ++++++++---- 2 files changed, 52 insertions(+), 11 deletions(-) diff --git a/tools/dv/kmdf/fail_driver_irql_violation/src/driver.rs b/tools/dv/kmdf/fail_driver_irql_violation/src/driver.rs index c2f31ec..626660a 100644 --- a/tools/dv/kmdf/fail_driver_irql_violation/src/driver.rs +++ b/tools/dv/kmdf/fail_driver_irql_violation/src/driver.rs @@ -4,7 +4,7 @@ use wdk::{nt_success, paged_code, println}; use wdk_sys::{ macros, - ntddk::{ExAllocatePool2, KeEnterCriticalRegion, KeGetCurrentIrql}, + ntddk::{ExAllocatePool2, ExFreePool, KeEnterCriticalRegion, KeGetCurrentIrql}, APC_LEVEL, DRIVER_OBJECT, NTSTATUS, @@ -194,7 +194,7 @@ extern "C" fn evt_driver_device_add( /// This event callback function is called before the driver is unloaded /// -/// The EvtDriverUnload callback function must deallocate any +/// The `EvtDriverUnload` callback function must deallocate any /// non-device-specific system resources that the driver's DriverEntry routine /// allocated. /// @@ -208,11 +208,25 @@ extern "C" fn evt_driver_device_add( extern "C" fn evt_driver_unload(_driver: WDFDRIVER) { println!("Enter: evt_driver_unload"); - unsafe { wdk_sys::ntddk::ExFreePool(GLOBAL_BUFFER) }; + unsafe { ExFreePool(GLOBAL_BUFFER) }; println!("Exit: evt_driver_unload"); } +/// `EvtDeviceD0Entry` event callback function performs operations +/// that are needed when the driver's device enters the D0 power state. +/// +/// # Arguments: +/// +/// * `Device` - A handle to a framework device object. +/// * `PreviousState` - A WDF_POWER_DEVICE_STATE-typed enumerator that +/// identifies the previous device power state. +/// +/// # Return Value: +/// +/// * STATUS_SUCCESS or another status value for which NT_SUCCESS(status) equals +/// TRUE. For failures, return a status value for which NT_SUCCESS(status) +/// equals FALSE extern "C" fn evt_device_d0_entry(_device: WDFDEVICE, _prev_state: i32) -> i32 { println!("Enter: evt_device_d0_entry"); unsafe { @@ -226,12 +240,29 @@ extern "C" fn evt_device_d0_entry(_device: WDFDEVICE, _prev_state: i32) -> i32 { spinlock.release(); } else { println!("Spinlock is not initialized"); + return -1; } } println!("Exit: evt_device_d0_entry"); 0 } +/// `EvtDeviceD0Exit` event callback function performs operations +/// that are needed when the driver's device leaves the D0 power state. +/// +/// NOTE: The IRQL violation fault is injected in this callback +/// +/// # Arguments: +/// +/// * `Device` - A handle to a framework device object. +/// * `TargetState` - A WDF_POWER_DEVICE_STATE-typed enumerator that identifies +/// the device power state that the device is about to enter. +/// +/// # Return Value: +/// +/// * STATUS_SUCCESS or another status value for which NT_SUCCESS(status) equals +/// TRUE. For failures, return a status value for which NT_SUCCESS(status) +/// equals FALSE extern "C" fn evt_device_d0_exit(_device: WDFDEVICE, _prev_state: i32) -> i32 { println!("Enter: evt_device_d0_exit"); unsafe { @@ -248,6 +279,7 @@ extern "C" fn evt_device_d0_exit(_device: WDFDEVICE, _prev_state: i32) -> i32 { spinlock.release(); } else { println!("Spinlock is not initialized"); + return -1; } } println!("Exit: evt_device_d0_exit"); diff --git a/tools/dv/kmdf/fail_driver_irql_violation/src/lib.rs b/tools/dv/kmdf/fail_driver_irql_violation/src/lib.rs index 5cd90f1..a033cb6 100644 --- a/tools/dv/kmdf/fail_driver_irql_violation/src/lib.rs +++ b/tools/dv/kmdf/fail_driver_irql_violation/src/lib.rs @@ -7,14 +7,12 @@ //! demonstrate the capabilities and features of Driver Verifier and the Device //! Fundamental tests. //! -//! The driver is designed to allocate memory using ExAllocatePool2 to 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. +//! The driver is designed to violate the `IrqlKeApcLte2` Rule by calling +//! KeEnterCriticalRegion() function after acquiring a spinlock. //! -//! By enabling 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. +//! By enabling Driver Verifier on this driver, the IRQL violation can be caught +//! when a device that this driver manages is removed by the PnP manager. With +//! an active KDNET session, the bug can be analyzed further. #![no_std] #![cfg_attr(feature = "nightly", feature(hint_must_use))] @@ -61,7 +59,18 @@ static mut GLOBAL_BUFFER: PVOID = core::ptr::null_mut(); // Spinlock to synchronize access to the global buffer static mut SPINLOCK: Option = None; -/// `initialize_spinlock` is called by +/// `initialize_spinlock` initializes a WDF Spinlock that can be used to +/// synchronize access to any shared data +/// +/// # Arguments: +/// +/// # Return Value: +/// * Returns a `Result` type - +/// - `Ok(())`: Indicates that the function executed successfully without any +/// errors. +/// - `Err(i32)`: Indicates that an error occurred during the execution of the +/// function. The `i32` value represents the error code, which can be used to +/// identify the specific error. fn initialize_spinlock() -> Result<(), i32> { let mut attributes = WDF_OBJECT_ATTRIBUTES { Size: core::mem::size_of::() as ULONG, From 8a0e43e5c1fdc293be09008a756d5d64896a3c2b Mon Sep 17 00:00:00 2001 From: Shravan Vasista Date: Mon, 21 Oct 2024 22:12:26 -0700 Subject: [PATCH 5/7] Merge branch 'main' into 'irql-violation-sample' --- Cargo.lock | 123 ++++++++++++++++++++++++++++------------------------- 1 file changed, 65 insertions(+), 58 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8172b3d..bbcdf87 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -61,9 +61,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.79" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" [[package]] name = "bindgen" @@ -96,9 +96,9 @@ checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" [[package]] name = "camino" -version = "1.1.6" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" dependencies = [ "serde", ] @@ -154,9 +154,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.0" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80c21025abd42669a92efc996ef13cfb2c5c627858421ea58d5c3b331a6c134f" +checksum = "0fbb260a053428790f3de475e304ff84cdbc4face759ea7a3e64c1edd938a7fc" dependencies = [ "clap_builder", "clap_derive", @@ -164,9 +164,9 @@ dependencies = [ [[package]] name = "clap-cargo" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6e2fd20c8f8c7cc395f69a86a61eb9d93e1de8fadc00338508cde2ffc656388" +checksum = "23b2ea69cefa96b848b73ad516ad1d59a195cdf9263087d977f648a818c8b43e" dependencies = [ "anstyle", "clap", @@ -174,9 +174,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.0" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "458bf1f341769dfcf849846f65dffdf9146daa56bcd2a47cb4e1de9915567c99" +checksum = "64b17d7ea74e9f833c7dbf2cbe4fb12ff26783eda4782a8975b72f895c9b4d99" dependencies = [ "anstream", "anstyle", @@ -186,9 +186,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.0" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" +checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" dependencies = [ "heck", "proc-macro2", @@ -275,9 +275,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "heck" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "home" @@ -305,9 +305,9 @@ checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" dependencies = [ "spin", ] @@ -401,9 +401,9 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "paste" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pin-project-lite" @@ -423,18 +423,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -504,9 +504,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "ryu" @@ -577,9 +577,9 @@ checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" [[package]] name = "spin" -version = "0.5.2" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" [[package]] name = "strsim" @@ -589,9 +589,9 @@ checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" dependencies = [ "proc-macro2", "quote", @@ -600,18 +600,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.57" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.57" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", @@ -826,7 +826,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" dependencies = [ "windows-core", - "windows-targets 0.52.0", + "windows-targets 0.52.6", ] [[package]] @@ -835,7 +835,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.6", ] [[package]] @@ -853,7 +853,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.6", ] [[package]] @@ -873,17 +873,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -894,9 +895,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -906,9 +907,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -918,9 +919,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -930,9 +937,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -942,9 +949,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -954,9 +961,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -966,6 +973,6 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" From 560f71171ee5b76699d91a9a7e642a81ab5d2814 Mon Sep 17 00:00:00 2001 From: Shravan Vasista Date: Tue, 22 Oct 2024 06:39:06 -0700 Subject: [PATCH 6/7] Update fail_driver_irql_violation sample to v0.3.0 --- Cargo.lock | 1 + tools/dv/kmdf/fail_driver_irql_violation/Cargo.toml | 4 ++++ tools/dv/kmdf/fail_driver_irql_violation/build.rs | 5 ++--- tools/dv/kmdf/fail_driver_irql_violation/src/driver.rs | 10 +++++----- tools/dv/kmdf/fail_driver_irql_violation/src/lib.rs | 5 ++--- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 21b71cd..a6a71e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -259,6 +259,7 @@ dependencies = [ name = "fail_driver_irql_violation" version = "0.1.0" dependencies = [ + "anyhow", "wdk", "wdk-alloc", "wdk-build", diff --git a/tools/dv/kmdf/fail_driver_irql_violation/Cargo.toml b/tools/dv/kmdf/fail_driver_irql_violation/Cargo.toml index d78f3b4..a753930 100644 --- a/tools/dv/kmdf/fail_driver_irql_violation/Cargo.toml +++ b/tools/dv/kmdf/fail_driver_irql_violation/Cargo.toml @@ -7,9 +7,12 @@ repository.workspace = true license.workspace = true [package.metadata.wdk] +# Using workspace wdk config [lib] crate-type = ["cdylib"] +# Tests from root driver crates must be excluded since there's no way to prevent linker args from being passed to their unit tests: https://github.com/rust-lang/cargo/issues/12663 +test = false [dependencies] wdk.workspace = true @@ -18,6 +21,7 @@ wdk-panic.workspace = true wdk-sys.workspace = true [build-dependencies] +anyhow.workspace = true wdk-build.workspace = true [features] diff --git a/tools/dv/kmdf/fail_driver_irql_violation/build.rs b/tools/dv/kmdf/fail_driver_irql_violation/build.rs index ebbc7e2..1cfdc9b 100644 --- a/tools/dv/kmdf/fail_driver_irql_violation/build.rs +++ b/tools/dv/kmdf/fail_driver_irql_violation/build.rs @@ -1,7 +1,6 @@ // 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(()) +fn main() -> anyhow::Result<()> { + Ok(wdk_build::configure_wdk_binary_build()?) } diff --git a/tools/dv/kmdf/fail_driver_irql_violation/src/driver.rs b/tools/dv/kmdf/fail_driver_irql_violation/src/driver.rs index 626660a..fc7c396 100644 --- a/tools/dv/kmdf/fail_driver_irql_violation/src/driver.rs +++ b/tools/dv/kmdf/fail_driver_irql_violation/src/driver.rs @@ -3,7 +3,7 @@ use wdk::{nt_success, paged_code, println}; use wdk_sys::{ - macros, + call_unsafe_wdf_function_binding, ntddk::{ExAllocatePool2, ExFreePool, KeEnterCriticalRegion, KeGetCurrentIrql}, APC_LEVEL, DRIVER_OBJECT, @@ -80,7 +80,7 @@ extern "system" fn driver_entry( let driver_handle_output = WDF_NO_HANDLE.cast::(); let nt_status = unsafe { - macros::call_unsafe_wdf_function_binding!( + call_unsafe_wdf_function_binding!( WdfDriverCreate, driver as PDRIVER_OBJECT, registry_path, @@ -143,7 +143,7 @@ extern "C" fn evt_driver_device_add( }; let [()] = [unsafe { - macros::call_unsafe_wdf_function_binding!( + call_unsafe_wdf_function_binding!( WdfDeviceInitSetPnpPowerEventCallbacks, device_init, &mut pnp_power_callbacks @@ -160,7 +160,7 @@ extern "C" fn evt_driver_device_add( let mut device = WDF_NO_HANDLE as WDFDEVICE; let mut nt_status = unsafe { - macros::call_unsafe_wdf_function_binding!( + call_unsafe_wdf_function_binding!( WdfDeviceCreate, &mut device_init, &mut attributes, @@ -174,7 +174,7 @@ extern "C" fn evt_driver_device_add( } nt_status = unsafe { - macros::call_unsafe_wdf_function_binding!( + call_unsafe_wdf_function_binding!( WdfDeviceCreateDeviceInterface, device, &GUID_DEVINTERFACE, diff --git a/tools/dv/kmdf/fail_driver_irql_violation/src/lib.rs b/tools/dv/kmdf/fail_driver_irql_violation/src/lib.rs index a033cb6..7a25b32 100644 --- a/tools/dv/kmdf/fail_driver_irql_violation/src/lib.rs +++ b/tools/dv/kmdf/fail_driver_irql_violation/src/lib.rs @@ -15,7 +15,6 @@ //! an active KDNET session, the bug can be analyzed further. #![no_std] -#![cfg_attr(feature = "nightly", feature(hint_must_use))] #![deny(clippy::all)] #![warn(clippy::pedantic)] #![warn(clippy::nursery)] @@ -27,11 +26,11 @@ extern crate wdk_panic; #[cfg(not(test))] -use wdk_alloc::WDKAllocator; +use wdk_alloc::WdkAllocator; #[cfg(not(test))] #[global_allocator] -static GLOBAL_ALLOCATOR: WDKAllocator = WDKAllocator; +static GLOBAL_ALLOCATOR: WdkAllocator = WdkAllocator; use wdk::{println, wdf::SpinLock}; use wdk_sys::{ From abcb8a2dd3352c7a26b1151519dc934d8664b3a4 Mon Sep 17 00:00:00 2001 From: Shravan Vasista Date: Tue, 22 Oct 2024 07:29:35 -0700 Subject: [PATCH 7/7] Remove unnecessary hashes around raw string literal echo\kmdf\exe\src\main.rs --- general/echo/kmdf/exe/src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/general/echo/kmdf/exe/src/main.rs b/general/echo/kmdf/exe/src/main.rs index 72ff860..bcdf6db 100644 --- a/general/echo/kmdf/exe/src/main.rs +++ b/general/echo/kmdf/exe/src/main.rs @@ -90,13 +90,13 @@ fn main() -> Result<(), Box> { } } else { eprintln!( - r##" + r" Usage: Echoapp.exe --- Send single write and read request synchronously Echoapp.exe -Async --- Send reads and writes asynchronously without terminating Echoapp.exe -Async --- Send reads and writes asynchronously Exit the app anytime by pressing Ctrl-C -"## +" ); return Err("Invalid Args".into()); }