Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Order of memory disposal and GC in C#

What actually happens in C# when:

1) A method gets invoked.
2) The method allocates memory (e.g. MemoryStream mm = new MemoryStream()).
3) An exception occurs in the method which is caught by the invoking classes.

Does the resource "mm" gets freed by the garbage collector? Is this a security risk (e.g. DoS)?

P.S.: I know it is best practice to explicitely free any allocated resource. That would mean to use the "using"-statement or "try/catch/finally"-block.

like image 959
bonobo Avatar asked Nov 15 '10 16:11

bonobo


2 Answers

Does the resource "mm" get freed by the garbage collector?

Once it is dead, yes. Eventually the GC will run and free the memory if it is unreferenced.

Is this a security risk?

Let's be precise in our terminology. An asset is something of value: private data, a user's time, and so on. An attacker is someone who wishes to do harm to the asset. A threat is the manner in which the attacker could do harm. A vulnerability is an aspect of the scenario which could be taken advantage of by the attacker to make good the threat.

To answer your question we need to know:

  • What is the asset?
  • Who is the attacker?
  • What is the threat the attacker poses to the asset?
  • What vulnerability can the attacker take advantage of to make good the threat?

Only once you state the answers to those questions can we possibly know whether failure to immediately release a memory buffer upon an exception is a security risk.

For a real-world example, the asset could be my television, the attacker could be a thief, the threat is theft, and the vulnerability is an unlocked second floor window and the ladder in my garage. The ladder and the window are both part of a vulnerability to that threat. However, neither of them are a vulnerability to the threat of, say, arson. You cannot determine the risk of a particular aspect of a situation until you know what the realistic threat is!

I know it is best practice to explicitly free any allocated resource.

It is good practice to explicitly clean up unmanaged resources, like file handles that are controlled by the operating system. Typically you let the garbage collector clean up managed memory.

like image 127
Eric Lippert Avatar answered Nov 07 '22 06:11

Eric Lippert


The memory allocated to mm does not get removed by the garbage collector until 1) the garbage collector runs and 2) the reference created by mm is flagged for garbage collection and 3) the reference is finalized.

Even in exception circumstances, the memory created for mm could still stay, particularly if some other object has a reference to mm.

Now... is that a security hole? Depends on the situation. Yes, it's entirely possible for a DoS from too much memory being allocated; this is an issue with any system, but it frankly rarely needs to be dealt with unless your code is particularly bad about dangling memory. Sometimes you might want to use a ValueType struct for transitory values; it all depends on the situation, there's no one right way to do things.

Regarding your PS: in .NET, it's not best practice to explicitly free every allocated resource; it's best practice to explicitly free unmanaged resources. Best practice is to let managed resources lie unless you find performance issues, at which point you can consider more draconian methods of memory management. Let the GC do its job properly, and in 99 of 100 cases, everything will be fine.

For more information:

http://msdn.microsoft.com/en-us/magazine/bb985010.aspx

like image 5
Randolpho Avatar answered Nov 07 '22 06:11

Randolpho