다음을 통해 공유


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.InputBufferLength 또는 Parameters.DeviceIoControl.OutputBufferLength를 검사 버퍼 제한을 결정합니다.

  • IOCTL 요청을 시작한 애플리케이션에 대한 데이터를 포함하는 드라이버 할당 버퍼는 항상 0개입니다. 이렇게 하면 중요한 데이터를 실수로 애플리케이션에 복사하지 않습니다.

  • METHOD_IN_DIRECT 및 METHOD_OUT_DIRECT 전송의 경우 위의 규칙을 따릅니다. 또한 매핑이 실패했거나 길이가 0인 버퍼가 제공되었음을 나타내는 MmGetSystemAddressForMdlSafeNULL 반환 값에 대한 검사.

  • METHOD_NEITHER 전송의 경우 버퍼링되지 않거나 직접 I/O 사용에서 제공하는 규칙을 따릅니다.