summaryrefslogtreecommitdiff
path: root/java/openjdk6/files/icedtea/security/20130416/8005943.patch
diff options
context:
space:
mode:
Diffstat (limited to 'java/openjdk6/files/icedtea/security/20130416/8005943.patch')
-rw-r--r--java/openjdk6/files/icedtea/security/20130416/8005943.patch202
1 files changed, 202 insertions, 0 deletions
diff --git a/java/openjdk6/files/icedtea/security/20130416/8005943.patch b/java/openjdk6/files/icedtea/security/20130416/8005943.patch
new file mode 100644
index 000000000000..02188fb6f551
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130416/8005943.patch
@@ -0,0 +1,202 @@
+# HG changeset patch
+# User andrew
+# Date 1365784383 -3600
+# Node ID dfa1c658a62a54dbcfa02e96c51af21a3cc71907
+# Parent 0938f449476b5c89ccb68f0c195a57a0e72e9dc4
+8005943: (process) Improved Runtime.exec
+Reviewed-by: alanb, ahgross
+
+diff --git a/src/share/classes/java/lang/ProcessBuilder.java b/src/share/classes/java/lang/ProcessBuilder.java
+--- jdk/src/share/classes/java/lang/ProcessBuilder.java
++++ jdk/src/share/classes/java/lang/ProcessBuilder.java
+@@ -27,6 +27,7 @@
+
+ import java.io.File;
+ import java.io.IOException;
++import java.security.AccessControlException;
+ import java.util.ArrayList;
+ import java.util.List;
+ import java.util.Map;
+@@ -459,8 +460,9 @@
+ String prog = cmdarray[0];
+
+ SecurityManager security = System.getSecurityManager();
+- if (security != null)
++ if (security != null) {
+ security.checkExec(prog);
++ }
+
+ String dir = directory == null ? null : directory.toString();
+
+@@ -470,13 +472,24 @@
+ dir,
+ redirectErrorStream);
+ } catch (IOException e) {
++ String exceptionInfo = ": " + e.getMessage();
++ Throwable cause = e;
++ if (security != null) {
++ // Can not disclose the fail reason for read-protected files.
++ try {
++ security.checkRead(prog);
++ } catch (AccessControlException ace) {
++ exceptionInfo = "";
++ cause = ace;
++ }
++ }
+ // It's much easier for us to create a high-quality error
+ // message than the low-level C code which found the problem.
+ throw new IOException(
+ "Cannot run program \"" + prog + "\""
+ + (dir == null ? "" : " (in directory \"" + dir + "\")")
+- + ": " + e.getMessage(),
+- e);
++ + exceptionInfo,
++ cause);
+ }
+ }
+ }
+diff --git a/src/windows/classes/java/lang/ProcessImpl.java b/src/windows/classes/java/lang/ProcessImpl.java
+--- jdk/src/windows/classes/java/lang/ProcessImpl.java
++++ jdk/src/windows/classes/java/lang/ProcessImpl.java
+@@ -47,6 +47,88 @@
+ return new ProcessImpl(cmdarray, envblock, dir, redirectErrorStream);
+ }
+
++ // We guarantee the only command file execution for implicit [cmd.exe] run.
++ // http://technet.microsoft.com/en-us/library/bb490954.aspx
++ private static final char CMD_BAT_ESCAPE[] = {' ', '\t', '<', '>', '&', '|', '^'};
++ private static final char WIN32_EXECUTABLE_ESCAPE[] = {' ', '\t', '<', '>'};
++
++ private static boolean isQuoted(boolean noQuotesInside, String arg,
++ String errorMessage) {
++ int lastPos = arg.length() - 1;
++ if (lastPos >=1 && arg.charAt(0) == '"' && arg.charAt(lastPos) == '"') {
++ // The argument has already been quoted.
++ if (noQuotesInside) {
++ if (arg.indexOf('"', 1) != lastPos) {
++ // There is ["] inside.
++ throw new IllegalArgumentException(errorMessage);
++ }
++ }
++ return true;
++ }
++ if (noQuotesInside) {
++ if (arg.indexOf('"') >= 0) {
++ // There is ["] inside.
++ throw new IllegalArgumentException(errorMessage);
++ }
++ }
++ return false;
++ }
++
++ private static boolean needsEscaping(boolean isCmdFile, String arg) {
++ // Switch off MS heuristic for internal ["].
++ // Please, use the explicit [cmd.exe] call
++ // if you need the internal ["].
++ // Example: "cmd.exe", "/C", "Extended_MS_Syntax"
++
++ // For [.exe] or [.com] file the unpaired/internal ["]
++ // in the argument is not a problem.
++ boolean argIsQuoted = isQuoted(isCmdFile, arg,
++ "Argument has embedded quote, use the explicit CMD.EXE call.");
++
++ if (!argIsQuoted) {
++ char testEscape[] = isCmdFile
++ ? CMD_BAT_ESCAPE
++ : WIN32_EXECUTABLE_ESCAPE;
++ for (int i = 0; i < testEscape.length; ++i) {
++ if (arg.indexOf(testEscape[i]) >= 0) {
++ return true;
++ }
++ }
++ }
++ return false;
++ }
++
++ private static String getExecutablePath(String path)
++ throws IOException
++ {
++ boolean pathIsQuoted = isQuoted(true, path,
++ "Executable name has embedded quote, split the arguments");
++
++ // Win32 CreateProcess requires path to be normalized
++ File fileToRun = new File(pathIsQuoted
++ ? path.substring(1, path.length() - 1)
++ : path);
++
++ // From the [CreateProcess] function documentation:
++ //
++ // "If the file name does not contain an extension, .exe is appended.
++ // Therefore, if the file name extension is .com, this parameter
++ // must include the .com extension. If the file name ends in
++ // a period (.) with no extension, or if the file name contains a path,
++ // .exe is not appended."
++ //
++ // "If the file name !does not contain a directory path!,
++ // the system searches for the executable file in the following
++ // sequence:..."
++ //
++ // In practice ANY non-existent path is extended by [.exe] extension
++ // in the [CreateProcess] funcion with the only exception:
++ // the path ends by (.)
++
++ return fileToRun.getPath();
++ }
++
++
+ private long handle = 0;
+ private FileDescriptor stdin_fd;
+ private FileDescriptor stdout_fd;
+@@ -61,30 +143,31 @@
+ boolean redirectErrorStream)
+ throws IOException
+ {
+- // Win32 CreateProcess requires cmd[0] to be normalized
+- cmd[0] = new File(cmd[0]).getPath();
++ // The [executablePath] is not quoted for any case.
++ String executablePath = getExecutablePath(cmd[0]);
++
++ // We need to extend the argument verification procedure
++ // to guarantee the only command file execution for implicit [cmd.exe]
++ // run.
++ String upPath = executablePath.toUpperCase();
++ boolean isCmdFile = (upPath.endsWith(".CMD") || upPath.endsWith(".BAT"));
+
+ StringBuilder cmdbuf = new StringBuilder(80);
+- for (int i = 0; i < cmd.length; i++) {
+- if (i > 0) {
+- cmdbuf.append(' ');
+- }
++
++ // Quotation protects from interpretation of the [path] argument as
++ // start of longer path with spaces. Quotation has no influence to
++ // [.exe] extension heuristic.
++ cmdbuf.append('"');
++ cmdbuf.append(executablePath);
++ cmdbuf.append('"');
++
++ for (int i = 1; i < cmd.length; i++) {
++ cmdbuf.append(' ');
+ String s = cmd[i];
+- if (s.indexOf(' ') >= 0 || s.indexOf('\t') >= 0) {
+- if (s.charAt(0) != '"') {
+- cmdbuf.append('"');
+- cmdbuf.append(s);
+- if (s.endsWith("\\")) {
+- cmdbuf.append("\\");
+- }
+- cmdbuf.append('"');
+- } else if (s.endsWith("\"")) {
+- /* The argument has already been quoted. */
+- cmdbuf.append(s);
+- } else {
+- /* Unmatched quote for the argument. */
+- throw new IllegalArgumentException();
+- }
++ if (needsEscaping(isCmdFile, s)) {
++ cmdbuf.append('"');
++ cmdbuf.append(s);
++ cmdbuf.append('"');
+ } else {
+ cmdbuf.append(s);
+ }