Отложить обработку IRP_MJ_WRITE в postoperation callback

Тема в разделе "WASM.NT.KERNEL", создана пользователем _Researcher_, 4 мар 2012.

  1. _Researcher_

    _Researcher_ New Member

    Публикаций:
    0
    Регистрация:
    4 мар 2012
    Сообщения:
    5
    Здравствуйте. Пишу минифильтр файловой системы. Необходимо после записи файла на диск подписывать файл цифровой подписью, а перед чтением её проверять. Решил поступить следующим образом: при обработке IRP_MJ_WRITE после записи на диск в postoperation callback открывать файл, подсчитывать подпись и записывать её, например, в конец файла.
    Проблема в следующем: поскольку postoperation callback может быть вызвана на высоком IRQL, приходится откладывать обработку с помощью FltQueueDeferredIoWorkItem. Однако здесь - http://msdn.microsoft.com/en-us/library/ff543449(v=vs.85).aspx сказано, что этого нельзя делать для запросов типа IRP_MJ_WRITE и IRP_MJ_READ, так как может привести к дедлоку. Как обойти это ограничение? Если это невозможно, как подобная обработка должна выполняться правильно?
     
  2. _Researcher_

    _Researcher_ New Member

    Публикаций:
    0
    Регистрация:
    4 мар 2012
    Сообщения:
    5
    Вопрос всё ещё актуален! Неужели никто из здешних гуру не знает ответ?
    Или вопрос настолько глупый? x64, h0t, shchetinin, подскажите, пожалуйста, очень нужно!
     
  3. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    _Researcher_
    1) Я толком не чего не понял из контекста задачи ((

    - Если хотите пописать файл то почему бы это не сделать при закрытии файла например? А проверять при открытии файла?
    - Если все таки хочешь формировать во время IRP_MJ_WRITE - IRP_MJ_READ то придется формировать контекст и подкитывать (Data,FltObjects).

    Делать отложеными
    IRP_MJ_WRITE, IRP_MJ_READ, IRP_MJ_FLUSH_BUFFERS действительно плохая идея, но если знать контекст, в некоторых функция это можно делать(Отложеный вызовы или же отдельный поток. ). Но это все равно криво.
     
  4. _Researcher_

    _Researcher_ New Member

    Публикаций:
    0
    Регистрация:
    4 мар 2012
    Сообщения:
    5
    Во – первых, спасибо большое за ответ!
    Задача такая: нужно сделать модель файловой системы с защитой от навязывания неактуальных файлов. Для этого надо перехватывать вызовы файловой системы прозрачно для приложений пользователя, для этого же нужна и цифровая подпись.

    Честно говоря, думал об этом в первую очередь, но проблема в том, что в модели файлы могут храниться
    на недоверенном сервере (т.е. эта ФС предполагается сетевой). Поскольку я мало знаком с драйверами сетевых ФС, для упрощения задачи было решено реализовать эту модель для локальной ФС. При этом мой фильтр предполагается доверенным компонентом, а всё, что лежит ниже, как бы недоверенное.
    Если проверять файл при открытии, то когда мы начнём из него читать, то может вернуться
    неактуальное/поддельное содержимое, и проверить это мы не сможем.

    Не могли бы вы про это рассказать поподробнее? Поделитесь, пожалуйста, примером, или хотя бы ссылкой, где про это можно почитать. Вообще я читал в WDK в разделе о минифильтрах про контексты, но там не очень понятно как работать с ними, и для чего они нужны (((. Подскажите, можно ли ещё что-нибудь почитать на эту тему?
     
  5. h0t

    h0t Member

    Публикаций:
    0
    Регистрация:
    3 апр 2011
    Сообщения:
    735
    _Researcher_
    Я не совсем понял Ваш предполагаемый алгоритм. Если Вы будите считать ЭЦП при КАЖДОЙ операции чтения то это будут ТАКИЕ ТОРМОЗА, что вы работать вообще не сможете. (все таки проверка/создание подписи достаточно "жирная" операция) Где Вы предполагаете хранить подпись? Не забывайте про FastIO


    P.S. Вы хотите "добить" ваш вариант?(т.е. сделать отложенную обработку write)
     
  6. _Researcher_

    _Researcher_ New Member

    Публикаций:
    0
    Регистрация:
    4 мар 2012
    Сообщения:
    5
    h0t
    Да, спасибо за ответ, вы правильно поняли, хочу проверять подпись при каждом чтении с диска, а обновлять при каждой операции записи. Полностью с вами согласен насчёт тормозов при каждой операции чтения и записи.
    Но! Вот выдержка из статьи по созданию аналогичной ФС под unix
    по поводу чтения:
    3.7. Reading a File
    The SiRiUS client takes the following steps to read a file.
    1. Obtain the md-file and identify the file owner by extracting the user name tag from the first encrypted key block.
    Obtain the owner’s MSK using a public key server and verify the signature on the md-file.
    Also verify the freshness of the md-file.
    2. Locate the encrypted key block with the reader’s user name in the md-file and decrypt the key block to obtain the FEK.
    3. Obtain the d-file (файл данных) and verify the signature using the public key of the FSK.
    4. Decrypt the encrypted file data with the FEK to obtain the file contents.
    (SiRiUS: Securing Remote Untrusted Storage – первая ссылка в гугле)
    Т.е. кроме проверки подписи, при чтении там проверяется ещё куча всего остального. Чтение там замедляется где-то в 18 раз (по данным в конце этой статьи).

    Написал в первом посте, что в конце файла, но я так полагаю, это не принципиально, можно, например,
    хранить её в дополнительном NTFS потоке. Или я здесь тоже чего-то недопонимаю?

    Тоже думал об этом, собираюсь подписывать файл только в случае непосредственной записи на диск
    (флаг IRP_NOCACHE в IrpFlags).

    Вы меня почти разубедили :). Но дело в том, что я не вижу ему достойной замены.
    Открытие/закрытие конечно хорошо, и гораздо проще в реализации, но как решать проблемы, описанные в моём предыдущем посте? Ещё я думал над созданием подписи в preoperation callback’е перед записью на диск, там нет проблем с IRQL, но тогда нужно там считывать файл и определять какая его часть перезаписывается новыми данными, что тоже не слишком-то удобно.

    В общем, поэтому я и хотел бы прояснить у знающих людей какой из этих вариантов наиболее правильный.
    Если у кого-нибудь ещё есть какие-нибудь идеи на этот счёт, или кто-то видит ошибку в моих рассуждениях,
    буду очень благодарен вам за советы.

    Заранее спасибо.
     
  7. h0t

    h0t Member

    Публикаций:
    0
    Регистрация:
    3 апр 2011
    Сообщения:
    735
    Смотрите я возможно не до конца понял Вашей задумки, но думаю вот что: хранить подпись например в конце файла идея не очень удачна так как если некто контролирует целостность фала и ничего не знает о вашей системе, то можете получить не работоспособный компонент ( если не будите заморачиваться с перехватом процедур).
    И пару вопросов:
    1. Не совсем понимаю как Вы хотите считать ЭЦП? при каждой операции чтения/записи пересчитывать ЭЦП для всего файла?
    2. И последний вопрос Вы хотите "прикрыть" всю систему так включая системные компоненты?
     
  8. _Researcher_

    _Researcher_ New Member

    Публикаций:
    0
    Регистрация:
    4 мар 2012
    Сообщения:
    5
    h0t
    Да, вы правы, я не подумал об этом. Но вообще-то, это для меня не настолько важно, чтобы учитывать такие тонкости. Прочитайте ещё раз мои предыдущие посты внимательнее. Дело в том, что нужна достаточно примитивная модель криптографической ФС, а не полноценная реализация. Поэтому, я естественно не собираюсь контролировать всю систему, включая системные компоненты. К примеру, я могу подписывать только файлы .txt, .doc и т.д.

    По поводу пересчёта ЭЦП для всего файла. Да, наверное, пока планирую так и поступить для упрощения задачи (понимаю, что это приведёт к БОЛЬШИМ тормозам при увеличении размера файла). Вообще для улучшения производительности, например, в том же SiRiUS, файлы разбиваются на блоки, и считается ЭЦП для каждого блока в отдельности. Но мне пока нужна хотя бы простейшая реализация, и до тех проблем, про которые вы пишете, я ещё не добрался, сначала нужно решить текущие (в какой момент считать ЭЦП?), и получить хотя бы примитивно работающее решение.