Проблемы безопасности для кодов элементов управления вводом-выводом
Безопасная обработка irP, содержащих коды управления вводом-выводом, зависит от правильного определения кодов IOCTL и тщательного изучения параметров, получаемых драйвером вместе с IRP.
При определении новых кодов IOCTL используйте следующие правила:
Всегда указывайте значение FunctionCode , которое равно или больше 0x800.
Всегда указывайте значение RequiredAccess . Диспетчер ввода-вывода не отправляет ioCTL, если у вызывающего объекта недостаточно прав доступа.
Не определяйте коды IOCTL, которые позволяют вызывающим устройствам считывать или записывать неспецифические области памяти ядра.
При обработке кодов IOCTL в драйвере используйте следующие правила:
Всякий раз, когда тест диспетчеризации драйвера получает коды IOCTL, они должны всегда тестировать все 32-разрядное значение.
Драйверы могут использовать IoValidateDeviceIoControlAccess для динамического выполнения более строгой проверки доступа, чем указано в значении RequiredAccess в определении кода элемента управления ввода-вывода.
Никогда не считывайте и не записывайте больше данных, чем буфер, на который указывает Irp-AssociatedIrp.SystemBuffer>. Поэтому всегда проверка Parameters.DeviceIoControl.InputBufferLength или Parameters.DeviceIoControl.OutputBufferLength в структуре IO_STACK_LOCATION, чтобы определить ограничения буфера.
Всегда ноль буферов, выделенных драйвером, которые будут содержать данные, предназначенные для приложения, которое было создано запросом IOCTL. Таким образом, вы не будете случайно копировать конфиденциальные данные в приложение.
Для передачи METHOD_IN_DIRECT и METHOD_OUT_DIRECT следуйте приведенным выше правилам. Кроме того, проверка возвращаемое значение NULL из MmGetSystemAddressForMdlSafe, которое указывает, что сопоставление завершилось сбоем или что был предоставлен буфер нулевой длины.
Для передачи METHOD_NEITHER следуйте правилам, приведенным в разделе Использование буферизованного и прямого ввода-вывода.