Compartilhar via


Falha ao validar identificadores de objeto

Alguns drivers devem manipular objetos passados para eles por chamadores ou devem manipular dois objetos de arquivo ao mesmo tempo. Por exemplo, um driver de modem pode receber um identificador para um objeto de evento ou um driver de rede pode receber identificadores para dois objetos de arquivo diferentes. O driver deve validar esses identificadores. Como eles são passados por um chamador e não por meio do gerente de E/S, o gerente de E/S não pode executar nenhuma verificação de validação.

Por exemplo, no snippet de código a seguir, o driver foi passado para o identificador AscInfo-AddressHandle>, mas não o validou antes de chamar 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) ) {

Embora a chamada para ObReferenceObjectByHandle seja bem-sucedida, o código falha ao garantir que o ponteiro retornado faça referência a um objeto de arquivo; ele confia no chamador para passar as informações corretas.

Mesmo que todos os parâmetros da chamada para ObReferenceObjectByHandle estejam corretos e a chamada for bem-sucedida, um driver ainda poderá obter resultados inesperados se o objeto de arquivo não for destinado ao driver. No fragmento de código a seguir, o driver pressupõe que uma chamada bem-sucedida retorna um ponteiro para o objeto de arquivo esperado:

   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 ) 

Embora ObReferenceObjectByHandle retorne um ponteiro para um objeto de arquivo, o driver não tem nenhuma garantia de que o ponteiro referencie o objeto de arquivo esperado. Nesse caso, o driver deve validar o ponteiro antes de acessar os dados específicos do driver em AcpEndpointFileObject-FsContext>.

Para evitar esses problemas, um driver deve marcar dados válidos, da seguinte maneira:

  • Verifique o tipo de objeto para verificar se é o que o driver espera.

  • Verifique se o acesso solicitado é apropriado para o tipo de objeto e as tarefas necessárias. Se o driver executar uma cópia de arquivo rápida, por exemplo, verifique se o identificador tem acesso de leitura.

  • Especifique o modo de acesso correto (UserMode ou KernelMode) e se o modo de acesso é compatível com o acesso solicitado.

  • Se o driver espera um identificador para um objeto de arquivo que o próprio driver criou, valide o identificador em relação ao objeto ou driver do dispositivo. No entanto, tenha cuidado para não quebrar filtros que enviam solicitações de E/S para dispositivos estranhos.

  • Se o driver der suporte a vários tipos de objetos de arquivo (como canais de controle, objetos de endereço e conexões de drivers TDI ou objetos Volume, Diretório e Arquivo de sistemas de arquivos), verifique se você tem uma maneira de diferenciá-los.