IRP_MJ_READ caused BSOD in vista/win7

I asked for help before for the same problem. It isn??t resolved yet.

I need to read data after IRP_MJ_CREATE completed successfully so I fire
IRP_MJ_READ.

The following source codes works well in xp, but it crashes in vista and
win7.

I found that if the irp->Flags in function KfcRead is set to
IRP_READ_OPERATION, the crash won??t occur. But the result isn??t what I
want.

Does any one know how the make the IRP_NOCACHE | IRP_PAGING_IO |
IRP_SYNCHRONOUS_PAGING_IO work instead of IRP_READ_OPERATION?

Or any one know why this happened?

********** Minidump *************

DRIVER_OVERRAN_STACK_BUFFER (f7)

A driver has overrun a stack-based buffer. This overrun could potentially

allow a malicious user to gain control of this machine.

DESCRIPTION

A driver overran a stack-based buffer (or local variable) in a way that
would

have overwritten the function’s return address and jumped back to an
arbitrary

address when the function returned. This is the classic “buffer overrun”

hacking attack and the system has been brought down to prevent a malicious
user

from gaining complete control of it.

Do a kb to get a stack backtrace – the last routine on the stack before the

buffer overrun handlers and bugcheck call is the one that overran its local

variable(s).

Arguments:

Arg1: 1f3a6424, Actual security check cookie from the stack

Arg2: 8a854a89, Expected security check cookie

Arg3: 757ab576, Complement of the expected security check cookie

Arg4: 00000000, zero

********** Source *************

NTSTATUS

DriverEntry (

IN PDRIVER_OBJECT DriverObject,

IN PUNICODE_STRING RegistryPath

)

{

for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)

{

DriverObject->MajorFunction[i] = SfPassThrough;

}

DriverObject->MajorFunction[IRP_MJ_CREATE] = SfCreate;

}

SfCreate( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )

{

PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );

Status = SfWaitIrpDone( … )

if (

( NT_SUCCESS( Status ) )

&&

( NULL != IrpSp->FileObject )

&&

( NULL != IrpSp->FileObject->FsContext )

)

{

PUCHAR strBuf = ExAllocatePool( NonPagedPool, 4096 );

LARGE_INTEGER liFileHead;

IO_STATUS_BLOCK IoStatusBlock;

DWORD dwIrpFlags = IRP_NOCACHE | IRP_PAGING_IO |
IRP_SYNCHRONOUS_PAGING_IO;

if ( NULL != strBuf )

{

liFileHead.QuadPart = 0;

KfcRead( DeviceObject, IrpSp->FileObject, &liFileHead, 4096, strBuf,
&IoStatusBlock, dwIrpFlags );

}

}

}

NTSTATUS SfWaitIrpDoneCompletion (

IN PDEVICE_OBJECT DeviceObject,

IN PIRP Irp,

IN PVOID Context

)

{

PKEVENT pEvent = Context;

if ( Irp->PendingReturned )

{

KeSetEvent( pEvent, IO_NO_INCREMENT, FALSE );

}

return STATUS_MORE_PROCESSING_REQUIRED;

}

NTSTATUS SfWaitIrpDone(

IN PDEVICE_OBJECT DeviceObject,

IN PIRP Irp

)

{

KEVENT Event;

NTSTATUS Status;

KeInitializeEvent( &Event, NotificationEvent, FALSE );

IoCopyCurrentIrpStackLocationToNext( Irp );

IoSetCompletionRoutine( Irp, SfWaitIrpDoneCompletion, &Event, TRUE, TRUE,
TRUE );

Status = IoCallDriver( DeviceObject, Irp );

if (STATUS_PENDING == Status)

{

KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, NULL );

}

Status = Irp->IoStatus.Status;

return Status;

}

static VOID KfcRead(PDEVICE_OBJECT v_pDeviceObject,

PFILE_OBJECT v_pFileObject,

PLARGE_INTEGER v_liOffset,

ULONG v_Length,

PUCHAR v_strBuf,

PIO_STATUS_BLOCK v_IoStatusBlock,

IN DWORD v_dwIrpFlags)

