DRIVER_VERIFIER_DETECTED_VIOLATION

Hi, I am currently debugging my File System Driver with the verifier tool. I try to pull out the USB cable while reading a file from the file system which resides on an external SSD.

I am getting the following BSOD claiming that “The IRP can only be completed with STATUS_SUCCESS.” I tried to impose a success to the status to the **FFSPnpSurpriseRemove **and **FFSPnpRemove **functions without success, could you please guide me what is the correct way to solve this issue?


  •                                                                         *
    
  •                    Bugcheck Analysis                                    *
    
  •                                                                         *
    

DRIVER_VERIFIER_DETECTED_VIOLATION (c4)
A device driver attempting to corrupt the system has been caught. This is
because the driver was specified in the registry as being suspect (by the
administrator) and the kernel has enabled substantial checking of this driver.
If the driver attempts to corrupt the system, bugchecks 0xC4, 0xC1 and 0xA will
be among the most commonly seen crashes.
Arguments:
Arg1: 0000000000043006, ID of the ‘PnpRemove’ rule that was violated.
Arg2: fffff8071d9a8178, A pointer to the string describing the violated rule condition.
Arg3: 0000000000000000, Reserved (unused).
Arg4: 0000000000000000, Reserved (unused).

Debugging Details:

Page 2007b70cf too large to be in the dump file.

KEY_VALUES_STRING: 1

PROCESSES_ANALYSIS: 1

SERVICE_ANALYSIS: 1

STACKHASH_ANALYSIS: 1

TIMELINE_ANALYSIS: 1

DUMP_CLASS: 1

DUMP_QUALIFIER: 401

BUILD_VERSION_STRING: 18362.1.amd64fre.19h1_release.190318-1202

SYSTEM_MANUFACTURER: HP

SYSTEM_PRODUCT_NAME: HP Z8 G4 Workstation

SYSTEM_SKU: Z3Z16AV

BIOS_VENDOR: HP

BIOS_VERSION: P60 v01.67

BIOS_DATE: 08/15/2018

BASEBOARD_MANUFACTURER: HP

BASEBOARD_PRODUCT: 81C7

BASEBOARD_VERSION: MVB 0C

DUMP_TYPE: 1

BUGCHECK_P1: 43006

BUGCHECK_P2: fffff8071d9a8178

BUGCHECK_P3: 0

BUGCHECK_P4: 0

DV_VIOLATED_CONDITION: The IRP can only be completed with STATUS_SUCCESS.

DV_MSDN_LINK: https://go.microsoft.com/fwlink/?LinkId=296842

DV_RULE_INFO: 0x43006

BUGCHECK_STR: 0xc4_PnpRemove_XDV

CPU_COUNT: 10

CPU_MHZ: 6a0

CPU_VENDOR: GenuineIntel

CPU_FAMILY: 6

CPU_MODEL: 55

CPU_STEPPING: 4

CPU_MICROCODE: 6,55,4,0 (F,M,S,R) SIG: 200005E’00000000 (cache) 200005E’00000000 (init)

BLACKBOXBSD: 1 (!blackboxbsd)

BLACKBOXNTFS: 1 (!blackboxntfs)

BLACKBOXPNP: 1 (!blackboxpnp)

BLACKBOXWINLOGON: 1

DEFAULT_BUCKET_ID: WIN8_DRIVER_FAULT

PROCESS_NAME: System

CURRENT_IRQL: 0

ANALYSIS_SESSION_HOST: KROYTER_LT

ANALYSIS_SESSION_TIME: 07-02-2020 12:58:29.0618

ANALYSIS_VERSION: 10.0.18362.1 amd64fre

LAST_CONTROL_TRANSFER: from fffff8071d995386 to fffff8071c7df3a0

