Jump-start your project by learning from devs who
write Windows drivers and file systems every day.
Take an OSR seminar!

OSR is Hiring! Click here to find out more.

Upcoming OSR Seminars:
Windows Internals & Software Drivers Lab, Santa Clara, CA 5-9 August, 2013
Kernel Debugging & Crash Analysis for Windows Lab, Santa Clara, CA 9-13 September, 2013
Writing WDF Drivers for Windows Lab, Boston, MA 7-11 October, 2013
Developing File Systems for Windows, Seattle, WA 5-8 November, 2013


Go Back   OSR Online Lists > ntfsd
Welcome, Guest
You must login to post to this list
  Message 1 of 4  
04 Jul 12 02:50
Musharraf Hussain
xxxxxx@yahoo.com
Join Date: 17 Sep 2008
Posts To This List: 88
APC level access local variable

Hi all, I am writing minifilter driver, and using Fast Mutex to lock before accessing my AVL TREE. DATAFILEINFO tbObj; // Local structure Variable BOOLEAN bSuccess = FALSE; // Local Boolean Variable if(uPath.Buffer != NULL && gListLock) { GetLock(DATALOCK); RtlStringCbCopyW(tbObj.m_DataPath,uPath.MaximumLength,uPath.Buffer); // accessing local variable in APC_LEVEL if(RtlIsGenericTableEmptyAvl(&gLockTable) == FALSE) { if(RtlLookupElementGenericTableAvl(&gLockTable,&tbObj) != NULL) { bSuccess = TRUE; } } ReleaseLock(DATALOCK); } return bSuccess; I have following queries : 1- AT APC_LEVEL memory can be allocated from any pool PagedPool or NonPagedPool ? 2- AT APC_LEVEL local variable can be accessed ? 3- AT APC_LEVEL Global variable can be accessed ?
  Message 2 of 4  
04 Jul 12 09:22
Tony Mason
xxxxxx@osr.com
Join Date:
Posts To This List: 2356
List Moderator
RE: APC level access local variable

<quote> 1- AT APC_LEVEL memory can be allocated from any pool PagedPool or NonPagedPool ? </quote> Yes. <quote> 2- AT APC_LEVEL local variable can be accessed ? </quote> Yes. <quote> 3- AT APC_LEVEL Global variable can be accessed ? </quote? Yes. However, it is at this level that you may need to implement synchronization. Tony OSR
  Message 3 of 4  
05 Jul 12 04:50
Musharraf Hussain
xxxxxx@yahoo.com
Join Date: 17 Sep 2008
Posts To This List: 88
RE: APC level access local variable