{

PIRP irp;

KEVENT event;

PIO_STACK_LOCATION ioStackLocation;

NTSTATUS Status;

KeInitializeEvent(&event, SynchronizationEvent, FALSE);

irp = IoBuildAsynchronousFsdRequest( IRP_MJ_READ, v_pDeviceObject,
v_strBuf, v_Length, v_liOffset, v_IoStatusBlock );

if( NULL==irp )

{

v_IoStatusBlock->Status = STATUS_INSUFFICIENT_RESOURCES;

v_IoStatusBlock->Information = 0;

return;

}

irp->Flags = v_dwIrpFlags;

irp->UserEvent = &event;

ioStackLocation = IoGetNextIrpStackLocation(irp);

ioStackLocation->MajorFunction = IRP_MJ_READ;

ioStackLocation->MinorFunction = 0;

ioStackLocation->DeviceObject = v_pDeviceObject;

ioStackLocation->FileObject = v_pFileObject;

ioStackLocation->Parameters.Read.Length = v_Length;

ioStackLocation->Parameters.Read.ByteOffset = *v_liOffset;

IoSetCompletionRoutine(irp, KfcIoCompletion, 0, TRUE, TRUE, TRUE);

Status = IoCallDriver(v_pDeviceObject, irp);

if(Status == STATUS_PENDING)

{

KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, 0);

}

}

static NTSTATUS KfcIoCompletion(PDEVICE_OBJECT DeviceObject,

PIRP Irp,

PVOID Context)

{

*Irp->UserIosb = Irp->IoStatus;

if (Irp->MdlAddress)

{

PVOID pBuffer = MmGetSystemAddressForMdlSafe( Irp->MdlAddress,
HighPagePriority );

if( NULL!=pBuffer )

{

MmUnmapLockedPages( pBuffer, Irp->MdlAddress );

}

MmUnlockPages(Irp->MdlAddress);

IoFreeMdl(Irp->MdlAddress);

Irp->MdlAddress = NULL;

}

KeSetEvent(Irp->UserEvent, 0, FALSE);

IoFreeIrp( Irp );

return STATUS_MORE_PROCESSING_REQUIRED;

}

NTSTATUS SfPassThrough (

IN PDEVICE_OBJECT DeviceObject,

IN PIRP Irp

)

{

IoSkipCurrentIrpStackLocation( Irp );

return IoCallDriver( ((PSFILTER_DEVICE_EXTENSION)
DeviceObject->DeviceExtension)->NLExtHeader.AttachedToDeviceObject, Irp );

}

I’m not sure I’ve read your code correctly, but in post create you are calling KfcRead which is firing off an *asynchronous* read and is not waiting for it to complete. However you are passing an IOSB (at the very least) which is allocated off the stack.

Oh yea, and watch out for STATUS_REPARSE - it’s a success status.

Rod

“½???” <luyunyan_xm> wrote in message news:xxxxx@ntfsd…
I asked for help before for the same problem. It isn??t resolved yet.

I need to read data after IRP_MJ_CREATE completed successfully so I fire IRP_MJ_READ.

The following source codes works well in xp, but it crashes in vista and win7.

I found that if the irp->Flags in function KfcRead is set to IRP_READ_OPERATION, the crash won??t occur. But the result isn??t what I want.

Does any one know how the make the IRP_NOCACHE | IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO work instead of IRP_READ_OPERATION?

Or any one know why this happened?

Minidump***

DRIVER_OVERRAN_STACK_BUFFER (f7)

A driver has overrun a stack-based buffer. This overrun could potentially

allow a malicious user to gain control of this machine.

DESCRIPTION

A driver overran a stack-based buffer (or local variable) in a way that would

have overwritten the function’s return address and jumped back to an arbitrary

address when the function returned. This is the classic “buffer overrun”

hacking attack and the system has been brought down to prevent a malicious user

from gaining complete control of it.

Do a kb to get a stack backtrace – the last routine on the stack before the

buffer overrun handlers and bugcheck call is the one that overran its local

variable(s).

Arguments:

Arg1: 1f3a6424, Actual security check cookie from the stack

Arg2: 8a854a89, Expected security check cookie

Arg3: 757ab576, Complement of the expected security check cookie

Arg4: 00000000, zero

Source***

NTSTATUS

DriverEntry (

IN PDRIVER_OBJECT DriverObject,

IN PUNICODE_STRING RegistryPath

)

{



for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)

{

DriverObject->MajorFunction[i] = SfPassThrough;

}

DriverObject->MajorFunction[IRP_MJ_CREATE] = SfCreate;



}

SfCreate( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )

{

PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );



Status = SfWaitIrpDone( … )

if (

( NT_SUCCESS( Status ) )

&&

( NULL != IrpSp->FileObject )

&&

( NULL != IrpSp->FileObject->FsContext )

)

