SPIN_LOCK ACQUIRING ISSUE

Hi all,

I am writing minifilter driver, and working functionality is that user mode application send message to driver, that reads data from file and load into doubly link list. I am acquiring and releasing SPIN_LOCK in both cases… (Insert into List and Remove from List).

Issue is that it is crashing… when user mode application continuous send message to load list, and also crashing in verifier.

(Msg to Driver)
User Mode Application -------------------> Driver(Remove List) -----> Driver (Read File ) ----> Driver (Load data into List).

Code are following.

NTSTATUS
FL_FltMessage (
__in PVOID ConnectionCookie,
__in_bcount_opt(InputBufferSize) PVOID InputBuffer,
__in ULONG InputBufferSize,
__out_bcount_part_opt(OutputBufferSize,*ReturnOutputBufferLength) PVOID OutputBuffer,
__in ULONG OutputBufferSize,
__out PULONG ReturnOutputBufferLength
)
{
LONG cBytes = 0;
char buffer[5];
UNICODE_STRING ustrEmpty,uStrPath;

NTSTATUS ntstatus;
LARGE_INTEGER offset;
UNICODE_STRING uniName;
UNICODE_STRING gDriveLetter;

RtlInitUnicodeString(&ustrEmpty, L"");

PAGED_CODE();
try
{
ProbeForRead(InputBuffer,InputBufferSize,1);

if(strcmp(InputBuffer,“updtlist”)==0) // Do Update
{
DbgPrint(“Update… List…\n”);
gLock = FALSE;
RemoveList(1);
_ReadDataFile(0);
gLock = TRUE;
}
}
except (EXCEPTION_EXECUTE_HANDLER)
{
DbgPrint(“Execption…\n”);
}

return STATUS_SUCCESS;
}

BOOLEAN Insertinto_Lock_List(UNICODE_STRING r_strUser,UNICODE_STRING r_strDataPath,BYTE r_dataType)
{
PFLDATALIST pCurrentNode;
KIRQL oldIrql;

pCurrentNode = ExAllocatePoolWithTag(PagedPool,sizeof(FLDATALIST),‘st1’);

RtlStringCbCopyW(pCurrentNode->m_DataPath,r_strDataPath.MaximumLength,r_strDataPath.Buffer);

pCurrentNode->m_bytType = r_dataType;

KeAcquireSpinLock(&gOutputBufferLock, &oldIrql ); // SPIN LOCK ACQUIRE

if(gLockList.Flink == &gLockList)
{
InsertHeadList(&gLockList, &pCurrentNode->m_ListEntry);
}
else
{
InsertTailList(&gLockList, &pCurrentNode->m_ListEntry);
}

KeReleaseSpinLock(&gOutputBufferLock, oldIrql ); // SPIN LOCK RELEASE

return TRUE;
}
BOOLEAN RemoveList(int r_Param)
{
PFLDATALIST pListNode;
PLIST_ENTRY pList;
KIRQL oldIrql;
if (gLockList.Flink != &gLockList && (r_Param == 0 || r_Param == 1))
{
KeAcquireSpinLock(&gOutputBufferLock, &oldIrql );
while(gLockList.Flink!=&gLockList)
{
pList = RemoveTailList(&gLockList);
pListNode = CONTAINING_RECORD( pList, FLDATALIST, m_ListEntry);
ExFreePoolWithTag(pListNode,‘st1’);
}
KeReleaseSpinLock(&gOutputBufferLock, oldIrql );
}
return TRUE;
}

Let me know where I am going wrong.

Thanks,

If you want someone to look at a crash for you, you need to post the
!analyze -v output.

-scott


Scott Noone
Consulting Associate and Chief System Problem Analyst
OSR Open Systems Resources, Inc.
http://www.osronline.com

wrote in message news:xxxxx@ntfsd…

Hi all,

I am writing minifilter driver, and working functionality is that user mode
application send message to driver, that reads data from file and load into
doubly link list. I am acquiring and releasing SPIN_LOCK in both cases…
(Insert into List and Remove from List).

