...
These processes may require input to be sent to their input stream, and they may also produce output on their output stream or , their error stream, or both. Incorrect handling of such external programs can cause unexpected exceptions, denial of serviceDoS, and other security problems.
...
Output from an external process can exhaust the available buffer reserved for its output or error stream. When this occurs, it the Java program can block the external process as well, preventing any forward progress for both the Java program and the external processesprocess. Note that many platforms limit the buffer size available for 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 Similarly, if the process sends any data to its error stream, the error stream must also be emptied.
...
In this noncompliant code example, the waitFor()
method blocks the calling thread until the the notemaker
process terminates. This prevents the IllegalThreadStateException
from the previous example. However, the example program may experience an arbitrary delay before termination. Output from the notemaker
process can exhaust the available buffer for the output or error stream because neither stream is read while waiting for the process to complete. If either buffer becomes full, it can block the notemaker
process as well, preventing all progress for both the notemaker
process and the Java program.
Code Block | ||
---|---|---|
| ||
public class Exec { public static void main(String args[]) throws IOException, InterruptedException { 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 process's output stream, thereby preventing the 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.
Code Block | ||
---|---|---|
| ||
public class Exec {
public static void main(String args[])
throws IOException, InterruptedException {
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec("notemaker");
InputStream is = proc.getInputStream();
int c;
while ((c = is.read()) != -1) {
System.out.print((char) c);
}
int exitVal = proc.waitFor();
}
}
|
...
Code Block | ||
---|---|---|
| ||
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 process's output stream and error stream. Consequently, the process cannot block indefinitely on those streams.
...
Code Block | ||
---|---|---|
| ||
class StreamGobbler extends Thread { InputStream is; PrintStream os; StreamGobbler(InputStream is, PrintStream os) { this.is = is; this.os = os; } public void run() { try { int c; while ((c = is.read()) != -1) os.print((char) c); } catch (IOException x) { // handle error } } } public class Exec { public static void main(String[] args) throws IOException, InterruptedException { Runtime rt = Runtime.getRuntime(); Process proc = rt.exec("notemaker"); // Any error message? StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), System.err); // Any output? StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), System.out); errorGobbler.start(); outputGobbler.start(); // Any error? int exitVal = proc.waitFor(); errorGobbler.join(); // Handle condition where the outputGobbler.join(); // process ends before the threads finish } } |
Exceptions
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 if, and only if, the process is of processes that are guaranteed not to use those streams.
...
Misuse of the exec()
method can result in runtime exceptions and in denial-of-service DoS vulnerabilities.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
FIO07-J | low | probable | medium | P4 | L3 |
...
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="2f81d3ea63afb85a-f08134ad-49df4f05-bae1a0e5-a5e41ed2571ded44988ad813"><ac:plain-text-body><![CDATA[ | [[API 2006 | AA. Bibliography#API 06]] | method [Method | 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="9d914f4173e6322f-910b7d24-416e4eaa-a8a3bb3f-23d8fac866c2607d70472844"><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="a0a427b6b9cc0379-8fcc22c5-46444e7b-a66ab3d7-91f292cc6471a4b5cd5fccd6"><ac:plain-text-body><![CDATA[ | [[Daconta 2003 | AA. Bibliography#Daconta 03]] | Pitfall 1 | ]]></ac:plain-text-body></ac:structured-macro> |
...