A static code analysis tool (Fortify from HP) is complaining about Visual Studio Designer generated WinForms code when Font property of any control is assigned. The analysis tool complains :
line 143: this.mCopyrightLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
The function InitializeComponent() in AboutWindowForm.cs fails to properly dispose of unmanaged system resources allocated by Font() on line 143.
Explanation:
The program fails to properly dispose of a managed object that uses unmanaged system resources. Failure to properly dispose of a managed object that uses unmanaged system resources has at least two common causes:
- Error conditions and other exceptional circumstances.
- Confusion over which part of the program is responsible for releasing the resource.
In this case, there are program paths on which the resource allocated in AboutWindowForm.cs at line 143 is not disposed of properly.
A small subset of managed .NET objects use unmanaged system resources. .NET's Garbage Collector may not free the original managed objects in a predictable way. As such, the application may run out of available memory as the Garbage Collector is unaware of the memory consumed by the unmanaged resources. Most unmanaged resource leak issues result in general software reliability problems, but if an attacker can intentionally trigger an unmanaged resource leak, the attacker might be able to launch a denial of service attack by depleting the unmanaged resource pool.
I have been searched the topic regarding the disposing of font in windows forms for a while, and these are the points I gathered:
- creating font will occupy a GDI object, which is an unmanaged resource and therefore is important to be released when no longer needed
- Since GDI objects are expensive and scarce, WinForm caches them.
- Dispose WinForms control will also dispose all its child control and "release the unmanaged resource obtained"
- Form will be disposed when closed if the Form is modeless
Therefore I want to conclude that there is no need to explicit dispose Font assigned to controls in VS-generated code, and probably we should not to do so since fonts are cached?
I created a very simple Form test program: by clicking a button I create a new empty form who uses a different font. The GDI object count in Task Manager goes down immediately after I close the newly opened Form. This is an evidence of the above mentioned points, isn't it?
However the static analyzer seems not to believe the same. It believes the Font will eventually be released by GC. It also believes this is not good for unmanaged resource since the memory consumed sits outside GC's knowledge therefore GC will not be triggered timely because GC feels no memory pressure. This give attacker an opportunity to intentionally trigger deplete the unmanaged pool.
Can you help me a little on understanding the explanation given by the analyzer? Is it valid for WinFroms ? It would be tedious to manually dispose every Font created.
To be precise:
Is Font disposed immediately and explicitly during the Dispose of a Control, or Control release the reference to the Font and let GC handle all the left?
Thanks!
A further update to my question: Another experiment I did is: I monitored my test WinForm application in both TaskManager and a memory profiler. The main Form has a button which will open another Form whose Font is different when clicked. I noticed that when I clicked the button and opened the new Form, the GDI object count in TaskManager goes up. So as the count of Font objects observed by memory profiler.
However, when I closed the new Form, the count of GDI objects in TaskManager went down immediately. The count of Font objects in the memory profiler did not change, implying the GC did not happen. These Font objects, however, were tagged as "disposed but not collected" in the memory profiler.
It gives me this feeling that Font object set to WinForms Control's Font property has been properly disposed when Form is closed. It seems the logic behind the scene is
- WinForm disposes a Form when it is closed (explicitly, not by GC)
- Dispose a Form will recursively dispose all its child Controls
- Dispose a Control will dispose the Font object associated with its Font property (again, explicitly, not by GC)
But this is just indirect proof + my analysis. I dont have any direct proof like source code or official document to support it.