EreTIk's Box » Cтатьи, исходники » FltSetInformationFile vs ZwSetInformationFile при переименовании файлов


Актуализируя один свой старый драйвер фильтра файловых систем, я стал портировать логику работы с файлами с Zw- и Io- функций на Flt-функции. У меня использовались операция создания файла и, при наступлении определенных условий, операция переименование файла. Описание функции FltCreateFile(...) достаточно однозначно указывает на то, что для переименования нужно использовать FltSetInformationFile(...):


Minifilter drivers must use FltSetInformationFile, not ZwSetInformationFile, to rename a file

Замена используемого API заняла не так много времени. Но после непродолжительного тестирования выяснилось, что операция переименования стала возвращать ошибку STATUS_ACCESS_DENIED. Обычно этот статус ошибки возвращается там, где идет создание описателя или reference объекта по уже созданному описателю. Именно по этому меня удивил такой статус, возвращенный из функции, работающей с объектом файла. Оказалось, что при переименовании драйвер NTFS сам активно работает с Se-функциями. Для WinXP SP3 захват subject-контекста происходит при следующем стеке вызовов:


0: kd> k3 ChildEBP RetAddr b217ca94 f84225d2 nt!SeCaptureSubjectContext b217caf0 f83e8b3b Ntfs!NtfsCommonSetInformation+0x2b3 b217cb58 804ef1f9 Ntfs!NtfsFsdSetInformation+0xa3

Сама проверка, вызов SeAccessCheck(...):


0: kd> k5 ChildEBP RetAddr b217c82c f8423450 nt!SeAccessCheck b217c890 f8422e9c Ntfs!NtfsCheckIndexForAddOrDelete+0x7b b217ca7c f842264e Ntfs!NtfsSetRenameInfo+0xaad b217caf0 f83e8b3b Ntfs!NtfsCommonSetInformation+0x3fb b217cb58 804ef1f9 Ntfs!NtfsFsdSetInformation+0xa3

1: kd> dps @esp+4 L 0n10 b217c834 e1595248 b217c838 e14b27d8 b217c83c 00000001 b217c840 00000002 b217c844 00000000 b217c848 b217c870 b217c84c 8067f3c0 nt!IopFileMapping b217c850 00000001 b217c854 b217c868 b217c858 b217c86c

То есть для приведенного выше примера видно, что драйвер NTFS проверяет DesiredAccess == 0x0002 (FILE_WRITE_ACCESS) для AccessMode == 1 (UserMode).


Следовательно при переходе на использование FltSetInformationFile(...) для переименования необходимо обеспечить себе PreviousMode == KernelMode, если операция не должна зависеть от контекста текущей нити.


ΞρεΤΙκ