Why I got a bugcheck in encryption filter?

I am having a problem with my encryption filter.
I created a function to handle the write requests(IRP_MJ_WRITE).

typedef struct _Write_CONTEXT {
PMDL OriginalMDL;
PVOID System;
PVOID User;
} Write_CONTEXT, *PWrite_CONTEXT;

{
case IRP_MJ_WRITE:

PIO_STACK_LOCATION currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
if( Irp->Flags & (IRP_NOCACHE | IRP_PAGING_IO |
IRP_SYNCHRONOUS_PAGING_IO) )
{
ULONG WriteLength = currentIrpStack->Parameters.Write.Length;
PVOID pbuf;
ULONG i;

if(Irp->MdlAddress != NULL)
{
pbuf = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
}
else
{
pbuf = Irp->UserBuffer;
}

WriteContext = ExAllocatePool( NonPagedPool, sizeof(Write_CONTEXT));
WriteContext->System = ExAllocatePool( NonPagedPool, WriteLength);
RtlCopyMemory(WriteContext->System, pbuf, WriteLength);

// here encrypt the data
for (i=0; i {
*( (BYTE *)WriteContext->SystemVirtual + i ) = ( (BYTE
)WriteContext->SystemVirtual + i ) + 1;
}

// save the original Mdl
WriteContext->OriginalMDL = Irp->MdlAddress;
Irp->MdlAddress = NULL;

//build a new MDL
IoAllocateMdl( WriteContext->System, WriteLength, FALSE, TRUE, Irp);
MmProbeAndLockPages(Irp->MdlAddress, Irp->RequestorMode, IoReadAccess);
//Lock the user address space
WriteContext->User = MmMapLockedPages(Irp->MdlAddress,
Irp->RequestorMode);

//Set Complete Routine
IoSetCompletionRoutine( Irp, WriteCompleteRoutine, (PVOID)WriteContext,
TRUE, TRUE, TRUE);

IoCopyCurrentIrpStackLocationToNext(Irp);
IoCallDriver( FileSystem, Irp );
}

And in my completionRoutine, I free the buffers.
NTSTATUS
WriteCompleteRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{

PWrite_CONTEXT WriteContext;
WriteContext = (PWrite_CONTEXT)Context;

MmUnmapLockedPages(WriteContext->User, Irp->MdlAddress);
MmUnlockPages(Irp->MdlAddress);
IoFreeMdl(Irp->MdlAddress);
Irp->MdlAddress = WriteContext->OriginalMDL;
ExFreePool(WriteContext->System);
ExFreePool(WriteContext);
if( Irp->PendingReturned )
{
IoMarkIrpPending( Irp );
}
return Irp->IoStatus.Status;
}

The code worked well when i just write one file at a time. If I write
several files at the same time ,it cause
page fault,and a KMODE_EXCEPTION_NOT_HANDLE bsod raise.

Anybody can tell me why?

Regards

At your completion, you don’t test if you have locked
the pages (before calling MmUnmapLockedPages)

L.

Diagnosing the cause of a bug check is not easy when only presented with
the code and a comment that you received a bug check. At a minimum, you
should include:

  • The bug check data (stop code + parameters)
  • The output from “!analyze -v” in the kernel debugger

In my quick glance at the code I noticed the following problems:

  • You do not build the MDL correctly (use MmBuildMdlForNonPagedPool with
    a non-paged pool buffer)
  • You do not update Irp->UserBuffer correctly
  • You do not check for memory allocation failures from ExAllocatePool
  • You should use ExAllocatePoolWithTag NOT ExAllocatePool (this will not
    cause a crash, but is good programming practice.)

Also, you should be running your driver under verifier - it will help
you find bugs more quickly.

Regards,

Tony

Tony Mason
Consulting Partner
OSR Open Systems Resources Inc
http://www.osr.com

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Kathe Zhou
Sent: Friday, April 30, 2004 8:21 AM
To: ntfsd redirect
Subject: [ntfsd] Why I got a bugcheck in encryption filter?

I am having a problem with my encryption filter.
I created a function to handle the write requests(IRP_MJ_WRITE).

typedef struct _Write_CONTEXT {
PMDL OriginalMDL;
PVOID System;
PVOID User;
} Write_CONTEXT, *PWrite_CONTEXT;

{
case IRP_MJ_WRITE:

PIO_STACK_LOCATION currentIrpStack =
IoGetCurrentIrpStackLocation(Irp);
if( Irp->Flags & (IRP_NOCACHE | IRP_PAGING_IO |
IRP_SYNCHRONOUS_PAGING_IO) )
{
ULONG WriteLength = currentIrpStack->Parameters.Write.Length;
PVOID pbuf;
ULONG i;

if(Irp->MdlAddress != NULL)
{
pbuf = MmGetSystemAddressForMdlSafe(Irp->MdlAddress,
NormalPagePriority);
}
else
{
pbuf = Irp->UserBuffer;
}

WriteContext = ExAllocatePool( NonPagedPool, sizeof(Write_CONTEXT));
WriteContext->System = ExAllocatePool( NonPagedPool, WriteLength);
RtlCopyMemory(WriteContext->System, pbuf, WriteLength);

// here encrypt the data
for (i=0; i {
*( (BYTE *)WriteContext->SystemVirtual + i ) = ( (BYTE
)WriteContext->SystemVirtual + i ) + 1;
}

// save the original Mdl
WriteContext->OriginalMDL = Irp->MdlAddress;
Irp->MdlAddress = NULL;

//build a new MDL
IoAllocateMdl( WriteContext->System, WriteLength, FALSE, TRUE, Irp);
MmProbeAndLockPages(Irp->MdlAddress, Irp->RequestorMode,
IoReadAccess);
//Lock the user address space
WriteContext->User = MmMapLockedPages(Irp->MdlAddress,
Irp->RequestorMode);

//Set Complete Routine
IoSetCompletionRoutine( Irp, WriteCompleteRoutine,
(PVOID)WriteContext,
TRUE, TRUE, TRUE);

IoCopyCurrentIrpStackLocationToNext(Irp);
IoCallDriver( FileSystem, Irp );
}

And in my completionRoutine, I free the buffers.
NTSTATUS
WriteCompleteRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{

PWrite_CONTEXT WriteContext;
WriteContext = (PWrite_CONTEXT)Context;

MmUnmapLockedPages(WriteContext->User, Irp->MdlAddress);
MmUnlockPages(Irp->MdlAddress);
IoFreeMdl(Irp->MdlAddress);
Irp->MdlAddress = WriteContext->OriginalMDL;
ExFreePool(WriteContext->System);
ExFreePool(WriteContext);
if( Irp->PendingReturned )
{
IoMarkIrpPending( Irp );
}
return Irp->IoStatus.Status;
}

The code worked well when i just write one file at a time. If I write
several files at the same time ,it cause
page fault,and a KMODE_EXCEPTION_NOT_HANDLE bsod raise.

Anybody can tell me why?

Regards


Questions? First check the IFS FAQ at
https://www.osronline.com/article.cfm?id=17

You are currently subscribed to ntfsd as: xxxxx@osr.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Thanks for your reply. Followed your advice, I modified my code as below.
But sometimes MmGetSystemAddressForMdlSafe(Irp->MdlAddress,
NormalPagePriority) return NULL. This make my system crashed. Why and
What can I do with it?
I also post the output of Windbg.

Regards,

{
case IRP_MJ_WRITE:

PMdl newMdl;
PIO_STACK_LOCATION currentIrpStack =
IoGetCurrentIrpStackLocation(Irp);
if( Irp->Flags & (IRP_NOCACHE | IRP_PAGING_IO |
IRP_SYNCHRONOUS_PAGING_IO) )
{
ULONG WriteLength = currentIrpStack->Parameters.Write.Length;
PVOID pbuf;
ULONG i;

if(Irp->MdlAddress != NULL)
{
pbuf = MmGetSystemAddressForMdlSafe(Irp->MdlAddress,
NormalPagePriority);
if (pbuf == NULL) {DbgPrint(("pbuf(MDL) is NULL"));}
}
else
{
pbuf = Irp->UserBuffer;
if (pbuf == NULL) {DbgPrint(("pbuf(UserBuf) is NULL"));}
}

WriteContext = ExAllocatePoolWithTag( NonPagedPool, sizeof(Write_CONTEXT),
'1gaT' );
if (WriteContext == NULL) {DbgPrint(("WriteContext is NULL"));}
WriteContext->System = ExAllocatePool( NonPagedPool, WriteLength,
'2gaT' );
if (WriteContext->System== NULL) {DbgPrint(("WriteContext->System is
NULL"));}
RtlCopyMemory(WriteContext->System, pbuf, WriteLength);

// save the original Mdl
WriteContext->OriginalMDL = Irp->MdlAddress;
Irp->MdlAddress = NULL;

//build a new MDL
newMdl= IoAllocateMdl( WriteContext->System, WriteLength, FALSE, TRUE,
Irp);
MmBuildMdlForNonPagedPool(newMdl);
MmProbeAndLockPages(Irp->MdlAddress, Irp->RequestorMode,
IoReadAccess);
//Lock the user address space
WriteContext->User = MmMapLockedPages(Irp->MdlAddress,
Irp->RequestorMode);
Irp->UserBuffer = MmGetMdlVirtualAddress(newMdl);

//Set Complete Routine
IoSetCompletionRoutine( Irp, WriteCompleteRoutine,
(PVOID)WriteContext,
TRUE, TRUE, TRUE);

IoCopyCurrentIrpStackLocationToNext(Irp);
IoCallDriver( FileSystem, Irp );
}

kd> !analyze -v
****************************************************************************
***
*
*
* Bugcheck Analysis
*
*
*
****************************************************************************
***

KMODE_EXCEPTION_NOT_HANDLED (1e)
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: c0000005, The exception code that was not handled
Arg2: ecb1535d, The address that the exception occurred at
Arg3: 00000000, Parameter 0 of the exception
Arg4: 00000000, Parameter 1 of the exception

Debugging Details:

EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - "0x%08lx" "0x%08lx"
"%s"

FAULTING_IP:
FILT!FiltHookRoutine+324 [c:\lda\sys\filt.c @ 5386]
ecb1535d f3a5 rep movsd

EXCEPTION_PARAMETER1: 00000000

EXCEPTION_PARAMETER2: 00000000

READ_ADDRESS: 00000000 Nonpaged pool

DEFAULT_BUCKET_ID: DRIVER_FAULT

BUGCHECK_STR: 0x1E

LAST_CONTROL_TRANSFER: from 8046a152 to 80455def

STACK_TEXT:
eb43bddc 8046a152 80419112 00000000 00000000 nt!RtlpSetSecurityObject+0x109
00000000 00000000 00000000 00000000 00000000 nt!NtMajorVersion+0x2

STACK_COMMAND: .bugcheck ; kb

FOLLOWUP_IP:
FILT!FiltHookRoutine+324 [c:\lda\sys\filt.c @ 5386]
ecb1535d f3a5 rep movsd

FOLLOWUP_NAME: MachineOwner

SYMBOL_NAME: FILT!FiltHookRoutine+324

-----Original Message-----
"Tony Mason" ???? news:xxxxx@ntfsd...
Diagnosing the cause of a bug check is not easy when only presented with
the code and a comment that you received a bug check. At a minimum, you
should include:

- The bug check data (stop code + parameters)
- The output from "!analyze -v" in the kernel debugger

In my quick glance at the code I noticed the following problems:

- You do not build the MDL correctly (use MmBuildMdlForNonPagedPool with
a non-paged pool buffer)
- You do not update Irp->UserBuffer correctly
- You do not check for memory allocation failures from ExAllocatePool
- You should use ExAllocatePoolWithTag NOT ExAllocatePool (this will not
cause a crash, but is good programming practice.)

Also, you should be running your driver under verifier - it will help
you find bugs more quickly.

Regards,

Tony

Tony Mason
Consulting Partner
OSR Open Systems Resources Inc
http://www.osr.com

If MmGetSystemAddressForMdlSafe is failing, it is probably because
memory is not being properly cleaned up. Have you tried analyzing the
memory usage of the system itself when this happens?

If I were going to guess, I'd guess that you are not unmapping your MDLs
properly. But since you only show the lock down fragment in your code,
not the clean up, that's strictly a guess.

Also, you call MmProbeAndLockPages, but you don't have a _try/__except
handler around it. How are you planning on trapping errors? That would
cause a KMODE_EXCEPTION_NOT_HANDLED error as well.

Remember: errors in memory access are reported either via a recoverable
mechanism (an exception that can be caught via __try/__except) or a bug
check (invalid kernel memory references). For every MDL you lock down
and map, you must unmap and unlock. If the MDL is attached to the IRP,
the OS will take care of it. If the MDL is created by your driver, then
you have to clean up appropriately.

Regards,

Tony Mason
Consulting Partner
OSR Open Systems Resources Inc

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Kathe Zhou
Sent: Monday, May 03, 2004 11:12 AM
To: ntfsd redirect
Subject: Re:[ntfsd] Why I got a bugcheck in encryption filter?

Thanks for your reply. Followed your advice, I modified my code as
below.
But sometimes MmGetSystemAddressForMdlSafe(Irp->MdlAddress,
NormalPagePriority) return NULL. This make my system crashed. Why and
What can I do with it?
I also post the output of Windbg.

Regards,

{
case IRP_MJ_WRITE:

PMdl newMdl;
PIO_STACK_LOCATION currentIrpStack =
IoGetCurrentIrpStackLocation(Irp);
if( Irp->Flags & (IRP_NOCACHE | IRP_PAGING_IO |
IRP_SYNCHRONOUS_PAGING_IO) )
{
ULONG WriteLength = currentIrpStack->Parameters.Write.Length;
PVOID pbuf;
ULONG i;

if(Irp->MdlAddress != NULL)
{
pbuf = MmGetSystemAddressForMdlSafe(Irp->MdlAddress,
NormalPagePriority);
if (pbuf == NULL) {DbgPrint(("pbuf(MDL) is NULL"));}
}
else
{
pbuf = Irp->UserBuffer;
if (pbuf == NULL) {DbgPrint(("pbuf(UserBuf) is NULL"));}
}

WriteContext = ExAllocatePoolWithTag( NonPagedPool,
sizeof(Write_CONTEXT),
'1gaT' );
if (WriteContext == NULL) {DbgPrint(("WriteContext is NULL"));}
WriteContext->System = ExAllocatePool( NonPagedPool, WriteLength,
'2gaT' );
if (WriteContext->System== NULL) {DbgPrint(("WriteContext->System is
NULL"));}
RtlCopyMemory(WriteContext->System, pbuf, WriteLength);

// save the original Mdl
WriteContext->OriginalMDL = Irp->MdlAddress;
Irp->MdlAddress = NULL;

//build a new MDL
newMdl= IoAllocateMdl( WriteContext->System, WriteLength, FALSE, TRUE,
Irp);
MmBuildMdlForNonPagedPool(newMdl);
MmProbeAndLockPages(Irp->MdlAddress, Irp->RequestorMode,
IoReadAccess);
//Lock the user address space
WriteContext->User = MmMapLockedPages(Irp->MdlAddress,
Irp->RequestorMode);
Irp->UserBuffer = MmGetMdlVirtualAddress(newMdl);

//Set Complete Routine
IoSetCompletionRoutine( Irp, WriteCompleteRoutine,
(PVOID)WriteContext,
TRUE, TRUE, TRUE);

IoCopyCurrentIrpStackLocationToNext(Irp);
IoCallDriver( FileSystem, Irp );
}

kd> !analyze -v
************************************************************************
****
***
*
*
* Bugcheck Analysis
*
*
*
************************************************************************
****
***

KMODE_EXCEPTION_NOT_HANDLED (1e)
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: c0000005, The exception code that was not handled
Arg2: ecb1535d, The address that the exception occurred at
Arg3: 00000000, Parameter 0 of the exception
Arg4: 00000000, Parameter 1 of the exception

Debugging Details:

EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - "0x%08lx" "0x%08lx"
"%s"

FAULTING_IP:
FILT!FiltHookRoutine+324 [c:\lda\sys\filt.c @ 5386]
ecb1535d f3a5 rep movsd

EXCEPTION_PARAMETER1: 00000000

EXCEPTION_PARAMETER2: 00000000

READ_ADDRESS: 00000000 Nonpaged pool

DEFAULT_BUCKET_ID: DRIVER_FAULT

BUGCHECK_STR: 0x1E

LAST_CONTROL_TRANSFER: from 8046a152 to 80455def

STACK_TEXT:
eb43bddc 8046a152 80419112 00000000 00000000
nt!RtlpSetSecurityObject+0x109
00000000 00000000 00000000 00000000 00000000 nt!NtMajorVersion+0x2

STACK_COMMAND: .bugcheck ; kb

FOLLOWUP_IP:
FILT!FiltHookRoutine+324 [c:\lda\sys\filt.c @ 5386]
ecb1535d f3a5 rep movsd

FOLLOWUP_NAME: MachineOwner

SYMBOL_NAME: FILT!FiltHookRoutine+324

-----Original Message-----
"Tony Mason" ???? news:xxxxx@ntfsd...
Diagnosing the cause of a bug check is not easy when only presented with
the code and a comment that you received a bug check. At a minimum, you
should include:

- The bug check data (stop code + parameters)
- The output from "!analyze -v" in the kernel debugger

In my quick glance at the code I noticed the following problems:

- You do not build the MDL correctly (use MmBuildMdlForNonPagedPool with
a non-paged pool buffer)
- You do not update Irp->UserBuffer correctly
- You do not check for memory allocation failures from ExAllocatePool
- You should use ExAllocatePoolWithTag NOT ExAllocatePool (this will not
cause a crash, but is good programming practice.)

Also, you should be running your driver under verifier - it will help
you find bugs more quickly.

Regards,

Tony

Tony Mason
Consulting Partner
OSR Open Systems Resources Inc
http://www.osr.com

---
Questions? First check the IFS FAQ at
The NT Insider:Windows NT Virtual Memory (Part I)

You are currently subscribed to ntfsd as: xxxxx@osr.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

yes, I must have something wrong with the memory. When writing files, the
memory
keep decreasing. I have thought I cleaned up the memory in
WriteCompletionroutine,
but it seems not work. Here is the code of WriteCompletionRoutine:

NTSTATUS
WriteCompleteRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{

PWrite_CONTEXT WriteContext;
WriteContext = (PWrite_CONTEXT)Context;

MmUnmapLockedPages(WriteContext->User, Irp->MdlAddress);
MmUnlockPages(Irp->MdlAddress);
IoFreeMdl(Irp->MdlAddress);
Irp->MdlAddress = WriteContext->OriginalMDL;
Irp->UserBuffer = WriteContext->OriginalBuf;
ExFreePool(WriteContext->System);
ExFreePool(WriteContext);
if( Irp->PendingReturned )
{
IoMarkIrpPending( Irp );
}
return Irp->IoStatus.Status;
}

I also add a try/except block to handle MmProbeAndLockPages.
Here is the modified code.

WriteDispatchRoutine:
{
case IRP_MJ_WRITE:

PMdl newMdl;
PIO_STACK_LOCATION currentIrpStack =
IoGetCurrentIrpStackLocation(Irp);
if( Irp->Flags & (IRP_NOCACHE | IRP_PAGING_IO |
IRP_SYNCHRONOUS_PAGING_IO) )
{
ULONG WriteLength = currentIrpStack->Parameters.Write.Length;
PVOID pbuf;
ULONG i;

if(Irp->MdlAddress != NULL)
{
pbuf = MmGetSystemAddressForMdlSafe(Irp->MdlAddress,
NormalPagePriority);
if (pbuf == NULL) {DbgPrint(("pbuf(MDL) is NULL"));}
}
else
{
pbuf = Irp->UserBuffer;
if (pbuf == NULL) {DbgPrint(("pbuf(UserBuf) is NULL"));}
}

WriteContext = ExAllocatePoolWithTag( NonPagedPool, sizeof(Write_CONTEXT),
'1gaT' );
if (WriteContext == NULL) {DbgPrint(("WriteContext is NULL"));}
WriteContext->System = ExAllocatePool( NonPagedPool, WriteLength,
'2gaT' );
if (WriteContext->System== NULL) {DbgPrint(("WriteContext->System is
NULL"));}
RtlCopyMemory(WriteContext->System, pbuf, WriteLength);

// save the original Mdl
WriteContext->OriginalMDL = Irp->MdlAddress;
WriteContext->OriginalBuf = Irp->UserBuffer;
Irp->MdlAddress = NULL;

//build a new MDL
newMdl= IoAllocateMdl( WriteContext->System, WriteLength, FALSE, TRUE,
Irp);
MmBuildMdlForNonPagedPool(newMdl);
__try {
MmProbeAndLockPages(Irp->MdlAddress, Irp->RequestorMode,
IoReadAccess);
}
__except (KMODE_EXCEPTION_NOT_HANDLED )
{
DbgPrint(("Error in MmProbeAndLockPages. \n"));
IoFreeMdl(newMdl);
ExFreePool(WriteContext->System);
ExFreePool(WriteContext);
// return false;
}
//Lock the user address space
WriteContext->User = MmMapLockedPages(Irp->MdlAddress,
Irp->RequestorMode);
Irp->UserBuffer = MmGetMdlVirtualAddress(newMdl);

//Set Complete Routine
IoSetCompletionRoutine( Irp, WriteCompleteRoutine,
(PVOID)WriteContext,
TRUE, TRUE, TRUE);

IoCopyCurrentIrpStackLocationToNext(Irp);
IoCallDriver( FileSystem, Irp );
}

-----Original Message-----
If MmGetSystemAddressForMdlSafe is failing, it is probably because
memory is not being properly cleaned up. Have you tried analyzing the
memory usage of the system itself when this happens?

If I were going to guess, I'd guess that you are not unmapping your MDLs
properly. But since you only show the lock down fragment in your code,
not the clean up, that's strictly a guess.

Also, you call MmProbeAndLockPages, but you don't have a _try/__except
handler around it. How are you planning on trapping errors? That would
cause a KMODE_EXCEPTION_NOT_HANDLED error as well.

Remember: errors in memory access are reported either via a recoverable
mechanism (an exception that can be caught via __try/__except) or a bug
check (invalid kernel memory references). For every MDL you lock down
and map, you must unmap and unlock. If the MDL is attached to the IRP,
the OS will take care of it. If the MDL is created by your driver, then
you have to clean up appropriately.

Regards,

Tony Mason
Consulting Partner
OSR Open Systems Resources Inc

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Kathe Zhou
Sent: Monday, May 03, 2004 11:12 AM
To: ntfsd redirect
Subject: Re:[ntfsd] Why I got a bugcheck in encryption filter?

Thanks for your reply. Followed your advice, I modified my code as
below.
But sometimes MmGetSystemAddressForMdlSafe(Irp->MdlAddress,
NormalPagePriority) return NULL. This make my system crashed. Why and
What can I do with it?
I also post the output of Windbg.

Regards,

{
case IRP_MJ_WRITE:

PMdl newMdl;
PIO_STACK_LOCATION currentIrpStack =
IoGetCurrentIrpStackLocation(Irp);
if( Irp->Flags & (IRP_NOCACHE | IRP_PAGING_IO |
IRP_SYNCHRONOUS_PAGING_IO) )
{
ULONG WriteLength = currentIrpStack->Parameters.Write.Length;
PVOID pbuf;
ULONG i;

if(Irp->MdlAddress != NULL)
{
pbuf = MmGetSystemAddressForMdlSafe(Irp->MdlAddress,
NormalPagePriority);
if (pbuf == NULL) {DbgPrint(("pbuf(MDL) is NULL"));}
}
else
{
pbuf = Irp->UserBuffer;
if (pbuf == NULL) {DbgPrint(("pbuf(UserBuf) is NULL"));}
}

WriteContext = ExAllocatePoolWithTag( NonPagedPool,
sizeof(Write_CONTEXT),
'1gaT' );
if (WriteContext == NULL) {DbgPrint(("WriteContext is NULL"));}
WriteContext->System = ExAllocatePool( NonPagedPool, WriteLength,
'2gaT' );
if (WriteContext->System== NULL) {DbgPrint(("WriteContext->System is
NULL"));}
RtlCopyMemory(WriteContext->System, pbuf, WriteLength);

// save the original Mdl
WriteContext->OriginalMDL = Irp->MdlAddress;
Irp->MdlAddress = NULL;

//build a new MDL
newMdl= IoAllocateMdl( WriteContext->System, WriteLength, FALSE, TRUE,
Irp);
MmBuildMdlForNonPagedPool(newMdl);
MmProbeAndLockPages(Irp->MdlAddress, Irp->RequestorMode,
IoReadAccess);
//Lock the user address space
WriteContext->User = MmMapLockedPages(Irp->MdlAddress,
Irp->RequestorMode);
Irp->UserBuffer = MmGetMdlVirtualAddress(newMdl);

//Set Complete Routine
IoSetCompletionRoutine( Irp, WriteCompleteRoutine,
(PVOID)WriteContext,
TRUE, TRUE, TRUE);

IoCopyCurrentIrpStackLocationToNext(Irp);
IoCallDriver( FileSystem, Irp );
}

kd> !analyze -v
************************************************************************
****
***
*
*
* Bugcheck Analysis
*
*
*
************************************************************************
****
***

KMODE_EXCEPTION_NOT_HANDLED (1e)
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: c0000005, The exception code that was not handled
Arg2: ecb1535d, The address that the exception occurred at
Arg3: 00000000, Parameter 0 of the exception
Arg4: 00000000, Parameter 1 of the exception

Debugging Details:

EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - "0x%08lx" "0x%08lx"
"%s"

FAULTING_IP:
FILT!FiltHookRoutine+324 [c:\lda\sys\filt.c @ 5386]
ecb1535d f3a5 rep movsd

EXCEPTION_PARAMETER1: 00000000

EXCEPTION_PARAMETER2: 00000000

READ_ADDRESS: 00000000 Nonpaged pool

DEFAULT_BUCKET_ID: DRIVER_FAULT

BUGCHECK_STR: 0x1E

LAST_CONTROL_TRANSFER: from 8046a152 to 80455def

STACK_TEXT:
eb43bddc 8046a152 80419112 00000000 00000000
nt!RtlpSetSecurityObject+0x109
00000000 00000000 00000000 00000000 00000000 nt!NtMajorVersion+0x2

STACK_COMMAND: .bugcheck ; kb

FOLLOWUP_IP:
FILT!FiltHookRoutine+324 [c:\lda\sys\filt.c @ 5386]
ecb1535d f3a5 rep movsd

FOLLOWUP_NAME: MachineOwner

SYMBOL_NAME: FILT!FiltHookRoutine+324

-----Original Message-----
"Tony Mason" ???? news:xxxxx@ntfsd...
Diagnosing the cause of a bug check is not easy when only presented with
the code and a comment that you received a bug check. At a minimum, you
should include:

- The bug check data (stop code + parameters)
- The output from "!analyze -v" in the kernel debugger

In my quick glance at the code I noticed the following problems:

- You do not build the MDL correctly (use MmBuildMdlForNonPagedPool with
a non-paged pool buffer)
- You do not update Irp->UserBuffer correctly
- You do not check for memory allocation failures from ExAllocatePool
- You should use ExAllocatePoolWithTag NOT ExAllocatePool (this will not
cause a crash, but is good programming practice.)

Also, you should be running your driver under verifier - it will help
you find bugs more quickly.

Regards,

Tony

Tony Mason
Consulting Partner
OSR Open Systems Resources Inc
http://www.osr.com

---
Questions? First check the IFS FAQ at
The NT Insider:Windows NT Virtual Memory (Part I)

You are currently subscribed to ntfsd as: xxxxx@osr.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Your use of IoAllocateMdl with the implicit assignment of
Irp->MdlAddress is confusing (I certainly missed it upon initial
review.) I often find it difficult, just by code inspection, to find
all the bugs. I'd want to observe a running system and look at the
leaking memory (use PoolTag from the DDK or from the OSRONLINE web site,
or the !poolused command in the kernel debugger.) Run with pool tagging
enabled and driver verifier disabled - OR run with verifier on your
driver, so you can see the explicit allocations of just your driver.

Since you are using a non-paged pool buffer, there's no reason to
perform the MmProbeAndLockPages at all (my initial reading was that you
were locking the user buffer, but now I see you are locking the system
buffer, but you do not need to lock a system buffer allocated from
non-paged pool.) There's no reason to unmap it, or to unlock it.
That's one of the benefits of using a system allocated buffer - building
MDLs for it is very straight-forward.

You should not return Irp->IoStatus.Status from your completion routine.
The only two values that are allowed are STATUS_SUCCESS (there's a new
alias STATUS_CONTINUE_COMPLETION with the same numeric value in the
latest IFS Kit) or STATUS_MORE_PROCESSING_REQUIRED.

You trust far too much to the potentially user mode address "pbuf".
That should be protected (__try/__except) and probed. Otherwise, I can
trivially crash your system or cause your filter to compromise the OS.

I do not know why your driver is leaking memory. Again, I would
strongly suggest using the development tools provided by the OS for
finding leaks and doing so.

Sorry I cannot be of more help. Perhaps someone else on the list that
is better at doing static analysis for bugs will see something.

Regards,

Tony

Tony Mason
Consulting Partner
OSR Open Systems Resources, Inc.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Kathe Zhou
Sent: Tuesday, May 04, 2004 1:56 AM
To: ntfsd redirect
Subject: Re:[ntfsd] Why I got a bugcheck in encryption filter?

yes, I must have something wrong with the memory. When writing files,
the memory keep decreasing. I have thought I cleaned up the memory in
WriteCompletionroutine, but it seems not work. Here is the code of
WriteCompletionRoutine:

NTSTATUS
WriteCompleteRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{

PWrite_CONTEXT WriteContext;
WriteContext = (PWrite_CONTEXT)Context;

MmUnmapLockedPages(WriteContext->User, Irp->MdlAddress);
MmUnlockPages(Irp->MdlAddress); IoFreeMdl(Irp->MdlAddress);
Irp->MdlAddress = WriteContext->OriginalMDL;
Irp->UserBuffer = WriteContext->OriginalBuf;
ExFreePool(WriteContext->System);
ExFreePool(WriteContext);
if( Irp->PendingReturned )
{
IoMarkIrpPending( Irp );
}
return Irp->IoStatus.Status;
}

I also add a try/except block to handle MmProbeAndLockPages.
Here is the modified code.

WriteDispatchRoutine:
{
case IRP_MJ_WRITE:

PMdl newMdl;
PIO_STACK_LOCATION currentIrpStack =
IoGetCurrentIrpStackLocation(Irp);
if( Irp->Flags & (IRP_NOCACHE | IRP_PAGING_IO |
IRP_SYNCHRONOUS_PAGING_IO) )
{
ULONG WriteLength = currentIrpStack->Parameters.Write.Length;
PVOID pbuf;
ULONG i;

if(Irp->MdlAddress != NULL)
{
pbuf = MmGetSystemAddressForMdlSafe(Irp->MdlAddress,
NormalPagePriority);
if (pbuf == NULL) {DbgPrint(("pbuf(MDL) is NULL"));}
}
else
{
pbuf = Irp->UserBuffer;
if (pbuf == NULL) {DbgPrint(("pbuf(UserBuf) is NULL"));}
}

WriteContext = ExAllocatePoolWithTag( NonPagedPool,
sizeof(Write_CONTEXT), '1gaT' );
if (WriteContext == NULL) {DbgPrint(("WriteContext is NULL"));}
WriteContext->System = ExAllocatePool( NonPagedPool, WriteLength,
'2gaT' );
if (WriteContext->System== NULL) {DbgPrint(("WriteContext->System is
NULL"));}
RtlCopyMemory(WriteContext->System, pbuf, WriteLength);

// save the original Mdl
WriteContext->OriginalMDL = Irp->MdlAddress;
WriteContext->OriginalBuf = Irp->UserBuffer;
Irp->MdlAddress = NULL;

//build a new MDL
newMdl= IoAllocateMdl( WriteContext->System, WriteLength, FALSE, TRUE,
Irp); MmBuildMdlForNonPagedPool(newMdl);
__try {
MmProbeAndLockPages(Irp->MdlAddress, Irp->RequestorMode,
IoReadAccess);
}
__except (KMODE_EXCEPTION_NOT_HANDLED )
{
DbgPrint(("Error in MmProbeAndLockPages. \n"));
IoFreeMdl(newMdl);
ExFreePool(WriteContext->System);
ExFreePool(WriteContext);
// return false;
}
//Lock the user address space
WriteContext->User = MmMapLockedPages(Irp->MdlAddress,
Irp->RequestorMode);
Irp->UserBuffer = MmGetMdlVirtualAddress(newMdl);

//Set Complete Routine
IoSetCompletionRoutine( Irp, WriteCompleteRoutine,
(PVOID)WriteContext, TRUE, TRUE, TRUE);

IoCopyCurrentIrpStackLocationToNext(Irp);
IoCallDriver( FileSystem, Irp );
}

-----Original Message-----
If MmGetSystemAddressForMdlSafe is failing, it is probably because
memory is not being properly cleaned up. Have you tried analyzing the
memory usage of the system itself when this happens?

If I were going to guess, I'd guess that you are not unmapping your MDLs
properly. But since you only show the lock down fragment in your code,
not the clean up, that's strictly a guess.

Also, you call MmProbeAndLockPages, but you don't have a _try/__except
handler around it. How are you planning on trapping errors? That would
cause a KMODE_EXCEPTION_NOT_HANDLED error as well.

Remember: errors in memory access are reported either via a recoverable
mechanism (an exception that can be caught via __try/__except) or a bug
check (invalid kernel memory references). For every MDL you lock down
and map, you must unmap and unlock. If the MDL is attached to the IRP,
the OS will take care of it. If the MDL is created by your driver, then
you have to clean up appropriately.

Regards,

Tony Mason
Consulting Partner
OSR Open Systems Resources Inc

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Kathe Zhou
Sent: Monday, May 03, 2004 11:12 AM
To: ntfsd redirect
Subject: Re:[ntfsd] Why I got a bugcheck in encryption filter?

Thanks for your reply. Followed your advice, I modified my code as
below.
But sometimes MmGetSystemAddressForMdlSafe(Irp->MdlAddress,
NormalPagePriority) return NULL. This make my system crashed. Why and
What can I do with it?
I also post the output of Windbg.

Regards,

{
case IRP_MJ_WRITE:

PMdl newMdl;
PIO_STACK_LOCATION currentIrpStack =
IoGetCurrentIrpStackLocation(Irp);
if( Irp->Flags & (IRP_NOCACHE | IRP_PAGING_IO |
IRP_SYNCHRONOUS_PAGING_IO) )
{
ULONG WriteLength = currentIrpStack->Parameters.Write.Length;
PVOID pbuf;
ULONG i;

if(Irp->MdlAddress != NULL)
{
pbuf = MmGetSystemAddressForMdlSafe(Irp->MdlAddress,
NormalPagePriority);
if (pbuf == NULL) {DbgPrint(("pbuf(MDL) is NULL"));}
}
else
{
pbuf = Irp->UserBuffer;
if (pbuf == NULL) {DbgPrint(("pbuf(UserBuf) is NULL"));}
}

WriteContext = ExAllocatePoolWithTag( NonPagedPool,
sizeof(Write_CONTEXT), '1gaT' );
if (WriteContext == NULL) {DbgPrint(("WriteContext is NULL"));}
WriteContext->System = ExAllocatePool( NonPagedPool, WriteLength,
'2gaT' );
if (WriteContext->System== NULL) {DbgPrint(("WriteContext->System is
NULL"));}
RtlCopyMemory(WriteContext->System, pbuf, WriteLength);

// save the original Mdl
WriteContext->OriginalMDL = Irp->MdlAddress;
Irp->MdlAddress = NULL;

//build a new MDL
newMdl= IoAllocateMdl( WriteContext->System, WriteLength, FALSE, TRUE,
Irp); MmBuildMdlForNonPagedPool(newMdl);
MmProbeAndLockPages(Irp->MdlAddress, Irp->RequestorMode,
IoReadAccess);
//Lock the user address space
WriteContext->User = MmMapLockedPages(Irp->MdlAddress,
Irp->RequestorMode);
Irp->UserBuffer = MmGetMdlVirtualAddress(newMdl);

//Set Complete Routine
IoSetCompletionRoutine( Irp, WriteCompleteRoutine,
(PVOID)WriteContext, TRUE, TRUE, TRUE);

IoCopyCurrentIrpStackLocationToNext(Irp);
IoCallDriver( FileSystem, Irp );
}

kd> !analyze -v
************************************************************************
****
***
*
*
* Bugcheck Analysis
*
*
*
************************************************************************
****
***

KMODE_EXCEPTION_NOT_HANDLED (1e)
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: c0000005, The exception code that was not handled
Arg2: ecb1535d, The address that the exception occurred at
Arg3: 00000000, Parameter 0 of the exception
Arg4: 00000000, Parameter 1 of the exception

Debugging Details:

EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - "0x%08lx" "0x%08lx"
"%s"

FAULTING_IP:
FILT!FiltHookRoutine+324 [c:\lda\sys\filt.c @ 5386]
ecb1535d f3a5 rep movsd

EXCEPTION_PARAMETER1: 00000000

EXCEPTION_PARAMETER2: 00000000

READ_ADDRESS: 00000000 Nonpaged pool

DEFAULT_BUCKET_ID: DRIVER_FAULT

BUGCHECK_STR: 0x1E

LAST_CONTROL_TRANSFER: from 8046a152 to 80455def

STACK_TEXT:
eb43bddc 8046a152 80419112 00000000 00000000
nt!RtlpSetSecurityObject+0x109
00000000 00000000 00000000 00000000 00000000 nt!NtMajorVersion+0x2

STACK_COMMAND: .bugcheck ; kb

FOLLOWUP_IP:
FILT!FiltHookRoutine+324 [c:\lda\sys\filt.c @ 5386]
ecb1535d f3a5 rep movsd

FOLLOWUP_NAME: MachineOwner

SYMBOL_NAME: FILT!FiltHookRoutine+324

-----Original Message-----
"Tony Mason" ???? news:xxxxx@ntfsd...
Diagnosing the cause of a bug check is not easy when only presented with
the code and a comment that you received a bug check. At a minimum, you
should include:

- The bug check data (stop code + parameters)
- The output from "!analyze -v" in the kernel debugger

In my quick glance at the code I noticed the following problems:

- You do not build the MDL correctly (use MmBuildMdlForNonPagedPool with
a non-paged pool buffer)
- You do not update Irp->UserBuffer correctly
- You do not check for memory allocation failures from ExAllocatePool
- You should use ExAllocatePoolWithTag NOT ExAllocatePool (this will not
cause a crash, but is good programming practice.)

Also, you should be running your driver under verifier - it will help
you find bugs more quickly.

Regards,

Tony

Tony Mason
Consulting Partner
OSR Open Systems Resources Inc
http://www.osr.com

---
Questions? First check the IFS FAQ at
The NT Insider:Windows NT Virtual Memory (Part I)

You are currently subscribed to ntfsd as: xxxxx@osr.com To unsubscribe
send a blank email to xxxxx@lists.osr.com

---
Questions? First check the IFS FAQ at
The NT Insider:Windows NT Virtual Memory (Part I)

You are currently subscribed to ntfsd as: xxxxx@osr.com To unsubscribe
send a blank email to xxxxx@lists.osr.com

Thank you very much. With the help of PoolTag, I found I made a big mistake.
There is something wrong when I set the complete routine. It never enter the
complete
routine, that’s why the system crashed. I made some modification and it
seem work well so far.
Maybe there still has some potential problem, but it can work now after
all.Thanks for your help again.

-----Original Message-----
Your use of IoAllocateMdl with the implicit assignment of
Irp->MdlAddress is confusing (I certainly missed it upon initial
review.) I often find it difficult, just by code inspection, to find
all the bugs. I’d want to observe a running system and look at the
leaking memory (use PoolTag from the DDK or from the OSRONLINE web site,
or the !poolused command in the kernel debugger.) Run with pool tagging
enabled and driver verifier disabled - OR run with verifier on your
driver, so you can see the explicit allocations of just your driver.

Since you are using a non-paged pool buffer, there’s no reason to
perform the MmProbeAndLockPages at all (my initial reading was that you
were locking the user buffer, but now I see you are locking the system
buffer, but you do not need to lock a system buffer allocated from
non-paged pool.) There’s no reason to unmap it, or to unlock it.
That’s one of the benefits of using a system allocated buffer - building
MDLs for it is very straight-forward.

You should not return Irp->IoStatus.Status from your completion routine.
The only two values that are allowed are STATUS_SUCCESS (there’s a new
alias STATUS_CONTINUE_COMPLETION with the same numeric value in the
latest IFS Kit) or STATUS_MORE_PROCESSING_REQUIRED.

You trust far too much to the potentially user mode address “pbuf”.
That should be protected (__try/__except) and probed. Otherwise, I can
trivially crash your system or cause your filter to compromise the OS.

I do not know why your driver is leaking memory. Again, I would
strongly suggest using the development tools provided by the OS for
finding leaks and doing so.

Sorry I cannot be of more help. Perhaps someone else on the list that
is better at doing static analysis for bugs will see something.

Regards,

Tony

Tony Mason
Consulting Partner
OSR Open Systems Resources, Inc.
http://www.osr.com