PAGE_FAULT_IN_NONPAGED_AREA in IRP_MJ_DIRECTORY_CONTROL

Hi:

I’m getting a PAGE_FAULT_IN_NONPAGED_AREA at the IRP_MJ_DIRECTORY_CONTROL
completion routine.

Below is the code fragment.

I modify the files information on the fly. Can anybody suggest what am I
doing wrong?. One detail is that I compiled it to XP and I’m getting this
error on a W2003 machine, but I guess there’s no relation. Isn’t it?.

Thanks in advance.

Best regards.

Pablo Frank

Here’s the code fragment (I just included the relevant information):

case IRP_MJ_DIRECTORY_CONTROL:

if(pIrpStack->MinorFunction == IRP_MN_QUERY_DIRECTORY &&
pIrpStack->Parameters.QueryDirectory.FileInformationClass ==
FileBothDirectoryInformation) {

PFILE_BOTH_DIR_INFORMATION QueryBuffer = NULL;
ULONG offset = 0;
ULONG bufferLength = pIrpStack->Parameters.QueryFile.Length;

QueryBuffer = (PFILE_BOTH_DIR_INFORMATION) Irp->UserBuffer;

if( QueryBuffer->NextEntryOffset > bufferLength ) {

break;
}

do {

if (QueryBuffer->FileNameLength != 0) { // I GOT THE
PAGE_FAULT_IN_NONPAGED_AREA error on this line

//Check file name here… not included for simplicity.

QueryBuffer->EndOfFile = NewEof; // I modify the file’s
information here
QueryBuffer->AllocationSize = NewAllocSize;
}

offset = QueryBuffer->NextEntryOffset;

if (offset != 0) {

QueryBuffer = (PFILE_BOTH_DIR_INFORMATION) ( (PUCHAR) QueryBuffer +
offset );

}

} while( offset != 0 );
}

break;

You are initializing the QueryBuffer pointer only if the
query directory request requires FileBothDirectoryInformation.

But IRP_MN_QUERY_DIRECTORY can require
FileDirectoryInformation or FileFullDirectoryInformation
as well.

You probably must handle all three cases.

L.

Pablo,

Did you run prefast on this code? It would have caught that
uninitialzed path…

IN ADDITION, this code is inherently unsafe - you are assuming the
application is passing down valid information (QueryBuffer is from user
mode). If you are going to use a user buffer, you must be very careful
about doing so (where are the __try/__except handlers here? Why no
probe of the address to ensure it is a UM address? I could generate a
PAGE_FAULT_IN_NONPAGED_AREA given your driver and a few minutes of
(yech) applications writing time.)

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 Pablo G. Frank
Sent: Wednesday, January 14, 2004 8:32 PM
To: ntfsd redirect
Subject: [ntfsd] PAGE_FAULT_IN_NONPAGED_AREA in IRP_MJ_DIRECTORY_CONTROL

Hi:

I’m getting a PAGE_FAULT_IN_NONPAGED_AREA at the
IRP_MJ_DIRECTORY_CONTROL completion routine.

Below is the code fragment.

I modify the files information on the fly. Can anybody suggest what am I
doing wrong?. One detail is that I compiled it to XP and I’m getting
this error on a W2003 machine, but I guess there’s no relation. Isn’t
it?.

Thanks in advance.

Best regards.

Pablo Frank

Here’s the code fragment (I just included the relevant information):

case IRP_MJ_DIRECTORY_CONTROL:

