驗證物件控制碼失敗
某些驅動程式必須操作呼叫端傳遞給它們的物件,或必須同時處理兩個檔案物件。 例如,數據機驅動程式可能會接收事件物件的控制碼,或者網路驅動程式可能會接收兩個不同的檔案物件的控制碼。 驅動程式必須驗證這些控制碼。 因為它們是由呼叫端傳遞,而不是透過 I/O 管理員傳遞,所以 I/O 管理員無法執行任何驗證檢查。
例如,在下列程式碼片段中,驅動程式已傳遞控制碼 AscInfo-AddressHandle >,但在呼叫 ObReferenceObjectByHandle之前尚未驗證它:
//
// This handle is embedded in a buffered request.
//
status = ObReferenceObjectByHandle(
AscInfo->AddressHandle,
0,
NULL,
KernelMode,
&fileObject,
NULL);
if (NT_SUCCESS(status)) {
if ( (fileObject->DeviceObject == DeviceObject) &&
(fileObject->FsContext2 == TRANSPORT_SOCK) ) {
雖然 對 ObReferenceObjectByHandle 的呼叫成功,但程式碼無法確保傳回的指標參考檔案物件;它會信任呼叫端傳入正確的資訊。
即使 呼叫 ObReferenceObjectByHandle 的所有參數都正確,而且呼叫成功,如果檔案物件不適合其驅動程式,驅動程式仍會收到非預期的結果。 在下列程式碼片段中,驅動程式假設成功呼叫會傳回預期之檔案物件的指標:
status = ObReferenceObjectByHandle (
AcpInfo->Handle,
0L,
DesiredAccess,
*IoFileObjectType,
Irp->RequestorMode,
(PVOID *)&AcpEndpointFileObject,
NULL);
if ( !NT_SUCCESS(status) ) {
goto complete;
}
AcpEndpoint = AcpEndpointFileObject->FsContext;
if ( AcpEndpoint->Type != BlockTypeEndpoint )
雖然 ObReferenceObjectByHandle 會傳回檔案物件的指標,但驅動程式不保證指標參考預期的檔案物件。 在此情況下,驅動程式應該先驗證指標,再存取 AcpEndpointFileObject-FsCoNtext >上的驅動程式特定資料。
若要避免這類問題,驅動程式應該檢查有效的資料,如下所示:
請檢查物件類型,確定其為驅動程式預期的內容。
請確定要求的存取權適用于物件類型和必要工作。 例如,如果您的驅動程式執行快速檔案複製,請確定控制碼具有讀取權限。
請務必指定正確的存取模式 (UserMode 或 KernelMode) ,且存取模式與要求的存取模式相容。
如果驅動程式預期驅動程式本身所建立的檔案物件有控制碼,請針對裝置物件或驅動程式驗證控制碼。 不過,請小心不要中斷傳送奇怪裝置 I/O 要求的篩選。
如果您的驅動程式支援多種檔案物件 (,例如 TDI 驅動程式的控制通道、位址物件,以及 TDI 驅動程式或磁片區、目錄和檔案系統的檔案物件) ,請確定您可以區分它們。