Run-Down 보호

Windows XP부터 커널 모드 드라이버에서 런다운 보호를 사용할 수 있습니다. 드라이버는 런다운 보호를 사용하여 다른 커널 모드 드라이버에서 만들고 삭제한 공유 시스템 메모리의 개체에 안전하게 액세스할 수 있습니다.

개체의 모든 미해결 액세스가 완료되고 개체에 액세스하기 위한 새 요청이 부여되지 않으면 개체가 실행 되지 않는다고 합니다. 예를 들어 공유 개체를 삭제하고 새 개체로 바꿀 수 있도록 실행해야 할 수 있습니다.

공유 개체를 소유하는 드라이버는 다른 드라이버가 개체에 대한 런다운 보호를 획득하고 해제할 수 있도록 할 수 있습니다. 런다운 보호가 적용되는 경우 소유자 이외의 드라이버는 액세스가 완료되기 전에 소유자가 개체를 삭제할 위험 없이 개체에 액세스할 수 있습니다. 액세스가 시작되기 전에 액세스하는 드라이버는 개체에 대한 런다운 보호를 요청합니다. 수명이 긴 개체의 경우 이 요청은 거의 항상 부여됩니다. 액세스가 완료되면 액세스하는 드라이버는 개체에서 이전에 획득한 런다운 보호를 해제합니다.

기본 런다운 보호 루틴

개체 공유를 시작하기 위해 개체를 소유하는 드라이버는 ExInitializeRundownProtection 루틴을 호출하여 개체에 대한 런다운 보호를 초기화합니다. 이 호출 후 개체에 액세스하는 다른 드라이버는 개체에 대한 런다운 보호를 획득하고 해제할 수 있습니다.

공유 개체에 액세스하는 드라이버는 ExAcquireRundownProtection 루틴을 호출하여 개체에 대한 런다운 보호를 요청합니다. 액세스가 완료되면 이 드라이버는 ExReleaseRundownProtection 루틴을 호출하여 개체에 대한 런다운 보호를 해제합니다.

소유 드라이버가 공유 개체를 삭제해야 한다고 판단하는 경우 이 드라이버는 개체의 미해결 액세스가 모두 완료될 때까지 개체 삭제를 기다립니다.

공유 개체를 삭제하기 위해 소유 드라이버는 ExWaitForRundownProtectionRelease 루틴을 호출하여 개체가 실행되기를 기다립니다. 이 호출 중에 ExWaitForRundownProtectionRelease 는 개체에 대해 이전에 부여된 모든 런다운 보호 인스턴스가 해제될 때까지 대기하지만 개체의 런다운 보호에 대한 새 요청이 부여되지 않도록 합니다. 마지막으로 보호된 액세스가 완료되고 모든 런다운 보호 인스턴스가 해제되면 ExWaitForRundownProtectionRelease 가 반환되고 소유 드라이버가 개체를 안전하게 삭제할 수 있습니다.

ExWaitForRundownProtectionRelease 는 공유 개체에 대한 런다운 보호를 유지하는 모든 드라이버가 이 보호를 해제할 때까지 호출 드라이버 스레드의 실행을 차단합니다. ExWaitForRundownProtectionRelease가 너무 오랫동안 실행을 차단하지 않도록 하려면 공유 개체에 액세스하는 드라이버 스레드가 개체에 대한 런다운 보호를 유지하는 동안 일시 중단되지 않아야 합니다. 이러한 이유로 드라이버 액세스는 중요한 지역 또는 보호된 지역 내에서 또는 IRQL = APC_LEVEL 실행되는 동안 ExAcquireRundownProtectionExReleaseRundownProtection 을 호출해야 합니다.

런다운 보호에 사용

런다운 보호는 거의 항상 사용할 수 있지만 경우에 따라 삭제하고 교체해야 할 수 있는 공유 개체에 대한 액세스를 제공하는 데 특히 유용합니다. 데이터에 액세스하거나 이 개체의 루틴을 호출하는 드라이버는 삭제된 후 개체에 액세스하려고 하면 안 됩니다. 그렇지 않으면 이러한 잘못된 액세스로 인해 예기치 않은 동작, 데이터 손상 또는 시스템 오류가 발생할 수 있습니다.

예를 들어 바이러스 백신 드라이버는 일반적으로 운영 체제가 실행될 때 메모리에 로드된 상태로 유지됩니다. 경우에 따라 이 드라이버를 언로드하고 업데이트된 드라이버 릴리스로 교체해야 할 수 있습니다. 다른 드라이버는 이 드라이버의 데이터 및 루틴에 액세스하기 위해 바이러스 백신 드라이버에 I/O 요청을 보냅니다. I/O 요청을 보내기 전에 파일 시스템 필터 관리자와 같은 커널 구성 요소는 I/O 요청을 처리하는 동안 바이러스 백신 드라이버의 조기 언로드를 방지하도록 런다운 보호를 획득할 수 있습니다. I/O 요청이 완료되면 런다운 보호를 해제할 수 있습니다.

