无法初始化输出缓冲区
驱动程序应先用零初始化所有输出缓冲区,然后再将其返回给调用方。 未能初始化缓冲区可能会导致任何未初始化字节中出现垃圾数据。
在以下示例中,驱动程序以未使用的字节为单位返回垃圾。
case IOCTL_GET_NAME: {
...
...
outputBufferLength =
ioStack->Parameters.DeviceIoControl.OutputBufferLength;
outputBuffer = (PGET_NAME) Irp->AssociatedIrp.SystemBuffer;
if (outputBufferLength >= sizeof(GET_NAME)) {
length = outputBufferLength - sizeof(GET_NAME);
ntStatus = IoGetDeviceProperty(
DeviceExtension->PhysicalDeviceObject,
DevicePropertyDriverKeyName,
length,
outputBuffer->DriverKeyName,
&length);
outputBuffer->ActualLength =
length + sizeof(GET_NAME);
Irp->IoStatus.Information = outputBufferLength;
} else {
ntStatus = STATUS_BUFFER_TOO_SMALL;
}
将 IoStatus.Information 设置为输出缓冲区大小会导致整个输出缓冲区返回到调用方。 I/O 管理器不会初始化超出输入缓冲区大小的数据 - 缓冲请求的输入和输出缓冲区重叠。 由于系统支持例程 IoGetDeviceProperty 不会写入整个缓冲区,因此此 IOCTL 会将未初始化的数据返回给调用方。
某些驱动程序使用 “信息” 字段返回提供有关 I/O 请求的额外详细信息的代码。 在执行此操作之前,此类驱动程序应检查 IRP 标志,以确保未设置IRP_INPUT_OPERATION。 如果未设置此标志,则 IOCTL 或 FSCTL 没有输出缓冲区,因此 “信息” 字段不需要提供缓冲区大小。 在本例中。 驱动程序可以安全地使用 “信息” 字段返回其自己的代码。