증상
orange.driver(ofilter, orange.sys)를 언로드하는 중 0x7E 블루스크린이 났다. FltMgr 필터 Verifier를 켠 VM에서 재현됐다.
스택
orange!DriverUnload
→ FltUnregisterFilter
→ FltpDrainActiveCompletions
→ orange!PostWrite+0x4f (File.Write.cpp:100)
→ FltvDoCompletionProcessingWhenSafe
→ DbgPrompt(int3)
→ 0x7E
원인
PostWrite가 FLTFL_POST_OPERATION_DRAINING 플래그가 설정된 상태에서도 FltDoCompletionProcessingWhenSafe를 불렀다. 이 함수는 DRAINING 중에는 호출이 금지되어 있다. FltUnregisterFilter가 필터를 언로드하면서 남아 있는 포스트 오퍼레이션을 비우는 FltpDrainActiveCompletions 단계에 들어가면 각 콜백에 DRAINING 플래그를 세우는데, PostWrite는 이 신호를 보지 않고 평소와 같은 완료 처리 경로를 그대로 탔다.
같은 함수에는 결함이 하나 더 있었다. 미뤄 처리가 실패하는 경우, 그 실패가 프로그램이 요청한 쓰기 자체의 결과(IoStatus)까지 STATUS_UNSUCCESSFUL로 덮어썼다. 미뤄 처리 실패와 쓰기 성공 여부는 서로 다른 일인데 하나의 상태값으로 섞여 있었다.
영향
배포 중인 orange.sys 0.3.1.53에도 있던 기존 결함이다. DRAINING 경로를 타는 시점(언로드)에만 드러나기 때문에 평소 동작에서는 보이지 않는다.
수정
- DRAINING 플래그가 설정되어 있으면
FltDoCompletionProcessingWhenSafe를 부르지 않고 바로 빠진다.PostRead·PostCleanup·PostCreate콜백이 이미 같은 방식으로 처리하고 있어,PostWrite를 그 패턴에 맞췄다. - 미뤄 처리가 실패해도 쓰기 집계만 건너뛰고, 프로그램이 받는
IoStatus는 건드리지 않는다.
확인
- 커밋(develop) —
2a8ea5ea고침,4029245borange.sys 0.3.1.54 - 덤프(시험 VM) —
C:\Windows\Minidump\103126-41203-01.dmp,C:\b37\b37_crash_0x7e_103126.dmp,C:\Windows\MEMORY.DMP
남은 일
0.3.1.54 MS 서명과 통합 시험(Verifier 유지, 재부팅, 언로드·로드 반복, 메모리 누수 확인)이 남아 있다.
Orange Platform 커널 드라이버의 언로드 경로 블루스크린 분석 및 수정에 관한 기술 리포트입니다.