STACK_TEXT:
ffff8e06d6ca1ac8 fffff8071d995386 : 00000000000000c4 0000000000043006 fffff8071d9a8178 0000000000000000 : nt!KeBugCheckEx
ffff8e06d6ca1ad0 fffff8071d993a89 : 0000000000043006 0000000000043006 ffffbc8b0783d210 0000000000000000 : VerifierExt!XdvInitiateBugcheck+0x3a
ffff8e06d6ca1b10 fffff8071d980043 : ffffbc8b05bbcf40 ffffbc8b0783d210 ffffbc8b07a26b80 0000000000000000 : VerifierExt!XdvUnifiedBugCheck+0x239
ffff8e06d6ca1b80 fffff8071d98008e : 0000000000400000 ffffbc8a0000004a 0000000000000000 0000000000000000 : VerifierExt!SLIC_IofCompleteRequest_entry_PnpRemove+0x57
ffff8e06d6ca1bc0 fffff8071cf86480 : ffffbc8b05bbcf40 ffff8e06d6ca1d40 ffffbc8b0783d210 ffffbc8b0783d190 : VerifierExt!IofCompleteRequest_wrapper+0x3e
ffff8e06d6ca1c10 fffff805b1714175 : ffffbc8b05bbcf40 ffffbc8b0783d210 ffffbc8b0783d190 00000000000000c0 : nt!VerifierIofCompleteRequest+0x10
ffff8e06d6ca1c40 fffff805b1713bef : ffffbc8b05bbcf40 ffffbc8b05bbcf40 00000000c000000d 0000000000050282 : NCDRFSV1!FFSPnpSurpriseRemove+0x161 [D:\workspace\NCDRFSv1\pnp.c @ 343]
ffff8e06d6ca1ca0 fffff805b170dcf4 : ffffbc8b05bbcf40 ffffbc8b0783d040 ffffbc8b07a26b80 ffffbc8b07a26b80 : NCDRFSV1!FFSPnp+0xa3 [D:\workspace\NCDRFSv1\pnp.c @ 117]
ffff8e06d6ca1ce0 fffff8071d98d84d : ffffbc8b07a26b80 fffff805b170dc50 ffffbc8b0783d040 ffffbc8b0783d040 : NCDRFSV1!FFSBuildRequest+0xa4 [D:\workspace\NCDRFSv1\dispatch.c @ 221]
ffff8e06d6ca1d20 fffff8071cfa1314 : 000000000000001b ffffbc8b0783d040 ffffbc8af89cf860 ffffbc8ae8f02c80 : VerifierExt!xdv_IRP_MJ_PNP_wrapper+0x9d
ffff8e06d6ca1d50 fffff8071cfa1546 : 0000000000000000 0000000000000000 0000000000000000 ffffbc8ae8f02c80 : nt!ViGenericDispatchHandler+0x40
ffff8e06d6ca1d90 fffff8071c79c78a : 0000000000000000 fffff8071cf8da5c ffffbc8b00000000 ffffbc8b00000000 : nt!ViGenericPnp+0x16
ffff8e06d6ca1dc0 fffff8071cf820a9 : ffffbc8b07a26b80 ffffbc8b0783d040 ffffc48b54588f78 ffffbc8b03c54c50 : nt!IopfCallDriver+0x56
ffff8e06d6ca1e00 fffff8071c83bb7d : ffffbc8ae8f34010 0000000000000000 ffffbc8b07a26f68 ffffbc8ae8f02c80 : nt!IovCallDriver+0x275
ffff8e06d6ca1e40 fffff8071d7355d9 : 0000000000000000 fffff8071cf9cd30 ffffbc8b07a26b80 ffff8e06d6ca1f30 : nt!IofCallDriver+0x184d1d
ffff8e06d6ca1e80 fffff8071d733f16 : ffff8e06d6ca1f20 ffffc48b535ba600 0000000000000001 ffffbc8ae9cef680 : FLTMGR!FltpLegacyProcessingAfterPreCallbacksCompleted+0x159
ffff8e06d6ca1f00 fffff8071c79c78a : ffffbc8b07a26b80 fffff8071cf8da5c ffffbc8b00000001 ffffbc8b00000001 : FLTMGR!FltpDispatch+0xb6
ffff8e06d6ca1f60 fffff8071cf820a9 : ffffbc8b07a26b80 ffffbc8b05dc9ae0 ffffbc8b07a26b80 fffff8071cf8df69 : nt!IopfCallDriver+0x56
ffff8e06d6ca1fa0 fffff8071c83bb7d : ffffbc8b05dc9ae0 ffff8e06d6ca2080 ffff8e06d6ca20e0 ffffc48b54588ec0 : nt!IovCallDriver+0x275
ffff8e06d6ca1fe0 fffff8071cc8e324 : ffff8e06d6ca2080 ffffbc8b05dc9ae0 ffff8e06d6ca20e0 ffffbc8b07a26b80 : nt!IofCallDriver+0x184d1d
ffff8e06d6ca2020 fffff8071cd4eb7a : 0000000000000017 ffffbc8b0783fc40 ffffbc8b03c54c50 ffffbc8b0783fc40 : nt!IopSynchronousCall+0xf8
ffff8e06d6ca20a0 fffff8071cd4e739 : ffffdd0f18ab17d0 0000000000000000 0000000000000308 0000000000000000 : nt!IopRemoveDevice+0x106
ffff8e06d6ca2160 fffff8071cd4e4fb : ffffbc8b0783fc40 0000000000000000 0000000000000000 0000000000000000 : nt!PnpSurpriseRemoveLockedDeviceNode+0xb5
ffff8e06d6ca21c0 fffff8071cd4e1ca : ffffbc8b0783fc40 ffff8e06d6ca2240 0000000000000000 fffff8071cd4def1 : nt!PnpDeleteLockedDeviceNode+0x57
ffff8e06d6ca2200 fffff8071cd4c9c7 : ffffbc8b03c54c50 0000000200000002 0000000000000002 0000000000000000 : nt!PnpDeleteLockedDeviceNodes+0x76
ffff8e06d6ca2280 fffff8071cd261ae : ffff8e06d6ca23d0 ffffbc8b0783fc00 ffff8e06d6ca2400 ffffdd0f00000002 : nt!PnpProcessQueryRemoveAndEject+0x1ef
ffff8e06d6ca2370 fffff8071cbe66d8 : ffffdd0f18ab17d0 ffffdd0f17771a40 ffffdd0f17771a40 0000000000000000 : nt!PnpProcessTargetDeviceEvent+0xea
ffff8e06d6ca23a0 fffff8071c6a0945 : ffffc48b4ae02c90 ffffbc8ae8f71040 ffffc48b4ae02c90 ffffbc8b061f2d68 : nt!PnpDeviceEventWorker+0x2d8
ffff8e06d6ca2430 fffff8071c73b135 : ffffbc8ae8f71040 0000000000000080 ffffbc8ae5cd9300 0000347fbd9bbfff : nt!ExpWorkerThread+0x105
ffff8e06d6ca24d0 fffff8071c7e69a8 : ffff98809a886180 ffffbc8ae8f71040 fffff8071c73b0e0 fffff8071c7e5db5 : nt!PspSystemThreadStartup+0x55
ffff8e06d6ca2520 0000000000000000 : ffff8e06d6ca3000 ffff8e06d6c9c000 0000000000000000 0000000000000000 : nt!KiStartSystemThread+0x28

