Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Qualquer driver, seja compatível com IRPs ou operações rápidas de E/S, deve validar qualquer endereço no espaço do usuário antes de tentar usá-lo. O gerenciador de E/S não valida esses endereços nem valida ponteiros inseridos em buffers passados para drivers.
Falha em validar os endereços passados em METHOD_NEITHER IOCTLs e FSCTLs
O gerente de E/S não faz nenhuma validação para METHOD_NEITHER IOCTLs e FSCTLs. Para garantir que os endereços de espaço do usuário sejam válidos, o driver deve usar as rotinas ProbeForRead e ProbeForWrite , incluindo todas as referências de buffer em blocos try/except .
No exemplo a seguir, o driver pressupõe que o valor passado no Type3InputBuffer representa um endereço válido.
case IOCTL_GET_HANDLER:
{
PULONG EntryPoint;
EntryPoint =
IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
*EntryPoint = (ULONG)DriverEntryPoint;
...
}
O código a seguir evita esse 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)
{
...
}
...
}
Observe também que o código correto converte DriverEntryPoint em um ULONG_PTR, em vez de um ULONG. Essa alteração permite o uso em um ambiente do Windows de 64 bits.
Falha ao validar ponteiros inseridos em solicitações de E/S em buffer
Geralmente, os drivers incorporam ponteiros em solicitações armazenadas em buffer, como no exemplo a seguir.
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));
Neste exemplo, o driver deve validar o ponteiro embutido usando as rotinas ProbeXxx dentro de um bloco try/except da mesma forma que para os IOCTLs METHOD_NEITHER descritos anteriormente. Embora a incorporação de um ponteiro permita que um driver retorne informações extras, um driver pode alcançar de forma mais eficiente o mesmo resultado usando um deslocamento relativo ou um buffer de comprimento variável.
Para obter mais informações sobre como usar blocos try/except para lidar com endereços inválidos, consulte Como lidar com exceções.