다음을 통해 공유


버퍼 크기를 확인하지 못했습니다.

버퍼링된 I/O를 구현하는 IOCTL 및 FSCTL을 처리할 때 드라이버는 항상 입력 및 출력 버퍼의 크기를 검사 버퍼가 요청된 모든 데이터를 저장할 수 있도록 해야 합니다. 요청이 대부분의 드라이버 IOCTL 및 FSCTL과 마찬가지로 FILE_ANY_ACCESS 지정하는 경우 디바이스에 대한 핸들이 있는 모든 호출자는 해당 디바이스에 대한 버퍼링된 IOCTL 또는 FSCTL 요청에 액세스할 수 있으며 버퍼 끝 이후의 데이터를 읽거나 쓸 수 있습니다.

입력 버퍼 크기

예를 들어 다음 코드가 Dispatch 루틴에서 호출되는 루틴에 나타나고 드라이버가 IRP에 전달된 버퍼 크기의 유효성을 검사하지 않았다고 가정합니다.

   switch (ControlCode)
      ...
      ...
      case IOCTL_NEW_ADDRESS:{
         tNEW_ADDRESS *pNewAddress = 
            pIrp->AssociatedIrp.SystemBuffer;

         pDeviceContext->Addr = RtlUlongByteSwap (pNewAddress->Address);

이 예제에서는 할당 문 앞에 버퍼 크기를 검사 않습니다(강조 표시됨). 결과적으로 입력 버퍼가 tNEW_ADDRESS 구조를 포함할 만큼 크지 않은 경우 다음 줄의 pNewAddress-Address> 참조에 오류가 발생할 수 있습니다.

다음 코드는 버퍼 크기를 검사하여 잠재적인 문제를 방지합니다.

   case IOCTL_NEW_ADDRESS: {
      tNEW_ADDRESS *pNewAddress =
         pIrp->AssociatedIrp.SystemBuffer;

      if (pIrpSp->Parameters.DeviceIoControl.InputBufferLength >=
             sizeof(tNEW_ADDRESS)) {
         pDeviceContext->Addr = RtlUlongByteSwap (pNewAddress->Address);

변수 크기 버퍼를 사용하는 WMI 요청과 같은 다른 버퍼링된 I/O를 처리하는 코드에도 비슷한 오류가 있을 수 있습니다.

출력 버퍼 크기

출력 버퍼 문제는 입력 버퍼 문제와 유사합니다. 풀을 쉽게 손상할 수 있으며 사용자 모드 호출자는 오류가 발생했음을 인식하지 못할 수 있습니다.

다음 예제에서는 드라이버가 SystemBuffer의 크기를 검사 못합니다.

   case IOCTL_GET_INFO: {

       Info = Irp->AssociatedIrp.SystemBuffer;

       Info->NumIF = NumIF;
       ...
       ...
       Irp->IoStatus.Information =
             NumIF*sizeof(GET_INFO_ITEM)+sizeof(ULONG);
       Irp->IoStatus.Status = ntStatus;
   }

시스템 버퍼의 NumIF 필드가 입력 항목 수를 지정한다고 가정하면 이 예제에서는 IoStatus.Information 을 출력 버퍼보다 큰 값으로 설정하여 사용자 모드 코드에 너무 많은 정보를 반환할 수 있습니다. 애플리케이션이 잘못 코딩되고 출력 버퍼가 너무 작은 를 호출하는 경우 이전 코드는 시스템 버퍼의 끝을 넘어 작성하여 풀을 손상시킬 수 있습니다.

I/O 관리자는 정보 필드의 값이 유효하다고 가정합니다. 호출자가 출력 버퍼에 대해 유효한 커널 모드 주소와 0바이트 크기를 전달하는 경우 드라이버가 출력 버퍼 크기를 검사 않아 오류를 찾을 경우 심각한 문제가 발생할 수 있습니다.