{

PUCHAR strBuf = ExAllocatePool( NonPagedPool, 4096 );

LARGE_INTEGER liFileHead;

IO_STATUS_BLOCK IoStatusBlock;

DWORD dwIrpFlags = IRP_NOCACHE | IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO;

if ( NULL != strBuf )

{

liFileHead.QuadPart = 0;

KfcRead( DeviceObject, IrpSp->FileObject, &liFileHead, 4096, strBuf, &IoStatusBlock, dwIrpFlags );

}



}



}

NTSTATUS SfWaitIrpDoneCompletion (

IN PDEVICE_OBJECT DeviceObject,

IN PIRP Irp,

IN PVOID Context

)

{

PKEVENT pEvent = Context;

if ( Irp->PendingReturned )

{

KeSetEvent( pEvent, IO_NO_INCREMENT, FALSE );

}

return STATUS_MORE_PROCESSING_REQUIRED;

}

NTSTATUS SfWaitIrpDone(

IN PDEVICE_OBJECT DeviceObject,

IN PIRP Irp

)

{

KEVENT Event;

NTSTATUS Status;

KeInitializeEvent( &Event, NotificationEvent, FALSE );

IoCopyCurrentIrpStackLocationToNext( Irp );

IoSetCompletionRoutine( Irp, SfWaitIrpDoneCompletion, &Event, TRUE, TRUE, TRUE );

Status = IoCallDriver( DeviceObject, Irp );

if (STATUS_PENDING == Status)

{

KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, NULL );

}

Status = Irp->IoStatus.Status;

return Status;

}

static VOID KfcRead(PDEVICE_OBJECT v_pDeviceObject,

PFILE_OBJECT v_pFileObject,

PLARGE_INTEGER v_liOffset,

ULONG v_Length,

PUCHAR v_strBuf,

PIO_STATUS_BLOCK v_IoStatusBlock,

IN DWORD v_dwIrpFlags)

{

PIRP irp;

KEVENT event;

PIO_STACK_LOCATION ioStackLocation;

NTSTATUS Status;

KeInitializeEvent(&event, SynchronizationEvent, FALSE);

irp = IoBuildAsynchronousFsdRequest( IRP_MJ_READ, v_pDeviceObject, v_strBuf, v_Length, v_liOffset, v_IoStatusBlock );

if( NULL==irp )

{

v_IoStatusBlock->Status = STATUS_INSUFFICIENT_RESOURCES;

v_IoStatusBlock->Information = 0;

return;

}

irp->Flags = v_dwIrpFlags;

irp->UserEvent = &event;

ioStackLocation = IoGetNextIrpStackLocation(irp);

ioStackLocation->MajorFunction = IRP_MJ_READ;

ioStackLocation->MinorFunction = 0;

ioStackLocation->DeviceObject = v_pDeviceObject;

ioStackLocation->FileObject = v_pFileObject;

ioStackLocation->Parameters.Read.Length = v_Length;

ioStackLocation->Parameters.Read.ByteOffset = *v_liOffset;

IoSetCompletionRoutine(irp, KfcIoCompletion, 0, TRUE, TRUE, TRUE);

Status = IoCallDriver(v_pDeviceObject, irp);

if(Status == STATUS_PENDING)

{

KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, 0);

}

}

static NTSTATUS KfcIoCompletion(PDEVICE_OBJECT DeviceObject,

PIRP Irp,

PVOID Context)

{

*Irp->UserIosb = Irp->IoStatus;

if (Irp->MdlAddress)

{

PVOID pBuffer = MmGetSystemAddressForMdlSafe( Irp->MdlAddress, HighPagePriority );

if( NULL!=pBuffer )

{

MmUnmapLockedPages( pBuffer, Irp->MdlAddress );

}

MmUnlockPages(Irp->MdlAddress);

IoFreeMdl(Irp->MdlAddress);

Irp->MdlAddress = NULL;

}

KeSetEvent(Irp->UserEvent, 0, FALSE);

IoFreeIrp( Irp );

return STATUS_MORE_PROCESSING_REQUIRED;

}

NTSTATUS SfPassThrough (

IN PDEVICE_OBJECT DeviceObject,

IN PIRP Irp

)

{

IoSkipCurrentIrpStackLocation( Irp );

return IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->NLExtHeader.AttachedToDeviceObject, Irp );

}</luyunyan_xm>