共用方式為


驗證物件控制碼失敗

某些驅動程式必須操作呼叫端傳遞給它們的物件,或必須同時處理兩個檔案物件。 例如,數據機驅動程式可能會接收事件物件的控制碼,或者網路驅動程式可能會接收兩個不同的檔案物件的控制碼。 驅動程式必須驗證這些控制碼。 因為它們是由呼叫端傳遞,而不是透過 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 >上的驅動程式特定資料。

若要避免這類問題,驅動程式應該檢查有效的資料,如下所示:

  • 請檢查物件類型,確定其為驅動程式預期的內容。

  • 請確定要求的存取權適用于物件類型和必要工作。 例如,如果您的驅動程式執行快速檔案複製,請確定控制碼具有讀取權限。

  • 請務必指定正確的存取模式 (UserModeKernelMode) ,且存取模式與要求的存取模式相容。

  • 如果驅動程式預期驅動程式本身所建立的檔案物件有控制碼,請針對裝置物件或驅動程式驗證控制碼。 不過,請小心不要中斷傳送奇怪裝置 I/O 要求的篩選。

  • 如果您的驅動程式支援多種檔案物件 (,例如 TDI 驅動程式的控制通道、位址物件,以及 TDI 驅動程式或磁片區、目錄和檔案系統的檔案物件) ,請確定您可以區分它們。