changeset 6706:01b9e1ec3b9b

Merge
author asaha
date Mon, 22 Jul 2013 15:47:32 -0700
parents ba3da584814b 447531e39bad
children 702c8d83dd8c
files
diffstat 13 files changed, 189 insertions(+), 57 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/demo/jvmti/hprof/Tracker.java	Mon Jul 22 12:21:16 2013 -0700
+++ b/src/share/classes/com/sun/demo/jvmti/hprof/Tracker.java	Mon Jul 22 15:47:32 2013 -0700
@@ -53,7 +53,10 @@
 
     public static void ObjectInit(Object obj)
     {
-        if ( engaged != 0 ) {
+        if ( engaged != 0) {
+            if (obj == null) {
+                throw new IllegalArgumentException("Null object.");
+            }
             nativeObjectInit(Thread.currentThread(), obj);
         }
     }
@@ -66,7 +69,10 @@
 
     public static void NewArray(Object obj)
     {
-        if ( engaged != 0 ) {
+        if ( engaged != 0) {
+            if (obj == null) {
+                throw new IllegalArgumentException("Null object.");
+            }
             nativeNewArray(Thread.currentThread(), obj);
         }
     }
@@ -82,6 +88,14 @@
     public static void CallSite(int cnum, int mnum)
     {
         if ( engaged != 0 ) {
+            if (cnum < 0) {
+                throw new IllegalArgumentException("Negative class index");
+            }
+
+            if (mnum < 0) {
+                throw new IllegalArgumentException("Negative method index");
+            }
+
             nativeCallSite(Thread.currentThread(), cnum, mnum);
         }
     }
@@ -95,6 +109,14 @@
     public static void ReturnSite(int cnum, int mnum)
     {
         if ( engaged != 0 ) {
+            if (cnum < 0) {
+                throw new IllegalArgumentException("Negative class index");
+            }
+
+            if (mnum < 0) {
+                throw new IllegalArgumentException("Negative method index");
+            }
+
             nativeReturnSite(Thread.currentThread(), cnum, mnum);
         }
     }
--- a/src/share/classes/java/lang/invoke/MethodHandleNatives.java	Mon Jul 22 12:21:16 2013 -0700
+++ b/src/share/classes/java/lang/invoke/MethodHandleNatives.java	Mon Jul 22 15:47:32 2013 -0700
@@ -492,6 +492,7 @@
             return defc == java.lang.ClassLoader.class;
         case "registerAsParallelCapable":
             return defc == java.lang.ClassLoader.class;
+        case "getInvocationHandler":
         case "getProxyClass":
         case "newProxyInstance":
             return defc == java.lang.reflect.Proxy.class;
--- a/src/share/classes/java/lang/invoke/MethodHandles.java	Mon Jul 22 12:21:16 2013 -0700
+++ b/src/share/classes/java/lang/invoke/MethodHandles.java	Mon Jul 22 15:47:32 2013 -0700
@@ -426,7 +426,7 @@
 
         Lookup(Class<?> lookupClass) {
             this(lookupClass, ALL_MODES);
-            checkUnprivilegedlookupClass(lookupClass);
+            checkUnprivilegedlookupClass(lookupClass, ALL_MODES);
         }
 
         private Lookup(Class<?> lookupClass, int allowedModes) {
@@ -480,7 +480,7 @@
                 // No permissions.
                 newModes = 0;
             }
-            checkUnprivilegedlookupClass(requestedLookupClass);
+            checkUnprivilegedlookupClass(requestedLookupClass, newModes);
             return new Lookup(requestedLookupClass, newModes);
         }
 
@@ -496,10 +496,19 @@
         /** Package-private version of lookup which is trusted. */
         static final Lookup IMPL_LOOKUP = new Lookup(Object.class, TRUSTED);
 
-        private static void checkUnprivilegedlookupClass(Class<?> lookupClass) {
+        private static void checkUnprivilegedlookupClass(Class<?> lookupClass, int allowedModes) {
             String name = lookupClass.getName();
             if (name.startsWith("java.lang.invoke."))
                 throw newIllegalArgumentException("illegal lookupClass: "+lookupClass);
+
+            // For caller-sensitive MethodHandles.lookup()
+            // disallow lookup more restricted packages
+            if (allowedModes == ALL_MODES && lookupClass.getClassLoader() == null) {
+                if (name.startsWith("java.") ||
+                        (name.startsWith("sun.") && !name.startsWith("sun.invoke."))) {
+                    throw newIllegalArgumentException("illegal lookupClass: " + lookupClass);
+                }
+            }
         }
 
         /**
--- a/src/share/classes/java/lang/reflect/Proxy.java	Mon Jul 22 12:21:16 2013 -0700
+++ b/src/share/classes/java/lang/reflect/Proxy.java	Mon Jul 22 15:47:32 2013 -0700
@@ -788,6 +788,7 @@
      * @throws  IllegalArgumentException if the argument is not a
      *          proxy instance
      */
+    @CallerSensitive
     public static InvocationHandler getInvocationHandler(Object proxy)
         throws IllegalArgumentException
     {
@@ -798,8 +799,19 @@
             throw new IllegalArgumentException("not a proxy instance");
         }
 
-        Proxy p = (Proxy) proxy;
-        return p.h;
+        final Proxy p = (Proxy) proxy;
+        final InvocationHandler ih = p.h;
+        if (System.getSecurityManager() != null) {
+            Class<?> ihClass = ih.getClass();
+            Class<?> caller = Reflection.getCallerClass();
+            if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(),
+                                                    ihClass.getClassLoader()))
+            {
+                ReflectUtil.checkPackageAccess(ihClass);
+            }
+        }
+
+        return ih;
     }
 
     private static native Class defineClass0(ClassLoader loader, String name,
--- a/src/share/classes/java/util/TimeZone.java	Mon Jul 22 12:21:16 2013 -0700
+++ b/src/share/classes/java/util/TimeZone.java	Mon Jul 22 15:47:32 2013 -0700
@@ -165,6 +165,11 @@
     // Proclaim serialization compatibility with JDK 1.1
     static final long serialVersionUID = 3581463369166924961L;
 
+    // TimeZone.setDefault maintains the compatible behavior of the AppContext-based
+    // default setting for untrusted code if allowSetDefault is true.
+    private static final boolean allowSetDefault = AccessController.doPrivileged(
+        new sun.security.action.GetPropertyAction("jdk.util.TimeZone.allowSetDefault")) != null;
+
     /**
      * Gets the time zone offset, for current date, modified in case of
      * daylight savings. This is the offset to add to UTC to get local time.
@@ -689,6 +694,9 @@
                 sm.checkPermission(new PropertyPermission
                                    ("user.timezone", "write"));
             } catch (SecurityException e) {
+                if (!allowSetDefault) {
+                    throw e;
+                }
                 hasPermission = false;
             }
         }
@@ -719,6 +727,7 @@
      * Returns the default TimeZone in an AppContext if any AppContext
      * has ever used. null is returned if any AppContext hasn't been
      * used or if the AppContext doesn't have the default TimeZone.
+     * null is also returned if allowSetDefault is false.
      *
      * Note that javaAWTAccess may be null if sun.awt.AppContext class hasn't
      * been loaded. If so, it implies that AWTSecurityManager is not our
@@ -726,18 +735,20 @@
      * This works around a build time issue.
      */
     private static TimeZone getDefaultInAppContext() {
-        // JavaAWTAccess provides access implementation-private methods without using reflection.
-        JavaAWTAccess javaAWTAccess = SharedSecrets.getJavaAWTAccess();
-        if (javaAWTAccess == null) {
-            return mainAppContextDefault;
-        } else {
-            if (!javaAWTAccess.isDisposed()) {
-                TimeZone tz = (TimeZone)
-                    javaAWTAccess.get(TimeZone.class);
-                if (tz == null && javaAWTAccess.isMainAppContext()) {
-                    return mainAppContextDefault;
-                } else {
-                    return tz;
+        if (allowSetDefault) {
+            // JavaAWTAccess provides access implementation-private methods without using reflection.
+            JavaAWTAccess javaAWTAccess = SharedSecrets.getJavaAWTAccess();
+            if (javaAWTAccess == null) {
+                return mainAppContextDefault;
+            } else {
+                if (!javaAWTAccess.isDisposed()) {
+                    TimeZone tz = (TimeZone)
+                        javaAWTAccess.get(TimeZone.class);
+                    if (tz == null && javaAWTAccess.isMainAppContext()) {
+                        return mainAppContextDefault;
+                    } else {
+                        return tz;
+                    }
                 }
             }
         }
@@ -745,9 +756,9 @@
     }
 
     /**
-     * Sets the default TimeZone in the AppContext to the given
-     * tz. null is handled special: do nothing if any AppContext
-     * hasn't been used, remove the default TimeZone in the
+     * Sets the default TimeZone in the AppContext to the given tz if
+     * allowSetDefault is true. null is handled special: do nothing if any
+     * AppContext hasn't been used, remove the default TimeZone in the
      * AppContext otherwise.
      *
      * Note that javaAWTAccess may be null if sun.awt.AppContext class hasn't
@@ -756,15 +767,17 @@
      * This works around a build time issue.
      */
     private static void setDefaultInAppContext(TimeZone tz) {
-        // JavaAWTAccess provides access implementation-private methods without using reflection.
-        JavaAWTAccess javaAWTAccess = SharedSecrets.getJavaAWTAccess();
-        if (javaAWTAccess == null) {
-            mainAppContextDefault = tz;
-        } else {
-            if (!javaAWTAccess.isDisposed()) {
-                javaAWTAccess.put(TimeZone.class, tz);
-                if (javaAWTAccess.isMainAppContext()) {
-                    mainAppContextDefault = null;
+        if (allowSetDefault) {
+            // JavaAWTAccess provides access implementation-private methods without using reflection.
+            JavaAWTAccess javaAWTAccess = SharedSecrets.getJavaAWTAccess();
+            if (javaAWTAccess == null) {
+                mainAppContextDefault = tz;
+            } else {
+                if (!javaAWTAccess.isDisposed()) {
+                    javaAWTAccess.put(TimeZone.class, tz);
+                    if (javaAWTAccess.isMainAppContext()) {
+                        mainAppContextDefault = null;
+                    }
                 }
             }
         }
--- a/src/share/classes/javax/management/remote/NotificationResult.java	Mon Jul 22 12:21:16 2013 -0700
+++ b/src/share/classes/javax/management/remote/NotificationResult.java	Mon Jul 22 15:47:32 2013 -0700
@@ -132,16 +132,17 @@
     }
 
     private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
-        ObjectInputStream.GetField gf = ois.readFields();
-        TargetedNotification[] tNotifs = (TargetedNotification[])gf.get("targetedNotifications", null);
-        long snStart = gf.get("earliestSequenceNumber", -1L);
-        long snNext = gf.get("nextSequenceNumber", -1L);
+        ois.defaultReadObject();
         try {
-            validate(tNotifs, snStart, snNext);
+            validate(
+                this.targetedNotifications,
+                this.earliestSequenceNumber,
+                this.nextSequenceNumber
+            );
 
-            this.targetedNotifications = tNotifs.length == 0 ? tNotifs : tNotifs.clone();
-            this.earliestSequenceNumber = snStart;
-            this.nextSequenceNumber = snNext;
+            this.targetedNotifications = this.targetedNotifications.length == 0 ?
+                                            this.targetedNotifications :
+                                            this.targetedNotifications.clone();
         } catch (IllegalArgumentException e) {
             throw new InvalidObjectException(e.getMessage());
         }
--- a/src/share/classes/javax/management/remote/TargetedNotification.java	Mon Jul 22 12:21:16 2013 -0700
+++ b/src/share/classes/javax/management/remote/TargetedNotification.java	Mon Jul 22 15:47:32 2013 -0700
@@ -132,13 +132,9 @@
 //     }
 
     private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
-        ObjectInputStream.GetField gf = ois.readFields();
-        Notification notification = (Notification)gf.get("notif", null);
-        Integer listenerId = (Integer)gf.get("id", null);
+        ois.defaultReadObject();
         try {
-            validate(notification, listenerId);
-            this.notif = notification;
-            this.id = listenerId;
+            validate(this.notif, this.id);
         } catch (IllegalArgumentException e) {
             throw new InvalidObjectException(e.getMessage());
         }
--- a/src/share/classes/sun/font/GlyphLayout.java	Mon Jul 22 12:21:16 2013 -0700
+++ b/src/share/classes/sun/font/GlyphLayout.java	Mon Jul 22 15:47:32 2013 -0700
@@ -468,9 +468,10 @@
                         _gvdata.grow();
                     }
                 }
-                if (_gvdata._count < 0) {
-                    break;
-                }
+            }
+            // Break out of the outer for loop if layout fails.
+            if (_gvdata._count < 0) {
+                break;
             }
         }
 
--- a/src/share/classes/sun/reflect/misc/ReflectUtil.java	Mon Jul 22 12:21:16 2013 -0700
+++ b/src/share/classes/sun/reflect/misc/ReflectUtil.java	Mon Jul 22 15:47:32 2013 -0700
@@ -26,8 +26,10 @@
 
 package sun.reflect.misc;
 
+import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.lang.reflect.Proxy;
+import java.util.Arrays;
 import sun.reflect.Reflection;
 
 public final class ReflectUtil {
@@ -249,4 +251,50 @@
         String pkg = (i != -1) ? name.substring(0, i) : "";
         return Proxy.isProxyClass(cls) && !pkg.equals(PROXY_PACKAGE);
     }
+
+    /**
+     * Check if the given method is a method declared in the proxy interface
+     * implemented by the given proxy instance.
+     *
+     * @param proxy a proxy instance
+     * @param method an interface method dispatched to a InvocationHandler
+     *
+     * @throws IllegalArgumentException if the given proxy or method is invalid.
+     */
+    public static void checkProxyMethod(Object proxy, Method method) {
+        // check if it is a valid proxy instance
+        if (proxy == null || !Proxy.isProxyClass(proxy.getClass())) {
+            throw new IllegalArgumentException("Not a Proxy instance");
 }
+        if (Modifier.isStatic(method.getModifiers())) {
+            throw new IllegalArgumentException("Can't handle static method");
+        }
+
+        Class<?> c = method.getDeclaringClass();
+        if (c == Object.class) {
+            String name = method.getName();
+            if (name.equals("hashCode") || name.equals("equals") || name.equals("toString")) {
+                return;
+            }
+        }
+
+        if (isSuperInterface(proxy.getClass(), c)) {
+            return;
+        }
+
+        // disallow any method not declared in one of the proxy intefaces
+        throw new IllegalArgumentException("Can't handle: " + method);
+    }
+
+    private static boolean isSuperInterface(Class<?> c, Class<?> intf) {
+        for (Class<?> i : c.getInterfaces()) {
+            if (i == intf) {
+                return true;
+            }
+            if (isSuperInterface(i, intf)) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
--- a/src/share/demo/jvmti/hprof/hprof_class.c	Mon Jul 22 12:21:16 2013 -0700
+++ b/src/share/demo/jvmti/hprof/hprof_class.c	Mon Jul 22 15:47:32 2013 -0700
@@ -527,7 +527,12 @@
     jmethodID  method;
 
     info = get_info(index);
-    HPROF_ASSERT(mnum < info->method_count);
+    if (mnum >= info->method_count) {
+        jclass newExcCls = (*env)->FindClass(env, "java/lang/IllegalArgumentException");
+        (*env)->ThrowNew(env, newExcCls, "Illegal mnum");
+
+        return NULL;
+    }
     method = info->method[mnum].method_id;
     if ( method == NULL ) {
         char * name;
@@ -535,7 +540,12 @@
         jclass clazz;
 
         name  = (char *)string_get(info->method[mnum].name_index);
-        HPROF_ASSERT(name!=NULL);
+        if (name==NULL) {
+            jclass newExcCls = (*env)->FindClass(env, "java/lang/IllegalArgumentException");
+            (*env)->ThrowNew(env, newExcCls, "Name not found");
+
+            return NULL;
+        }
         sig   = (char *)string_get(info->method[mnum].sig_index);
         HPROF_ASSERT(sig!=NULL);
         clazz = class_get_class(env, index);
--- a/src/share/demo/jvmti/hprof/hprof_event.c	Mon Jul 22 12:21:16 2013 -0700
+++ b/src/share/demo/jvmti/hprof/hprof_event.c	Mon Jul 22 15:47:32 2013 -0700
@@ -195,7 +195,12 @@
 
     HPROF_ASSERT(env!=NULL);
     HPROF_ASSERT(thread!=NULL);
-    HPROF_ASSERT(cnum!=0 && cnum!=gdata->tracker_cnum);
+    if (cnum == 0 || cnum == gdata->tracker_cnum) {
+        jclass newExcCls = (*env)->FindClass(env, "java/lang/IllegalArgumentException");
+        (*env)->ThrowNew(env, newExcCls, "Illegal cnum.");
+
+        return;
+    }
 
     /* Prevent recursion into any BCI function for this thread (pstatus). */
     if ( tls_get_tracker_status(env, thread, JNI_FALSE,
@@ -204,8 +209,10 @@
 
         (*pstatus) = 1;
         method      = class_get_methodID(env, cnum, mnum);
-        HPROF_ASSERT(method!=NULL);
-        tls_push_method(tls_index, method);
+        if (method != NULL) {
+            tls_push_method(tls_index, method);
+        }
+
         (*pstatus) = 0;
     }
 }
@@ -248,7 +255,13 @@
 
     HPROF_ASSERT(env!=NULL);
     HPROF_ASSERT(thread!=NULL);
-    HPROF_ASSERT(cnum!=0 && cnum!=gdata->tracker_cnum);
+
+    if (cnum == 0 || cnum == gdata->tracker_cnum) {
+        jclass newExcCls = (*env)->FindClass(env, "java/lang/IllegalArgumentException");
+        (*env)->ThrowNew(env, newExcCls, "Illegal cnum.");
+
+        return;
+    }
 
     /* Prevent recursion into any BCI function for this thread (pstatus). */
     if ( tls_get_tracker_status(env, thread, JNI_FALSE,
@@ -257,8 +270,10 @@
 
         (*pstatus) = 1;
         method      = class_get_methodID(env, cnum, mnum);
-        HPROF_ASSERT(method!=NULL);
-        tls_pop_method(tls_index, thread, method);
+        if (method != NULL) {
+            tls_pop_method(tls_index, thread, method);
+        }
+
         (*pstatus) = 0;
     }
 }
--- a/src/share/native/sun/font/layout/SunLayoutEngine.cpp	Mon Jul 22 12:21:16 2013 -0700
+++ b/src/share/native/sun/font/layout/SunLayoutEngine.cpp	Mon Jul 22 15:47:32 2013 -0700
@@ -104,6 +104,10 @@
 
 int putGV(JNIEnv* env, jint gmask, jint baseIndex, jobject gvdata, const LayoutEngine* engine, int glyphCount) {
     int count = env->GetIntField(gvdata, gvdCountFID);
+    if (count < 0) {
+      JNU_ThrowInternalError(env, "count negative");
+      return 0;
+    }
 
     jarray glyphArray = (jarray)env->GetObjectField(gvdata, gvdGlyphsFID);
     if (IS_NULL(glyphArray)) {
--- a/test/javax/management/remote/mandatory/loading/MissingClassTest.java	Mon Jul 22 12:21:16 2013 -0700
+++ b/test/javax/management/remote/mandatory/loading/MissingClassTest.java	Mon Jul 22 15:47:32 2013 -0700
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 4915825 4921009 4934965 4977469
+ * @bug 4915825 4921009 4934965 4977469 8019584
  * @summary Tests behavior when client or server gets object of unknown class
  * @author Eamonn McManus
  * @run clean MissingClassTest SingleClassLoader