Search code examples
c++windowskernelwindbgcorruption

Is Windows Kernel safe from corruptions that could happen in User mode


I'm currently performing a kernel debug with liveKD.

In all the cases where my blocking happens ( a ::CloseHandle() function call which never returns ) I happen to have a stacktrace which blocks in the kernel on a synchronisationEvent.

But when I do !object 12345678 if 123456789 is my synchronisationEvent as reported in the thread information of the process, it says Not a valid object (ObjectType invalid).

I'm worrying if corruptions at our application level in user mode could corrupt the kernel ? Does windows guarantee anything like a seperation of the memory spaces that would prevent from something like that ?

The code of the application uses C++, COM/DCOM, and Win32 intensively.


One comment asked for more information about the stacktrace and the handle type. In this case it is related to serial com port. But I think I also have it for file handles (not debugged those cases yet) This is the kind of stacktrace I have:

        THREAD 856a2d48  Cid 0660.0350  Teb: 7ff25000 Win32Thread: ffaaedd8 WAIT: (Executive) KernelMode Non-Alertable
            860c6f9c  SynchronizationEvent
        IRP List:
            babea5d8: (0006,01d8) Flags: 00000404  Mdl: 00000000
        Not impersonating
        DeviceMap                 89809fc8
        Owning Process            86212d40       Image:         DataCaptorIS.exe
        Attached Process          N/A            Image:         N/A
        Wait Start TickCount      27315407       Ticks: 6067021 (1:02:17:26.134)
        Context Switch Count      2259           IdealProcessor: 0
        UserTime                  00:00:04.976
        KernelTime                00:00:02.184
        Win32 Start Address 0x775c03e9
        Stack Init 8aa0dfd0 Current 8aa0da98 Base 8aa0e000 Limit 8aa0b000 Call 0
        Priority 9 BasePriority 8 UnusualBoost 0 ForegroundBoost 0 IoPriority 2 PagePriority 5
        ChildEBP RetAddr  Args to Child
        8aa0dab0 824bfced 856a2d48 00000000 8ab00120 nt!KiSwapContext+0x26 (FPO: [Uses EBP] [0,0,4])
        8aa0dae8 824beb4b 856a2e08 856a2d48 860c6f9c nt!KiSwapThread+0x266
        8aa0db10 824b856f 856a2d48 856a2e08 00000000 nt!KiCommitThreadWait+0x1df
        8aa0db88 914539fb 860c6f9c 00000000 00000000 nt!KeWaitForSingleObject+0x393
        8aa0dbcc 82478c1e 860c6f98 babea5d8 babea73c serial!SerialClose+0x332 (FPO: [Non-Fpo])
        8aa0dbe4 886206b9 babea5d8 861986d0 bc859308 nt!IofCallDriver+0x63
        8aa0dc08 82478c1e 861986d0 860c6890 00000800 serenum!Serenum_CreateClose+0x77 (FPO: [Non-Fpo])
        8aa0dc20 82673be6 84aa7a00 bc8592f0 00000000 nt!IofCallDriver+0x63
        8aa0dc64 826647c9 bc859308 bc859308 bc8592f0 nt!IopDeleteFile+0x10c
        8aa0dc7c 824ba1e0 00000000 856a2d48 bc8592f0 nt!ObpRemoveObjectRoutine+0x59
        8aa0dc90 824ba150 bc859308 82687556 960a5578 nt!ObfDereferenceObjectWithTag+0x88 (FPO: [0,0,3])
        8aa0dc98 82687556 960a5578 856a2d48 00000c80 nt!ObfDereferenceObject+0xd (FPO: [0,1,0])
        8aa0dcdc 8268727c 960a5578 a7d21900 86212d40 nt!ObpCloseHandleTableEntry+0x21d
        8aa0dd0c 82687616 86212d40 856a2d01 0763f3b4 nt!ObpCloseHandle+0x7f
        8aa0dd28 8247f8a6 00000c80 0763f3b8 775d7094 nt!NtClose+0x4e
        8aa0dd28 775d7094 00000c80 0763f3b8 775d7094 nt!KiSystemServicePostCall (FPO: [0,3] TrapFrame @ 8aa0dd34)
WARNING: Frame IP not in any known module. Following frames may be wrong.
        0763f3b8 00000000 00000000 00000000 00000000 0x775d7094

This stacktrace states that the thread is waiting on synchronisationEvent 860c6f9c.

The command kd> !object 860c6f9c returns Not a valid object (ObjectType invalid). I don't know if this does mean that the synchronisationEvent is corrupted in the Kernel. When I apply the command on other synchronisationEvent of the process I get an output rather like:

0: kd> !object 95369c68
Object: 95369c68  Type: (84aa6378) Event
    ObjectHeader: 95369c50 (new version)
    HandleCount: 1  PointerCount: 2

At the application level, in usermode, this happens after that kind of code that should have canceled and purged any IRP:

::CancelIoEx(m_handle_to_serial_port_com);
WaitForRequestToComplete(); // our function calls ::GetOverlappedResult(..., bWait) for any OVERLAPPED that was pending, with bWait == TRUE

::PurgeComm(m_handle_to_serial_port_com);
WaitForRequestToComplete(); // our function calls ::GetOverlappedResult(..., bWait) for any OVERLAPPED that was pending, with bWait == TRUE

::CloseHandle(m_handle_to_serial_port_com); // the closeHandle which never returns

The problems occurs really randomly. Sometimes it takes days before it reproduces.


Displaying the memory for the synchronisationEvent object a address 86184f9c ( on another machine with the same bug):

0: kd> dp 86184f9c - @@c++(sizeof(nt!_object_header) - #RTL_FIELD_SIZE(nt!_object_header, Body)) 
86184f84  00000006 00000000 00000000 00000000
86184f94  00000000 00000001 00040001 00000000
86184fa4  85917420 85917420 00000000 00000000
86184fb4  00000000 00000000 00000000 0000000d
86184fc4  86184890 00000040 00000000 00000800
86184fd4  00000000 85747a68 00000000 00000000
86184fe4  00000000 00000000 86184fec 86184fec
86184ff4  86184ff4 86184ff4 96d4c000 040d0000

and trying to display the object header:

0: kd> dt nt!_object_header 86184f9c - @@c++(sizeof(nt!_object_header) - #RTL_FIELD_SIZE(nt!_object_header, Body))
Cannot find specified field members.

Solution

  • It's definitely supposed to be. If the kernel were corruptable from user mode, you would have a security flaw that would potentially impact all users on the machine. You could deny service by making the kernel crash. You could elevate privileges by taking advantage of a kernel buffer overrun. You could steal someone else's data by using a kernel information disclosure flaw.

    Just because you feed the kernel bad data does not mean it has such a vuln. The kernel may be smart enough to detect and prevent such issues, or it may execute any code that could suffer from corrupt userland input in userland.

    If you have actually found a bug that lets you crash the kernel, read someone else's data that was passed to the kernel, or something similar, then you should report it to Microsoft. If you suspect that you have found something, try contacting MS support and see if they can help. They are the experts on the OS and most likely to be able to identify if your suspected flaw is a real flaw.