Condividi tramite


Errori nel riferimento agli indirizzi User-Space

Qualsiasi driver, indipendentemente dal supporto di IRP o operazioni di I/O veloci, deve convalidare qualsiasi indirizzo nello spazio utente prima di provare a usarlo. Il gestore di I/O non convalida tali indirizzi, né convalida i puntatori incorporati nei buffer passati ai driver.

Errore di convalida degli indirizzi passati in METHOD_NEITHER IOCTLs eLS

Il gestore di I/O non esegue alcuna convalida per METHOD_NEITHER IOCTLs e MDFTLs. Per garantire che gli indirizzi dello spazio utente siano validi, il driver deve usare le routine ProbeForRead e ProbeForWrite , racchiudendo tutti i riferimenti al buffer in blocchi try/except .

Nell'esempio seguente, il driver presuppone che il valore passato in Type3InputBuffer rappresenti un indirizzo valido.

   case IOCTL_GET_HANDLER:
   {
      PULONG EntryPoint;

      EntryPoint =
         IrpSp->Parameters.DeviceIoControl.Type3InputBuffer; 
      *EntryPoint = (ULONG)DriverEntryPoint; 
      ...
   }

Il codice seguente evita questo problema:

   case IOCTL_GET_HANDLER:
   {
      PULONG_PTR EntryPoint;

      EntryPoint =
         IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
 
      try
      {
         if (Irp->RequestorMode != KernelMode)
         { 
            ProbeForWrite(EntryPoint,
                          sizeof(ULONG_PTR),
                          TYPE_ALIGNMENT(ULONG_PTR));
         }
         *EntryPoint = (ULONG_PTR)DriverEntryPoint;
      }
      except(EXCEPTION_EXECUTE_HANDLER)
      {
        ...
      }
      ...
   }

Si noti anche che il codice corretto esegue il cast di DriverEntryPoint a un ULONG_PTR, invece di un ULONG. Questa modifica consente l'uso in un ambiente Windows a 64 bit.

Errore di convalida dei puntatori incorporati nelle richieste di I/O memorizzate nel buffer

Spesso i puntatori di incorporamento all'interno delle richieste memorizzate nel buffer, come nell'esempio seguente:

   struct ret_buf
   {
      void  *arg;  // Pointer embedded in request
      int  rval;
   };

   pBuf = Irp->AssociatedIrp.SystemBuffer;
   ...
   arg = pBuf->arg;  // Fetch the embedded pointer
   ...
   // If the arg pointer is not valid, the following
   // statement can corrupt the system:
   RtlMoveMemory(arg, &info, sizeof(info));

In questo esempio, il driver deve convalidare il puntatore incorporato usando le routine ProbeXxx racchiuse in un blocco try/except nello stesso modo dei METHOD_NEITHER IOCTLs descritti in precedenza. Anche se l'incorporamento di un puntatore consente a un driver di restituire informazioni aggiuntive, un driver può ottenere in modo più efficiente lo stesso risultato usando un offset relativo o un buffer di lunghezza variabile.

Per altre informazioni sull'uso di blocchi try/except per gestire indirizzi non validi, vedere Gestione delle eccezioni.