
According to \[[JLS 05|AA. Java References#JLS 05]\] Section 11.2:"to the Java Language Specification, §11.1.1, "The Kinds of Exceptions" [JLS 2013], Wiki Markup
The unchecked exceptions classes are the class
RuntimeException
and its subclasses, and the classError
and its subclasses. All other exception classes are checked exception classes.
...
Unchecked exception classes such as Error
and its subclasses do not undergo compile time checking as are not subject to compile-time checking because it is tedious to account for all cases exceptional conditions and because recovery is generally often difficult or impossible. However, most often even when recovery is not impossible or at least a graceful exit that logs the error is feasibleimpossible, the Java Virtual Machine (JVM) allows a graceful exit and a chance to at least log the error. This is made possible by using a try-catch
block that catches Throwable
. Also, when code must avoid leaking potentially sensitive information, catching Throwable
is permitted. In all other cases, catching Throwable
is not recommended because it makes handling specific exceptions difficult. Where cleanup operations such as releasing system resources can be performed, code should use a finally
block to release the resources or a try
-with-resources statement.
Catching Throwable
is disallowed in general by ERR08-J. Do not catch NullPointerException or any of its ancestors, but it is permitted when filtering exception traces by the exception ERR08-EX0 in that rule.
Noncompliant Code Example
This noncompliant code example generates a StackOverflowError
due to as a result of infinite recursion. This would tend to exhaust the existing stack spaceIt exhausts the available stack space and may result in denial of service.
Code Block | ||
---|---|---|
| ||
public class StackOverflow { public static void main(String[] args) { infiniteRun(); System// .out.println("Continuing..."); } private static void infiniteRun() { infiniteRun(); } } |
Compliant Solution
This compliant solution shows how a try-catch
block that can be used to capture java.lang.Error
or java.lang.Throwable
. A log entry can be made at this point, followed by attempts to free key system resources in the finally
block.
Code Block | ||
---|---|---|
| ||
public class StackOverflow { public static void main(String[] args) { infiniteRun(); try { System.out.println("Continuing..."infiniteRun(); } catch (Throwable t) { private static// voidForward infiniteRun()to {handler try} finally { infiniteRun(); }catch(Throwable t) { System.out.println("Handling error...");// Free cache, release resources } // ... } //free cache, release resources and log error to file private static void infiniteRun() { infiniteRun(); } } } |
...
Note that the Forward to handler
code must operate correctly in constrained memory conditions because the stack or heap may be nearly exhausted. In such a scenario, one useful technique is for the program to initially reserve memory specifically to be used by an out-of-memory exception handler.
Note that this solution catches Throwable
in an attempt to handle the error; it falls under exception ERR08-EX2 in ERR08-J. Do not catch NullPointerException or any of its ancestors.
Applicability
Allowing a system error to propagate right out of abruptly terminate a Java program may result in a denial-of-service attack.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
EXC03-J | low | unlikely | medium | P2 | L3 |
Automated Detection
TODO
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
vulnerability.
Bibliography
[JLS 2013] | §11.2, "Compile-Time Checking of Exceptions" |
[Kalinovsky 2004] | Chapter 16, "Intercepting Control Flow: Intercepting System Errors" |
...
\[[Kalinovsky 04|AA. Java References#Kalinovsky 04]\] Chapter 16, Intercepting Control Flow - Intercepting System Errors
\[[JLS 05|AA. Java References#JLS 05]\] Section 11.2, Compile-Time Checking of Exceptions Wiki Markup
In the event of actually running out of memory, it is likely that some program data will be in an inconsistent state. Consequently, it might be best to restart the process. If an attempt is made to carry on, reducing the number of threads may be an effective workaround. This measure can help in such scenarios because threads often leak memory, and their continued existence can increase the memory footprint of the program.
The methods
Thread.setUncaughtExceptionHandler()
andThreadGroup.uncaughtException()
can be used to help deal with anOutOfMemoryError
in threads.