šŸ“œ ā¬†ļø ā¬‡ļø

Bug in NTFS, or how to hang the whole system

Not so long ago, when developing a file system filter, there was a problem that caused the entire system to hang. It would seem that the filter performed very simple actions and was very primitive itself. To find out the reason, I had to go down to debugging and reverse engineering the NTFS driver. The analysis revealed a very interesting effect. If you compile and run a very simple program shown in the figure below, access to the corresponding volume will hang.


Those. in this example, if you try to open any file relative to the $ mft file, access to the entire volume ā€œCā€ will hang, and since this volume is system-wide, the entire system will also freeze. You do not need to have any rights. If the volume was not a system volume, then only access to this volume will hang, but if you perform a reboot, the system will hang on it.

Some theory


Before describing the essence of the problem, it is worth considering the basic principles of building file systems. When a process opens a file, in addition to the received HANDLE on it, structures also form in the kernel space, both by the kernel itself and by the file system, which, in essence, represent the volume file in memory. The figure below shows these structures.


The HANDLE file always refers to the structure of the FILE_OBJECT kernel. This structure is formed by the kernel before sending a request to the file system. The file system, in turn, initializes the fields of this structure. Thus, the FILE_OBJECT structure will contain pointers to file system structures: FCB (File control block, contains all the necessary data for file management) and CCB (Context Control Block, contains data unique to a particular open instance). It is also possible that two different HANDLEs will refer to the same volume file, as reflected on the left. The FCB structure contains a list of all CCB structures. The CCB structure contains a pointer to the corresponding FCB. Those. There will be exactly one FCB structure for each open volume file in memory. If a file is opened several times, exactly as many CCB structures will be formed, how many times the corresponding file has been opened, and all these structures will refer to a single FCB structure.
')
Since file access can be performed simultaneously by a different or the same process, these parallel operations must be serialized. It is possible that some operations will be performed simultaneously (for example, reading), however, there are situations where access must be performed exclusively (for example, writing). For this, the kernel provides a serialization mechanism - ERESOURCE. This object can be captured both exclusively and shared. If the object is captured exclusively, then any attempt to capture it will be in the waiting queue. If an object is captured shared, then attempts to also capture it shared will be satisfied immediately. If the object is captured separately and the waiting queue is not empty (i.e. there was an attempt of exclusive capture), then any attempts to capture it will be placed in the waiting queue.

FCB file system structures for access serialization contain these mechanisms and actively use them during file access. This ensures the integrity of the file both in memory and on the volume.

The $ mft file of the NTFS file system is system file. This file describes the location of all files on the volume. NTFS when mounted opens it for personal use. If you try to read the contents of a directory or while opening a file, NTFS will read the $ mft file. Whenever you try to delete a file or create a file, NTFS will write to this file. Consequently, before any such operation, the ERESOURCE mechanism of this file will also be captured, then the operation itself will be executed, after which the mechanism will be released.

NtfsCommonCreate function


To understand the essence of the problem, it is necessary to understand the principle of operation of the NTFS file system NtfsCommonCreate function. A very simplified pseudocode is shown below. Only those parts of the function that are directly related to the problem are given.


The NTFS file system stores a tree of already open files / directories. Therefore, it is advisable in order to improve performance to find the target file in this tree instead of repeatedly reading the volume. Consequently, the function will try to find it using the function NtfsFindStartingNode. If the file could not be found, then the function will try to find the directory in which it is located. This attempt will be performed up to the root of the file system. The NtfsFindStartingNode function returns a pointer to the FCB structure of either the file itself or the directory that is closest in depth to the target file. The function will also return a part of the raw path relative to the found directory. Also, the function pre-captures the ERESOURCE of the found directory or file is shared.

Next, the NtfsCommonCreate function checks if there is a part of the raw path, if not, then the NtfsFindStartingNode function has found the file itself, and in this case, the NtfsCommonCreate function ends. Otherwise, the function continues to search for the file, but already on the volume.

As can be seen from the pseudo-code, the function contains a loop in which the directories leading to the file are opened successively. At the beginning of the cycle, it is checked whether the file is a directory, and if not, then the function ends with an error. Otherwise, the next name in the path is extracted and an attempt is made to open a file / directory with that name using the NtfsOpenSubdirectory function. The NtfsOpenSubdirectory function also captures the open file / directory exclusively. Before calling the NtfsOpenSubdirectory function, the previous open directory is also released with the NtfsOpenSubdirectory function. The work cycle will continue to the directory in which the alleged file will be located.

Upon completion of its work in the event of unsuccessful completion, the NtfsCommonCreate function will close the last found directory using the NtfsTeardownStructures function. Also, this function will release the ERESOURCE directory / file, if possible. Those. if this directory / file is not open. Since this directory / file has been opened by the file system only, most likely, that their ERESOURCE will be released, and the FCB file will be closed.

The essence of the problem


When an attempt is made to open a file relative to the $ mft file, the NtfsFindStartingNode function will not find it, since this function performs the search a little differently, unlike the NtfsOpenSubdirectory function, which always finds this file. Consequently, a cycle will start, starting at the root of the file system. Next, the NtfsOpenSubdirectory function will open this file and capture it with ERESOURCE exclusively. At the next iteration, the loop will find that the file is not a directory, and, therefore, will interrupt its operation with an error. And when you finish your work, the NtfsCommonCreate function will use the NtfsTeardownStructures function to attempt to close it. The function NtfsTeardownStructures, in turn, will face the fact that it will not be able to close the file, because it is opened by the file system itself when mounted. In this case, contrary to the expectations of the NtfsCommonCreate function, the NtfsTeardownStructures function will not release the ERESOURCE $ mft file. Thus, he will remain captured forever. Therefore, for example, when attempting to create a file or read a file of a volume, the NTFS file system will attempt to capture the ERESOURCE $ mft file and freeze at this point forever.

Conclusion


This problem can not be called a vulnerability, but with remote access to the machine, it is possible to disrupt its operation. This error persists up to the latest versions of Windows, with the exception of the latest updates, starting at least with Windows Vista. As already mentioned, the description of the operation of the NTFS file system in this case is very simplified and reflects only the essence of the problem. In fact, the implementation is much more complicated than the above description.

Source: https://habr.com/ru/post/329166/


All Articles