Am I missing operatons I should be filtering in my mini filter?

I have read many posts and articles from this site and it has helped me tremendously.

I am a new mini filter (mf) developer writing a mf driver which filters requests to read or write files within specific folders on non-network volumes and makes a decision to allow or not. Since an open can result in a file being modified (truncated), I have a PreCreate (IRP_MJ_CREATE) callback. Hardlink creation and renames do not come through PreCreate so I filter those with a PreSetInformation (IRP_MJ_SET_INFORMATION) callback .

So I am only filtering on PreCreate and PreSetInformation on requests that can either lead to a read or write of the file contents -or- a write of security info such as the DAC or owner (read of file attributes is always allowed). I use PFLT_CALLBACK_DATA->Iopb->Parameters.Create.SecurityContext->DesiredAccess to check what access is being requested and FltGetFileNameInformation, FltGetDestinationFileNameInformation (PreSetInformation only) to get the normalized path being accessed.

My general concern is, are there cases that I am missing.

Specific questions:

  1. Other than hardlink creation and renames, must a request to read or write a file be preceded by an open and so I will see it in my PreCreate callback?
  2. I have read on some old posts that the FltGetFileNameInformation and FltGetDestinationFileNameInformation functions may be unreliable. If this is still the case, what scenarios may I not obtain a valid filename?
  3. Can I rely on the DesiredAccess field on PreCreate to determine the level of access being requested?
  4. I know this is a complex area so is there anything beyond what I've asked that you think I should be aware of?

Any feedback is appreciated.

Hello OSR community. I have continued development but these questions are still outstanding for me.

Is there anyone out there who can provide some feedback? Is there somewhere I can look to better understand these areas and formulate an answer for myself? Question 1 is key for me.

Thanks.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.

Sorry, I’m not sure I understand the design/question.

Are you trying to control just read and write or delete as well? Renames and hard links don’t read or write files though they can certainly destroy the destination, hence my confusion.

And what are your use cases? A locked down configuration somewhere or just any system? Which file systems do you need to support? You’re also presumably aware that normalized names in pre-create are generally pretty expensive (they at least 2x the number of opens across the system) so it’s better if you can design to only do that in cases where you absolutely, positively need to (e.g. destructive opens and delete on close handling on non-NTFS or pre-1607 NTFS systems).

Unfortunately there’s no one right answer for every solution, so general guidance is hard to provide. If you have a specific case or behavior you’re having trouble understanding then the forum can generally be more helpful.

In terms of specific questions about read and write:

  1. Yes, you have to open for read or write to do anything that would read or write the file data (including memory mapping). Of course, if you dynamically load you won’t see every create…
  2. I’ve never had to write my own name query routine since FltMgr. If there are reproducible issues that FltMgr isn’t handling then that’s something we should try to report.
  3. Yes.
  4. It entirely depends on use cases and threat model. But ultimately file I/O in Windows requires a file object so create is the starting point.

Thanks Scott for the response.

The end goal is to control the following operations against a given folder:

  1. read of file data
  2. write (including delete) of file data or attributes

Instead of making the decision on the read or write, I make the decision on the open. This is because

  1. an open can cause modification
  2. I don’t have to keep making the same decision on every read/write.
  3. simpler

I mention hardlinks and renames for the following reasons.

  1. For hardlinks, if the source (file being linked to) is within the folder of interest, I would like to know because that means that that file can now be accessed from a path outside the one I am looking for. As for the destination, it does not go through create processing. So I make a decision on that in the SetInfo callback.
  2. For a rename, my create callback receives a request for the existing file with the delete flag on in DesiredAccess so that gets handled there. But the create callback isn’t called for the new file. By filtering on SetInfo, I can make a decision on the create of the new file.

So here you can see the reason for my question about create being called. I suspect because a new file is not actually being created and all that is happening is manipulating file system pointers, we don’t see those in the create callback. Are you aware of any others like these or otherwise where we might not see a create?

To answer your questions:

  1. My plan is to support any non-network volume on Win 11.
  2. I have read that normalized names in precreate are more expensive than postcreate. I plan to do some performance testing in this area.

Followup questions based on your response:

  1. Are you aware of any other scenarios where we might not see a create?
  2. Are you saying normalized names in precreate are 2x as expensive as postcreate?
  3. Could you elaborate on this point? Are you talking about my filter? My filter gets loaded at startup and remains loaded as far as I know.
    ”Of course, if you dynamically load you won’t see every create…”
  4. Any non-network volumes that may not work with this design?