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.