Hello everyone,
I’m working on a network driver, which is based on the Windows Filtering Platform and stands for the network packets interception. Then the intercepted packets are pushed to the user-mode system service, which is analyzing these packets.
The driver is quite stable for me, but according to users’ feedback it produces the PAGE_FAULT_IN_NONPAGED_AREA bugcheck on the OpenVPN startup (for desktops) and on Windows Surface Pro. I tried to reproduce the issue with the OpenVPN, but failed.
Here is the bugcheck info:
PAGE_FAULT_IN_NONPAGED_AREA (50)
Invalid system memory was referenced. This cannot be protected by try-except,
it must be protected by a Probe. Typically the address is just plain bad or it
is pointing at freed memory.
Arguments:
Arg1: ffffe000815550f4, memory referenced.
Arg2: 0000000000000000, value 0 = read operation, 1 = write operation.
Arg3: fffff80083c54450, If non-zero, the instruction address which referenced the bad memory address.
Arg4: 0000000000000000, (reserved)
Analyzing the crash dump I have found out that the problem is about the following code:
void *pbuf_data_v = NULL;
NET_BUFFER *pbuf_v = NULL;
ulong pkt_size_v = 0;
bb_byte_blob_t pkt_v; // the source code of the bb_byte_blob_t is below
pbuf_v = NET_BUFFER_LIST_FIRST_NB(pdata->_ppkt); // pdata->_ppkt is a pointer to the NET_BUFFER_LIST structure
CHECK_NULL(pbuf_v, status_v, exit_l); // just checks whether the pbuf_v is NULL
pbuf_data_v = NdisGetDataBuffer(pbuf_v, pkt_size_v, NULL, 1, 0); // getting the pointer to the buffer
CHECK_NULL(pbuf_data_v, status_v, exit_l);
status_v = bb_assign(&pkt_v, pbuf_data_v, pkt_size_v); // makes a copy of the packet (source is below). BSOD happens here
CHECK_ERROR(status_v, exit_l);
…
Here is the source code of the bb_byte_blob_t:
#pragma pack(push, 1)
struct bb_byte_blob_t
{
void *_buffer;
uint _size;
};
#pragma pack(pop)
Here is the source of the bb_assign():
NTSTATUS bb_assign(bb_byte_blob_t *pbb, void *pdata, uint size)
{
NTSTATUS status_v = STATUS_UNSUCCESSFUL;
NULL_ASSERT(“pbb == NULL”, pbb);
NULL_ASSERT(“pdata == NULL”, pdata);
status_v = bb_allocate(pbb, size); // allocates the buffer the source code is below
CHECK_ERROR(status_v, exit_l);
RtlCopyMemory(pbb->_buffer, pdata, size); // the BSOD is here
exit_l:
return status_v;
}
NTSTATUS bb_allocate(bb_byte_blob_t *pbb, uint size)
{
NTSTATUS status_v = STATUS_MEMORY_NOT_ALLOCATED;
NULL_ASSERT(“pbb == NULL”, pbb);
pbb->_buffer = NULL;
pbb->_size = 0;
if (size > 0)
{
M_ALLOC(pbb->_buffer, size); // macros for ExAllocatePoolWithTag()
if (NULL != pbb->_buffer)
{
pbb->_size = size;
status_v = STATUS_SUCCESS;
}
}
return status_v;
}
Since the crash dump’s Arg2 is 0, I may assume that the problem is in the NdisGetDataBuffer() function, which is probably returns the corrupted pointer, but I have no idea why this may happen?
Any help will be appreciated!
Thanks in advance,
Richard