THREAD_SHA1_HASH_MOD_FUNC: 4a6536d844c32c22633ce2eb6632c3654b69127a

THREAD_SHA1_HASH_MOD_FUNC_OFFSET: 991df832ec8f09a7484a74012b1232d518d9be27

THREAD_SHA1_HASH_MOD: 6c3869616665c459e28a2d50fc755e84b50b8b9d

FOLLOWUP_IP:
NCDRFSV1!FFSPnpSurpriseRemove+161 [D:\workspace\NCDRFSv1\pnp.c @ 343]
fffff805`b1714175 4883630800 and qword ptr [rbx+8],0

FAULT_INSTR_CODE: 8638348

FAULTING_SOURCE_LINE: D:\workspace\NCDRFSv1\pnp.c

FAULTING_SOURCE_FILE: D:\workspace\NCDRFSv1\pnp.c

FAULTING_SOURCE_LINE_NUMBER: 343

FAULTING_SOURCE_CODE:
339: __finally
340: {
341: FFSCompleteRequest( IrpContext->Irp, (CCHAR)(NT_SUCCESS(Status)? IO_DISK_INCREMENT : IO_NO_INCREMENT));
342: Status = STATUS_SUCCESS; // ID of the ‘PnpRemove’ rule that was violated: The IRP can only be completed with STATUS_SUCCESS

343: IrpContext->Irp = NULL;
344: }
345:
346: return Status;
347: }
348:

SYMBOL_STACK_INDEX: 6

SYMBOL_NAME: NCDRFSV1!FFSPnpSurpriseRemove+161

FOLLOWUP_NAME: MachineOwner

MODULE_NAME: NCDRFSV1

IMAGE_NAME: NCDRFSV1.sys

DEBUG_FLR_IMAGE_TIMESTAMP: 5efda317

STACK_COMMAND: .thread ; .cxr ; kb

BUCKET_ID_FUNC_OFFSET: 161

FAILURE_BUCKET_ID: 0xc4_PnpRemove_XDV_VRF_NCDRFSV1!FFSPnpSurpriseRemove

BUCKET_ID: 0xc4_PnpRemove_XDV_VRF_NCDRFSV1!FFSPnpSurpriseRemove

PRIMARY_PROBLEM_CLASS: 0xc4_PnpRemove_XDV_VRF_NCDRFSV1!FFSPnpSurpriseRemove

TARGET_TIME: 2020-07-02T09:36:19.000Z

OSBUILD: 18362

OSSERVICEPACK: 0

SERVICEPACK_NUMBER: 0

OS_REVISION: 0

SUITE_MASK: 272

PRODUCT_TYPE: 1

OSPLATFORM_TYPE: x64

OSNAME: Windows 10

OSEDITION: Windows 10 WinNt TerminalServer SingleUserTS

OS_LOCALE:

USER_LCID: 0

OSBUILD_TIMESTAMP: 2012-07-07 00:22:33

BUILDDATESTAMP_STR: 190318-1202

BUILDLAB_STR: 19h1_release

BUILDOSVER_STR: 10.0.18362.1.amd64fre.19h1_release.190318-1202

ANALYSIS_SESSION_ELAPSED_TIME: 2546

ANALYSIS_SOURCE: KM

FAILURE_ID_HASH_STRING: km:0xc4_pnpremove_xdv_vrf_ncdrfsv1!ffspnpsurpriseremove

FAILURE_ID_HASH: {9b64180c-e712-f000-17c2-71ac24eba35c}

Followup: MachineOwner

What’s the value of IrpContext->Irp->IoStatus.Status? Here Verifier cares about the value in the IRP and not whatever value you’re returning (which should match and is a different Verifier violation).

Scott, hi,

thanks for the prompt response.

I didn’t have the chance to debug it. Though following is the removal function:

NTSTATUS
FFSPnpRemove(
PFFS_IRP_CONTEXT IrpContext,
PFFS_VCB Vcb)
{
PAGED_CODE()

NTSTATUS Status = STATUS_ACCESS_DENIED;
KEVENT   Event;
BOOLEAN  bDeleted;

__try
{

#ifdef DBG
DbgPrint(DRIVER_NAME “FFSPnpRemove by FFSPnp …\n”);
#endif
#if (_WIN32_WINNT >= 0x0500)
CcWaitForCurrentLazyWriterActivity();
#endif
ExAcquireResourceExclusiveLite( &Vcb->MainResource, TRUE);
Status = FFSLockVcb(Vcb, IrpContext->FileObject);
ExReleaseResourceForThreadLite( &Vcb->MainResource, ExGetCurrentResourceThread());

	if ( !(NT_SUCCESS(Status) )	)
		__leave;

	//
	// Setup the Irp. We'll send it to the lower disk driver.
	//

	IoCopyCurrentIrpStackLocationToNext(IrpContext->Irp);
	KeInitializeEvent(&Event, NotificationEvent, FALSE);
	IoSetCompletionRoutine(IrpContext->Irp, FFSPnpCompletionRoutine, &Event, TRUE, TRUE, TRUE);

	Status = IoCallDriver(Vcb->TargetDeviceObject, IrpContext->Irp);

	if (Status == STATUS_PENDING)
	{
		KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
		Status = IrpContext->Irp->IoStatus.Status;
	}

	ExAcquireResourceExclusiveLite( &Vcb->MainResource, TRUE);
	FFSPurgeVolume(Vcb, FALSE);
	ExReleaseResourceForThreadLite( &Vcb->MainResource, ExGetCurrentResourceThread());

	bDeleted = FFSCheckDismount(IrpContext, Vcb, TRUE);
}

__finally
{
	FFSCompleteRequest( IrpContext->Irp, (CCHAR)(NT_SUCCESS(Status)? IO_DISK_INCREMENT : IO_NO_INCREMENT));
	IrpContext->Irp = NULL;
	//Status = STATUS_SUCCESS; // ID of the 'PnpRemove' rule that was violated: The IRP can only be completed with STATUS_SUCCESS
}

return Status;

}

I guess that the driver below set the value of IrpContext->Irp->IoStatus.Status, if it is not of SUCCESS type should I impose it?

Scott, hi,

thanks for your prompt reply.
Following is the removal function:
NTSTATUS
FFSPnpRemove(
PFFS_IRP_CONTEXT IrpContext,
PFFS_VCB Vcb)
{
PAGED_CODE()

NTSTATUS Status = STATUS_ACCESS_DENIED;
KEVENT   Event;
BOOLEAN  bDeleted;

__try
{

#ifdef DBG
DbgPrint(DRIVER_NAME “FFSPnpRemove by FFSPnp …\n”);
#endif
#if (_WIN32_WINNT >= 0x0500)
CcWaitForCurrentLazyWriterActivity();
#endif
ExAcquireResourceExclusiveLite( &Vcb->MainResource, TRUE);
Status = FFSLockVcb(Vcb, IrpContext->FileObject);
ExReleaseResourceForThreadLite( &Vcb->MainResource, ExGetCurrentResourceThread());

	if ( !(NT_SUCCESS(Status) )	)
		__leave;

	//
	// Setup the Irp. We'll send it to the lower disk driver.
	//

	IoCopyCurrentIrpStackLocationToNext(IrpContext->Irp);
	KeInitializeEvent(&Event, NotificationEvent, FALSE);
	IoSetCompletionRoutine(IrpContext->Irp, FFSPnpCompletionRoutine, &Event, TRUE, TRUE, TRUE);

	Status = IoCallDriver(Vcb->TargetDeviceObject, IrpContext->Irp);

	if (Status == STATUS_PENDING)
	{
		KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
		Status = IrpContext->Irp->IoStatus.Status;
	}

	ExAcquireResourceExclusiveLite( &Vcb->MainResource, TRUE);
	FFSPurgeVolume(Vcb, FALSE);
	ExReleaseResourceForThreadLite( &Vcb->MainResource, ExGetCurrentResourceThread());

	bDeleted = FFSCheckDismount(IrpContext, Vcb, TRUE);
}

__finally
{
	FFSCompleteRequest( IrpContext->Irp, (CCHAR)(NT_SUCCESS(Status)? IO_DISK_INCREMENT : IO_NO_INCREMENT));
	IrpContext->Irp = NULL;
	//Status = STATUS_SUCCESS; // ID of the 'PnpRemove' rule that was violated: The IRP can only be completed with STATUS_SUCCESS
}

return Status;

}

I guess that the value of IrpContext->Irp->IoStatus.Status is set by the invoked driver. Should I modify it?

Status came from either FFSLockVcb or the lower drivers. I’d suspect FFSLockVcb is the culprit.

This handling of surprise removal is wrong in any case because you can’t ever fail the request. You pass the request down first and then make a best effort to tear down what you can.

The FFSLockVcb is invoked to serialize access to the Vcb “object”. Should I ignore the FFSLockVcb and send the driver the command as is?

This isn’t my code so I have absolutely no idea…You need to “do what you need to do” to handle the surprise removal.

The volume is physically gone at this point so you can’t fail the request. However, there might still be references/open files so you need to get into a state where you fail subsequent operations. See FASTFAT for an example:

https://github.com/microsoft/Windows-driver-samples/blob/master/filesys/fastfat/pnp.c#L655