How to solve the bsod caused by cccopyread?

My driver has a BSOD with a very low probability of recurrence,

IRQL_NOT_LESS_OR_EQUAL (a)
An attempt was made to access a pageable (or completely invalid) address at an
interrupt request level (IRQL) that is too high.  This is usually
caused by drivers using improper addresses.
If a kernel debugger is available get the stack backtrace.
Arguments:
Arg1: 0000000018800111, memory referenced
Arg2: 0000000000000002, IRQL
Arg3: 0000000000000001, bitfield :
	bit 0 : value 0 = read operation, 1 = write operation
	bit 3 : value 0 = not an execute operation, 1 = execute operation (only on chips which support this level of status)
Arg4: fffff80424257d38, address which referenced memory


My Stack:
STACK_TEXT:  
ffffdd09`92d567a8 fffff804`2422bf29     : 00000000`0000000a 00000000`18800111 00000000`00000002 00000000`00000001 : nt!KeBugCheckEx
ffffdd09`92d567b0 fffff804`24227389     : 00001000`00000000 00000000`00000000 ffff8008`20d9d3b0 fffff804`00001000 : nt!KiBugCheckDispatch+0x69
ffffdd09`92d568f0 fffff804`24257d38     : ffffdd09`92d56ad8 00000000`00000001 ffff8008`00000003 ffffcb80`3f000000 : nt!KiPageFault+0x489
ffffdd09`92d56a80 fffff804`24257bf4     : ffffcb80`3f051180 ffff8008`21ac71a0 ffff8008`20d9d300 00000000`00000000 : nt!KxWaitForLockOwnerShipWithIrql+0x50
ffffdd09`92d56ae0 fffff804`2413b4f6     : ffff8008`20d9d270 ffff8008`4b07b9d0 ffff8008`20d9d368 ffff8008`20d9d358 : nt!KiAcquireQueuedSpinLockInstrumented+0x66
ffffdd09`92d56b20 fffff804`21dc8b41     : ffff8008`25ae1010 ffffdd09`92d56be9 00000000`00000004 00000000`00000000 : nt!KeAcquireInStackQueuedSpinLock+0xa6
ffffdd09`92d56b50 fffff804`21dc85e0     : ffff8008`20d9d200 00000000`00000000 00000000`00060400 00000000`00000000 : FLTMGR!FltpPerformPostCallbacksWorker+0x1b1
ffffdd09`92d56c20 fffff804`21dca741     : ffffdd09`92d51000 ffffdd09`92d58000 ffff8008`20d9d270 00000000`00000001 : FLTMGR!FltpPassThroughCompletionWorker+0x120
ffffdd09`92d56cd0 fffff804`21dc7e43     : ffffdd09`92d56d60 00000000`c0000005 00000000`00000000 fffff804`244a4f42 : FLTMGR!FltpLegacyProcessingAfterPreCallbacksCompleted+0x6a1
ffffdd09`92d56d40 fffff804`24112695     : ffff8008`255039d0 fffff804`2404fe87 ffff8008`255039d0 ffff8008`2dd44080 : FLTMGR!FltpDispatch+0xa3
ffffdd09`92d56da0 fffff804`2407f7c7     : ffff8008`2f043b40 ffff8008`37ec76a8 00000000`00000403 00000000`00000002 : nt!IofCallDriver+0x55
ffffdd09`92d56de0 fffff804`2400cef8     : ffff8008`1d89c5c0 fffff804`24143398 ffff8008`1d89c620 ffff8008`1d89c5e0 : nt!IoPageReadEx+0x2d7
ffffdd09`92d56e50 fffff804`244a408b     : ffff8008`1d89c5c0 ffff8008`2dd44080 ffff8008`1d89c6d0 00000000`00000001 : nt!MiPageRead+0x28
ffffdd09`92d56ea0 fffff804`244a3ed6     : ffffdd09`92d57018 00000000`00000001 ffff8008`2dd44080 00000000`00000000 : nt!MiPfExecuteReadList+0xf3
ffffdd09`92d56f10 fffff804`24022003     : ffff8008`37ec7630 00000000`00001000 00000000`00001000 00000000`00000000 : nt!MmPrefetchForCacheManager+0x10a
ffffdd09`92d56f90 fffff804`244a7603     : 00000000`00000000 00000000`00000000 ffff8008`2f045a80 00000000`00000018 : nt!CcFetchDataForRead+0x123
ffffdd09`92d56ff0 fffff804`2401e29b     : ffff8008`2f045a80 00000000`00000000 00000000`00000000 ffff8008`190d5201 : nt!CcMapAndCopyFromCache+0xf3
ffffdd09`92d570b0 fffff804`245998e3     : 00000000`00000000 00000000`00000000 ffff8008`00000018 ffff8008`28cbc101 : nt!CcCopyReadEx+0x22b
ffffdd09`92d57170 fffff804`3f738aa0     : ffff8008`28cbc0f8 00000000`00000018 00000000`00000000 00000000`00000000 : nt!CcCopyRead+0x23
ffffdd09`92d571c0 fffff804`3f7371b2     : ffff8008`28cbc0f8 ffffdd09`92d57560 ffff8008`2a2f8730 ffffdd09`92d57579 : MyDrv!MyFsdCommonRead+0x11d0 [d:\MyFsdRead.c @ 1011] 
ffffdd09`92d57480 fffff804`21dc963b     : ffff8008`28cbc0f8 ffffdd09`92d57560 ffffdd09`92d57538 ffffdd09`92d57500 : MyDrv!PtPreOperationRead+0x102 [d:\MyFsdRead.c @ 205] 
ffffdd09`92d574d0 fffff804`21dc90c1     : ffffdd09`92d576f0 00000000`00000003 00000000`00000000 00000000`00000000 : FLTMGR!FltpPerformPreCallbacksWorker+0x37b
ffffdd09`92d575e0 fffff804`21dc8049     : ffffdd09`92d58000 ffffdd09`92d51000 00000000`00000000 ffffdd09`92d57700 : FLTMGR!FltpPassThroughInternal+0xd1
ffffdd09`92d57630 fffff804`21dc7e2b     : 00000000`00000042 00000000`00000000 00000000`00000200 ffff8008`00000000 : FLTMGR!FltpPassThrough+0x179
ffffdd09`92d576d0 fffff804`24112695     : ffff8008`265eb990 fffff804`2424aee8 ffff8008`1d6cdd30 00000000`00000001 : FLTMGR!FltpDispatch+0x8b
ffffdd09`92d57730 fffff804`245c3590     : ffff8008`265eb990 ffffdd09`92d577d1 ffffdd09`92d577d1 00000000`4af5d900 : nt!IofCallDriver+0x55
ffffdd09`92d57770 fffff804`245e1114     : 00000000`00000000 00000000`00000000 00000000`00000000 ffff8008`2f045a80 : nt!IopSynchronousServiceTail+0x1d0
ffffdd09`92d57820 fffff804`245e0c0b     : ffff8008`2f045a80 00000000`00000000 00000000`00000000 00000000`4af5d968 : nt!IopReadFile+0x4d4
ffffdd09`92d57920 fffff804`2422b605     : ffff8008`2dd44080 ffffdd09`92d57aa0 00000000`4af5d8d8 ffffdd09`92d579c8 : nt!NtReadFile+0xdb
ffffdd09`92d579b0 00007ffe`fd3101f4     : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : nt!KiSystemServiceCopyEnd+0x25
00000000`4af5d8b8 00000000`00000000     : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : 0x00007ffe`fd3101f4

function MyFsdCommonRead :

			if (!FlagOn(IrpContext->MinorFunction, IRP_MN_MDL)) {

				CHAR* DecryptBuf = NULL;
				SystemBuffer = MyFsdMapUserBuffer( Data );
				
				if (!CcCopyRead( FileObject,
					(PLARGE_INTEGER)&StartingByte,
					(ULONG)ByteCount,
					Wait,
					SystemBuffer,
					&Data->IoStatus )) 
				{

					try_return( PostIrp = TRUE );
				}

dv:
Wait = 0x01 ''

StartingByte = {0}

FltObjects = 0xffffdd09`92d57560