if(pIrpStack->MinorFunction == IRP_MN_QUERY_DIRECTORY &&
pIrpStack->Parameters.QueryDirectory.FileInformationClass ==
FileBothDirectoryInformation) {

PFILE_BOTH_DIR_INFORMATION QueryBuffer = NULL;
ULONG offset = 0;
ULONG bufferLength = pIrpStack->Parameters.QueryFile.Length;

QueryBuffer = (PFILE_BOTH_DIR_INFORMATION) Irp->UserBuffer;

if( QueryBuffer->NextEntryOffset > bufferLength ) {

break;
}

do {

if (QueryBuffer->FileNameLength != 0) { // I GOT THE
PAGE_FAULT_IN_NONPAGED_AREA error on this line

//Check file name here… not included for simplicity.

QueryBuffer->EndOfFile = NewEof; // I modify the
file’s
information here
QueryBuffer->AllocationSize = NewAllocSize;
}

offset = QueryBuffer->NextEntryOffset;

if (offset != 0) {

QueryBuffer = (PFILE_BOTH_DIR_INFORMATION) ( (PUCHAR) QueryBuffer +
offset );

}

} while( offset != 0 );
}

break;


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

Hi, Tony.

Thanks, very much, for your answer.

I ran prefast but it found no defects.

Also I omitted the Probe and Try for simplicity.

This is a code excerpt for the probe I used
************************************************

bufferLength = pIrpStack->Parameters.QueryDirectory.Length;

QueryBuffer = (PFILE_BOTH_DIR_INFORMATION) Irp->UserBuffer;

try {

ProbeForWrite((PVOID) QueryBuffer, bufferLength, sizeof(UCHAR));

} except (EXCEPTION_EXECUTE_HANDLER) {

Irp->IoStatus.Status = GetExceptionCode();
Irp->IoStatus.Information = 0;
break;
}

*************************************

But in the Do … While it still fails
*************************************

do {

if (QueryBuffer->FileNameLength != 0) {
//This line fails

// Other stuff here…

}

offset = QueryBuffer->NextEntryOffset;

if (offset != 0) {

QueryBuffer = (PFILE_BOTH_DIR_INFORMATION) ( (PUCHAR) QueryBuffer +
offset );

}
} while( offset != 0 );

*********************************************************

This is what I did to solve the problem. Am I crazy?
*********************************************************

try {

ProbeForRead((PVOID) &QueryBuffer->FileNameLength, 4, 1);

} except (EXCEPTION_EXECUTE_HANDLER) {

Irp->IoStatus.Status = GetExceptionCode();
Irp->IoStatus.Information = 0;
break;
}