Hi Tony, I using following PreOperation to trace IRP_MJ_CREATE for specific file. FLT_PREOP_CALLBACK_STATUS FltPreOperationCallback ( __inout PFLT_CALLBACK_DATA Data, __in PCFLT_RELATED_OBJECTS FltObjects, __deref_out PVOID *CompletionContext ) { FLT_PREOP_CALLBACK_STATUS returnStatus = FLT_PREOP_SUCCESS_NO_CALLBACK; //assume we are NOT going to call our completion routine PFLT_FILE_NAME_INFORMATION nameInfo = NULL; UNICODE_STRING defaultName; PFLT_VOLUME pFLTVolume; PUNICODE_STRING nameToUse = NULL; UNICODE_STRING uStrGuidName,uStrPath,uVolume,uStrExtension; PUNICODE_STRING pStrExtension = NULL; NTSTATUS status,nStatus; UNICODE_STRING uStrVolume; UNICODE_STRING uStrParentPath; BYTE bAccessType = 0; BOOLEAN bMatched = FALSE; try { RtlInitUnicodeString(&uStrExtension,L"exe"); if(KeGetCurrentIrql()== PASSIVE_LEVEL && (Data->Iopb->MajorFunction == IRP_MJ_CREATE ||Data->Iopb->MajorFunction==IRP_MJ_SET_INFORMATION || Data->Iopb->MajorFunction==IRP_MJ_WRITE || Data->Iopb->MajorFunction==IRP_MJ_READ || Data->Iopb->MajorFunction==IRP_MJ_CLEANUP)) { RtlInitUnicodeString(&uStrGuidName,NULL); RtlInitUnicodeString(&uStrPath,NULL); RtlInitUnicodeString(&uStrParentPath,NULL); if (FltObjects->FileObject != NULL) { // Check if FileObject is NULL status = FltGetFileNameInformation( Data,FLT_FILE_NAME_OPENED |FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP, &nameInfo ); } else { status = STATUS_UNSUCCESSFUL; } if (NT_SUCCESS( status )) { status = FltParseFileNameInformation( nameInfo ); ASSERT(NT_SUCCESS(status)); } if(NT_SUCCESS(status)) { nStatus = FltGetVolumeFromFileObject(WinFLTData.m_Filter,FltObjects->FileObject,&pFLTVolume ); if(NT_SUCCESS(nStatus)) { uStrGuidName.Length = 0; uStrGuidName.MaximumLength = 520; uStrGuidName.Buffer = (PWSTR)ExAllocatePoolWithTag(NonPagedPool,520,'uLT1'); if(uStrGuidName.Buffer != NULL) nStatus = FltGetVolumeGuidName(pFLTVolume,&uStrGuidName,NULL); FltObjectDereference(pFLTVolume); if(NT_SUCCESS(nStatus) && uStrGuidName.Buffer != NULL && nameInfo->Name.Length > 0) { uStrPath.Length = 0 ; uStrPath.MaximumLength = nameInfo->Name.Length + 520; uStrPath.Buffer = (PWSTR)ExAllocatePoolWithTag(NonPagedPool,nameInfo->Name.Length + 520,'uLT2'); uStrParentPath.Length = 0 ; uStrParentPath.MaximumLength = nameInfo->Name.Length + 520; uStrParentPath.Buffer = (PWSTR)ExAllocatePoolWithTag(NonPagedPool,nameInfo->Name.Length + 520,'uLT3'); if(uStrPath.Buffer != NULL && uStrParentPath.Buffer != NULL) { RtlAppendUnicodeStringToString(&uStrPath,&uStrGuidName); RtlAppendUnicodeStringToString(&uStrPath,&nameInfo->ParentDir); RtlAppendUnicodeStringToString(&uStrPath,&nameInfo->FinalComponent); RtlAppendUnicodeStringToString(&uStrParentPath,&uStrGuidName); RtlAppendUnicodeStringToString(&uStrParentPath,&nameInfo->ParentDir); if(Data->Iopb->MajorFunction == IRP_MJ_CREATE && gListLock ) { if(Traverseinto_NoAccess_List(uStrPath)) bMatched = TRUE; } } if(uStrParentPath.Buffer != NULL) { ExFreePoolWithTag(uStrParentPath.Buffer,'uLT3'); uStrParentPath.Buffer = NULL; } if(uStrPath.Buffer != NULL) { ExFreePoolWithTag(uStrPath.Buffer,'uLT2'); uStrPath.Buffer = NULL; } } if(uStrGuidName.Buffer != NULL) { ExFreePoolWithTag(uStrGuidName.Buffer,'uLT1'); uStrGuidName.Buffer = NULL; } } } if (nameInfo != NULL) { FltReleaseFileNameInformation( nameInfo ); nameInfo = NULL; } if(bMatched) { Data->IoStatus.Status = STATUS_ACCESS_DENIED ; Data->IoStatus.Information = 0; FltSetCallbackDataDirty(Data); return FLT_PREOP_COMPLETE; } } } except (EXCEPTION_EXECUTE_HANDLER) { if(uStrParentPath.Buffer != NULL) { ExFreePoolWithTag(uStrParentPath.Buffer,'uLT3'); uStrParentPath.Buffer = NULL; } if(uStrPath.Buffer != NULL) { ExFreePoolWithTag(uStrPath.Buffer,'uLT2'); uStrPath.Buffer = NULL; } if(uStrGuidName.Buffer != NULL) { ExFreePoolWithTag(uStrGuidName.Buffer,'uLT1'); uStrGuidName.Buffer = NULL; } if (nameInfo != NULL) { FltReleaseFileNameInformation( nameInfo ); nameInfo = NULL; } } if (Data->Iopb->MajorFunction == IRP_MJ_SHUTDOWN) { FltPostOperationCallback( Data, FltObjects, NULL, 0 ); returnStatus = FLT_PREOP_SUCCESS_NO_CALLBACK; } else { *CompletionContext = NULL; returnStatus = FLT_PREOP_SUCCESS_WITH_CALLBACK; } return returnStatus; } In above preoperation function to match with specific file using following function like : // RTL_AVL_TABLE gLockTable // FAST_MUTEX hLockMutex // DATAFILEINFO structure typedef struct _DATAFILEINFO { int m_ID; BYTE m_SecurityLevel; BYTE m_NoAccessType; BYTE m_NoVisibleType; BYTE m_NoDeleteType; BYTE m_NoWriteType; BYTE m_DataType; BYTE m_Mask; wchar_t m_MaskCode[10]; wchar_t m_DataPath[MAX_PATH]; }DATAFILEINFO, *PDATAFILEINFO; BOOLEAN Traverseinto_NoAccess_List(UNICODE_STRING uPath) { DATAFILEINFO tbObj; BOOLEAN bSuccess = FALSE; DbgPrint("Traverse into Lock List"); if(gListLock) { ExAcquireFastMutex( &hLockMutex ); RtlStringCbCopyW(tbObj.m_DataPath,uPath.MaximumLength,uPath.Buffer); //GetLock(DATALOCK); if(RtlIsGenericTableEmptyAvl(&gLockTable) == FALSE) { if(RtlLookupElementGenericTableAvl(&gLockTable,&tbObj) != NULL) { bSuccess = TRUE; } } //ReleaseLock(DATALOCK); ExReleaseFastMutex( &hLockMutex ); } return bSuccess; } Note when I am not this function to traverse table then working fine , but when I traversed this function then getting BSOD, with this message Debug overrun buffer like. Let me know if anybody can help this. Thanks
  Message 4 of 4  
05 Jul 12 11:35
Tony Mason
xxxxxx@osr.com
Join Date:
Posts To This List: 2356
List Moderator
RE: RE:APC level access local variable

This has nothing to do with APCs or IRQL APC_LEVEL. This looks like a basic coding bug (buffer overrun) to me. RtlStringCbCopyW(tbObj.m_DataPath,uPath.MaximumLength,uPath.Buffer); You use the size of the SOURCE buffer for the second parameter. I would expect this to be MAX_PATH (I have no idea what your value to this is, but I guarantee that if it were large enough this code would have crashed sooner). The maximum path length in Windows is 65534 bytes (32767 wide characters) . If MAX_PATH is 32767 (which is what it should be according to your sample code) then this structure would have overflowed the stack and you would have crashed prior to that time. So, to fix the immediate cause of your problem, try setting the second parameter: RtlStringCbCopyW(tbObj.m_DataPath,MAX_PATH*sizeof(WCHAR),uPath.Buffer); But I suspect you will find that truncates the path (based on whatever value that you have set for MAX_PATH). For example, if you use the value from windef.h (260) that would explain your problem - that's the max path length for an MS-DOS program (or for the Win32 API without using the path length escaping syntax for the name). Tony OSR
Posting Rules  
You may not post new threads
You may not post replies
You may not post attachments
You must login to OSR Online AND be a member of the ntfsd list to be able to post.

All times are GMT -5. The time now is 19:05.


Copyright ©2012, OSR Open Systems Resources, Inc.
Based on vBulletin Copyright ©2000 - 2005, Jelsoft Enterprises Ltd.
Modified under license