Compartir a través de


Error al validar identificadores de objeto

Algunos controladores deben manipular objetos pasados por autores de llamadas o deben controlar dos objetos de archivo al mismo tiempo. Por ejemplo, un controlador de módem podría recibir un identificador para un objeto de evento o un controlador de red podría recibir identificadores para dos objetos de archivo diferentes. El controlador debe validar estos identificadores. Dado que se pasan por un autor de la llamada y no a través del administrador de E/S, el administrador de E/S no puede realizar ninguna comprobación de validación.

Por ejemplo, en el siguiente fragmento de código, el controlador se ha pasado el identificador AscInfo-AddressHandle>, pero no lo ha validado antes de llamar a 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) ) {

Aunque la llamada a ObReferenceObjectByHandle se realiza correctamente, el código no puede asegurarse de que el puntero devuelto hace referencia a un objeto de archivo; confía en que el autor de la llamada pase la información correcta.

Incluso si todos los parámetros de la llamada a ObReferenceObjectByHandle son correctos y la llamada se realiza correctamente, un controlador todavía puede obtener resultados inesperados si el objeto de archivo no está pensado para su controlador. En el fragmento de código siguiente, el controlador supone que una llamada correcta devuelve un puntero al objeto de archivo que esperaba:

   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 ) 

Aunque ObReferenceObjectByHandle devuelve un puntero a un objeto de archivo, el controlador no tiene ninguna garantía de que el puntero haga referencia al objeto de archivo que esperaba. En este caso, el controlador debe validar el puntero antes de acceder a los datos específicos del controlador en AcpEndpointFileObject-FsContext>.

Para evitar estos problemas, un controlador debe comprobar si hay datos válidos, como se indica a continuación:

  • Compruebe el tipo de objeto para asegurarse de que es lo que espera el controlador.

  • Asegúrese de que el acceso solicitado sea adecuado para el tipo de objeto y las tareas necesarias. Si el controlador realiza una copia rápida de archivos, por ejemplo, asegúrese de que el identificador tenga acceso de lectura.

  • Asegúrese de especificar el modo de acceso correcto (UserMode o KernelMode) y de que el modo de acceso sea compatible con el acceso solicitado.

  • Si el controlador espera un identificador a un objeto de archivo que creó el propio controlador, valide el identificador en el objeto de dispositivo o controlador. Sin embargo, tenga cuidado de no interrumpir los filtros que envían solicitudes de E/S para dispositivos extraños.

  • Si el controlador admite varios tipos de objetos de archivo (como los canales de control, los objetos de dirección y las conexiones de controladores TDI o objetos Volume, Directory y File de sistemas de archivos), asegúrese de que tiene una manera de diferenciarlos.