I/O 控制代码的安全问题

包含 I/O 控制代码的 IRP 的安全处理取决于正确定义 IOCTL 代码,以及仔细检查驱动程序使用 IRP 接收的参数。

定义新的 IOCTL 代码时,请使用以下规则:

  • 始终指定等于或大于0x800的 FunctionCode 值。

  • 始终指定 RequiredAccess 值。 如果调用方的访问权限不足,I/O 管理器不会发送 IOCTLs。

  • 不要定义允许调用方读取或写入内核内存的非特定区域的 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 转移,请遵循上述规则。 此外,检查 MmGetSystemAddressForMdlSafe 中的 NULL 返回值,该值指示映射失败或提供零长度缓冲区。

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