Поделиться через


Сбой проверки дескрипторов объектов

Некоторые драйверы должны управлять объектами, переданными им вызывающими объектами, или обрабатывать два объекта файлов одновременно. Например, драйвер модема может получать дескриптор объекта события или сетевой драйвер может получать дескрипторы для двух разных файловых объектов. Драйвер должен проверить эти дескрипторы. Поскольку они передаются вызывающим абонентом, а не через диспетчер ввода-вывода, диспетчер операций ввода-вывода не может выполнять проверочные проверки.

Например, в следующем фрагменте кода драйверу передан дескриптор 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) и что режим доступа совместим с запрошенным доступом.

  • Если драйвер ожидает дескриптора для объекта файла, созданного самим драйвером, проверьте дескриптор на соответствие объекту устройства или драйверу. Однако будьте осторожны, чтобы не нарушать фильтры, отправляющие запросы ввода-вывода для странных устройств.

  • Если драйвер поддерживает несколько типов файловых объектов (например, каналы управления, объекты адресов и подключения драйверов TDI или объекты томов, каталогов и файлов файловых систем), убедитесь, что у вас есть способ их отличия.