Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Before Posting...
Please check out the Community Guidelines in the Announcements and Administration Category.

Encryption Filter Doesn't Work for Memory Mapped Files

Aram_Havarneanu-2Aram_Havarneanu-2 Member Posts: 161
Hello

I have created a simple encryption filter, it works fine for regular
I/O, but fails for memory mapped files. When opening text files with
notepad, which uses memory mapped files, I see encrypted content,
other programs that use regular I/O (Write) work fine.

How can I correct this behavior? Thanks,

--
Aram Hăvărneanu

Comments

  • Aram_Havarneanu-2Aram_Havarneanu-2 Member Posts: 161
    On Sun, Sep 5, 2010 at 7:31 PM, Aram Hăvărneanu <xxxxx@mgk.ro> wrote:
    > I have created a simple encryption filter, it works fine for regular
    > I/O, but fails for memory mapped files. When opening text files with
    > notepad, which uses memory mapped files, I see encrypted content,
    > other programs that use regular I/O (Write) work fine.
    >
    > How can I correct this behavior? Thanks,

    I think I only need to do crypto in the non-caching paths? I tried
    FLTFL_OPERATION_REGISTRATION_SKIP_CACHED_IO in
    FLT_OPERATION_REGISTRATION but it doesn't seem to work.

    --
    Aram Hăvărneanu
  • Aram_Havarneanu-2Aram_Havarneanu-2 Member Posts: 161
    On Sun, Sep 5, 2010 at 7:48 PM, Aram Hăvărneanu <xxxxx@mgk.ro> wrote:
    > On Sun, Sep 5, 2010 at 7:31 PM, Aram Hăvărneanu <xxxxx@mgk.ro> wrote:
    >> I have created a simple encryption filter, it works fine for regular
    >> I/O, but fails for memory mapped files. When opening text files with
    >> notepad, which uses memory mapped files, I see encrypted content,
    >> other programs that use regular I/O (Write) work fine.
    >>
    >> How can I correct this behavior? Thanks,
    >
    > I think I only need to do crypto in the non-caching paths? I tried
    > FLTFL_OPERATION_REGISTRATION_SKIP_CACHED_IO in
    > FLT_OPERATION_REGISTRATION but it doesn't seem to work.

    Could it be that I decrypt the plain data from the cache? How do I
    skip the caching paths if FLTFL_OPERATION_REGISTRATION_SKIP_CACHED_IO
    doesn't work?

    Thanks,

    --
    Aram Hăvărneanu
  • Aram_Havarneanu-2Aram_Havarneanu-2 Member Posts: 161
    On Sun, Sep 5, 2010 at 11:11 PM, Aram Hăvărneanu <xxxxx@mgk.ro> wrote:
    > On Sun, Sep 5, 2010 at 7:48 PM, Aram Hăvărneanu <xxxxx@mgk.ro> wrote:
    >> On Sun, Sep 5, 2010 at 7:31 PM, Aram Hăvărneanu <xxxxx@mgk.ro> wrote:
    >>> I have created a simple encryption filter, it works fine for regular
    >>> I/O, but fails for memory mapped files. When opening text files with
    >>> notepad, which uses memory mapped files, I see encrypted content,
    >>> other programs that use regular I/O (Write) work fine.
    >>>
    >>> How can I correct this behavior? Thanks,
    >>
    >> I think I only need to do crypto in the non-caching paths? I tried
    >> FLTFL_OPERATION_REGISTRATION_SKIP_CACHED_IO in
    >> FLT_OPERATION_REGISTRATION but it doesn't seem to work.
    >
    > Could it be that I decrypt the plain data from the cache? How do I
    > skip the caching paths if FLTFL_OPERATION_REGISTRATION_SKIP_CACHED_IO
    > doesn't work?

    From the FAQ:

    For example, a traditional mistake for an encryption filter is to trap
    the IRP_MJ_WRITE where the IRP_NOCACHE bit is set (which catches both
    user non-cached I/O as well as paging I/O) and, using the provided MDL
    or user buffer, encrypt the data in-place. The risk here is that some
    other thread will gain access to that memory in its encrypted state.
    For example, if the file is memory mapped, the application will
    observe the modified data, rather than the original, cleartext data.

    That is the behavior I get, though I don't encrypt in place. I replace
    the user buffer (I started from SwapBuffers that does this correctly).

    --
    Aram Hăvărneanu
  • This is a real old question, I myself asked this few years back :),

    To start with you need to encrypt/decrypt only in case of non-cached (and paging) path. change your read, write accordingly.
  • Aram_Havarneanu-2Aram_Havarneanu-2 Member Posts: 161
    On Mon, Sep 6, 2010 at 4:59 PM, <xxxxx@gmail.com> wrote:
    > To start with you need to encrypt/decrypt only in case of non-cached (and paging) path. change your read, write accordingly.

    I understand this, that's why I specified
    FLTFL_OPERATION_REGISTRATION_SKIP_CACHED_IO, but it doesn't seem to be
    enough. From my understanding, if I specify
    FLTFL_OPERATION_REGISTRATION_SKIP_CACHED_IO then my filter callbacks
    won't get called for cached i/o. Is my understanding wrong? Do I need
    to specify something else?

    Thanks,

    --
    Aram Hăvărneanu
  • Aram_Havarneanu-2Aram_Havarneanu-2 Member Posts: 161
    On Mon, Sep 6, 2010 at 5:17 PM, Aram Hăvărneanu <xxxxx@mgk.ro> wrote:
    > On Mon, Sep 6, 2010 at 4:59 PM,  <xxxxx@gmail.com> wrote:
    >> To start with you need to encrypt/decrypt only in case of non-cached (and paging) path. change your read, write accordingly.
    >
    > I understand this, that's why I specified
    > FLTFL_OPERATION_REGISTRATION_SKIP_CACHED_IO, but it doesn't seem to be
    > enough. From my understanding, if I specify
    > FLTFL_OPERATION_REGISTRATION_SKIP_CACHED_IO then my filter callbacks
    > won't get called for cached i/o. Is my understanding wrong? Do I need
    > to specify something else?

    More precisely, if I use FLTFL_OPERATION_REGISTRATION_SKIP_CACHED_IO,
    then I get NO encryption at all.

    --
    Aram Hăvărneanu
  • you are using this flag for both read and write IRPs? As per docs it should work but I did not tried it. Instead I checked the flags from call back data.
  • Aram_Havarneanu-2Aram_Havarneanu-2 Member Posts: 161
    On Tue, Sep 7, 2010 at 7:45 AM, <xxxxx@gmail.com> wrote:
    > you are using this flag for both read and write IRPs? As per docs it should work but I did not tried it. Instead I checked the flags from call back data.

    I am using the flags for both read and write. I will try checking the
    flags from the call back data.

    Could it be that read-ahead is caching my test files before I attach
    the filter so that after I attach the filter, I only get caching I/O?

    --
    Aram Hăvărneanu
  • >>Could it be that read-ahead is caching my test files before I attach the filter so that after I attach the filter, I only get caching I/O?

    IF the file is being read before your filter is loaded than yes, prefetcher could also play its part here. A simple test is to use dbgprint or step into debugger and verify whether you are getting a (non-cached/paging) read operation on that file or not? This is the first thing I would verify.
  • Aram_Havarneanu-2Aram_Havarneanu-2 Member Posts: 161
    On Tue, Sep 7, 2010 at 12:39 PM, <xxxxx@gmail.com> wrote:
    >>>Could it be that read-ahead is caching my test files before I attach the filter so that after I attach the filter, I only get caching I/O?
    > IF the file is being read before your filter is loaded than yes, prefetcher could also play its part here. A simple test is to use dbgprint or step into debugger and verify whether you are getting a (non-cached/paging) read operation on that file or not?

    I am getting non-cached I/O from read-ahead. That is the good news.
    It's also good news that I determined why if I set
    FLTFL_OPERATION_REGISTRATION_SKIP_CACHED_IO the driver appears not to
    work. I am doing encryption only for some files and
    FltGetFileNameInformation() fails with
    STATUS_FLT_INVALID_NAME_REQUEST. Why can't I get the name for
    non-cached I/O? Is there an alternative?

    Thanks,

    --
    Aram Hăvărneanu
  • Aram_Havarneanu-2Aram_Havarneanu-2 Member Posts: 161
    On Tue, Sep 7, 2010 at 6:14 PM, Aram Hăvărneanu <xxxxx@mgk.ro> wrote:
    > I am doing encryption only for some files and
    > FltGetFileNameInformation() fails with
    > STATUS_FLT_INVALID_NAME_REQUEST. Why can't I get the name for
    > non-cached I/O?

    I found the answer:

    ><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><

    A minifilter can call FltGetFileNameInformation() at any point during
    its IO processing when it is executing an IRQL less than DPC. _If the
    minifilter is requesting to query the name at a time when it is
    possible for the name query to cause the system to deadlock (e.g.,
    while processing paging IO), the call will fail if the name is not
    found in the cache or the caller requested to only query the file
    system._
    A minifilter can use FltGetFileNameInformationUnsafe() to query a name
    for a file object if it does not have a callback data to describe the
    current operation targeting this file object and the filter knows that
    this is a safe time to potentially query the file system to get a
    name. This routine cannot detect that a file system query could
    potentially deadlock the system and return a failure status as
    FltGetFileNameInformation() can.

    ><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><

    I think it's safe to use FltGetFileNameInformationUnsafe(). I'm using
    that function and my filter performs just fine with regular I/O and
    memory mapped I/O. For reference, I'm processing only non cached I/O
    via FLTFL_OPERATION_REGISTRATION_SKIP_CACHED_IO.

    Thanks for help.

    --
    Aram Hăvărneanu
  • FltGetFileNameInformationUnsafe does not look *safe* to me :) (obvious from name in fact), read the remark section and it should be clear.

    You can actually call it only in create and than store it, later in read/write you can referred to the stored value. Will actually save you from overhead.

    IF you have not looked yet, than take a look at contexts.
  • OSR_Community_UserOSR_Community_User Member Posts: 110,217
    On 9/7/2010 9:35 AM, Aram Hăvărneanu wrote:
    >
    > I think it's safe to use FltGetFileNameInformationUnsafe(). I'm using
    > that function and my filter performs just fine with regular I/O and
    > memory mapped I/O. For reference, I'm processing only non cached I/O
    > via FLTFL_OPERATION_REGISTRATION_SKIP_CACHED_IO.
    >
    > Thanks for help.
    >

    I definitely recommend obtaining the name information during post-crate
    processing and storing it in a stream context. This way you are not
    having to obtain the name information on every IO, you can simply
    retrieve the stream context and you will have the name.

    Pete

    --
    Kernel Drivers
    Windows File System and Device Driver Consulting
    www.KernelDrivers.com
    866.263.9295
  • Aram_Havarneanu-2Aram_Havarneanu-2 Member Posts: 161
    On Tue, Sep 7, 2010 at 7:29 PM, <xxxxx@gmail.com> wrote:
    > FltGetFileNameInformationUnsafe does not look *safe* to me :) (obvious from name in fact), read the remark section and it should be clear.
    >
    > You can actually call it only in create and than store it, later in read/write you can referred to the stored value. Will actually save you from overhead.
    >
    > IF you have not looked yet, than take a look at contexts.

    On Tue, Sep 7, 2010 at 7:29 PM, Peter Scott <xxxxx@kerneldrivers.com> wrote:
    > I definitely recommend obtaining the name information during post-crate
    > processing and storing it in a stream context. This way you are not having
    > to obtain the name information on every IO, you can simply retrieve the
    > stream context and you will have the name.

    Oh, I am very aware of this facts. However, I was under the impression
    that file contexts require at least Windows Vista? I think stram
    context are what I want though.

    --
    Aram Hăvărneanu
  • OSR_Community_UserOSR_Community_User Member Posts: 110,217
    On 9/7/2010 1:18 PM, Aram Hăvărneanu wrote:
    >
    > Oh, I am very aware of this facts. However, I was under the impression
    > that file contexts require at least Windows Vista? I think stram
    > context are what I want though.
    >

    Stream contexts, FLT_STREAM_CONTEXT, are supported on all platforms
    where Filter Manager is supported which includes 2000 sp4 + SRP, XP sp2
    and above, 2K3 sp1, Vista and above. FLT_FILE_CONTEXT and
    FLT_TRANSACTION_CONTEXT types are the ones which are only supported on
    Vista and above.

    Pete

    --
    Kernel Drivers
    Windows File System and Device Driver Consulting
    www.KernelDrivers.com
    866.263.9295
  • Aram_Havarneanu-2Aram_Havarneanu-2 Member Posts: 161
    On Tue, Sep 7, 2010 at 10:41 PM, Peter Scott <xxxxx@kerneldrivers.com> wrote:
    > Stream contexts, FLT_STREAM_CONTEXT, are supported on all platforms where
    > Filter Manager is supported which includes 2000 sp4 + SRP, XP sp2 and above,
    > 2K3 sp1, Vista and above. FLT_FILE_CONTEXT and FLT_TRANSACTION_CONTEXT types
    > are the ones which are only supported on Vista and above.

    I have updated my filter to use stream context. I check what I need
    only in the post-create path, and then save the information in the
    context. It works perfectly and the performance of my filter is great.
    No problems with Driver Verifier either. Prefast is clean, too bad SDV
    doesn't work for file system minifilters.

    --
    Aram Hăvărneanu
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Upcoming OSR Seminars
Writing WDF Drivers 25 Feb 2019 OSR Seminar Space
Developing Minifilters 8 April 2019 OSR Seminar Space