Issue is that it is crashing… when user mode application continuous send
message to load list, and also crashing in verifier.

(Msg to Driver)
User Mode Application -------------------> Driver(Remove List) -----> Driver
(Read File ) ----> Driver (Load data into List).

Code are following.

NTSTATUS
FL_FltMessage (
__in PVOID ConnectionCookie,
__in_bcount_opt(InputBufferSize) PVOID InputBuffer,
__in ULONG InputBufferSize,
__out_bcount_part_opt(OutputBufferSize,*ReturnOutputBufferLength) PVOID
OutputBuffer,
__in ULONG OutputBufferSize,
__out PULONG ReturnOutputBufferLength
)
{
LONG cBytes = 0;
char buffer[5];
UNICODE_STRING ustrEmpty,uStrPath;

NTSTATUS ntstatus;
LARGE_INTEGER offset;
UNICODE_STRING uniName;
UNICODE_STRING gDriveLetter;

RtlInitUnicodeString(&ustrEmpty, L"");

PAGED_CODE();
try
{
ProbeForRead(InputBuffer,InputBufferSize,1);

if(strcmp(InputBuffer,“updtlist”)==0) // Do Update
{
DbgPrint(“Update… List…\n”);
gLock = FALSE;
RemoveList(1);
_ReadDataFile(0);
gLock = TRUE;
}
}
except (EXCEPTION_EXECUTE_HANDLER)
{
DbgPrint(“Execption…\n”);
}

return STATUS_SUCCESS;
}

BOOLEAN Insertinto_Lock_List(UNICODE_STRING r_strUser,UNICODE_STRING
r_strDataPath,BYTE r_dataType)
{
PFLDATALIST pCurrentNode;
KIRQL oldIrql;

pCurrentNode = ExAllocatePoolWithTag(PagedPool,sizeof(FLDATALIST),‘st1’);

RtlStringCbCopyW(pCurrentNode->m_DataPath,r_strDataPath.MaximumLength,r_strDataPath.Buffer);

pCurrentNode->m_bytType = r_dataType;

KeAcquireSpinLock(&gOutputBufferLock, &oldIrql ); // SPIN LOCK ACQUIRE

if(gLockList.Flink == &gLockList)
{
InsertHeadList(&gLockList, &pCurrentNode->m_ListEntry);
}
else
{
InsertTailList(&gLockList, &pCurrentNode->m_ListEntry);
}

KeReleaseSpinLock(&gOutputBufferLock, oldIrql ); // SPIN LOCK RELEASE

return TRUE;
}
BOOLEAN RemoveList(int r_Param)
{
PFLDATALIST pListNode;
PLIST_ENTRY pList;
KIRQL oldIrql;
if (gLockList.Flink != &gLockList && (r_Param == 0 || r_Param == 1))
{
KeAcquireSpinLock(&gOutputBufferLock, &oldIrql );
while(gLockList.Flink!=&gLockList)
{
pList = RemoveTailList(&gLockList);
pListNode = CONTAINING_RECORD( pList, FLDATALIST, m_ListEntry);
ExFreePoolWithTag(pListNode,‘st1’);
}
KeReleaseSpinLock(&gOutputBufferLock, oldIrql );
}
return TRUE;
}

Let me know where I am going wrong.

Thanks,

Well the actual crash is because you allocate the list entry from
PagedPool then manipulate it inside a spin lock. You should not
reference paged memory at DISPATCH_LEVEL which is what the spin lock
causes.

In general this code is a mess, and something I hope would never go into
a file system stack on a real machine. You are using strcmp to test a
user buffer with no validation, so you have a great security hole to
crash the system. You also have bogus code for your list handling
testing that the lists Flink points to itself is actually at test for an
empty list (use IsListEmpty() ) but why are you doing this since if you
always inserted at the end of the list the same result would occur.

Go back and learn some basics, mucking in the file system stack when you
general kernel knowledge is this low is just a cause for disasters.

