无法初始化输出缓冲区

驱动程序应先用零初始化所有输出缓冲区,然后再将其返回给调用方。 未能初始化缓冲区可能会导致任何未初始化字节中出现垃圾数据。

在以下示例中,驱动程序以未使用的字节为单位返回垃圾。

   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 没有输出缓冲区,因此 “信息” 字段不需要提供缓冲区大小。 在本例中。 驱动程序可以安全地使用 “信息” 字段返回其自己的代码。