diff options
Diffstat (limited to 'java/openjdk6/files/icedtea/security/20130416/8005943.patch')
-rw-r--r-- | java/openjdk6/files/icedtea/security/20130416/8005943.patch | 202 |
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); + } |