Don Burn (MVP, Windows DKD)
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

xxxxx@yahoo.com” wrote in message
news:xxxxx@ntfsd:

> Hi all,
>
> I am writing minifilter driver, and working functionality is that user mode application send message to driver, that reads data from file and load into doubly link list. I am acquiring and releasing SPIN_LOCK in both cases… (Insert into List and Remove from List).
>
> Issue is that it is crashing… when user mode application continuous send message to load list, and also crashing in verifier.
>
> (Msg to Driver)
> User Mode Application -------------------> Driver(Remove List) -----> Driver (Read File ) ----> Driver (Load data into List).
>
> Code are following.
>
>
>
>
> NTSTATUS
> FL_FltMessage (
> in PVOID ConnectionCookie,
>
in_bcount_opt(InputBufferSize) PVOID InputBuffer,
> in ULONG InputBufferSize,
>
out_bcount_part_opt(OutputBufferSize,*ReturnOutputBufferLength) PVOID OutputBuffer,
> in ULONG OutputBufferSize,
>
out PULONG ReturnOutputBufferLength
> )
> {
> LONG cBytes = 0;
> char buffer[5];
> UNICODE_STRING ustrEmpty,uStrPath;
>
> NTSTATUS ntstatus;
> LARGE_INTEGER offset;
> UNICODE_STRING uniName;
> UNICODE_STRING gDriveLetter;
>
> RtlInitUnicodeString(&ustrEmpty, L"");
>
> PAGED_CODE();
> try
> {
> ProbeForRead(InputBuffer,InputBufferSize,1);
>
> if(strcmp(InputBuffer,“updtlist”)==0) // Do Update
> {
> DbgPrint(“Update… List…\n”);
> gLock = FALSE;
> RemoveList(1);
> _ReadDataFile(0);
> gLock = TRUE;
> }
> }
> except (EXCEPTION_EXECUTE_HANDLER)
> {
> DbgPrint(“Execption…\n”);
> }
>
> return STATUS_SUCCESS;
> }
>
> BOOLEAN Insertinto_Lock_List(UNICODE_STRING r_strUser,UNICODE_STRING r_strDataPath,BYTE r_dataType)
> {
> PFLDATALIST pCurrentNode;
> KIRQL oldIrql;
>
>
>
> pCurrentNode = ExAllocatePoolWithTag(PagedPool,sizeof(FLDATALIST),‘st1’);
>
> RtlStringCbCopyW(pCurrentNode->m_DataPath,r_strDataPath.MaximumLength,r_strDataPath.Buffer);
>
> pCurrentNode->m_bytType = r_dataType;
>
> KeAcquireSpinLock(&gOutputBufferLock, &oldIrql ); // SPIN LOCK ACQUIRE
>
> if(gLockList.Flink == &gLockList)
> {
> InsertHeadList(&gLockList, &pCurrentNode->m_ListEntry);
> }
> else
> {
> InsertTailList(&gLockList, &pCurrentNode->m_ListEntry);
> }
>
> KeReleaseSpinLock(&gOutputBufferLock, oldIrql ); // SPIN LOCK RELEASE
>
> return TRUE;
> }
> BOOLEAN RemoveList(int r_Param)
> {
> PFLDATALIST pListNode;
> PLIST_ENTRY pList;
> KIRQL oldIrql;
> if (gLockList.Flink != &gLockList && (r_Param == 0 || r_Param == 1))
> {
> KeAcquireSpinLock(&gOutputBufferLock, &oldIrql );
> while(gLockList.Flink!=&gLockList)
> {
> pList = RemoveTailList(&gLockList);
> pListNode = CONTAINING_RECORD( pList, FLDATALIST, m_ListEntry);
> ExFreePoolWithTag(pListNode,‘st1’);
> }
> KeReleaseSpinLock(&gOutputBufferLock, oldIrql );
> }
> return TRUE;
> }
>
> Let me know where I am going wrong.
>
> Thanks,