changeset 6257:c450b20e8030

Merge
author smarks
date Wed, 27 Feb 2013 15:04:56 -0800
parents bdbb9f5a2ee7 b1a2b9ac9714
children 294da2a34164
files
diffstat 8 files changed, 150 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Wed Feb 27 13:58:55 2013 -0800
+++ b/.hgtags	Wed Feb 27 15:04:56 2013 -0800
@@ -239,3 +239,4 @@
 8261e56b7f91c7553e8485b206bdc9030a3546e4 jdk7u21-b01
 a5e712ea6944b1c81bcd5343a50645964f12b107 jdk7u21-b02
 9d87f5f84afef6ba4c92523a76e3c81fd9acfa00 jdk7u21-b03
+139d3e3b62d49374112ce1add84cd3d1e5ed5335 jdk7u21-b04
--- a/src/share/classes/java/lang/ProcessBuilder.java	Wed Feb 27 13:58:55 2013 -0800
+++ b/src/share/classes/java/lang/ProcessBuilder.java	Wed Feb 27 15:04:56 2013 -0800
@@ -30,6 +30,7 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.FileOutputStream;
+import java.security.AccessControlException;
 import java.util.Arrays;
 import java.util.ArrayList;
 import java.util.List;
@@ -1012,8 +1013,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();
 
@@ -1024,13 +1026,24 @@
                                      redirects,
                                      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);
         }
     }
 }
--- a/src/share/classes/java/nio/file/Files.java	Wed Feb 27 13:58:55 2013 -0800
+++ b/src/share/classes/java/nio/file/Files.java	Wed Feb 27 15:04:56 2013 -0800
@@ -1484,10 +1484,19 @@
     // lazy loading of default and installed file type detectors
     private static class FileTypeDetectors{
         static final FileTypeDetector defaultFileTypeDetector =
-            sun.nio.fs.DefaultFileTypeDetector.create();
+            createDefaultFileTypeDetector();
         static final List<FileTypeDetector> installeDetectors =
             loadInstalledDetectors();
 
+        // creates the default file type detector
+        private static FileTypeDetector createDefaultFileTypeDetector() {
+            return AccessController
+                .doPrivileged(new PrivilegedAction<FileTypeDetector>() {
+                    @Override public FileTypeDetector run() {
+                        return sun.nio.fs.DefaultFileTypeDetector.create();
+                }});
+        }
+
         // loads all installed file type detectors
         private static List<FileTypeDetector> loadInstalledDetectors() {
             return AccessController
--- a/src/solaris/classes/sun/nio/fs/GnomeFileTypeDetector.java	Wed Feb 27 13:58:55 2013 -0800
+++ b/src/solaris/classes/sun/nio/fs/GnomeFileTypeDetector.java	Wed Feb 27 15:04:56 2013 -0800
@@ -67,6 +67,8 @@
         NativeBuffer buffer = NativeBuffers.asNativeBuffer(path.getByteArrayForSysCalls());
         try {
             if (gioAvailable) {
+                // GIO may access file so need permission check
+                path.checkRead();
                 byte[] type = probeUsingGio(buffer.address());
                 return (type == null) ? null : new String(type);
             } else {
@@ -76,7 +78,6 @@
                 String s = new String(type);
                 return s.equals(GNOME_VFS_MIME_TYPE_UNKNOWN) ? null : s;
             }
-
         } finally {
             buffer.release();
         }
--- a/src/solaris/native/sun/awt/awt_GraphicsEnv.c	Wed Feb 27 13:58:55 2013 -0800
+++ b/src/solaris/native/sun/awt/awt_GraphicsEnv.c	Wed Feb 27 15:04:56 2013 -0800
@@ -978,6 +978,8 @@
 static jint canUseShmExtPixmaps = UNSET_MITSHM;
 static jboolean xshmAttachFailed = JNI_FALSE;
 
+extern int mitShmPermissionMask;
+
 int J2DXErrHandler(Display *display, XErrorEvent *xerr) {
     int ret = 0;
     if (xerr->minor_code == X_ShmAttach) {
@@ -1016,7 +1018,8 @@
      * we need to test that we can actually do XShmAttach.
      */
     if (XShmQueryExtension(awt_display)) {
-        shminfo.shmid = shmget(IPC_PRIVATE, 0x10000, IPC_CREAT|0777);
+        shminfo.shmid = shmget(IPC_PRIVATE, 0x10000,
+                               IPC_CREAT|mitShmPermissionMask);
         if (shminfo.shmid < 0) {
             AWT_UNLOCK();
             J2dRlsTraceLn1(J2D_TRACE_ERROR,
--- a/src/solaris/native/sun/awt/awt_GraphicsEnv.h	Wed Feb 27 13:58:55 2013 -0800
+++ b/src/solaris/native/sun/awt/awt_GraphicsEnv.h	Wed Feb 27 15:04:56 2013 -0800
@@ -47,6 +47,9 @@
 #include <X11/extensions/shmproto.h>
 #endif
 
+#define MITSHM_PERM_COMMON (0666)
+#define MITSHM_PERM_OWNER  (0600)
+
 extern int XShmQueryExtension();
 
 void TryInitMITShm(JNIEnv *env, jint *shmExt, jint *shmPixmaps);
--- a/src/solaris/native/sun/java2d/x11/X11SurfaceData.c	Wed Feb 27 13:58:55 2013 -0800
+++ b/src/solaris/native/sun/java2d/x11/X11SurfaceData.c	Wed Feb 27 15:04:56 2013 -0800
@@ -92,6 +92,7 @@
 jint useMitShmExt = CANT_USE_MITSHM;
 jint useMitShmPixmaps = CANT_USE_MITSHM;
 jint forceSharedPixmaps = JNI_FALSE;
+int mitShmPermissionMask = MITSHM_PERM_OWNER;
 
 /* Cached shared image, one for all surface datas. */
 static XImage * cachedXImage;
@@ -122,6 +123,13 @@
     if (getenv("NO_AWT_MITSHM") == NULL &&
         getenv("NO_J2D_MITSHM") == NULL) {
         char * force;
+        char * permission = getenv("J2D_MITSHM_PERMISSION");
+        if (permission != NULL) {
+            if (strcmp(permission, "common") == 0) {
+                mitShmPermissionMask = MITSHM_PERM_COMMON;
+            }
+        }
+
         TryInitMITShm(env, &useMitShmExt, &useMitShmPixmaps);
 
         if(allowShmPixmaps) {
@@ -558,7 +566,8 @@
         return NULL;
     }
     shminfo->shmid =
-        shmget(IPC_PRIVATE, height * img->bytes_per_line, IPC_CREAT|0777);
+        shmget(IPC_PRIVATE, height * img->bytes_per_line,
+               IPC_CREAT|mitShmPermissionMask);
     if (shminfo->shmid < 0) {
         J2dRlsTraceLn1(J2D_TRACE_ERROR,
                        "X11SD_SetupSharedSegment shmget has failed: %s",
--- a/src/windows/classes/java/lang/ProcessImpl.java	Wed Feb 27 13:58:55 2013 -0800
+++ b/src/windows/classes/java/lang/ProcessImpl.java	Wed Feb 27 15:04:56 2013 -0800
@@ -144,6 +144,88 @@
 
     }
 
+    // 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 OutputStream stdin_stream;
     private InputStream stdout_stream;
@@ -156,30 +238,31 @@
                         final 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);
             }