Prevent file deletion

I have a file my driver uses to track state information. I create it as HIDDEN and SYSTEM and I set share to 0. However I see that a user can delete the file. I do not want to implement a file system filter. Why is the file deletable? If share is 0 and the handle is open how is the file deletable?

Are you sure user deletes it when your driver has it opened? What I’d do is to rename the file and delete it after reboot.

Still requires DELETE access.

What does ProcMon say?

I’ve isolated the issue. i open the file with access of 0. This is for two reasons; 1) I do no IO via the file system to this file, and 2) If the file is open with access not 0 during boot time chkdsk it will fail ; if the file is opened with access of 0 chkdsk works. So I guess if you have an open handled with no access you can delete the file.

However I see that a user can delete the file.
User or elevated administrator? (Administrator can do a lot, even prevent your driver from starting)

I create it as HIDDEN and SYSTEM and I set share to 0
Try to protect it with ACL.
– pa

I have a file my driver uses to track state information. I create it as HIDDEN and SYSTEM and I set share to 0.
However I see that a user can delete the file. I do not want to implement a file system filter. Why is the file deletable?

Well, in order to delete a file one needs to know its path, right. Therefore, assuming that the calling process knows a path to the target file and has the sufficient privilege level, it can modify file attributes the way it wishes, effectively overriding your settings. Nothing particularly surprising here, don’t you think…

If share is 0 and the handle is open how is the file deletable?

Well, the only thing you can prevent by setting 'ShareMode" to 0 is opening the target file by another caller. However, neither SetFileAttributes() nor DeleteFile() require opening a handle to the file, right. The only thing they need is a file path.

Therefore, assuming that a caller has the sufficient privilege level, there is nothing that can be done here. If you search the archives, you will see quite a few “exciting” threads discussing this topic, with lots of shouting in capitals by the usual suspects ( and with not-so-short diatribes on the subject from Truly Yours as well)…

Anton Bassov

Both setfileattributes and deletefile open file and use ntsetinformationfile

@anton_bassov said:

I have a file my driver uses to track state information. I create it as HIDDEN and SYSTEM and I set share to 0.
However I see that a user can delete the file. I do not want to implement a file system filter. Why is the file deletable?

Well, in order to delete a file one needs to know its path, right. Therefore, assuming that the calling process knows a path to the target file and has the sufficient privilege level, it can modify file attributes the way it wishes, effectively overriding your settings. Nothing particularly surprising here, don’t you think…

If share is 0 and the handle is open how is the file deletable?

Well, the only thing you can prevent by setting 'ShareMode" to 0 is opening the target file by another caller. However, neither SetFileAttributes() nor DeleteFile() require opening a handle to the file, right. The only thing they need is a file path.

Therefore, assuming that a caller has the sufficient privilege level, there is nothing that can be done here. If you search the archives, you will see quite a few “exciting” threads discussing this topic, with lots of shouting in capitals by the usual suspects ( and with not-so-short diatribes on the subject from Truly Yours as well)…

Anton Bassov

I did something in this area years ago. Basically I opened the file and kept it open while my driver was running, I wanted it there on reboot so I changed the FileDispositionInformation to zero just before closing as my driver was shutting down.

This was XP era, but it worked then.

Both setfileattributes and deletefile open file and use ntsetinformationfile

This is true, but:

  1. In order to set file attribute by means of ZwSetFileInformation() you may need a handle with FILE_WRITE_ATTRIBUTES access. However,
    both ZwCreateFile() and ZwOpenFile() allow you to open a file for either exclusive access, or for FILE_SHARE_READ, FILE_SHARE_WRITE or FILE_SHARE_DELETE one. In other words, opening a file for the exclusive access does not seem to prevent opening it with FILE_WRITE_ATTRIBUTES one by the other caller, so that SetFileAttributes() may be working just fine.
  2. Although DeleteFile(), indeed, relies (or at least used to) upon ZwSetFileInformation() with FileDispositionInformation infoclass behind the scenes, you can also delete a file by calling ZwDeleteFile() . This function does not require opening a file handle.

Anton Bassov

What model breakage does ZwDeleteFile do to not require opening the file?:slight_smile:
Whether it does so internally or not is unimprtant.

It still requires DELETE access, not WRITE_ATTRIBUTES to delete the
file (via either DELETE_ON_CLOSE or FileDispositionInformation/Ex).

Even inside a driver, I could not delete an open file when I specify
IO_IGNORE_SHARE_ACCESS_CHECK.

D.