if (QueryBuffer->FileNameLength != 0) { // Now
this line is not reached and the driver doesn’t crash

*******************************************************

But I guess I’m doing something wrong here, as I think the probe would have
to fail when I probed the Buffer the first time.

Best regards.

Pablo Frank

“Tony Mason” escribió en el mensaje news:xxxxx@ntfsd…
Pablo,

Did you run prefast on this code? It would have caught that
uninitialzed path…

IN ADDITION, this code is inherently unsafe - you are assuming the
application is passing down valid information (QueryBuffer is from user
mode). If you are going to use a user buffer, you must be very careful
about doing so (where are the try/ except handlers here? Why no
probe of the address to ensure it is a UM address? I could generate a
PAGE_FAULT_IN_NONPAGED_AREA given your driver and a few minutes of
(yech) applications writing time.)

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 Pablo G. Frank
Sent: Wednesday, January 14, 2004 8:32 PM
To: ntfsd redirect
Subject: [ntfsd] PAGE_FAULT_IN_NONPAGED_AREA in IRP_MJ_DIRECTORY_CONTROL

Hi:

I’m getting a PAGE_FAULT_IN_NONPAGED_AREA at the
IRP_MJ_DIRECTORY_CONTROL completion routine.

Below is the code fragment.

I modify the files information on the fly. Can anybody suggest what am I
doing wrong?. One detail is that I compiled it to XP and I’m getting
this error on a W2003 machine, but I guess there’s no relation. Isn’t
it?.

Thanks in advance.

Best regards.

Pablo Frank

Here’s the code fragment (I just included the relevant information):

case IRP_MJ_DIRECTORY_CONTROL:

if(pIrpStack->MinorFunction == IRP_MN_QUERY_DIRECTORY &&
pIrpStack->Parameters.QueryDirectory.FileInformationClass ==
FileBothDirectoryInformation) {

PFILE_BOTH_DIR_INFORMATION QueryBuffer = NULL;
ULONG offset = 0;
ULONG bufferLength = pIrpStack->Parameters.QueryFile.Length;

QueryBuffer = (PFILE_BOTH_DIR_INFORMATION) Irp->UserBuffer;

if( QueryBuffer->NextEntryOffset > bufferLength ) {

break;
}

do {

if (QueryBuffer->FileNameLength != 0) { // I GOT THE
PAGE_FAULT_IN_NONPAGED_AREA error on this line

//Check file name here… not included for simplicity.

QueryBuffer->EndOfFile = NewEof; // I modify the
file’s
information here
QueryBuffer->AllocationSize = NewAllocSize;
}

offset = QueryBuffer->NextEntryOffset;

if (offset != 0) {

QueryBuffer = (PFILE_BOTH_DIR_INFORMATION) ( (PUCHAR) QueryBuffer +
offset );

}

} while( offset != 0 );
}

break;


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

Pablo,

From the information you are providing I can’t tell exactly what you are doing wrong here. I *can* see some logical errors in the code, but they are not going to cause a page fault in non paged area.

1 - the ENIRE access (probe and use of the buffer) must be inside the try/except. Otherwise, I can write a program that will eventually cause you to crash.

2 - the FIELD inside the buffer could be invalid even if the buffer itself is valid. But again, this wouldn’t cause the specific crash.

Can you provide information from the debugger? If so, tell us the specific faulting address as well as Irp->UserBuffer address and then the data contents of Irp->UserBuffer.

Finally, can you tell me why you think QueryBuffer->FileLength will be valid in this case? Is this AFTER the response from the file system?

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 Pablo G. Frank
Sent: Thursday, January 15, 2004 3:30 PM
To: ntfsd redirect
Subject: Re:[ntfsd] PAGE_FAULT_IN_NONPAGED_AREA in IRP_MJ_DIRECTORY_CONTROL

Hi, Tony.

Thanks, very much, for your answer.

I ran prefast but it found no defects.

Also I omitted the Probe and Try for simplicity.

This is a code excerpt for the probe I used
************************************************

bufferLength = pIrpStack->Parameters.QueryDirectory.Length;

QueryBuffer = (PFILE_BOTH_DIR_INFORMATION) Irp->UserBuffer;

try {

ProbeForWrite((PVOID) QueryBuffer, bufferLength, sizeof(UCHAR));

} except (EXCEPTION_EXECUTE_HANDLER) {

Irp->IoStatus.Status = GetExceptionCode();
Irp->IoStatus.Information = 0;
break;
}

*************************************

But in the Do … While it still fails
*************************************

do {

if (QueryBuffer->FileNameLength != 0) {
//This line fails

// Other stuff here…

}

offset = QueryBuffer->NextEntryOffset;

if (offset != 0) {

QueryBuffer = (PFILE_BOTH_DIR_INFORMATION) ( (PUCHAR) QueryBuffer +
offset );

}
} while( offset != 0 );

*********************************************************

This is what I did to solve the problem. Am I crazy?
*********************************************************

try {

ProbeForRead((PVOID) &QueryBuffer->FileNameLength, 4, 1);

} except (EXCEPTION_EXECUTE_HANDLER) {

Irp->IoStatus.Status = GetExceptionCode();
Irp->IoStatus.Information = 0;
break;
}

if (QueryBuffer->FileNameLength != 0) { // Now
this line is not reached and the driver doesn’t crash

*******************************************************

But I guess I’m doing something wrong here, as I think the probe would have
to fail when I probed the Buffer the first time.

Best regards.

Pablo Frank

“Tony Mason” escribi? en el mensaje news:xxxxx@ntfsd…
Pablo,

Did you run prefast on this code? It would have caught that
uninitialzed path…

IN ADDITION, this code is inherently unsafe - you are assuming the
application is passing down valid information (QueryBuffer is from user
mode). If you are going to use a user buffer, you must be very careful
about doing so (where are the try/ except handlers here? Why no
probe of the address to ensure it is a UM address? I could generate a
PAGE_FAULT_IN_NONPAGED_AREA given your driver and a few minutes of
(yech) applications writing time.)

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 Pablo G. Frank
Sent: Wednesday, January 14, 2004 8:32 PM
To: ntfsd redirect
Subject: [ntfsd] PAGE_FAULT_IN_NONPAGED_AREA in IRP_MJ_DIRECTORY_CONTROL

Hi:

I’m getting a PAGE_FAULT_IN_NONPAGED_AREA at the
IRP_MJ_DIRECTORY_CONTROL completion routine.

Below is the code fragment.

I modify the files information on the fly. Can anybody suggest what am I
doing wrong?. One detail is that I compiled it to XP and I’m getting
this error on a W2003 machine, but I guess there’s no relation. Isn’t
it?.

Thanks in advance.

Best regards.

Pablo Frank

Here’s the code fragment (I just included the relevant information):

case IRP_MJ_DIRECTORY_CONTROL:

if(pIrpStack->MinorFunction == IRP_MN_QUERY_DIRECTORY &&
pIrpStack->Parameters.QueryDirectory.FileInformationClass ==
FileBothDirectoryInformation) {

PFILE_BOTH_DIR_INFORMATION QueryBuffer = NULL;
ULONG offset = 0;
ULONG bufferLength = pIrpStack->Parameters.QueryFile.Length;

QueryBuffer = (PFILE_BOTH_DIR_INFORMATION) Irp->UserBuffer;

if( QueryBuffer->NextEntryOffset > bufferLength ) {

break;
}

do {

if (QueryBuffer->FileNameLength != 0) { // I GOT THE
PAGE_FAULT_IN_NONPAGED_AREA error on this line

//Check file name here… not included for simplicity.

QueryBuffer->EndOfFile = NewEof; // I modify the
file’s
information here
QueryBuffer->AllocationSize = NewAllocSize;
}

offset = QueryBuffer->NextEntryOffset;

if (offset != 0) {

QueryBuffer = (PFILE_BOTH_DIR_INFORMATION) ( (PUCHAR) QueryBuffer +
offset );

}

} while( offset != 0 );
}

break;


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


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

Tony:

Thanks very much for your help.

I solved the problem!!!. I found the answer from your question: “why you
think QueryBuffer->FileLength will be valid in this case?”. Well I thougth I
knew that it’s valid because it’s in the completion routine. But I didn’t
take into account that the status could be different than STATUS_SUCCESS. So
I solved the problem adding the following code at the start of the CASE
option (pretty obvious):

case IRP_MJ_DIRECTORY_CONTROL:

if (Irp->IoStatus.Status != STATUS_SUCCESS) {

break;
}

Now it works ok. Again, I thank you very much for your help

Best regards.

Pablo Frank

“Tony Mason” escribió en el mensaje news:xxxxx@ntfsd…
Pablo,

From the information you are providing I can’t tell exactly what you are
doing wrong here. I can see some logical errors in the code, but they are
not going to cause a page fault in non paged area.

# 1 - the ENIRE access (probe and use of the buffer) must be inside the
try/except. Otherwise, I can write a program that will eventually cause you
to crash.

# 2 - the FIELD inside the buffer could be invalid even if the buffer itself
is valid. But again, this wouldn’t cause the specific crash.

Can you provide information from the debugger? If so, tell us the specific
faulting address as well as Irp->UserBuffer address and then the data
contents of Irp->UserBuffer.

Finally, can you tell me why you think QueryBuffer->FileLength will be valid
in this case? Is this AFTER the response from the file system?

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 Pablo G. Frank
Sent: Thursday, January 15, 2004 3:30 PM
To: ntfsd redirect
Subject: Re:[ntfsd] PAGE_FAULT_IN_NONPAGED_AREA in IRP_MJ_DIRECTORY_CONTROL

Hi, Tony.

Thanks, very much, for your answer.

I ran prefast but it found no defects.

Also I omitted the Probe and Try for simplicity.

This is a code excerpt for the probe I used


bufferLength = pIrpStack->Parameters.QueryDirectory.Length;

QueryBuffer = (PFILE_BOTH_DIR_INFORMATION) Irp->UserBuffer;

try {

ProbeForWrite((PVOID) QueryBuffer, bufferLength, sizeof(UCHAR));

} except (EXCEPTION_EXECUTE_HANDLER) {

Irp->IoStatus.Status = GetExceptionCode();
Irp->IoStatus.Information = 0;
break;
}



But in the Do … While it still fails


do {

if (QueryBuffer->FileNameLength != 0) {
//This line fails

// Other stuff here…

}

offset = QueryBuffer->NextEntryOffset;

if (offset != 0) {

QueryBuffer = (PFILE_BOTH_DIR_INFORMATION) ( (PUCHAR) QueryBuffer +
offset );

}
} while( offset != 0 );



This is what I did to solve the problem. Am I crazy?


try {

ProbeForRead((PVOID) &QueryBuffer->FileNameLength, 4, 1);

} except (EXCEPTION_EXECUTE_HANDLER) {

Irp->IoStatus.Status = GetExceptionCode();
Irp->IoStatus.Information = 0;
break;
}

if (QueryBuffer->FileNameLength != 0) { // Now
this line is not reached and the driver doesn’t crash

*****************************

But I guess I’m doing something wrong here, as I think the probe would have
to fail when I probed the Buffer the first time.

Best regards.

Pablo Frank

“Tony Mason” escribió en el mensaje news:xxxxx@ntfsd…
Pablo,

Did you run prefast on this code? It would have caught that
uninitialzed path…

IN ADDITION, this code is inherently unsafe - you are assuming the
application is passing down valid information (QueryBuffer is from user
mode). If you are going to use a user buffer, you must be very careful
about doing so (where are the try/ except handlers here? Why no
probe of the address to ensure it is a UM address? I could generate a
PAGE_FAULT_IN_NONPAGED_AREA given your driver and a few minutes of
(yech) applications writing time.)

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 Pablo G. Frank
Sent: Wednesday, January 14, 2004 8:32 PM
To: ntfsd redirect
Subject: [ntfsd] PAGE_FAULT_IN_NONPAGED_AREA in IRP_MJ_DIRECTORY_CONTROL

Hi:

I’m getting a PAGE_FAULT_IN_NONPAGED_AREA at the
IRP_MJ_DIRECTORY_CONTROL completion routine.

Below is the code fragment.

I modify the files information on the fly. Can anybody suggest what am I
doing wrong?. One detail is that I compiled it to XP and I’m getting
this error on a W2003 machine, but I guess there’s no relation. Isn’t
it?.

Thanks in advance.

Best regards.

Pablo Frank

Here’s the code fragment (I just included the relevant information):

case IRP_MJ_DIRECTORY_CONTROL:

if(pIrpStack->MinorFunction == IRP_MN_QUERY_DIRECTORY &&
pIrpStack->Parameters.QueryDirectory.FileInformationClass ==
FileBothDirectoryInformation) {

PFILE_BOTH_DIR_INFORMATION QueryBuffer = NULL;
ULONG offset = 0;
ULONG bufferLength = pIrpStack->Parameters.QueryFile.Length;

QueryBuffer = (PFILE_BOTH_DIR_INFORMATION) Irp->UserBuffer;

if( QueryBuffer->NextEntryOffset > bufferLength ) {

break;
}

do {

if (QueryBuffer->FileNameLength != 0) { // I GOT THE
PAGE_FAULT_IN_NONPAGED_AREA error on this line

//Check file name here… not included for simplicity.

QueryBuffer->EndOfFile = NewEof; // I modify the
file’s
information here
QueryBuffer->AllocationSize = NewAllocSize;
}

offset = QueryBuffer->NextEntryOffset;

if (offset != 0) {

QueryBuffer = (PFILE_BOTH_DIR_INFORMATION) ( (PUCHAR) QueryBuffer +
offset );

}

} while( offset != 0 );
}

break;


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


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