Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

Unreleased Resource Stream: Sometimes Garbage Collectors Do Not Save Us

Alessandro InnocenziFollowBetter Programming--ListenShareThe problem with not releasing the resources we use is that over time the server fills up with things to do and can no longer process incoming requests, causing a disservice. This may be due to a wrong program architecture in which it’s not clear who has to release what or simply to a conceptual error on the part of the developer that creates problems in a few lines of code.The worst case is when an attacker finds a way to generate a Resource leak by exploiting this lack of management, falling into what everyone knows as Denial Of Service.Specifically, the unreleased resource Stream occurs when a stream is opened, both in input and output, and for some reason, it’s not closed, so the memory occupied by this stream is not released.Among these reasons, we often find the fact that the program crashes and the error are handled through a catch block, but the resource in the finally block is not released, such as:Or we simply always trust too much in the Garbage Collector (which works like the AMA, an Italian company for the collection, treatment, and disposal of municipal solid waste: sometimes it passes, sometimes not, sometimes late), and we don’t worry in the least to release the resources, because “it will pass by to clean.”In this example, we consider a conceptual error by the developer. Let’s start with the following piece of Java code:The SAST tool used was Fortify SCA and reported Unreleased Resource: Stream on the httpInputStream variable. This is because in the finally block, the closure of that stream is only performed if the http variable is different from null (and obviously, if httpInputStream is different from null, to avoid a possible Null Dereference by invoking the close() method).What is the problem? If by chance http becomes null for some hidden reason, the stream is not released. But the developer didn’t agree; they told me this exactly:But it is passed by reference. If I close http, I close the stream too, so if http becomes null, it is also null httpInputStream. In Java, all objects are passed by reference.Well, no. I’m sorry. Because in this case, an object is not passed by reference but a stream is opened. It’s not that anything vaguely resembles an object is passed by reference.But the developer still wasn’t convinced, so I created a little test program to show him what was going on.I wrote a simple class that loads the page of a very famous site and prints the body. It’s pretty much like the code block seen above, but it does something if I run it.This code is wrong. As I said earlier, checking if http is non-null makes no sense to release httpInputStream. Also, the InputStreamReader is not closed, but we’ll talk about this later.OK, I need evidence, so I modified the code by deliberately setting http to null and inserting several println to understand what is happening (obviously, in debug, it’s easier, but so I had the evidence to give to the developer).Let’s run the program and see what gets printed:As we can see, even if http is null, httpInputStream has NOT become automagically null, and the body of the page loads without problems, and no finally block messages are printed.Of course, the exact finally block should look like this:It’s not necessary to close the URLConnection because closing the stream connected to it should free up the network resources associated with that instance.But when we close a stream, we have to catch a potential IOException, which could be thrown for several reasons: if we have opened a file and the operating system changes the metadata of that file during the closing (it practically never happens, but I always prevent any apocalyptic scenario), or in the case of reading an input stream from a connection and at the moment of closure the network is down (most likely), or other various and possible ones.However, if an already closed stream is closed, nothing is reported—at least that.In this article, I want to point out that sometimes we get confused about how to manage things when we develop, giving the example of a fact that happened.Writing the small test program, however, I added another variant to take into consideration, that is, the use of the InputStreamReader, which, as we have seen, had not been closed in the previous code because that was not the demonstration purpose at that time.To be fair, the exact final code should be this (I renamed http and httpInputStream because they were misleading):Closing an InputStreamReader releases all associated resources, so it is not necessary to close the InputStream.If there are any doubts about this, here is another test program:This program crashes with a nice Exception: java.io.IOException: Stream Closed because you are trying to close inputStream when it has already been closed by the reader.I’d say the above test might be enough, but you might be wondering:What if, instead of setting http to null, which might still keep a connection hanging somewhere, I close the connection?In fact, it’s a good question.The problem is that URLConnection has no methods to close or disconnect the connection. But we can try with the HttpURLConnection, which instead has disconnect(). Here’s what the code looks like:Let’s run the program and let’s get the output:In this case, the program crashes because we closed the connection, and then the stream opened by inputStream is no longer valid. Note that they are all different from null anyway.The finally block in the case of using an HttpURLConnection, however, is the following:This is because each instance of HttpURLConnection is used to make a single request, but other instances can transparently share the underlying network connection to the HTTP server.With the close() method of the InputStream and OutputStream used with an HttpURLConnection, the network resources associated with this instance are freed, but there is no effect on any shared connection. Using the HttpURLConnection disconnect() instead, we close the socket if there are no other active connections at that time.The release of resources should always be managed. I know that with some languages, we have the Garbage Collector support, but are you really sure? Do you know it so well? Have you ever gone to dinner together? Are you sure it does it right and when needed? Would you ever entrust your dog to it?If you answered “yes” to all the questions (or at least the dog’s question), I’m sorry to tell you that Java’s Garbage Collector frees the memory that is no longer referenced, but it cannot free resources such as open file descriptors or connections to the database.This is because it takes care of the resources inside the heap area of the JVM, while the resources assigned by the operating system, such as files or connection openings, are external to this management. So you have to be careful.Using threads and streams is always quite delicate. Many developers are intrigued by patterns and best practices related to these two topics. I myself, who am a very good, beautiful, but above all, modest, developer, sometimes lose absolute control of the situation and directly format the server.But in this specific case, if a class has the close() method, there is a reason, right? Use it! Or at least ask yourself two questions about why it exists.Anyway, when in doubt, throw everything in the finally block, don’t leave anything to chance, don’t trust the Garbage Collector, and don’t accept sweets from sysadmins.Stay safe. Stay close();----Better ProgrammingSoftware Architect, Cybersecurity Padawan and Bartender. Interested in reverse engineering, code review and video games 👾Sergei SavvovinBetter Programming--5Sami MaameriinBetter Programming--7Dmitry KruglovinBetter Programming--31Sami MaameriinBetter Programming--3Zuhal PolatinTrendyol Tech--6Jari RoomerinBetter Humans--102David Rodenas, Ph. D.--47Love SharmainByteByteGo System Design Alliance--50Samuel Catalano--3Microsoft DesigninMicrosoft Design--61HelpStatusWritersBlogCareersPrivacyTermsAboutText to speechTeams



This post first appeared on VedVyas Articles, please read the originial post: here

Share the post

Unreleased Resource Stream: Sometimes Garbage Collectors Do Not Save Us

×

Subscribe to Vedvyas Articles

Get updates delivered right to your inbox!

Thank you for your subscription

×