Re-opening the file from PostOpCreate

Hello,

I have raised this topic in multiple different (but possibly related) threads before. However, unfortunately, I haven’t really got any concrete/conclusive recommendation on the topic which should work *almost all the times* on *all* Windows flavors from Windows XP to Windows 2012.

Hence I thought like raising the topic in a dedicated thread.

Currently my mini-filter checks if the file object passed to PostOpCreate has read permissions using fltObjects->FileObject->ReadAccess. If it has read permissions, it uses the same file object to perform the scan, otherwise, it re-opens the file using FltCreateFile call (with maximum sharing) and performs the scan using that file object.

The re-opening of the file may cause an op-lock break. This typically happens when the file system request is coming from the srv.sys, but may happen otherwise also. This forces me to wait for the op-lock break to complete before I can scan the file again. Recently I ran into sharing violation issues with office applications trying to save documents over network share protected by my minifilter. This happens when minifilter is scanning the file after op-lock break completes.

All of this makes me revisit the point that: Should I re-open the file at all in my mini-filter? Few reasons that drove my decision to re-open were.

  1. My mini-filter can perform the reads on the file object even if fltObjects->FileObject->ReadAccess is FALSE. However, I have seen that this works only for local files but not for network files.
  2. Sometimes (especially on Windows XP/2003) I am passed stack based file objects. These file objects have fltObjects->FileObject->ReadAccess set to FALSE and if I try to read on them, I run into sporadic crashes later on, possibly because cache manager keeps reference to these objects.

These two points can potentially be addressed by re-opening the files only when they are network files OR when the file object is stack based. The former is easy to detect. For later, I am thinking of using IoGetStackLimits and checking if the PFILE_OBJECT lies in the stack limits. Would that suffice?

Are there any other known issues of using the file object passed to PostOpCreate to perform the scan?

For remediation (delete, truncate, write), I am not sure if I can use the same file object. However, I think, requiring remediation is probably an exception rather than rule and hence re-opening the file which may cause breaking op-locks OR causing sharing violations etc. may be fine for infected files.

I am sincerely looking forward to experts on this forum to provide an advice on the topic.

Thanks.
-Prasad

Can you say something about the nature of the file and the “scan”? For
example, if the nature of the file is that it is written from beginning to
end, with no random access, a “scan” can be done as the IRP_MJ_WRITE
commands are processed. This would avoid the problem of needing to
re-open it. The other question about the scan is whether or not it must
be purely deterministic, or only statistically robust.

joe

Hello,

I have raised this topic in multiple different (but possibly related)
threads before. However, unfortunately, I haven’t really got any
concrete/conclusive recommendation on the topic which should work *almost
all the times* on *all* Windows flavors from Windows XP to Windows 2012.

Hence I thought like raising the topic in a dedicated thread.

Currently my mini-filter checks if the file object passed to PostOpCreate
has read permissions using fltObjects->FileObject->ReadAccess. If it has
read permissions, it uses the same file object to perform the scan,
otherwise, it re-opens the file using FltCreateFile call (with maximum
sharing) and performs the scan using that file object.

The re-opening of the file may cause an op-lock break. This typically
happens when the file system request is coming from the srv.sys, but may
happen otherwise also. This forces me to wait for the op-lock break to
complete before I can scan the file again. Recently I ran into sharing
violation issues with office applications trying to save documents over
network share protected by my minifilter. This happens when minifilter is
scanning the file after op-lock break completes.

All of this makes me revisit the point that: Should I re-open the file at
all in my mini-filter? Few reasons that drove my decision to re-open were.

  1. My mini-filter can perform the reads on the file object even if
    fltObjects->FileObject->ReadAccess is FALSE. However, I have seen that
    this works only for local files but not for network files.
  2. Sometimes (especially on Windows XP/2003) I am passed stack based file
    objects. These file objects have fltObjects->FileObject->ReadAccess set to
    FALSE and if I try to read on them, I run into sporadic crashes later on,
    possibly because cache manager keeps reference to these objects.

These two points can potentially be addressed by re-opening the files only
when they are network files OR when the file object is stack based. The
former is easy to detect. For later, I am thinking of using
IoGetStackLimits and checking if the PFILE_OBJECT lies in the stack
limits. Would that suffice?

Are there any other known issues of using the file object passed to
PostOpCreate to perform the scan?

For remediation (delete, truncate, write), I am not sure if I can use the
same file object. However, I think, requiring remediation is probably an
exception rather than rule and hence re-opening the file which may cause
breaking op-locks OR causing sharing violations etc. may be fine for
infected files.

I am sincerely looking forward to experts on this forum to provide an
advice on the topic.

Thanks.
-Prasad


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

@Joseph, the scan is like any antivirus scan. Hope that answers all your questions.

The goal is to ensure that:

  1. The file is always scanned on initial open and subsequent opens as needed (e.g. if the clean scan result is not found in our cache)
  2. Whenever the file gets dirty (which we track in stream context by looking at IRP_MJ_WRITE), the file is scanned again on last handle close OR subsequent re-open.
  3. If we are not able to scan the file for whatever reason e.g. op-lock-break-in-progress, we would like to scan the file as soon as op-lock break completes.
  4. We do not cause any side effects to applications e.g. sharing violation errors

Thanks.
-Prasad

Any inputs please?

Thanks.
-Prasad

Hi Prasad,

First, are you noticed, on the local machine you can use the FILE_OBJECT to read the file even if there is no read access requested (and granted). This is only a problem when dealing with FILE_OBJECTs for remote machines.

I think the question to answer is whether you even need to scan the FILE_OBJECT in this case, since the user can’t get the file data anyway so I don’t think there’s any security risk. Also, in case of the remote machine you probably can’t do much in the way of remediation anyway? So I think it would be perfectly acceptable to ignore this open for this file (and not mark it as scanned with your stream context or anything). Does this make sense ?

Thanks,
Alex.
On Sep 10, 2013, at 9:27 PM, xxxxx@vmware.com wrote:

Any inputs please?

Thanks.
-Prasad


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Hi Alex,

Thanks for your response.

So are you suggesting that I should not scan the file at all if fltObjects->FileObject->ReadAccess is FALSE? I see this to be always the case when the request is coming from srv.sys on behalf of network client.

Can I be 100% sure that the file opened in such a way cannot be read/executed from a local/network client?

I am not sure about the remediation point? For remediation, I re-open the file in writable mode (if the original file object doesn’t have write access) in the same thread context. Hence I am not sure why would remediation not work for network files?

Thanks.
-Prasad

Hi Prasad,

Could you please help to review my question ?I felt frustrated to solve it . thanks a lot .
http://www.osronline.com/cf.cfm?PageURL=showThread.CFM?link=247859

Joe.Wang

Yeah, that was basically what I was suggesting. I mean, if the handle can’t be used to read any data then I would imagine the user would need to open a new one if they need to access the data, in which case you’ll be able to scan it.

“Can I be 100% sure that the file opened in such a way cannot be read/executed from a local/network client?” - I’m not 100% sure of anything these days :). Anyway, I’m not an expert on network file systems and there are others on this list that are in a better position to answer, but as far as I understand a new FILE_OBJECT must be opened for the file to be read/executed.

Sorry about mentioning remediation, I thought you were reusing the FILE_OBJECT. Since that’s not the case please ignore that comment.

Thanks,
Alex.
On Sep 11, 2013, at 9:04 PM, xxxxx@vmware.com wrote:

Hi Alex,

Thanks for your response.

So are you suggesting that I should not scan the file at all if fltObjects->FileObject->ReadAccess is FALSE? I see this to be always the case when the request is coming from srv.sys on behalf of network client.

Can I be 100% sure that the file opened in such a way cannot be read/executed from a local/network client?

I am not sure about the remediation point? For remediation, I re-open the file in writable mode (if the original file object doesn’t have write access) in the same thread context. Hence I am not sure why would remediation not work for network files?

Thanks.
-Prasad


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Thanks Alex.

Looking forward to other experts on the forum to share their thoughts. I am sure that every AV vendor deals with the situation one way or the other.

I have seen that most of the AV vendors have patches released for handling sharing violation errors with office applications saving files to network share. So I am sure that the issue that I am running into is pretty common and there is a known way of solving it.

I wish that scanner sample in the DDK was demonstrating how to handle such cases.

Thanks
-Prasad

Hi Alex,

Yeah, that was basically what I was suggesting. I mean, if the handle can’t be used to read any
data then I would imagine the user would need to open a new one if they need to access the data,
in which case you’ll be able to scan it.

I investigated this further and I don’t think we can go this path. The DLLs loaded by the application are skipped from the scan in this case. For each of the DLL, the PostOpCreate gets triggered with the following callstack. The file object does not have read permissions.

Child-SP RetAddr : Args to Child : Call Site
fffff88004125310 fffff880012d9288 : fffffa8004fd3e60 fffff88004125478 0000000000000000 0000000000000000 : MYFILTER!MyPostOpCreate+0x8b1
fffff88004125430 fffff880012d7d1b : fffffa80041ba030 fffffa8004fd3f00 fffffa800513fc00 fffffa800513fe20 : fltmgr!FltpPerformPostCallbacks+0x368
fffff88004125500 fffff880012f72b9 : fffffa8004ae7b30 fffffa80041b8010 fffffa8004ae7b00 fffffa8004193de0 : fltmgr!FltpLegacyProcessingAfterPreCallbacksCompleted+0x39b
fffff88004125590 fffff80001b8c625 : 0000000000000045 fffffa8004ffc5c8 fffff880041259e0 0000000000000000 : fltmgr!FltpCreate+0x2a9
fffff88004125640 fffff80001b88ec8 : fffffa80041b7cd0 fffff80000000000 fffffa8004ffc410 fffff80000000001 : nt!IopParseDevice+0x5a5
fffff880041257d0 fffff80001b8a0e6 : 0000000000000000 fffffa8004ffc410 fa800425de780460 fffffa8003d28210 : nt!ObpLookupObjectName+0x588
fffff880041258c0 fffff80001b6a0d6 : 0000000000000000 00000000000df770 fffff680003bbc01 fffff800018ac0b3 : nt!ObOpenObjectByName+0x306
fffff88004125990 fffff8000188df93 : 0000000000000008 00000000777979f3 fffffa80051cfb60 00000000c0000034 : nt!NtQueryAttributesFile+0x145
fffff88004125c20 00000000777b16ea : 000000007779aa63 00000000000df820 0000000000000000 0000000077877718 : nt!KiSystemServiceCopyEnd+0x13 (TrapFrame @ fffff88004125c20) 00000000000df738 000000007779aa63 : 00000000000df820 0000000000000000 0000000077877718 0000000000220230 : ntdll!NtQueryAttributesFile+0xa 00000000000df740 00000000777aa7d4 : 0000000000224ecc 0000000000000005 0000000000000005 0000000000000008 : ntdll!LdrpResolveFileName+0x83 00000000000df7e0 00000000777911fa : 000007fffffd0654 00000000000dfc20 0000000000000005 000000007789aa70 : ntdll!LdrpSearchPath+0x1e4 00000000000df850 0000000077787cc8 : 00000000000dfc78 0000000000000000 00000000c0150008 00000000000dfc00 : ntdll!LdrpFindOrMapDll+0x20d 00000000000df9d0 0000000077787b2e : 0000000000000000 0000000000000000 00000000000dfc70 000007fefdc7fe0d : ntdll!LdrpLoadDll+0x148 00000000000dfbe0 000007fefdc7c71f : 0000000000000000 0000000000000000 0000000000000000 000007fe`0000000e : ntdll!LdrLoadDll+0x9a

Initially I though that this happens only if the DLL is already mapped for some other application and it will still be scanned when it’s originally mapped.

However, then I tried with a brand new DLL that is never mapped before and loaded it using LoadLibrary. It was loaded without PostOpCreate getting a file object with read permissions.

This essentially means that DLLs won’t be scanned at all!

Thanks.
-Prasad

It can not be mapped without read permission.

First call is just for read attributes but there will be a subsequent create call with read access | execute. That first create call is used to fetch the basic attributes; your call stack also has NtQueryAttributesFile in it; so may be its that.

“It was loaded without PostOpCreate getting a file object with read permissions.”

This is interesting. I doubt that the file doesn’t have read permissions so I’m wondering if it’s possible that read permissions get somehow added behind the scenes between the time of the open and the time of the read. Also, I thought the IO manager would fail requests to read from a file handle that doesn’t have read permissions, so that’s also worth looking into.

I would try to use wireshark and procmon together to figure out what exactly is happening…

Sorry I can’t be more useful.

Thanks,
Alex.

On Sep 17, 2013, at 1:44 AM, xxxxx@gmail.com wrote:

It can not be mapped without read permission.

First call is just for read attributes but there will be a subsequent create call with read access | execute. That first create call is used to fetch the basic attributes; your call stack also has NtQueryAttributesFile in it; so may be its that.


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Hi Alex and Aditya,

Apologies, my analysis in “Message 10” was wrong. When the DLL is loaded, I am indeed getting another create with FO->ReadAccess set to TRUE apart from the one triggered by NtQueryAttributesFile.

I missed this because, in my experiment, I was ignoring the scan if FO->ReadAccess is set to FALSE, however I still ended up caching the clean scan result without scanning it. Because of this, in subsequent create (with readaccess=TRUE), I ended up skipping the scan based on the cached scan result. This gave me an illusion that I am not getting a create with readaccess=TRUE for DLLs. My bad, sorry about that.

On other note, one can always open the file in write only mode (readaccess = FALSE, writeaccess=TRUE) and in this case, I would like to scan the file on close if it’s written to (which I am tracking using the dirty bit set in the stream context on IRP_MJ_WRITE). Hence, in the close path, I would need to scan the file even if readaccess=FALSE.

Considering this and the inputs on this thread so far, I am going ahead with following approach.

  1. If FO->ReadAccess = FALSE and FO->WriteAccess = FALSE, do not scan the file at all. There is no way the file can be read from/executed/written to with such an FO.
  2. If FO->ReadAccess = TRUE, use the same file object to perform the scan.
  3. If FO->ReadAccess = FALSE, use the same file object to perform the scan assuming that it’s a local file and FO is not a stack based FO, otherwise, re-open the file to perform the scan.

Please comment if anybody has any thoughts/suggestions.

Thanks
-Prasad

Is point 1) about network files only?

Because AFAIK for local files; think about a kernel driver creating a FO with read attributes and than using it to read the file. Your AV will not scan it.

Aditya

Well, I’m glad my advice was good :).

Also, I agree with Aditya, I think this whole logic should only apply to network files.

On the write only mode thing, things are slightly more complicated. From a security perspective you could ignore those as well since whatever is written in the file can’t be executed or read on that handle so a new handle will have to be opened at some point, on which you can perform your scan. However, one could make the point that if something creates a malicious file on a network share your product should remove it anyway. However, in this case I point out that this means that same piece of malware is already running on your system so you’re probably unable to detect it, and also that the file already exists on the network share so other machines might have accessed it already…

So you could try to reason with your PMs and sales people or, for write-only files, implement your solution to reopen the file and scan it :).

Thanks,
Alex.
On Sep 18, 2013, at 3:51 AM, xxxxx@gmail.com wrote:

Is point 1) about network files only?

Because AFAIK for local files; think about a kernel driver creating a FO with read attributes and than using it to read the file. Your AV will not scan it.

Aditya


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Are you talking about about local files being accessed by Srv.sys on behalf of network client or network files like \severname\sharename\filename? My filter is going to see both. When I talk about logic for network files I meant the latter case

Aditya, if I do (1) for network files only, I will go back to my original issue and will cause oplock breaks and sharing violations when office tries to save documents from a network client. For handling the case that you are talking about, I will have to distinguish between local files being opened by Srv.sys vs. other kernel drivers.

Alex, point taken about write only files.

Thanks
-Prasad

>> For handling the case that you are talking about, I will have to distinguish between local files being opened by Srv.sys vs. other kernel drivers.

You do not have to re-open the FO for local files; you can simply reuse it. No matter what permissions it have.

>For network file (\serverName\…)

Deploy your logic mentioned above.

>About special handling of srv.sys FO
I do not see why you should be seeing them any different than other local FOs.

Taking a step back; isn’t AV an endpoint based solution? Say a VM1 is accessing a file from VM2; don’t they anyways check it in the VM1?

Thanks Aditya. However, I still need to handle the case for stack based FOs and ensure that i don’t issue reads on them.

The network share could be residing on a VM that is not protected OR it could be a non-Windows share as well.

Thanks all for your help!

Thanks.
-Prasad

Prasad,

You can explicitly check for stacked based FO’s, if you have one re-open
the file otherwise use the one you have.

Pete

On 9/20/2013 12:43 AM, xxxxx@vmware.com wrote:

Thanks Aditya. However, I still need to handle the case for stack based FOs and ensure that i don’t issue reads on them.

The network share could be residing on a VM that is not protected OR it could be a non-Windows share as well.

Thanks all for your help!

Thanks.
-Prasad


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer


Kernel Drivers
Windows File System and Device Driver Consulting
www.KernelDrivers.com
866.263.9295

@Pete, yes, you mean calling IoGetStackLimits and checking if the PFILE_OBJECT lies in the stack limits right?

Thanks.
-Prasad