런다운 보호는 공유 개체에 대한 액세스를 직렬화하지 않습니다. 두 개 이상의 액세스 드라이버가 동시에 개체에 대한 런다운 보호를 유지할 수 있고 개체에 대한 액세스를 직렬화해야 하는 경우 상호 배제 잠금과 같은 다른 메커니즘을 사용하여 액세스를 직렬화해야 합니다.

EX_RUNDOWN_REF 구조체

EX_RUNDOWN_REF 구조체는 공유 개체의 런다운 보호 상태를 추적합니다. 이 구조는 드라이버에 불투명합니다. 시스템에서 제공하는 런다운 보호 루틴은 이 구조를 사용하여 현재 개체에 적용되는 런다운 보호 인스턴스 수를 계산합니다. 또한 이러한 루틴은 이 구조를 사용하여 개체가 실행 중인지 아니면 실행 중인지 추적합니다.

개체 공유를 시작하려면 개체를 소유하는 드라이버가 ExInitializeRundownProtection 을 호출하여 개체와 연결된 EX_RUNDOWN_REF 구조를 초기화합니다. 초기화 후 소유 드라이버는 개체에 액세스해야 하는 다른 드라이버에서 이 구조를 사용할 수 있도록 할 수 있습니다. 액세스 드라이버는 이 구조를 ExAcquireRundownProtectionExReleaseRundownProtection 호출에 매개 변수로 전달하여 개체에 대한 런다운 보호를 획득하고 해제합니다. 소유 드라이버는 안전하게 삭제할 수 있도록 개체가 실행될 때까지 기다리는 ExWaitForRundownProtectionRelease 호출에 이 구조를 매개 변수로 전달합니다.

잠금 비교

런다운 보호는 공유 개체에 대한 안전한 액세스를 보장하는 여러 가지 방법 중 하나입니다. 또 다른 방법은 상호 배제 소프트웨어 잠금을 사용하는 것입니다. 드라이버가 현재 다른 드라이버에 의해 잠겨 있는 개체에 액세스해야 하는 경우 첫 번째 드라이버는 두 번째 드라이버가 잠금을 해제할 때까지 기다려야 합니다. 그러나 잠금을 획득하고 해제하면 성능 병목 현상이 발생할 수 있으며 잠금은 많은 양의 메모리를 사용할 수 있습니다. 잘못 사용하면 잠금으로 인해 동일한 공유 개체에 대해 경쟁하는 드라이버가 교착 상태가 될 수 있습니다. 교착 상태를 감지하고 방지하려면 일반적으로 상당한 컴퓨팅 리소스를 전환해야 합니다.

잠금과 달리 런다운 보호에는 비교적 간단한 처리 시간과 메모리 요구 사항이 있습니다. 개체의 모든 미해결 액세스가 완료될 때까지 개체 삭제가 지연되도록 하는 간단한 참조 수가 개체와 연결됩니다. 이 방법을 사용하면 상호 배제 소프트웨어 잠금 대신 원자성 연동 하드웨어 명령을 사용하여 개체에 안전하게 액세스할 수 있습니다. 런다운 보호를 획득 및 해제하기 위한 호출은 일반적으로 매우 빠릅니다. 런다운 보호와 같은 경량 메커니즘을 사용하는 이점은 수명이 길고 많은 드라이버 간에 공유되는 공유 개체에 중요할 수 있습니다.

기타 런다운 보호 루틴

이전에 언급한 루틴 외에도 몇 가지 다른 런다운 보호 루틴을 사용할 수 있습니다. 이러한 추가 루틴은 일부 드라이버에서 사용할 수 있습니다.

ExReInitializeRundownProtection 루틴을 사용하면 이전에 사용한 EX_RUNDOWN_REF 구조체를 새 개체와 연결하고 이 개체에 대한 런다운 보호를 초기화합니다.

ExRundownCompleted 루틴은 연결된 개체의 실행이 완료되었음을 나타내도록 EX_RUNDOWN_REF 구조를 업데이트합니다.

ExAcquireRundownProtectionExExReleaseRundownProtectionEx 루틴은 ExAcquireRundownProtectionExReleaseRundownProtection과 유사합니다. 이러한 네 가지 루틴은 공유 개체에 적용되는 런다운 보호 인스턴스의 수를 증가 또는 감소합니다. 반면 ExAcquireRundownProtectionExReleaseRundownProtection 은 이 수를 1씩 증가 및 감소시키고, ExAcquireRundownProtectionExExReleaseRundownProtectionEx 는 임의 양만큼 증가 및 감소합니다.