0xA bugcheck in RtlInitializeBitmap

Bugcheck: 0xA (IRQL_NOT_LESS_OR_EQUAL)
Param 2: 2 (DPC)
Param 3: 0x8 (Execute)

Param 1 and Param 4 are both the address of RtlInitializeBitmap.
This is inside a spinlock (as the bitmap is accessed during all sorts
of read/write requests), and only with Verifier IRQL checking enabled.

Which would make perfect sense if either the API itself, or the memory
accessed (Header and bitmap data region) were in paged pool. But they
are not…

Is the verifier faulting without a reason, the API documentation
incorrect (the API cannot be called at DPC level even though neither
the header nor the data is in paged pool), or am I missing something?

What OS? Remember I mentioned a bug in this routine in Win 7 when called above IRQL PASSIVE_LEVEL?

Peter

Yep, that was it :frowning: W7.
I did remember you mentioned something about the RtlxxxBits functions,
but not it being in paged code in particular.

Thanks.

How do I tell if a code page is paged or nonpaged pool? (Yes, I am
quite a bit out of touch, I had about a 3 year hiatus from kernel
programming and debugging :))

What OS? Remember I mentioned a bug in this routine in Win 7 when called
above IRQL PASSIVE_LEVEL?

What is supposed to happen is that you can look at the documentation for RtlInitializeBitMap, and it says that it’s callable at IRQL < DISPATCH_LEVEL. But I see that the documentation doesn’t mention that Windows 7 and earlier had more restrictive requirements. So there’s a doc bug here. The doc should say something like this:

IRQL: Any IRQL.
Windows 7 and earlier: <= APC_LEVEL
Note that this routine must be called at <= APC_LEVEL if the bitmap header is stored in pageable memory.

Above is the engineer’s answer to your question. But I can’t help but provide the nerd’s answer too. You can prove that a function is not callable at DISPATCH_LEVEL by using the debugger’s !dh command to calcualte which segment a function is in. Note, however, that you cannot prove the inverse: just because a function is located in a non-paged segment doesn’t give you permission to call it at DISPATCH_LEVEL. (Perhaps it touches pageable pool, for example.)

kd> ? nt!RtlInitializeBitMap - nt
Evaluate expression: 3726372 = 00000000`0038dc24

kd> !dh nt
SECTION HEADER #C
    PAGE name
  23597E virtual size
  2C6000 virtual address

kd> ? 23597E + 2C6000 
Evaluate expression: 5224830 = 00000000`004fb97e

First, we calculate the RVA (relative virtual address) of the function, relative to the top of the module. Then we skim through the module’s sections until we find one that contains that RVA. Since 2C6000 <= 0038dc24 <= 004fb97e, you know that RtlInitializeBitMap is contained in the PAGE section. By default, any section whose name begins with the 4 ascii characters ‘P’, ‘A’, ‘G’, and ‘E’ will automatically be made pageable by the memory manager. So you can conclude that it is never safe to call RtlInitializeBitMap at DISPATCH_LEVEL on this version of the kernel. (This discussion applies to Windows 7. Windows 8 moved this routine to the .text section, and more importantly, made a documented guarantee that you can use the function at any IRQL.)

Thank you, Jeff, that is exactly what I needed!

FYI, docs say it is callable at any IRQL if the header and data are nonpaged. The Windows 7 note needs to be added.

The activities of RtlInitializeBitMap aren’t that difficult to figure out. What WE do, is if we’re called at IRQL > DISPATCH_LEVEL and we’re on Win7, we just “do the initialization ourselves”… from this thread:

Looks like this function does not do anything more except intialize RTL structure.
If I do Following instead of RtlInitializebitmap, It works fine:

pRtlBitmap->Buffer = myBuffer;
pRtlBitmap->SizeOfBitmap = _myBufferSizeInBits;

docs say it is callable at any IRQL if the header and data are nonpaged. The Windows 7 note needs to be added.

Just click “Edit”… and help the guy who comes after you, right??

Peter

GitHub does not work with IE11 any more, and other browsers are a
major pain for me (visually impaired).
I tend to submit feedback to the DDI docs instead. That works.

> docs say it is callable at any IRQL if the header and data are nonpaged.
> The Windows 7 note needs to be added.

Just click “Edit”… and help the guy who comes after you, right??

To close the loop, I see that @“Jeffrey_Tippet_[MSFT]” has put in a doc bug on github. Thanks