Поделиться через


Создание обработки

Для файловой системы большая часть интересных работ по обеспечению безопасности происходит во время обработки IRP_MJ_CREATE. Это шаг, который должен проанализировать входящий запрос, определить, имеет ли вызывающий объект соответствующие права для выполнения операции, а также предоставить или запретить операцию соответствующим образом. К счастью, для разработчиков файловой системы большинство механизмов принятия решений реализованы в мониторе ссылок на безопасность. Таким образом, в большинстве случаев файловая система должна вызывать только соответствующие подпрограммы монитора ссылок на безопасность для правильного определения доступа. Риск для файловой системы возникает, когда не удается вызвать эти подпрограммы по мере необходимости и неуместно предоставляет доступ вызывающему объекту.

Для стандартной файловой системы, например файловой системы FAT, проверки, сделанные в рамках IRP_MJ_CREATE, в основном представляют собой семантические проверки. Например, файловая система FAT проводит множество проверок, чтобы гарантировать разрешение на обработку IRP_MJ_CREATE, исходя из состояния файла или каталога. Эти проверки, выполняемые файловой системой FAT, включают проверки на наличие носителей только для чтения (например, попытки выполнить разрушительные операции создания, такие как перезапись или замена на носителях только для чтения, запрещены), проверки общего доступа и проверки оплоков. Одной из самых сложных частей этого анализа является то, что операция на одном уровне (например, на уровне файла) может быть запрещена из-за состояния другого ресурса уровня (например, уровня тома). Например, файл не может быть открыт, если другой процесс исключительно заблокировал том. Распространенные случаи проверки включают:

  • Совместимо ли состояние уровня файла с состоянием уровня тома? Блокировка на уровне тома должна соблюдаться. Таким образом, если один процесс имеет исключительную блокировку уровня тома, только потоки этого процесса могут открывать файлы. Потокам из других процессов не должно быть разрешено открывать файлы.

  • Совместим ли уровень файла с состоянием мультимедиа? Некоторые операции create изменяют файл в рамках операции create. Это будет включать перезапись, замену и даже обновление последнего времени доступа в файле. Эти операции создания не разрешены на носителе только для чтения, и время последнего доступа не обновляется.

  • Совместим ли открытый уровень тома с состоянием уровня файла? Открытие эксклюзивного доступа к тому не разрешено, если на нём уже открыты существующие файлы. Это распространенная проблема для новых разработчиков, так как они пытаются открыть том и обнаруживают, что это не удается. Если это не удается, FSCTL_DISMOUNT_VOLUME можно использовать для аннулирования открытых дескрипторов и принудительного отключения, предоставляя эксклюзивный доступ к новому подключенному тому.

Кроме того, атрибуты файлов должны быть совместимыми. Файл с атрибутом только для чтения не может быть открыт для доступа на запись. Обратите внимание, что требуемый доступ следует проверить после расширения универсальных прав. Например, эта проверка в файловой системе FASTFAT находится в функции FatCheckFileAccess (см. исходный файл Acchksup.c из примеров fastfat, содержащихся в WDK).

Следующий пример кода относится к семантике файловой системы FAT. Файловая система, реализующая списки DACL, также будет выполнять дополнительную проверку безопасности с помощью подпрограмм монитора безопасности (например,SeAccessCheck).

    //
    //  check for a read-only Dirent
    //

    if (FlagOn(DirentAttributes, FAT_DIRENT_ATTR_READ_ONLY)) {

        //
        //  Check the desired access for a read-only Dirent
        // Don't allow 
        //  WRITE, FILE_APPEND_DATA, FILE_ADD_FILE,
        //  FILE_ADD_SUBDIRECTORY, and FILE_DELETE_CHILD
        //

        if (FlagOn(*DesiredAccess, ~(DELETE |
                                     READ_CONTROL |
                                     WRITE_OWNER |
                                     WRITE_DAC |
                                     SYNCHRONIZE |
                                     ACCESS_SYSTEM_SECURITY |
                                     FILE_READ_DATA |
                                     FILE_READ_EA |
                                     FILE_WRITE_EA |
                                     FILE_READ_ATTRIBUTES |
                                     FILE_WRITE_ATTRIBUTES |
                                     FILE_EXECUTE |
                                     FILE_LIST_DIRECTORY |
                                     FILE_TRAVERSE))) {

            DebugTrace(0, Dbg, "Cannot open readonly\n", 0);

            try_return( Result = FALSE );
        }

Более тонкая проверка, реализованная в FASTFAT, заключается в обеспечении того, чтобы доступ, запрашиваемый вызывающей функцией, соответствовал тому, о чем знает файловая система FAT (в функции fatCheckFileAccess в Acchksup.c из примера fastfat, который входит в состав WDK):

В следующем примере кода демонстрируется важная концепция безопасности файловой системы. Убедитесь, что то, что передается в файловую систему, не выходит за пределы ожидаемого. Консервативный и правильный подход с точки зрения безопасности заключается в том, что если вы не понимаете запрос на доступ, следует отклонить этот запрос.

    //
    // Check the desired access for the object. 
    // Reject what we do not understand.
    // The model of file systems using ACLs is that
    // they do not type the ACL to the object that the 
    // ACL is on. 
    // Permissions are not checked for consistency vs.
    // the object type - dir/file.
    //

    if (FlagOn(*DesiredAccess, ~(DELETE |
                                 READ_CONTROL |
                                 WRITE_OWNER |
                                 WRITE_DAC |
                                 SYNCHRONIZE |
                                 ACCESS_SYSTEM_SECURITY |
                                 FILE_WRITE_DATA |
                                 FILE_READ_EA |
                                 FILE_WRITE_EA |
                                 FILE_READ_ATTRIBUTES |
                                 FILE_WRITE_ATTRIBUTES |
                                 FILE_LIST_DIRECTORY |
                                 FILE_TRAVERSE |
                                 FILE_DELETE_CHILD |
                                 FILE_APPEND_DATA))) {

        DebugTrace(0, Dbg, "Cannot open object\n", 0);

        try_return( Result = FALSE );
    }

К счастью для файловых систем, после выполнения проверки безопасности во время первоначальной обработки создания последующие проверки безопасности выполняются диспетчером ввода-вывода. Таким образом, диспетчер операций ввода-вывода гарантирует, что приложения пользовательского режима не выполняют операцию записи в файле, который был открыт только для доступа на чтение. На самом деле файловая система не должна пытаться применить семантику только для чтения для объекта файла, даже если он был открыт только для доступа на чтение, во время процедуры отправки IRP_MJ_WRITE. Это связано с тем, как диспетчер памяти связывает определенный файловый объект с заданным объектом раздела. Последующие записи в этом разделе будут отправляться как операции IRP_MJ_WRITE для объекта файла, даже если файл был открыт для чтения. Другими словами, принудительное применение доступа осуществляется при преобразовании дескриптора файла в соответствующий объект файла в точках входа службы системы NT, используя ObReferenceObjectByHandle.

В файловой системе есть два дополнительных места, где семантические проверки безопасности должны выполняться аналогично обработке create:

  • Во время переименования или обработки жестких ссылок.

  • При обработке операций управления файловой системой.

Обработка переименований и обработка управления файловой системой рассматривается в последующих разделах.

Обратите внимание, что это не исчерпывающий список семантических проблем, связанных с обработкой "create". Цель этого раздела — привлечь внимание к этим проблемам для разработчиков файловой системы. Все семантические проблемы должны быть определены для конкретной файловой системы, реализованы для удовлетворения конкретной семантики и проверены, чтобы реализация обрабатывала различные случаи.