Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: overhauled stream terminology

The exec() method of the java.lang.Runtime class and the related ProcessBuilder.start() method can be used to invoke external programs. While running, these programs are represented by a java.lang.Process object. Like any POSIX process, this process contains an input stream, output stream, and error stream. Because the Process object allows a Java program to communicate with its external program, the process's input stream is an OutputStream object, accessible by the Process.getOutputStream() method. Likewise, the process's output stream and error streams are both represented by InputStream objects, accessible by the Process.getInputStream() and Process.getErrorStream() methods.

These processes These programs may require input to be sent to their input stream, and they may also produce output on their output stream or error stream. Incorrect handling of such external programs can cause unexpected exceptions, denial of service, and other security problems.

...

Output from an external process can exhaust the available buffer for the its output or error stream. When this occurs, it can block the external process as well, preventing any forward progress for both the Java program and the external processes. Note that many platforms limit the buffer size available for the output streams. Consequently, when invoking an external process, if the process sends any data to its output stream, the process's output stream must be emptied. And if the process sends any data to its error stream, the error stream must also be emptied.

...

This noncompliant code example invokes notemaker using the exec() method, which returns an object of a subclass of the abstract class java.lang.Process Process object. The exitValue() method returns the exit value for processes that have terminated, but it throws an IllegalThreadStateException when invoked on an active process. Because this noncompliant example program fails to wait for the notemaker process to terminate, the call to exitValue() is likely to throw an IllegalThreadStateException.

...

Code Block
bgColor#FFcccc
public class Exec {
  public static void main(String args[]) throws IOException {
    Runtime rt = Runtime.getRuntime();
    Process proc = rt.exec("notemaker");
    int exitVal = proc.waitFor();
  }
}

Noncompliant Code Example (

...

process output stream)

This noncompliant code example properly empties the input stream from the processprocess's output stream, thereby preventing the input output stream buffer from becoming full and blocking. However, it ignores the process's error stream, which can also fill and cause the process to block.

...

This compliant solution redirects the process's error stream to its input output stream. Consequently, the program can empty the single output stream without fear of blockage.

Code Block
bgColor#ccccff
public class Exec {
  public static void main(String args[]) throws IOException, InterruptedException {
    ProcessBuilder pb = new ProcessBuilder("notemaker");
    pb = pb.redirectErrorStream(true);
    Process proc = pb.start();
    InputStream is = proc.getInputStream();
    int c;
    while ((c = is.read()) != -1) {
      System.out.print((char) c);
    }
    int exitVal = proc.waitFor();
  }
}

Compliant Solution (

...

process output stream and error stream)

This compliant solution spawns two threads to consume the input process's output stream and error stream. Consequently, the process cannot block indefinitely on those streams.

...

FIO07-EX0: Failure to supply input to a process that never reads input from its input stream is harmless, and can be beneficial. Failure to empty the output or error streams of a process that never sends output to its output or error streams is similarly harmless, or even beneficial. Consequently, programs are permitted to ignore the input, output, or error streams whenif, and only whenif, the process is guaranteed not to use those streams.

Risk Assessment

...

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="2096e0888abcfc86-9ab62c7b-444a46f2-96d9b594-a34e138587f15e92f2954ea8"><ac:plain-text-body><![CDATA[

[[API 2006

AA. Bibliography#API 06]]

method [exec()

http://java.sun.com/javase/6/docs/api/java/lang/Runtime.html#exec(java.lang.String)]

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

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="992e65b206a7c581-409bbe2d-458243ec-8a7f9fe7-88fceff7680cc7588fbbbbff"><ac:plain-text-body><![CDATA[

[[Daconta 2000

AA. Bibliography#Daconta 00]]

 

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

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="9fd3fe634c0c708a-facb8fdd-4fff4b64-b4948382-b25a2146d878d308b0c45576"><ac:plain-text-body><![CDATA[

[[Daconta 2003

AA. Bibliography#Daconta 03]]

Pitfall 1

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

...