I/O 控制代码的安全问题
安全处理包含 I/O 控制代码的 IRP 取决于正确定义 IOCTL 代码,以及仔细检查驱动程序使用 IRP 接收的参数。
定义新的 IOCTL 代码时,请使用以下规则:
始终指定等于或大于 0x800 的 FunctionCode 值。
始终指定 RequiredAccess 值。 如果调用方没有足够的访问权限,I/O 管理器不会发送 IOCTL。
不要定义允许调用方读取或写入内核内存的非特定区域的 IOCTL 代码。
在驱动程序中处理 IOCTL 代码时,请使用以下规则:
每当驱动程序的调度例程测试收到 IOCTL 代码时,它们必须始终测试整个 32 位值。
驱动程序可以使用 IoValidateDeviceIoControlAccess 动态执行比 I/O 控制代码定义中 RequiredAccess 值指定的更严格的访问检查。
读取或写入的数据永远不会超过 Irp-AssociatedIrp.SystemBuffer> 可以包含的缓冲区。 因此,始终在IO_STACK_LOCATION结构中检查 Parameters.DeviceIoControl.InputBufferLength 或 Parameters.DeviceIoControl.OutputBufferLength 以确定缓冲区限制。
始终为零驱动程序分配的缓冲区,其中包含用于发起 IOCTL 请求的应用程序的数据。 这样,就不会意外地将敏感数据复制到应用程序。
对于METHOD_IN_DIRECT和METHOD_OUT_DIRECT转移,请遵循上述规则。 此外,检查 MmGetSystemAddressForMdlSafe 的 NULL 返回值,该值指示映射失败或提供了零长度缓冲区。
对于METHOD_NEITHER传输,请遵循 使用非缓冲 I/O 和直接 I/O 中提供的规则。