1
0
java-1_8_0-openjdk/8197925.patch

80 lines
3.4 KiB
Diff

--- icedtea-3.8.0/openjdk/jdk/src/share/classes/java/io/ObjectStreamClass.java 2018-09-18 09:59:41.495643758 +0200
+++ icedtea-3.8.0/openjdk/jdk/src/share/classes/java/io/ObjectStreamClass.java 2018-09-18 09:59:57.923733188 +0200
@@ -86,6 +86,18 @@
private static final ObjectStreamField[] serialPersistentFields =
NO_FIELDS;
+ /** true if deserialization constructor checking is disabled */
+ private static boolean disableSerialConstructorChecks =
+ AccessController.doPrivileged(
+ new PrivilegedAction<Boolean>() {
+ public Boolean run() {
+ String prop = "jdk.disableSerialConstructorChecks";
+ return "true".equals(System.getProperty(prop))
+ ? Boolean.TRUE : Boolean.FALSE;
+ }
+ }
+ ).booleanValue();
+
/** reflection factory for obtaining serialization constructors */
private static final ReflectionFactory reflFactory =
AccessController.doPrivileged(
@@ -1497,6 +1509,46 @@
}
/**
+ * Given a class, determines whether its superclass has
+ * any constructors that are accessible from the class.
+ * This is a special purpose method intended to do access
+ * checking for a serializable class and its superclasses
+ * up to, but not including, the first non-serializable
+ * superclass. This also implies that the superclass is
+ * always non-null, because a serializable class must be a
+ * class (not an interface) and Object is not serializable.
+ *
+ * @param cl the class from which access is checked
+ * @return whether the superclass has a constructor accessible from cl
+ */
+ private static boolean superHasAccessibleConstructor(Class<?> cl) {
+ Class<?> superCl = cl.getSuperclass();
+ assert Serializable.class.isAssignableFrom(cl);
+ assert superCl != null;
+ if (packageEquals(cl, superCl)) {
+ // accessible if any non-private constructor is found
+ for (Constructor<?> ctor : superCl.getDeclaredConstructors()) {
+ if ((ctor.getModifiers() & Modifier.PRIVATE) == 0) {
+ return true;
+ }
+ }
+ return false;
+ } else {
+ // accessible if the parent is public and any constructor
+ // is protected or public
+ if ((superCl.getModifiers() & Modifier.PUBLIC) == 0) {
+ return false;
+ }
+ for (Constructor<?> ctor : superCl.getDeclaredConstructors()) {
+ if ((ctor.getModifiers() & (Modifier.PROTECTED | Modifier.PUBLIC)) != 0) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ /**
* Returns subclass-accessible no-arg constructor of first non-serializable
* superclass, or null if none found. Access checks are disabled on the
* returned constructor (if any).
@@ -1504,7 +1556,9 @@
private static Constructor<?> getSerializableConstructor(Class<?> cl) {
Class<?> initCl = cl;
while (Serializable.class.isAssignableFrom(initCl)) {
- if ((initCl = initCl.getSuperclass()) == null) {
+ Class<?> prev = initCl;
+ if ((initCl = initCl.getSuperclass()) == null ||
+ (!disableSerialConstructorChecks && !superHasAccessibleConstructor(prev))) {
return null;
}
}