Skip to content

Initialize reflect subsystem before the device becomes openable (fixes #330 / #408) - #409

Open
chenmohan123 wants to merge 1 commit into
basil00:masterfrom
chenmohan123:fix-reflect-init-race
Open

Initialize reflect subsystem before the device becomes openable (fixes #330 / #408)#409
chenmohan123 wants to merge 1 commit into
basil00:masterfrom
chenmohan123:fix-reflect-init-race

Conversation

@chenmohan123

Copy link
Copy Markdown

Fixes the driver-load initialization race behind #330 and #408: bugcheck 0xD1 (DRIVER_IRQL_NOT_LESS_OR_EQUAL) in windivert_reflect_open_event() when a handle is opened concurrently with driver load.

Bug. DriverEntry creates the device, symbolic link, and finishes initializing the control device (lines ~1036-1063) before windivert_reflect_init() runs at the very end of DriverEntry. During that window the device is openable: a concurrent WinDivertOpen() succeeds at CreateFile (dll/WinDivert.c ~531) and issues IOCTL_WINDIVERT_STARTUPwindivert_reflect_open_event()InsertTailList(&reflect_event_queue, ...) on still-zeroed list heads → read of NULL+8 at DISPATCH_LEVEL → 0xD1 at WinDivert64+0xab69. Five independent minidumps (and the one attached to #330) show the identical fault offset; all crashes occur ~25 s after boot in a multi-threaded client whose first open also installs/starts the service. Full analysis with disassembly: #408 and EasyTier/EasyTier#2487.

Fix. Call windivert_reflect_init() immediately after WdfDriverCreate(), i.e. before the device becomes openable, parenting the reflect work item to the driver object instead of the device. The work item was never explicitly deleted anyway (windivert_reflect_close() has no callers); like the device-parented work item before, it is cleaned up implicitly when the parent object is deleted on driver unload, so lifetime semantics are unchanged.

Notes. Not compile-tested (no WDK on the authoring machine); the change is intentionally minimal (one call moved, parent object changed). Happy to adjust to whatever variant you prefer (e.g. splitting list/lock init from work-item creation, or guarding the reflect event paths with reflect_inited).

DriverEntry exposed the device and symbolic link before
windivert_reflect_init() ran, so a WinDivertOpen() racing with driver
load could hit zeroed reflect list heads at DISPATCH_LEVEL in
windivert_reflect_open_event() (bugcheck 0xD1, WinDivert64+0xab69).
Initialize the reflect subsystem right after WdfDriverCreate, with the
work item parented to the driver object. Fixes basil00#330, see also basil00#408.
@CLAassistant

CLAassistant commented Aug 9, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants