Getting wrong File object in Paging I/O Write

I am working on minifilter, i opened 2 file objects for same file one with desired access “GENERIC_WRITE” and another with “GENERIC_READ”. When i read the file then write the same file without closing any FO, i could see the Paging Write I/O receives File Object Opened for GENERIC_READ. Since this FO doesnt have Write permission so Paging Write results in ACCESS_DENIED.

1 FileTest.exe FFFFFA800221E540 IRP_MJ_CREATE 00000884 FFFFFA80022602A0 FFFFFA80021CE6D0 FFFFFA80020351D0 Z:\RCRelease\1.txt STATUS_SUCCESS
2 FileTest.exe FFFFFA80021A8300 IRP_MJ_CREATE 00000884 FFFFFA8001A16F20 FFFFFA80021CE6D0 FFFFFA8002058940 Z:\RCRelease\1.txt STATUS_SUCCESS
4 FileTest.exe FFFFFA80021A8300 IRP_MJ_READ 00060900 FFFFFA8001A16F20 FFFFFA80021CE6D0 FFFFFA8002058940 Z:\RCRelease\1.txt STATUS_SUCCESS
3 FileTest.exe FFFFFA800204A770 IRP_MJ_READ 00060403 FFFFFA8001A16F20 FFFFFA80021CE6D0 FFFFFA8002058940 Z:\RCRelease\1.txt STATUS_SUCCESS
5 FileTest.exe FFFFFA80021A8300 IRP_MJ_WRITE 00060A00 FFFFFA80022602A0 FFFFFA80021CE6D0 FFFFFA80020351D0 Z:\RCRelease\1.txt STATUS_SUCCESS
6 System FFFFFA80021A8300 IRP_MJ_WRITE 00060043 FFFFFA8001A16F20 FFFFFA80021CE6D0 FFFFFA8002058940 Z:\RCRelease\1.txt STATUS_ACCESS_DENIED
7 System FFFFFA80021A8300 IRP_MJ_WRITE 00060043 FFFFFA8001A16F20 FFFFFA80021CE6D0 FFFFFA8002058940 Z:\RCRelease\1.txt STATUS_ACCESS_DENIED

Filespy shows changed FO for paging IO…this FO was opened for reading…

This behavior is weird!!!

One more point to add … This is happening on Remote File System only not on local FS

It can happen on any file system and relates to the way that this state is managed by the Cache Manager/Memory Manager.

Tony
OSR

Thanks Tony For your reply…

I understood that file object received in Paging IO is most likely the one on which cashing was initiated and in my case first file object was opened for READ and i am getting Paging IO FO with only Read permission which is failing in case of remote file system.

Any solution to this problem?

Use a different file object. There’s an FsRtl routine for swapping the file object that Cc and Mm are using (if you own the cache): https://msdn.microsoft.com/en-us/library/windows/hardware/ff545749(v=vs.85).aspx

You can also just keep track of the file objects as they fly by and snag one with write access on it. Isolation filters can also try adding it to the lower file object, though that will fail if the caller doesn’t have permission to obtain write access (so you end up dealing with the error failure case).

Tony
OSR

FsRtlChangeBackingFileObject does not allow subsequent swapping of the file object if the caller obtained the file object with a call to CcGetFileObjectFromSectionPtrs.

OK, so get the file object some other way - store it on your own. For example, in your stream context structure, keep a pointer to the file object and the access granted to it. Then when you see a new file object come along that has MORE access (FILE_WRITE_DATA for example) do the swap at that point and update your stream context information.

Tony