Best practices for caching filenames in kernel from minifilter?

I’m writing a security minifilter that uses a combination of kernel space and user space processing to decide whether a user should have access to a file or not, and fortunately it’s been decided I only need to do this expensive processing once per file per user session. This means I can cache the allow/deny results on a per-file basis, and my first thought was to implement a simple least-recently-used (LRU) cache using a hashtable/doubly linked list containing each file’s name in UNICODE_STRING format. However I thought I’d check with experts to see if there’s a “minifilter-approved” way of doing something like this, after seeing what a timesaver minifilter communication ports are over other KM-UM communication options like WinSock.

Any suggestions appreciated including “that’s a really bad idea”!

I would do some reading about mini filter contexts, which you can attach to all kinds of things, including files, streams, stream handles. I think this may do what you are trying to accomplish. Here would be a good place to start.

Thanks for the suggestion, I thought about attaching file contexts but I couldn’t exactly figure out their lifetime from reading this document, especially if files are deleted.

One of the applications I’m coding against constantly deletes documents and renames temp files to the old filename (e.g. if you have test.log it writes to ~test.log.tmp, then regularly deletes test.log and changes the name of ~test.log.tmp to test.log). If I roll my own cache based on filename then I don’t have to worry about this situation, but if I’m using file contexts I was concerned that the original file being deleted and replaced might lead to a situation where I would look for a context and not find it (or worse, I get the context but it’s referencing a file that’s been deleted).

Clearly my understanding of NTFS/Windows kernel is pretty limited so apologies if these are very dumb questions!

I can’t grasp really what you are after…
When Word creates ~FileName.tmp, then renames it to FileName.doc, what
is it that you consider a cache?

Thanks for the suggestion, I thought about attaching file contexts but I
couldn’t exactly figure out their lifetime from reading this document,
especially if files are deleted.

One of the applications I’m coding against constantly deletes documents and
renames temp files to the old filename (e.g. if you have test.log it writes
to ~test.log.tmp, then regularly deletes test.log and changes the name of
~test.log.tmp to test.log). If I roll my own cache based on filename then I
don’t have to worry about this situation, but if I’m using file contexts I
was concerned that the original file being deleted and replaced might lead
to a situation where I would look for a context and not find it (or worse, I
get the context but it’s referencing a file that’s been deleted).

I’m not quite sure how Word works but in that case we would intercept the first time the user opens FileName.doc, authorize their access, then cache FileName.doc as a trusted filename.

In this case my concern with file contexts would be if Word deletes the original file and replaces it with the .tmp file, what would I see in the kernel next time the user opens FileName.doc? I assumed the file context was bound to the Windows/NTFS file object itself, which now is either gone or points to a deleted file.

@Alorynn said:
I’m not quite sure how Word works but in that case we would intercept the first time the user opens FileName.doc, authorize their access, then cache FileName.doc as a trusted filename.

Is your policy really just based on the name and not the content? So, I open a benign Foo.docx once and then I can rename any existing file to Foo.docx and do whatever I want with it? Note that I could run an executable named Foo.docx.

And don’t forget about hard links…Using this model I could presumably:

  1. Open c:\public\Holidays.docx
  2. Delete c:\public\Holidays.docx
  3. Hard link c:\secrets\PepsiRecipe.docx → c:\public\Holidays.docx
  4. Do whatever I want with c:\public\Holidays.docx

(Maybe you’ve thought through this stuff, but a purely path based policy usually falls apart at some point. Whether or not this matters is entirely up to your product requirements and threat model)

In this case my concern with file contexts would be if Word deletes the original file and replaces it with the .tmp file, what would I see in the kernel next time the user opens FileName.doc? I assumed the file context was bound to the Windows/NTFS file object itself, which now is either gone or points to a deleted file.

You would end up with a new file context because it is in fact a new file.

1 Like

Is your policy really just based on the name and not the content? So, I open a benign Foo.docx once and then I can rename any existing file to Foo.docx and do whatever I want with it? Note that I could run an executable named Foo.docx.

Yes for this phase that’s the case. The next phase will implement write monitoring to cached filenames and re-authorization.

I’ll give the file context method a try and see if it meets our needs; requiring re-auth isn’t a functional issue and we can cache credentials elsewhere to mitigate any performance issues.

One final note: make sure you actually want file contexts and not stream contexts (people usually end up wanting stream contexts).

1 Like

A hard link creation would require opening the c:\secrets, and can be tracked.
It needs to be thought of, but it is trackable with filenames.

(not suggesting doing so for any security, just pointing out the technical side!)

And don’t forget about hard links…Using this model I could presumably:

  1. Open c:\public\Holidays.docx
  2. Delete c:\public\Holidays.docx
  3. Hard link c:\secrets\PepsiRecipe.docx → c:\public\Holidays.docx
  4. Do whatever I want with c:\public\Holidays.docx