changeset 10000:963d6ac6635a jdk7u281-b01 jdk7u281-ga jdk7u285-b00

8236862: Enhance support of Proxy class 8249927: Specify limits of jdk.serialProxyInterfaceLimit Reviewed-by: rriggs, coffeys, yan, dcherepanov
author bae
date Fri, 07 Aug 2020 11:02:19 +0000
parents c032da475287
children 7261c7ebe02e
files src/share/classes/java/io/ObjectInputStream.java
diffstat 1 files changed, 41 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/io/ObjectInputStream.java	Mon Jun 22 14:30:37 2020 +0100
+++ b/src/share/classes/java/io/ObjectInputStream.java	Fri Aug 07 11:02:19 2020 +0000
@@ -28,6 +28,7 @@
 import java.io.ObjectStreamClass.WeakClassKey;
 import java.lang.ref.ReferenceQueue;
 import java.lang.reflect.Array;
+import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Modifier;
 import java.lang.reflect.Proxy;
 import java.security.AccessControlContext;
@@ -50,6 +51,7 @@
 import sun.reflect.misc.ReflectUtil;
 import sun.util.logging.PlatformLogger;
 import sun.security.action.GetBooleanAction;
+import sun.security.action.GetIntegerAction;
 
 /**
  * An ObjectInputStream deserializes primitive data and objects previously
@@ -252,6 +254,15 @@
         static final boolean SET_FILTER_AFTER_READ =
                 privilegedGetProperty("jdk.serialSetFilterAfterRead");
 
+        /**
+         * Property to override the implementation limit on the number
+         * of interfaces allowed for Proxies. The property value is clamped to 0..65535.
+         * The maximum number of interfaces allowed for a proxy is limited to 65535 by
+         * {@link java.lang.reflect.Proxy#newProxyInstance(ClassLoader, Class[], InvocationHandler)}
+         */
+        static final int PROXY_INTERFACE_LIMIT = Math.max(0, Math.min(65535,
+                privilegedGetIntegerProperty("jdk.serialProxyInterfaceLimit", 65535)));
+
         private static boolean privilegedGetProperty(String theProp) {
             if (System.getSecurityManager() == null) {
                 return Boolean.getBoolean(theProp);
@@ -260,6 +271,15 @@
                         new GetBooleanAction(theProp));
             }
         }
+
+        private static int privilegedGetIntegerProperty(String theProp, int defaultValue) {
+            if (System.getSecurityManager() == null) {
+                return Integer.getInteger(theProp, defaultValue);
+            } else {
+                return AccessController.doPrivileged(
+                        new GetIntegerAction(theProp, defaultValue));
+            }
+        }
     }
 
     static {
@@ -1862,14 +1882,23 @@
 
         int numIfaces = bin.readInt();
         if (numIfaces > 65535) {
-            throw new InvalidObjectException("interface limit exceeded: "
-                    + numIfaces);
+            // Report specification limit exceeded
+            throw new InvalidObjectException("interface limit exceeded: " +
+                    numIfaces +
+                    ", limit: " + Caches.PROXY_INTERFACE_LIMIT);
         }
         String[] ifaces = new String[numIfaces];
         for (int i = 0; i < numIfaces; i++) {
             ifaces[i] = bin.readUTF();
         }
 
+        // Recheck against implementation limit and throw with interface names
+        if (numIfaces > Caches.PROXY_INTERFACE_LIMIT) {
+            throw new InvalidObjectException("interface limit exceeded: " +
+                    numIfaces +
+                    ", limit: " + Caches.PROXY_INTERFACE_LIMIT +
+                    "; " + Arrays.toString(ifaces));
+        }
         Class cl = null;
         ClassNotFoundException resolveEx = null;
         bin.setBlockDataMode(true);
@@ -1892,6 +1921,11 @@
             }
         } catch (ClassNotFoundException ex) {
             resolveEx = ex;
+        } catch (OutOfMemoryError memerr) {
+            IOException ex = new InvalidObjectException("Proxy interface limit exceeded: " +
+                    Arrays.toString(ifaces));
+            ex.initCause(memerr);
+            throw ex;
         }
 
         // Call filterCheck on the class before reading anything else
@@ -1903,6 +1937,11 @@
             totalObjectRefs++;
             depth++;
             desc.initProxy(cl, resolveEx, readClassDesc(false));
+        } catch (OutOfMemoryError memerr) {
+            IOException ex = new InvalidObjectException("Proxy interface limit exceeded: " +
+                    Arrays.toString(ifaces));
+            ex.initCause(memerr);
+            throw ex;
         } finally {
             depth--;
         }