ByteCount = 0x18 

SystemBuffer = 0x00000000`4af5d988

I suspect there is something wrong with my buffering.

2: kd> db 0x00000000`4af5d988
00000000`4af5d988  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
00000000`4af5d998  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
00000000`4af5d9a8  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
00000000`4af5d9b8  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
00000000`4af5d9c8  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
00000000`4af5d9d8  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
00000000`4af5d9e8  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
00000000`4af5d9f8  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????

Does this mean that the buffer cannot be read or written??

Part of the code of MyFsdMapUserBuffer function

		SystemBuffer = MmGetSystemAddressForMdlSafe(MdlAddress, NormalPagePriority);

		if (SystemBuffer == NULL)
		{
			X70FsdRaiseStatus(NULL, STATUS_INSUFFICIENT_RESOURCES);
		}

		return SystemBuffer;

Is there something wrong with my call to MmGetSystemAddressForMdlSafe, or is it that I cannot use this function at all in this place?

Is the Data variable allocated from the paged pool?

hi Mulleteer
I checked the information of Data.
2: kd> dv
DecryptBuf = 0x00000000`00000000 ""

               Data = 0xffff8008`28cbc0f8
         FltObjects = 0xffffdd09`92d57560
         IrpContext = 0xffff8008`2a2f8730

