다음을 통해 공유


파일 시스템 제어 처리

IRP_MJ_FILE_SYSTEM_CONTROL 작업 처리는 파일 시스템 내의 다른 작업에 필요한 데이터 버퍼 처리와 다릅니다. 이는 각 작업이 CTL_CODE 매크로를 통해 I/O 관리자에 대한 특정 데이터 전송 메커니즘을 제어 코드의 일부로 설정하기 때문입니다. 또한 컨트롤 코드는 호출자에 필요한 파일 액세스를 지정합니다. 이 액세스는 I/O 관리자에 의해 적용되므로 파일 시스템은 컨트롤 코드를 정의할 때 이 문제를 특히 인식해야 합니다. 일부 I/O 제어 코드(예: FSCTL_MOVE_FILE)는 파일 시스템에서 파일 시스템에서 직접 작업의 보안을 확인할 수 있도록 하는 메커니즘인 FILE_SPECIAL_ACCESS 지정합니다. FILE_SPECIAL_ACCESS FILE_ANY_ACCESS 수치적으로 동일하므로 I/O 관리자는 파일 시스템으로 지연되는 특정 보안 검사를 제공하지 않습니다. FILE_SPECIAL_ACCESS 주로 파일 시스템에서 추가 검사를 수행하는 설명서를 제공합니다.

여러 파일 시스템 작업에서 FILE_SPECIAL_ACCESS 지정합니다. FSCTL_MOVE_FILE 작업은 파일 시스템에 대한 조각 모음 인터페이스의 일부로 사용되며 FILE_SPECIAL_ACCESS 지정합니다. 적극적으로 읽고 쓰고 있는 열려 있는 파일을 조각 모음할 수 있기를 원하기 때문에 사용할 핸들에는 공유 액세스 충돌을 방지하기 위해 FILE_READ_ATTRIBUTES 액세스 권한만 부여됩니다. 그러나 디스크가 낮은 수준에서 수정되므로 이 작업은 권한 있는 작업이어야 합니다. 솔루션은 FSCTL_MOVE_FILE 발급하는 데 사용되는 핸들이 권한 있는 핸들인 DASD(직접 액세스 스토리지 디바이스) 사용자 볼륨 열기인지 확인하는 것입니다. 열려 있는 사용자 볼륨에 대해 이 작업이 수행되도록 하는 FASTFAT 파일 시스템 코드는 FatMoveFile 함수에 있습니다(WDK에 포함된 fastfat 샘플의 fsctrl.c 소스 파일 참조).

    //
    //  extract and decode the file object and check for type of open
    //

    if (FatDecodeFileObject( IrpSp->FileObject, &Vcb, &FcbOrDcb, &Ccb ) != UserVolumeOpen) {

        FatCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER );

        DebugTrace(-1, Dbg, "FatMoveFile -> %08lx\n", STATUS_INVALID_PARAMETER);
        return STATUS_INVALID_PARAMETER;
    }

FSCTL_MOVE_FILE 작업에서 사용하는 구조체는 이동 중인 파일을 지정합니다.

typedef struct {
    HANDLE FileHandle;
    LARGE_INTEGER StartingVcn;
    LARGE_INTEGER StartingLcn;
    ULONG ClusterCount;
} MOVE_FILE_DATA, *PMOVE_FILE_DATA;

앞에서 설명한 것처럼 FSCTL_MOVE_FILE 발급하는 데 사용되는 핸들은 전체 볼륨의 "열린" 작업이지만 작업은 실제로 MOVE_FILE_DATA 입력 버퍼에 지정된 파일 핸들에 적용됩니다. 이렇게 하면 이 작업에 대한 보안 검사가 다소 복잡해집니다. 예를 들어 이 인터페이스는 파일 핸들을 이동 중인 파일을 나타내는 파일 개체로 변환해야 합니다. 이를 위해서는 모든 드라이버의 부분에 대해 신중하게 고려해야 합니다. FASTFAT는 WDK에 포함된 fastfat 샘플의 fsctrl.c 소스 파일에서 FatMoveFile 함수에서 보호된 방식으로 ObReferenceObject를 사용하여 이 작업을 수행합니다.

    //
    //  Try to get a pointer to the file object from the handle passed in.
    //

    Status = ObReferenceObjectByHandle( InputBuffer->FileHandle,
                                        0,
                                        *IoFileObjectType,
                                        Irp->RequestorMode,
                                        &FileObject,
                                        NULL );

    if (!NT_SUCCESS(Status)) {

        FatCompleteRequest( IrpContext, Irp, Status );

        DebugTrace(-1, Dbg, "FatMoveFile -> %08lx\n", Status);
        return Status;
    }
    //  Complete the following steps to ensure that this is not an invalid attempt
    //
    //    - check that the file object is opened on the same volume as the
    //      DASD handle used to call this routine.
    //
    //    - extract and decode the file object and check for type of open.
    //
    //    - if this is a directory, verify that it's not the root and that
    //      you are not trying to move the first cluster.  You cannot move the
    //      first cluster because sub-directories have this cluster number
    //      in them and there is no safe way to simultaneously update them
    //      all.
    //
    //  Allow movefile on the root directory if it's FAT32, since the root dir
    //  is a real chained file.
    //    //

Irp-RequestorMode>를 사용하여 호출자가 사용자 모드 애플리케이션인 경우 핸들이 커널 핸들이 될 수 없도록 합니다. 필요한 액세스 권한은 0이므로 적극적으로 액세스하는 동안 파일을 이동할 수 있습니다. 마지막으로 호출이 사용자 모드에서 시작된 경우 올바른 프로세스 컨텍스트에서 이 호출을 수행해야 합니다. FASTFAT 파일 시스템의 소스 코드는 fsctrl.c의 FatMoveFile 함수에서도 이를 적용합니다.

    //
    //  Force WAIT to true. There is a handle in the input buffer that can only
    //  be referenced within the originating process.
    //

    SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT );

FAT 파일 시스템에서 수행하는 이러한 의미 체계 보안 검사는 핸들을 전달하는 모든 작업에 대해 파일 시스템에서 요구하는 것과 일반적입니다. 또한 FAT 파일 시스템은 작업과 관련된 온전성 검사도 수행해야 합니다. 이러한 온전성 검사는 호출자가 허용되지 않을 때 권한 있는 작업을 수행하지 못하도록 하기 위해 서로 다른 매개 변수가 호환되는지 확인하는 것입니다(예: 이동 중인 파일은 열린 볼륨에 있습니다).

모든 파일 시스템의 경우 올바른 보안은 다음을 포함하는 파일 시스템 제어 작업의 필수적인 부분입니다.

  • 사용자 핸들의 유효성을 적절하게 검사합니다.

  • 사용자 버퍼 액세스 보호.

  • 특정 작업의 의미 체계 유효성을 검사합니다.

대부분의 경우 적절한 유효성 검사 및 보안을 수행하는 데 필요한 코드는 지정된 함수 내에서 코드의 상당 부분을 구성할 수 있습니다.