Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Jakýkoli ovladač, bez ohledu na to, jestli podporuje irps nebo rychlé vstupně-výstupní operace, by měl před pokusem o jeho použití ověřit jakoukoli adresu v uživatelském prostoru. Správce vstupně-výstupních operací tyto adresy neověřuje ani neověřuje ukazatele vložené do vyrovnávacích pamětí předávaných ovladačům.
Selhání ověření adres předaných v METHOD_NEITHER IOCTLs a FSCTLs
Správce vstupně-výstupních operací neprovádí žádné ověřování pro "METHOD_NEITHER" IOCTLs a FSCTLs. Aby bylo zajištěno, že adresy uživatelského prostoru jsou platné, musí ovladač použít rutiny ProbeForRead a ProbeForWrite a ohraničit všechny odkazy na vyrovnávací paměť bloky try/except.
V následujícím příkladu ovladač předpokládá, že hodnota předaná v Type3InputBuffer představuje platnou adresu.
case IOCTL_GET_HANDLER:
{
PULONG EntryPoint;
EntryPoint =
IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
*EntryPoint = (ULONG)DriverEntryPoint;
...
}
Následující kód se tomuto problému vyhne:
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)
{
...
}
...
}
Všimněte si také, že správný kód přetypuje DriverEntryPoint na ULONG_PTR místo ULONG. Tato změna umožňuje použití v 64bitovém prostředí Windows.
Nepodařilo se ověřit ukazatele vložené do vstupně-výstupních požadavků ve vyrovnávací paměti
Ovladače často vkládají ukazatele do vyrovnávacích požadavků, což je vidět v následujícím příkladu:
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));
V tomto příkladu by ovladač měl ověřit vložený ukazatel pomocí rutin ProbeXxx uzavřených v bloku try/except stejným způsobem jako pro IOCTLs s metodou METHOD_NEITHER popsanou výše. I když vložení ukazatele umožňuje ovladači vrátit další informace, ovladač může efektivněji dosáhnout stejného výsledku pomocí relativního posunu nebo vyrovnávací paměti proměnné délky.
Další informace o použití try/s výjimkou bloků pro zpracování neplatných adres naleznete v tématu Zpracování výjimek.