2: kd> !pool 0xffff8008`28cbc0f8
Pool page ffff800828cbc0f8 region is Nonpaged pool
*ffff800828cbc000 size: 5c0 previous size: 0 (Allocated) *FMic
Pooltag FMic : IRP_CTRL structure, Binary : fltmgr.sys
ffff800828cbc5c0 size: 80 previous size: 0 (Free) ...a
ffff800828cbc650 size: 300 previous size: 0 (Allocated) MmCi
ffff800828cbc960 size: 270 previous size: 0 (Allocated) CcSc
ffff800828cbcbd0 size: 20 previous size: 0 (Free) X..a
ffff800828cbcc00 size: 290 previous size: 0 (Allocated) Wfpn
ffff800828cbce90 size: 150 previous size: 0 (Free) Z..a

Obviously, it is in the non-paged pool

Personally I would check the MDL structure that you're passing to this function when the bug check happens. If the MdlAddress object has been released or corrupted you may get an invalid pointer as a return value. (MdlFlags matches the bits and MappedSystemVa points to some random location, Look the implementation in wdm.h).

thanks

I will add relevant code to my code, but how does this happen? This part of the data is passed to me by the system.

If I return an error directly, will it cause the READ IRP to fail and cause an application error?

I would review the locking that you are doing to protect your SOP. Make sure you have appropriate locking around all your cc operations.

Can you be a little more specific? For example, what things need to be protected?

It could be for any reason, just guessing without seeing the whole code. At least but not limited to:

  • Irp is pending and has been cancelled
  • The same file object is simultaneously read and closed from two threads
  • Array overruns somewhere in your code

If you've used Microsoft drivers samples as basis of your implementation be aware that they may have bugs too. Don't assume the bug is in your additions.

Thank you for your reply.
My code comes from Microsoft's fastfat, in read.c
................
if ( StartingVbo + ByteCount > ValidDataLength ) {

SystemBuffer = FatMapUserBuffer( IrpContext, Irp );

if (StartingVbo < ValidDataLength) {

if (Irp->MdlAddress == NULL) {

return Irp->UserBuffer;

}
............

FatMapUserBuffer function
.........
PVOID Address = MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority | MdlMappingNoExecute );

if (Address == NULL) {

ExRaiseStatus( STATUS_INSUFFICIENT_RESOURCES );
}

return Address;
}
...........
Why doesn't he need to do any security checks? Multi-threaded access to files or cancellation of irp are upper-level operations. Won't he encounter these problems?

So, you are a filesystem or you are pretending to be one, either way you are filling in the file object you get given and completing the IRP_MJ_CREATE you got sent.

One of the fields you filled in was fileObject->SectionObjectPointers you need to make sure that all the operations that look that up (mostly they start Cc but some start Mm and there are others) are called with the correct lock held.

Fat does all this, but it isnt obvious; however if you based your locking on that you’ll not go far wrong.

And by the way, it is rare but non un heard of to have an MDL in a non paging read so its worth poking at that when you are looking for a repro.

hi rod_widdowson

I have two questions

  1. This problem is not inevitable. If there is a problem with my fileObject->SectionObjectPointers, why is there no problem with reading and writing most of the time? Or is this object not used at other times?

  2. Can I write my own application code to simulate the use mdl in non-paged read?Or use filetest.exe to simulate this action?

That is the nature of timing windows. That's we have locks.

Not directly. You need to look at the dump and see what the application oruser mode entity was that issued these operations. Also look for third party products.

At a SWAG this is from SVR in which case you might be able to provoke the issue (indirectly) by provoking MUP.

I'd not scientific but "get a feel" for the dump. What is the file name? why have you been called? What else is going on inside you FSD that sort of stuff. None of it it immediately useful but it can give you the bigger picture and can point you onwards (kernel debugging 101 I guess)

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.