On 4/29/20, anton_bassov wrote:
> OSR https://community.osr.com/
>
> anton_bassov commented on Prevent file deletion
>
>> Both setfileattributes and deletefile open file and use
>> ntsetinformationfile
>
> This is true, but:
>
> * In order to set file attribute by means of ZwSetFileInformation() you may
> need a handle with FILE_WRITE_ATTRIBUTES access. However,
>
> both ZwCreateFile() and ZwOpenFile() allow you to open a file for either
> exclusive access, or for FILE_SHARE_READ, FILE_SHARE_WRITE or
> FILE_SHARE_DELETE one. In other words, opening a file for the exclusive
> access does not seem to prevent opening it with FILE_WRITE_ATTRIBUTES one
> by the other caller, so that SetFileAttributes() may be working just fine.
> * Although DeleteFile(), indeed, relies (or at least used to) upon
> ZwSetFileInformation() with FileDispositionInformation infoclass behind the
> scenes, you can also delete a file by calling ZwDeleteFile() . This function
> does not require opening a file handle.
>
> Anton Bassov
>
> –
> Reply to this email directly or follow the link below to check it out:
> https://community.osr.com/discussion/comment/297037#Comment_297037
>
> Check it out:
> https://community.osr.com/discussion/comment/297037#Comment_297037
>

Anton I don’t know what you trying to prove now. You were implying that you don’t need opened handle to delete a file. This is false.

And as Dejan already said ntdeletefile just opens file itself.

Still requires DELETE access.

What about MoveFileEx() with MOVEFILE_DELAY_UNTIL_REBOOT flag? I think it doesn’t open file at all and just stores to the registry the action to be done after reboot. With NULL new name the file is deleted after reboot.

It still requires DELETE access, not WRITE_ATTRIBUTES to delete the

As long as this delete operation results from a call to ZwSetFileInformation() , this is certainly true. However, please note that some
attributes may prevent a file from being deleted, so that they may have to be removed first.

https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-deletefilea

[begin quote]

To delete a read-only file, first you must remove the read-only attribute.

[end quote]

In fact, I am not sure if it applies to ZwDeleteFile(), but anyway

What model breakage does ZwDeleteFile do to not require opening the file?:slight_smile:

Well, if it does not require a file handle, a requirement for a file handle with DELETE access simply disappears in itself, don’t you think…

Anton Bassov

> What about MoveFileEx() with

MOVEFILE_DELAY_UNTIL_REBOOT? I think it doesn’t
open file at all and just stores to the registry
the action to be done after reboot. With NULL new
name the file is deleted after reboot.
That still requires DELETE access to the file. (on reboot, not right away)

> What model breakage does ZwDeleteFile do to not require opening the
> file?:slight_smile:

Well, if it does not require a file handle, a requirement for a file handle
with DELETE access simply disappears in itself, don’t you think…

And how does it delete a file without opening it first?
Please do describe the technical side of this, because if that were
true, the entire NT file system stack model is broken.

That still requires DELETE access to the file. (on reboot, not right away)

Yes, but it can be deleted before driver opens it. However, I have no idea when it happens.

To be clear I am setting FileAccess to 0. So if I open a file with no sharing and file access set to zero I can delete the file while it is open.

And how does it delete a file without opening it first?

Could you please provide some quotation of me saying something like that.

The only thing I am saying is that it does not need a file handle as a parameter, because a handle opened by a higher-level API like ZwOpenFile() may be simply insufficient for the purpose due to 'ShareAccess’parameter that cannot be ignored/overridden in a higher-level call. Instead of taking a a file handle parameter, it can call a lower-level IoCreateFileEx() with IO_IGNORE_SHARE_ACCESS_CHECK option behind the scenes, which simply eliminates the issue under consideration. This is why STATUS_ACCESS_DENIED is not on the list of errors that ZwDeleteFile() may return

https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-zwdeletefile

Anton Bassov

>> And how does it delete a file without opening it first?

Could you please provide some quotation of me saying something like that.
If you say it does not require a handle, then it does not require a
file opening.
It may not require a passed-in handle, which is quite a different thing.

Instead of taking
a a file handle parameter, it can call a lower-level IoCreateFileEx() with
IO_IGNORE_SHARE_ACCESS_CHECK option behind the scenes,
That will still not allow it to open (much less delete) the file.

You miss my point Anton. I open the file in my driver at boot time and I keep it open until a volume dismounts or the system reboots. The issue is that I have the file open with exclusive access (no sharing) and no access flags, and I can, as administrator, delete my file from explorer; even though I have an open handle to the file. If I add access flags (anything will do; read, write, write attributes, delete, &c.) then the file is prevented from being deleted. So without providing any access flags (FILE_SPECIAL_ACCESS is what I am using) you can delete a file with an exclusively opened handle. I do not like having my file yanked out from underneath me.

If you say it does not require a handle, then it does not require a file opening.
It may not require a passed-in handle, which is quite a different thing.

Apparently, I just did not express myself clear enough. My bad…

That will still not allow it to open (much less delete) the file.

Why not? Please note that we are speaking about an access getting denied solely because of someone having had opened the target file exclusively. Certainly, if a requesting process cannot pass the access check against the target file’s security descriptor the call is going to fail, but we are speaking about the Admin account here. The only potential issue here is of someone having had opened exclusively, so that IO_IGNORE_SHARE_ACCESS_CHECK should do the trick (unless the underlying FSD enforces it anyway, of course)…

Anton Bassov