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.InputBufferLengthParameters.DeviceIoControl.OutputBufferLength 以确定缓冲区限制。

  • 始终为零驱动程序分配的缓冲区,其中包含用于发起 IOCTL 请求的应用程序的数据。 这样,就不会意外地将敏感数据复制到应用程序。

  • 对于METHOD_IN_DIRECT和METHOD_OUT_DIRECT转移,请遵循上述规则。 此外,检查 MmGetSystemAddressForMdlSafeNULL 返回值,该值指示映射失败或提供了零长度缓冲区。

  • 对于METHOD_NEITHER传输,请遵循 使用非缓冲 I/O 和直接 I/O 中提供的规则。