Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Java provides two options for program termination: Runtime.exit() (this is equivalent to System.exit()) and Runtime.halt().

Runtime.exit()

Runtime.exit() is the typical way of exiting a program:

...

The Runtime.addShutdownHook() method can be used to customize Runtime.exit() to perform additional actions at program termination.
This method takes a single Thread, which must be initalized but unstarted. Then, when the JVM begins to shut down, the thread will be run. Since the JVM usually has a fixed time to shut down, these threads should not be long-running and should not attempt user interaction.

Runtime.halt()

Runtime.halt() works similarly but does NOT run shutdown hooks or finalizers:

...

In contrast with C and C++, Java does not flush unwritten buffered data or close open files when it exits, so programs must perform this manually. Programs must also perform any other cleanup that involves external resources, such as releasing shared locks.

Noncompliant Code Example

This example creates a new file, outputs some text to it, and abruptly exits using Runtime.exit(). Consequently, the file is closed without the text actually being written to it.

Code Block
bgColor#ffcccc
public class CreateFile {
  public static void main(String[] args) throws FileNotFoundException {
    final PrintStream out = new PrintStream( new BufferedOutputStream(
                                        new FileOutputStream("foo.txt")));
    out.println("hello");
    Runtime.getRuntime().exit(1);
  }
}

Compliant Solution (close())

This solution explicitly closes the file before exiting.

Code Block
bgColor#ccccff
public class CreateFile {
  public static void main(String[] args) throws FileNotFoundException {
    final PrintStream out = new PrintStream( new BufferedOutputStream(
                                        new FileOutputStream("foo.txt")));
    out.println("hello");
    out.close();
    Runtime.getRuntime().exit(1);
  }
}

Compliant Solution (Shutdown Hook)

This compliant solution adds a shutdown hook to close the file. This hook is invoked by Runtime.exit() is called before the JVM is halted.

Code Block
bgColor#ccccff
public class CreateFile {
  public static void main(String[] args) throws FileNotFoundException {
    final PrintStream out = new PrintStream( new BufferedOutputStream(
                                        new FileOutputStream("foo.txt")));
    Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
        public void run() {
          out.close();
        }
      }));
    out.println("hello");
    Runtime.getRuntime().exit(1);
  }
}

Noncompliant Code Example (Runtime.halt())

This noncompliant code example calls Runtime.halt() instead of Runtime.exit(). Runtime.halt() stops the JVM without invoking any shutdown hooks; consequently the file is not properly written to or closed.

Code Block
bgColor#ffcccc
public class CreateFile {
  public static void main(String[] args) throws FileNotFoundException {
    final PrintStream out = new PrintStream( new BufferedOutputStream(
                                        new FileOutputStream("foo.txt")));
    Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
        public void run() {
          out.close();
        }
      }));
    out.println("hello");
    Runtime.getRuntime().halt(1);
  }
}

Noncompliant Code Example (signal)

When a user forcefully exits a program by pressing the ctrl + c key or by using the kill command, the JVM terminates abruptly. Although this event cannot be captured, the program should nevertheless perform any mandatory clean-up operations before exiting. This noncompliant code example fails to do so.

Code Block
bgColor#FFcccc
public class InterceptExit {
  public static void main(String[] args) {
    System.out.println("Regular code block");
    // Abrupt exit such as ctrl + c key pressed
    System.out.println("This never executes");
  }
}

Compliant Solution (addShutdownHook())

Use the addShutdownHook() method of java.lang.Runtime to assist with performing clean-up operations in the event of abrupt termination. The JVM starts the shutdown hook thread when abrupt termination is initiated; the shutdown hook runs concurrently with other JVM threads.

...

The JVM can abort for external reasons, such as an external SIGKILL signal (UNIX) or the TerminateProcess call (Microsoft Windows), or memory corruption caused by native methods. Shutdown hooks may fail to execute as expected in such cases, because the JVM cannot guarantee that they will be executed as intended.

Risk Assessment

Using Runtime.halt() in place of Runtime.exit() may not perform necessary cleanup, potentially leaving sensitive data exposed or leaving data in an inconsistent state.

Recommendation

Severity

Likelihood

Remediation Cost

Priority

Level

FIO16-J

medium

likely

medium

P12

L1

Other Languages

This rule appears in the C Secure Coding Standard as ERR04-C. Choose an appropriate termination strategy.

This rule appears in the C++ Secure Coding Standard as ERR04-CPP. Choose an appropriate termination strategy.

Related Guidelines

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="726fbf5c381353a1-c59c640c-4d484c84-90cface7-7637fdf19bb2b5fcdb1b2e65"><ac:plain-text-body><![CDATA[

[[MITRE 07

AA. Bibliography#MITRE 07]]

[CWE ID 705

http://cwe.mitre.org/data/definitions/705.html], "Incorrect Control Flow Scoping"

]]></ac:plain-text-body></ac:structured-macro>

Bibliography

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="087f870164c26838-db232e2b-41004a0f-a29d8895-57ebb7ff72d102e3c913b33a"><ac:plain-text-body><![CDATA[

[[ISO/IEC PDTR 24772

AA. Bibliography#ISO/IEC PDTR 24772]]

"REU Termination strategy"

]]></ac:plain-text-body></ac:structured-macro>

...