WinDbg のカーネルデバッガに10年以上前からある致命的な欠陥
Windows 8 (x64)向けのドライバ開発で、メモリリークが発生して WinDbgで リーク場所探してたんですが…。
Debugging memory leaks - DRIVER_VERIFIER_DETECTED_VIOLATION (C4): 0x62 (Windows Drivers)
*** Fatal System Error: 0x000000c4 (0x0000000000000062,0xFFFFE0000015F508,0xFFFFE000032B2500,0x0000000000000001) Break instruction exception - code 80000003 (first chance) A fatal system error has occurred. A fatal system error has occurred. nt!DbgBreakPointWithStatus: 0: kd> !verifier 3 mofusb64.sys Verify Flags Level 0x000209bb STANDARD FLAGS: ADDITIONAL FLAGS: [X] Indicates flag is enabled Summary of All Verifier Statistics RaiseIrqls 0xe Pool Allocations Attempted 0x2b85 Current paged pool allocations 0x5a for 00002E13 bytes Driver Verification List MODULE: 0xffffe00000058960 mofusb64.sys (Loaded) Pool Allocation Statistics: ( NonPagedPool / PagedPool ) Current Pool Allocations: ( 0x00000001 / 0x00000001 ) Pool Allocations: Address Length Tag Caller Address |
コマンド !verifier 3 ドライバ名 で表示されるはずが何も表示されない…!
いや、 Current Pool Allocations にちゃんと 1って出てる!
ネットで調べてみたところ驚愕の事実が発覚!・ω・
OSR's ntdev List: !verifier analysis question
Crash, but allocations not showing in list: -------------------------------------------------- This is an issue with the Verifier debugger extension and how the pool alloc/free information is stored. The leaked allocations were all an odd number of bytes, and when walking through the list of allocations and frees for a driver, when the number of bytes is odd (non-even), that allocation is not displayed in the list. The three allocations in the !analyze output from the first post add up to 0x85 bytes, meaning at least one had to be odd. As it turns out, all three were odd, and hence, none were displayed in the "!verifier 3 MyDriver.sys" output. (Had 2 been even and 1 odd, the 2 evens would've shown up, no matter their place in the list). Thanks again for bringing these to our attention, Dave! Determining what to do and "fixing" these is already under way. |
メモリリークした確保領域のサイズが奇数バイトだと表示されない
ちょっww!
|・ω・)・ω・)・ω・) な、なんだってー!?
どうやら、このバグ10年以上前からあるらしいんですがw。
メモリーリーク場所を突き止めた後で、偶数バイトにしてみました
Driver Verification List ------------------------ MODULE: 0xffffe00000058960 Mofusb64.sys (Loaded) Pool Allocation Statistics: ( NonPagedPool / PagedPool ) Current Pool Allocations: ( 0x00000002 / 0x00000000 ) Pool Allocations: Address Length Tag Caller Address |
出てきたー!
・ω・ すげー悩んじまったわい。
Pentium以降だとメモリに対しては4Byteアクセスなので偶数アドレスにアラインされているのが当然という考え方なんでしょうね。
インテル系は奇数番地からの読み書きだとその分ペナルティが発生しますが、とりあえず動きます。
RISC系だともっと深刻で例外割り込みが発生して停まってしまうこともあるようですね。
データーの割り当てアドレスは8の倍数を指定しています。
その割り当てサイズが奇数だった場合でてこないのです・ω・