diff options
author | Elliott Hughes <enh@google.com> | 2009-10-27 13:39:09 -0700 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2009-10-28 11:04:39 -0700 |
commit | 1805727c24b2b80161fef93c4b7742cf2322bdea (patch) | |
tree | a114559001c3b2960364f2e12f75f6bcd9162cc1 /luni-kernel/src/main/java | |
parent | 31ba233988135e90b3e98548d9e40452639cf00c (diff) | |
download | libcore-1805727c24b2b80161fef93c4b7742cf2322bdea.zip libcore-1805727c24b2b80161fef93c4b7742cf2322bdea.tar.gz libcore-1805727c24b2b80161fef93c4b7742cf2322bdea.tar.bz2 |
Implement ProcessBuilder.redirectErrorStream.
Also simplify and correct the security to ensure that the user can't modify
the command to be executed after the SecurityManager has approved it.
Bug: 2180063
Diffstat (limited to 'luni-kernel/src/main/java')
-rw-r--r-- | luni-kernel/src/main/java/java/lang/ProcessManager.java | 42 | ||||
-rw-r--r-- | luni-kernel/src/main/java/java/lang/Runtime.java | 38 |
2 files changed, 41 insertions, 39 deletions
diff --git a/luni-kernel/src/main/java/java/lang/ProcessManager.java b/luni-kernel/src/main/java/java/lang/ProcessManager.java index 1e21b57..318fe9a 100644 --- a/luni-kernel/src/main/java/java/lang/ProcessManager.java +++ b/luni-kernel/src/main/java/java/lang/ProcessManager.java @@ -169,15 +169,45 @@ final class ProcessManager { * Executes a native process. Fills in in, out, and err and returns the * new process ID upon success. */ - static native int exec(String[] commands, String[] environment, + static native int exec(String[] command, String[] environment, String workingDirectory, FileDescriptor in, FileDescriptor out, - FileDescriptor err) throws IOException; + FileDescriptor err, boolean redirectErrorStream) throws IOException; /** * Executes a process and returns an object representing it. */ - Process exec(String[] commands, String[] environment, - File workingDirectory) throws IOException { + Process exec(String[] taintedCommand, String[] taintedEnvironment, File workingDirectory, + boolean redirectErrorStream) throws IOException { + // Make sure we throw the same exceptions as the RI. + if (taintedCommand == null) { + throw new NullPointerException(); + } + if (taintedCommand.length == 0) { + throw new IndexOutOfBoundsException(); + } + + // Handle security and safety by copying mutable inputs and checking them. + String[] command = taintedCommand.clone(); + String[] environment = taintedEnvironment != null ? taintedEnvironment.clone() : null; + SecurityManager securityManager = System.getSecurityManager(); + if (securityManager != null) { + securityManager.checkExec(command[0]); + } + // Check we're not passing null Strings to the native exec. + for (String arg : command) { + if (arg == null) { + throw new NullPointerException(); + } + } + // The environment is allowed to be null or empty, but no element may be null. + if (environment != null) { + for (String env : environment) { + if (env == null) { + throw new NullPointerException(); + } + } + } + FileDescriptor in = new FileDescriptor(); FileDescriptor out = new FileDescriptor(); FileDescriptor err = new FileDescriptor(); @@ -191,10 +221,10 @@ final class ProcessManager { synchronized (processReferences) { int pid; try { - pid = exec(commands, environment, workingPath, in, out, err); + pid = exec(command, environment, workingPath, in, out, err, redirectErrorStream); } catch (IOException e) { IOException wrapper = new IOException("Error running exec()." - + " Commands: " + Arrays.toString(commands) + + " Command: " + Arrays.toString(command) + " Working Directory: " + workingDirectory + " Environment: " + Arrays.toString(environment)); wrapper.initCause(e); diff --git a/luni-kernel/src/main/java/java/lang/Runtime.java b/luni-kernel/src/main/java/java/lang/Runtime.java index 28cc96f..8560399 100644 --- a/luni-kernel/src/main/java/java/lang/Runtime.java +++ b/luni-kernel/src/main/java/java/lang/Runtime.java @@ -190,39 +190,11 @@ public class Runtime { * execution. * @see SecurityManager#checkExec * @since Android 1.0 - */ - public Process exec(String[] progArray, String[] envp, File directory) - throws java.io.IOException { - - // Sanity checks - if (progArray == null) { - throw new NullPointerException(); - } else if (progArray.length == 0) { - throw new IndexOutOfBoundsException(); - } else { - for (int i = 0; i < progArray.length; i++) { - if (progArray[i] == null) { - throw new NullPointerException(); - } - } - } - - if (envp != null) { - for (int i = 0; i < envp.length; i++) { - if (envp[i] == null) { - throw new NullPointerException(); - } - } - } - - // Security checks - SecurityManager smgr = System.getSecurityManager(); - if (smgr != null) { - smgr.checkExec(progArray[0]); - } - - // Delegate the execution - return ProcessManager.getInstance().exec(progArray, envp, directory); + */ + public Process exec(String[] progArray, String[] envp, File directory) throws IOException { + // BEGIN android-changed: push responsibility for argument checking into ProcessManager + return ProcessManager.getInstance().exec(progArray, envp, directory, false); + // END android-changed } /** |