none
Driver verifier fail with 0x7E on WdfRegistryQueryMultiString when data is empty RRS feed

  • Question

  • Hi,

    In my driver I get data from a registry key, this key has a multi-string value named XXX and for testing purpose I set its Data to be empty.

    when my driver tries get this data by WdfRegistryQueryMultiString I get 0x7E bugcheck (SYSTEM_THREAD_EXCEPTION_NOT_HANDLED) and in the logdump I can see this print:

    "FxPoolAllocator - Invalid Allocation Size of 0 requested". how can I know that data is empty so I won't call the WdfRegistryQueryMultiString? I had expect the framework to don't fail about it but not allocate anything, but now that I see it fail, I must know that data is NULL, how can I do it in advanced?Thanks,

    Shsho

    Sunday, December 6, 2015 6:56 AM

All replies

  • First show us the code that sets up the collection and the call to WdfRegistryQueryMultiString.  Second take the crash dump and get the output of !analyze -v so we can see where the crash occurred.   This is a failure due to one of your parameters being wrong, not a default in WDF.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    Sunday, December 6, 2015 12:56 PM
  • The collection creation code:

    status = WdfCollectionCreate(WDF_NO_OBJECT_ATTRIBUTES, &hiddenInfo_Always.collection);
    	if (!NT_SUCCESS(status)) {
    		TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, "%!FUNC!: WdfCollectionCreate failed %!STATUS!\n", status);
    		return status;
    	}
    registry calls:

    RtlInitUnicodeString( &KeyStr, HIDDEN_DEVICES ); DECLARE_CONST_UNICODE_STRING(hiddenAlways, HIDDEN_DEVICE_VALUE_ALWAYS); status = WdfRegistryCreateKey( NULL, &KeyStr, KEY_ALL_ACCESS, REG_OPTION_NON_VOLATILE, &CreateDisposition, WDF_NO_OBJECT_ATTRIBUTES, &hiddenDevicesKey ); if (NT_SUCCESS(status)) { if (REG_OPENED_EXISTING_KEY == CreateDisposition) {

    //get the values of hideAlways key

    WDF_OBJECT_ATTRIBUTES_INIT(&stringAttributes);

    stringAttributes.ParentObject = hiddenInfo_Always.collection;

    status = WdfRegistryQueryMultiString(

    hiddenDevicesKey,

    &hiddenAlways,

    &stringAttributes,

    hiddenInfo_Always.collection

    );

    }


    the output of !analyze -v:

    !analyze -v
    *******************************************************************************
    *                                                                             *
    *                        Bugcheck Analysis                                    *
    *                                                                             *
    *******************************************************************************
    
    SYSTEM_THREAD_EXCEPTION_NOT_HANDLED (7e)
    This is a very common bugcheck.  Usually the exception address pinpoints
    the driver/function that caused the problem.  Always note this address
    as well as the link date of the driver/image that contains this address.
    Arguments:
    Arg1: ffffffff80000003, The exception code that was not handled
    Arg2: fffff801afb666b0, The address that the exception occurred at
    Arg3: ffffd00024267268, Exception Record Address
    Arg4: ffffd00024266a80, Context Record Address
    
    Debugging Details:
    ------------------
    
    
    EXCEPTION_CODE: (HRESULT) 0x80000003 (2147483651) - One or more arguments are invalid
    
    FAULTING_IP: 
    nt!DbgBreakPoint+0
    fffff801`afb666b0 cc              int     3
    
    EXCEPTION_RECORD:  ffffd00024267268 -- (.exr 0xffffd00024267268)
    ExceptionAddress: fffff801afb666b0 (nt!DbgBreakPoint)
       ExceptionCode: 80000003 (Break instruction exception)
      ExceptionFlags: 00000000
    NumberParameters: 1
       Parameter[0]: 0000000000000000
    
    CONTEXT:  ffffd00024266a80 -- (.cxr 0xffffd00024266a80;r)
    rax=ffffe0013a59dc90 rbx=0000000000000000 rcx=fffff80002f07780
    rdx=ffffe0013a59de40 rsi=ffffe0013a59dc90 rdi=0000000000000000
    rip=fffff801afb666b0 rsp=ffffd000242674a8 rbp=0000000000000001
     r8=ffffd000242674f0  r9=ffffe0013a59de40 r10=7efefefefefeff71
    r11=8101010101010100 r12=0000000000000304 r13=0000000000000000
    r14=ffffe0013a59dcf8 r15=ffffd00024267690
    iopl=0         nv up ei pl nz na pe nc
    cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
    nt!DbgBreakPoint:
    fffff801`afb666b0 cc              int     3
    Last set context:
    rax=ffffe0013a59dc90 rbx=0000000000000000 rcx=fffff80002f07780
    rdx=ffffe0013a59de40 rsi=ffffe0013a59dc90 rdi=0000000000000000
    rip=fffff801afb666b0 rsp=ffffd000242674a8 rbp=0000000000000001
     r8=ffffd000242674f0  r9=ffffe0013a59de40 r10=7efefefefefeff71
    r11=8101010101010100 r12=0000000000000304 r13=0000000000000000
    r14=ffffe0013a59dcf8 r15=ffffd00024267690
    iopl=0         nv up ei pl nz na pe nc
    cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
    nt!DbgBreakPoint:
    fffff801`afb666b0 cc              int     3
    Resetting default scope
    
    DEFAULT_BUCKET_ID:  WIN8_DRIVER_FAULT
    
    BUGCHECK_STR:  AV
    
    PROCESS_NAME:  System
    
    CURRENT_IRQL:  0
    
    ERROR_CODE: (NTSTATUS) 0x80000003 - {EXCEPTION}  Breakpoint  A breakpoint has been reached.
    
    EXCEPTION_PARAMETER1:  0000000000000000
    
    ANALYSIS_VERSION: 6.3.9600.16384 (debuggers(dbg).130821-1623) amd64fre
    
    LAST_CONTROL_TRANSFER:  from fffff80002f2783b to fffff801afb666b0
    
    STACK_TEXT:  
    ffffd000`242674a8 fffff800`02f2783b : ffffe001`3a4f5400 ffffe001`3a59de40 ffffd000`242674f0 ffffe001`3a59de40 : nt!DbgBreakPoint
    ffffd000`242674b0 fffff800`02f14ce2 : 00000000`00737973 00000000`00000001 ffffe001`3a59dc90 00001ffe`c3cf2c88 : Wdf01000!FxVerifierDbgBreakPoint+0x43 [d:\th\minkernel\wdf\framework\shared\inc\private\common\fxverifier.h @ 97]
    ffffd000`242674f0 fffff800`02ef843c : ffffe001`3a59dc90 ffffd000`242675a8 ffffd000`24267670 00000000`00000000 : Wdf01000!FxPoolAllocator+0x3b5e2 [d:\th\minkernel\wdf\framework\shared\object\wdfpool.cpp @ 147]
    ffffd000`24267540 fffff800`060d2289 : 00001ffe`00000000 00001ffe`c3cf2c88 00001ffe`00000007 ffffd000`24267690 : Wdf01000!imp_WdfRegistryQueryMultiString+0x12c [d:\th\minkernel\wdf\framework\shared\support\fxregistryapi.cpp @ 676]
    ffffd000`242675f0 fffff800`060d1993 : ffffe001`3c164180 ffffe001`3c164180 ffffe001`3c164280 fffff801`afa70859 : MyDriver!EnumerateSensorDevicesRes+0x475 [d:\buildagent_prod\workspace\6457\MyDriver\device.c @ 1489]
    ffffd000`24267960 fffff800`02ef4074 : ffffe001`3c164180 ffffe001`3c1510c0 00000000`00000000 00000000`00000008 : MyDriver!CompleteDeviceEnumerationMessage+0xa7 [d:\buildagent_prod\workspace\6457\MyDriver\device.c @ 711]
    ffffd000`24267990 fffff800`02ef4d89 : 00000000`00000000 ffffe001`3c164180 00000000`00000000 00000000`00000000 : Wdf01000!FxWorkItem::WorkItemHandler+0x7c [d:\th\minkernel\wdf\framework\shared\core\fxworkitem.cpp @ 374]
    ffffd000`242679d0 fffff801`afaa1530 : ffffcf80`0be42fa0 00000000`00000001 00000000`00000000 00000000`00000000 : Wdf01000!FxWorkItem::WorkItemThunk+0x29 [d:\th\minkernel\wdf\framework\shared\core\fxworkitem.cpp @ 439]
    ffffd000`24267a10 fffff801`afa89b79 : fffff801`afdb2200 ffffe001`3a8ad040 fffff801`afaa1440 fffff801`afdb2340 : nt!IopProcessWorkItem+0xf0
    ffffd000`24267a80 fffff801`afa28125 : ffffe001`3ac5f2f8 00000000`00000080 ffffe001`3926b680 ffffe001`3a8ad040 : nt!ExpWorkerThread+0xe9
    ffffd000`24267b10 fffff801`afb66126 : fffff801`afd3c180 ffffe001`3a8ad040 fffff801`afa280e4 ffffd000`24267c19 : nt!PspSystemThreadStartup+0x41
    ffffd000`24267b60 00000000`00000000 : ffffd000`24268000 ffffd000`24261000 00000000`00000000 00000000`00000000 : nt!KiStartSystemThread+0x16
    

    the output of !wdfkd.wdflogdump:

    ...
    27: FxPkgPnp::PnpEnterNewState - WDFDEVICE 0x00001FFEC50F0FD8 !devobj 0xFFFFE0013C1510C0 entering PnP State WdfDevStatePnpEnableInterfaces from WdfDevStatePnpHardwareAvailable
    28: FxPkgPnp::PnpEnterNewState - WDFDEVICE 0x00001FFEC50F0FD8 !devobj 0xFFFFE0013C1510C0 entering PnP State WdfDevStatePnpStarted from WdfDevStatePnpEnableInterfaces
    29: FxDeviceBase::_SearchForDevice - WDFHANDLE 00001FFEC5B0ABF8 does not have a WDFDEVICE as an ancestor
    30: FxPoolAllocator - Invalid Allocation Size of 0 requested
    

    thanks a lot!

    Sunday, December 6, 2015 1:34 PM
  • Hi Shosho,

    Thank you for the detailed information. We will try to set up a local repro, please check this thread soon for a follow up.

    Monday, December 7, 2015 9:19 PM
  • Any update? Is it a framework issue?
    Wednesday, December 9, 2015 6:43 AM
  • as I can see from your code, it's a quite clear that it's Microsoft bug:

    _Must_inspect_result_ 
    604 __drv_maxIRQL(PASSIVE_LEVEL) 
    605 NTSTATUS 
    606 WDFEXPORT(WdfRegistryQueryMultiString)( 
    607     __in 
    608     PWDF_DRIVER_GLOBALS DriverGlobals, 
    609     __in 
    610     WDFKEY Key, 
    611     __in 
    612     PCUNICODE_STRING ValueName, 
    613     __in_opt 
    614     PWDF_OBJECT_ATTRIBUTES StringsAttributes, 
    615     __in 
    616     WDFCOLLECTION Collection 
    617     ) 
    618 { 
    619     DDI_ENTRY(); 
    620 
     
    621     PFX_DRIVER_GLOBALS pFxDriverGlobals; 
    622     FxDeviceBase* pDeviceBase; 
    623     FxCollection* pCollection; 
    624     FxRegKey* pKey; 
    625     NTSTATUS status; 
    626     ULONG dataLength, type; 
    627     PVOID dataBuffer; 
    628 
     
    629     FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), 
    630                                    Key, 
    631                                    FX_TYPE_REG_KEY, 
    632                                    (PVOID*) &pKey, 
    633                                    &pFxDriverGlobals); 
    634 
     
    635     pDeviceBase = NULL; 
    636 
     
    637     FxPointerNotNull(pFxDriverGlobals, ValueName); 
    638     FxPointerNotNull(pFxDriverGlobals, Collection); 
    639 
     
    640     status = FxValidateObjectAttributes(pFxDriverGlobals, StringsAttributes); 
    641     if (!NT_SUCCESS(status)) { 
    642         return status; 
    643     } 
    644 
     
    645     status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL); 
    646     if (!NT_SUCCESS(status)) { 
    647         return status; 
    648     } 
    649 
     
    650     status = FxValidateUnicodeString(pFxDriverGlobals, ValueName); 
    651     if (!NT_SUCCESS(status)) { 
    652         return status; 
    653     } 
    654 
     
    655     FxObjectHandleGetPtr(pFxDriverGlobals, 
    656                          Collection, 
    657                          FX_TYPE_COLLECTION, 
    658                          (PVOID*) &pCollection); 
    659 
     
    660     pDeviceBase = FxDeviceBase::_SearchForDevice(pFxDriverGlobals, 
    661                                                  StringsAttributes); 
    662 
     
    663     status = pKey->QueryValue(ValueName, 0, NULL, &dataLength, &type); 
    664     if (!NT_SUCCESS(status) && status != STATUS_BUFFER_OVERFLOW) { 
    665         DoTraceLevelMessage( 
    666             pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGERROR, 
    667             "WDFKEY %p QueryPartial failed: %!STATUS!", Key, status); 
    668 
     
    669         return status; 
    670     } 
    671 
     
    672     if (type != REG_MULTI_SZ) { 
    673         return STATUS_OBJECT_TYPE_MISMATCH; 
    674     } 
    675 
     
    676     dataBuffer = FxPoolAllocate(pFxDriverGlobals, PagedPool, dataLength); 
    ...
    }

    there is no examination about dataLength value. so in my case, it contains zero, then in the FxPoolAllocate:
    PVOID 
    76 FxPoolAllocator( 
    77     __in PFX_DRIVER_GLOBALS FxDriverGlobals, 
    78     __in PFX_POOL  Pool, 
    79     __in POOL_TYPE Type, 
    80     __in SIZE_T    Size, 
    81     __in ULONG     Tag, 
    82     __in PVOID     Caller 
    83     ) 
    84 /*++ 
    85  
    86 Routine Description: 
    87  
    88     Allocates system pool tracked in a FX_POOL tracking object. 
    89  
    90 Arguments: 
    91  
    92     Pool    - FX_POOL object for tracking allocations 
    93  
    94     Type    - POOL_TYPE from ntddk.h 
    95  
    96     Size    - Size in bytes of the allocation 
    97  
    98     Tag     - Caller specified additional tag value for debugging/tracing 
    99  
    100     Caller  - Caller's address 
    101  
    102 Returns: 
    103  
    104     NULL - Could not allocate pool 
    105     !NULL - Pointer to pool of minimum Size bytes 
    106  
    107 Remarks: 
    108  
    109     In kernel mode this routine conditionally adds header on top iff the 
    110     allocation size is < PAGE_SIZE. If the allocation size is >= PAGE_SIZE 
    111     the caller would expect a page aligned pointer, hence no header is added. 
    112     In addition, ExAllocatePool* functions guarantee that a buffer < PAGE_SIZE 
    113     doesn't straddle page boundary. This allows FxPoolFree to determine whether 
    114     a header is added to buffer or not based on whether the pointer passed in 
    115     is page aligned or not. (In addition, when pool tracking is ON, this 
    116     routine adds pool tracking header based on whether additional space for this 
    117     header will push the buffer size beyond PAGE_SIZE, which is an optimization.) 
    118  
    119     Such guarantees are not available with user mode allocator, hence in case 
    120     of user mode we always add the header. (In user mode a buffer < PAGE_SIZE 
    121     can straddle page boundary and the pointer returned may happen to be page 
    122     aligned, causing FxPoolFree to free the wrong pointer.) 
    123  
    124 --*/ 
    125 { 
    126     PVOID ptr; 
    127     PCHAR pTrueBase; 
    128     PFX_POOL_TRACKER pTracker; 
    129     PFX_POOL_HEADER pHeader; 
    130     NTSTATUS status; 
    131     SIZE_T allocationSize; 
    132 
     
    133 
     
    134     ptr = NULL; 
    135 
     
    136     // 
    137     // Allocations of a zero request size are invalid. 
    138     // 
    139     // Besides, with a zero request size, special pool could place us 
    140     // at the end of a page, and adding our header would give us a page 
    141     // aligned address, which is ambiguous with large allocations. 
    142     // 
    143     if (Size == 0) { 
    144         DoTraceLevelMessage(FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPOOL, 
    145                             "Invalid Allocation Size of 0 requested"); 
    146         FxVerifierDbgBreakPoint(FxDriverGlobals); 
    147         return NULL; 
    148     } 
    

    you throw an exception instead of no allocate... am I right?

    Thursday, December 17, 2015 1:42 PM